summaryrefslogtreecommitdiff
path: root/0042-DFE-Fix-bugs.patch
diff options
context:
space:
mode:
Diffstat (limited to '0042-DFE-Fix-bugs.patch')
-rw-r--r--0042-DFE-Fix-bugs.patch665
1 files changed, 665 insertions, 0 deletions
diff --git a/0042-DFE-Fix-bugs.patch b/0042-DFE-Fix-bugs.patch
new file mode 100644
index 0000000..5801558
--- /dev/null
+++ b/0042-DFE-Fix-bugs.patch
@@ -0,0 +1,665 @@
+From f8308a2b440efe124cd6ff59924f135e85e53888 Mon Sep 17 00:00:00 2001
+From: Mingchuan Wu <wumingchuan1992@foxmail.com>
+Date: Sat, 18 Jun 2022 17:51:04 +0800
+Subject: [PATCH 08/12] [DFE] Fix bugs
+
+Fix bugs:
+1. Fixed a bug in check replace type.
+2. Use new to update field access for ref.
+3. We now replace the dead fields in stmt by creating a new ssa.
+4. The replaced type is no longer optimized in NORMAL mode.
+
+Also we added 5 dejaGNU test cases.
+---
+ gcc/ipa-struct-reorg/ipa-struct-reorg.c | 77 ++++++---
+ gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c | 56 ++++++
+ gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c | 162 ++++++++++++++++++
+ gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c | 126 ++++++++++++++
+ .../gcc.dg/struct/dfe_extr_tcp_usrreq.c | 58 +++++++
+ .../gcc.dg/struct/dfe_extr_ui_main.c | 61 +++++++
+ 6 files changed, 516 insertions(+), 24 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
+ create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
+ create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
+ create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
+ create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
+
+diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+index 2fa560239..00dc4bf1d 100644
+--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
++++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+@@ -252,6 +252,7 @@ enum struct_layout_opt_level
+
+ static bool is_result_of_mult (tree arg, tree *num, tree struct_size);
+ bool isptrptr (tree type);
++void get_base (tree &base, tree expr);
+
+ srmode current_mode;
+
+@@ -631,7 +632,15 @@ srtype::analyze (void)
+ into 2 different structures. In future we intend to add profile
+ info and/or static heuristics to differentiate splitting process. */
+ if (fields.length () == 2)
+- fields[1]->clusternum = 1;
++ {
++ for (hash_map<tree, tree>::iterator it = replace_type_map.begin ();
++ it != replace_type_map.end (); ++it)
++ {
++ if (types_compatible_p ((*it).second, this->type))
++ return;
++ }
++ fields[1]->clusternum = 1;
++ }
+
+ /* Otherwise we do nothing. */
+ if (fields.length () >= 3)
+@@ -3278,12 +3287,33 @@ ipa_struct_reorg::find_vars (gimple *stmt)
+ /* Update field_access in srfield. */
+
+ static void
+-update_field_access (tree record, tree field, unsigned access, void *data)
++update_field_access (tree node, tree op, unsigned access, void *data)
+ {
+- srtype *this_srtype = ((ipa_struct_reorg *)data)->find_type (record);
++ HOST_WIDE_INT offset = 0;
++ switch (TREE_CODE (op))
++ {
++ case COMPONENT_REF:
++ {
++ offset = int_byte_position (TREE_OPERAND (op, 1));
++ break;
++ }
++ case MEM_REF:
++ {
++ offset = tree_to_uhwi (TREE_OPERAND (op, 1));
++ break;
++ }
++ default:
++ return;
++ }
++ tree base = node;
++ get_base (base, node);
++ srdecl *this_srdecl = ((ipa_struct_reorg *)data)->find_decl (base);
++ if (this_srdecl == NULL)
++ return;
++ srtype *this_srtype = this_srdecl->type;
+ if (this_srtype == NULL)
+ return;
+- srfield *this_srfield = this_srtype->find_field (int_byte_position (field));
++ srfield *this_srfield = this_srtype->find_field (offset);
+ if (this_srfield == NULL)
+ return;
+
+@@ -3291,9 +3321,9 @@ update_field_access (tree record, tree field, unsigned access, void *data)
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "record field access %d:", access);
+- print_generic_expr (dump_file, record);
++ print_generic_expr (dump_file, this_srtype->type);
+ fprintf (dump_file, " field:");
+- print_generic_expr (dump_file, field);
++ print_generic_expr (dump_file, this_srfield->fielddecl);
+ fprintf (dump_file, "\n");
+ }
+ return;
+@@ -3302,15 +3332,10 @@ update_field_access (tree record, tree field, unsigned access, void *data)
+ /* A callback for walk_stmt_load_store_ops to visit store. */
+
+ static bool
+-find_field_p_store (gimple *, tree node, tree op, void *data)
++find_field_p_store (gimple *stmt ATTRIBUTE_UNUSED,
++ tree node, tree op, void *data)
+ {
+- if (TREE_CODE (op) != COMPONENT_REF)
+- return false;
+- tree node_type = TREE_TYPE (node);
+- if (!handled_type (node_type))
+- return false;
+-
+- update_field_access (node_type, TREE_OPERAND (op, 1), WRITE_FIELD, data);
++ update_field_access (node, op, WRITE_FIELD, data);
+
+ return false;
+ }
+@@ -3318,15 +3343,10 @@ find_field_p_store (gimple *, tree node, tree op, void *data)
+ /* A callback for walk_stmt_load_store_ops to visit load. */
+
+ static bool
+-find_field_p_load (gimple *, tree node, tree op, void *data)
++find_field_p_load (gimple *stmt ATTRIBUTE_UNUSED,
++ tree node, tree op, void *data)
+ {
+- if (TREE_CODE (op) != COMPONENT_REF)
+- return false;
+- tree node_type = TREE_TYPE (node);
+- if (!handled_type (node_type))
+- return false;
+-
+- update_field_access (node_type, TREE_OPERAND (op, 1), READ_FIELD, data);
++ update_field_access (node, op, READ_FIELD, data);
+
+ return false;
+ }
+@@ -4629,7 +4649,7 @@ ipa_struct_reorg::check_other_side (srdecl *decl, tree other, gimple *stmt, vec<
+
+ return;
+ }
+- if (!is_replace_type (t1->type, type->type))
++ if (!is_replace_type (inner_type (t), type->type))
+ {
+ if (t1)
+ t1->mark_escape (escape_cast_another_ptr, stmt);
+@@ -5898,7 +5918,16 @@ ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi)
+ fprintf (dump_file, "\n rewriting statement (remove): \n");
+ print_gimple_stmt (dump_file, stmt, 0);
+ }
+- return true;
++ /* Replace the dead field in stmt by creating a dummy ssa. */
++ tree dummy_ssa = make_ssa_name (TREE_TYPE (gimple_assign_lhs (stmt)));
++ gimple_assign_set_lhs (stmt, dummy_ssa);
++ update_stmt (stmt);
++ if (dump_file && (dump_flags & TDF_DETAILS))
++ {
++ fprintf (dump_file, "To: \n");
++ print_gimple_stmt (dump_file, stmt, 0);
++ }
++ return false;
+ }
+
+ if (gimple_clobber_p (stmt))
+diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
+new file mode 100644
+index 000000000..13a226ee8
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
+@@ -0,0 +1,56 @@
++/* { dg-do compile} */
++
++#define NULL ((void*)0)
++typedef unsigned long size_t;
++typedef long intptr_t;
++typedef unsigned long uintptr_t;
++typedef long scalar_t__;
++typedef int bool;
++#define false 0
++#define true 1
++
++typedef struct TYPE_4__ TYPE_2__;
++typedef struct TYPE_3__ TYPE_1__;
++
++typedef int uint8_t;
++typedef int uint16_t;
++
++struct TYPE_4__
++{
++ size_t cpu_id;
++};
++
++struct TYPE_3__
++{
++ int cpuc_dtrace_flags;
++};
++
++TYPE_2__ *CPU;
++volatile int CPU_DTRACE_FAULT;
++TYPE_1__ *cpu_core;
++scalar_t__ dtrace_load8 (uintptr_t);
++
++__attribute__((used)) static int
++dtrace_bcmp (const void *s1, const void *s2, size_t len)
++{
++ volatile uint16_t *flags;
++ flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
++ if (s1 == s2)
++ return (0);
++ if (s1 == NULL || s2 == NULL)
++ return (1);
++ if (s1 != s2 && len != 0)
++ {
++ const uint8_t *ps1 = s1;
++ const uint8_t *ps2 = s2;
++ do
++ {
++ if (dtrace_load8 ((uintptr_t)ps1++) != *ps2++)
++ return (1);
++ }
++ while (--len != 0 && !(*flags & CPU_DTRACE_FAULT));
++ }
++ return (0);
++}
++
++/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
+diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
+new file mode 100644
+index 000000000..1fff2cb9d
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
+@@ -0,0 +1,162 @@
++/* { dg-do compile} */
++
++#define NULL ((void*)0)
++typedef unsigned long size_t;
++typedef long intptr_t;
++typedef unsigned long uintptr_t;
++typedef long scalar_t__;
++typedef int bool;
++#define false 0
++#define true 1
++
++struct mrb_context
++{
++ size_t stack;
++ size_t stbase;
++ size_t stend;
++ size_t eidx;
++ int *ci;
++ int *cibase;
++ int status;
++};
++
++struct RObject
++{
++ int dummy;
++};
++
++struct RHash
++{
++ int dummy;
++};
++
++struct RFiber
++{
++ struct mrb_context *cxt;
++};
++
++struct RClass
++{
++ int dummy;
++};
++
++struct RBasic
++{
++ int tt;
++};
++
++struct RArray
++{
++ int dummy;
++};
++
++typedef int mrb_state;
++typedef int mrb_gc;
++typedef int mrb_callinfo;
++size_t ARY_LEN (struct RArray *);
++size_t MRB_ENV_STACK_LEN (struct RBasic *);
++int MRB_FIBER_TERMINATED;
++
++#define MRB_TT_ARRAY 140
++#define MRB_TT_CLASS 139
++#define MRB_TT_DATA 138
++#define MRB_TT_ENV 137
++#define MRB_TT_EXCEPTION 136
++#define MRB_TT_FIBER 135
++#define MRB_TT_HASH 134
++#define MRB_TT_ICLASS 133
++#define MRB_TT_MODULE 132
++#define MRB_TT_OBJECT 131
++#define MRB_TT_PROC 130
++#define MRB_TT_RANGE 129
++#define MRB_TT_SCLASS 128
++
++size_t ci_nregs (int *);
++int gc_mark_children (int *, int *, struct RBasic *);
++size_t mrb_gc_mark_hash_size (int *, struct RHash *);
++size_t mrb_gc_mark_iv_size (int *, struct RObject *);
++size_t mrb_gc_mark_mt_size (int *, struct RClass *);
++
++__attribute__((used)) static size_t
++gc_gray_mark (mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
++{
++ size_t children = 0;
++ gc_mark_children (mrb, gc, obj);
++ switch (obj->tt)
++ {
++ case MRB_TT_ICLASS:
++ children++;
++ break;
++
++ case MRB_TT_CLASS:
++ case MRB_TT_SCLASS:
++ case MRB_TT_MODULE:
++ {
++ struct RClass *c = (struct RClass *)obj;
++ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
++ children += mrb_gc_mark_mt_size (mrb, c);
++ children ++;
++ }
++ break;
++
++ case MRB_TT_OBJECT:
++ case MRB_TT_DATA:
++ case MRB_TT_EXCEPTION:
++ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
++ break;
++
++ case MRB_TT_ENV:
++ children += MRB_ENV_STACK_LEN (obj);
++ break;
++
++ case MRB_TT_FIBER:
++ {
++ struct mrb_context *c = ((struct RFiber *)obj)->cxt;
++ size_t i;
++ mrb_callinfo *ci;
++ if (!c || c->status == MRB_FIBER_TERMINATED)
++ break;
++
++ i = c->stack - c->stbase;
++ if (c->ci)
++ {
++ i += ci_nregs (c->ci);
++ }
++ if (c->stbase + i > c->stend)
++ i = c->stend - c->stbase;
++
++ children += i;
++ children += c->eidx;
++ if (c->cibase)
++ {
++ for (i = 0, ci = c->cibase; ci <= c->ci; i++, ci++)
++ ;
++ }
++ children += i;
++ }
++ break;
++
++ case MRB_TT_ARRAY:
++ {
++ struct RArray *a = (struct RArray *)obj;
++ children += ARY_LEN (a);
++ }
++ break;
++
++ case MRB_TT_HASH:
++ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
++ children += mrb_gc_mark_hash_size (mrb, (struct RHash *)obj);
++ break;
++
++ case MRB_TT_PROC:
++ case MRB_TT_RANGE:
++ children += 2;
++ break;
++ default:
++ break;
++ }
++
++ return children;
++}
++
++/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
+diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
+new file mode 100644
+index 000000000..0f577667c
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
+@@ -0,0 +1,126 @@
++/* { dg-do compile} */
++
++#define NULL ((void*)0)
++typedef unsigned long size_t;
++typedef long intptr_t;
++typedef unsigned long uintptr_t;
++typedef long scalar_t__;
++typedef int bool;
++#define false 0
++#define true 1
++
++typedef struct TYPE_6__ TYPE_3__;
++typedef struct TYPE_5__ TYPE_2__;
++typedef struct TYPE_4__ TYPE_1__;
++
++struct io_accel2_cmd
++{
++ int dummy;
++};
++
++struct hpsa_tmf_struct
++{
++ int it_nexus;
++};
++
++struct hpsa_scsi_dev_t
++{
++ int nphysical_disks;
++ int ioaccel_handle;
++ struct hpsa_scsi_dev_t **phys_disk;
++};
++
++struct ctlr_info
++{
++ TYPE_3__ *pdev;
++ struct io_accel2_cmd *ioaccel2_cmd_pool;
++};
++struct TYPE_4__
++{
++ int LunAddrBytes;
++};
++
++struct TYPE_5__
++{
++ TYPE_1__ LUN;
++};
++
++struct CommandList
++{
++ size_t cmdindex;
++ int cmd_type;
++ struct hpsa_scsi_dev_t *phys_disk;
++ TYPE_2__ Header;
++};
++
++struct TYPE_6__
++{
++ int dev;
++};
++
++int BUG ();
++#define CMD_IOACCEL1 132
++#define CMD_IOACCEL2 131
++#define CMD_IOCTL_PEND 130
++#define CMD_SCSI 129
++#define IOACCEL2_TMF 128
++int dev_err (int *, char *, int);
++scalar_t__ hpsa_is_cmd_idle (struct CommandList *);
++int le32_to_cpu (int);
++int test_memcmp (unsigned char *, int *, int);
++
++__attribute__((used)) static bool
++hpsa_cmd_dev_match (struct ctlr_info *h, struct CommandList *c,
++ struct hpsa_scsi_dev_t *dev, unsigned char *scsi3addr)
++{
++ int i;
++ bool match = false;
++ struct io_accel2_cmd * c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
++ struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *)c2;
++
++ if (hpsa_is_cmd_idle (c))
++ return false;
++
++ switch (c->cmd_type)
++ {
++ case CMD_SCSI:
++ case CMD_IOCTL_PEND:
++ match = !test_memcmp (scsi3addr, &c->Header.LUN.LunAddrBytes,
++ sizeof (c->Header.LUN.LunAddrBytes));
++ break;
++
++ case CMD_IOACCEL1:
++ case CMD_IOACCEL2:
++ if (c->phys_disk == dev)
++ {
++ match = true;
++ }
++ else
++ {
++ for (i = 0; i < dev->nphysical_disks && !match; i++)
++ {
++ match = dev->phys_disk[i] == c->phys_disk;
++ }
++ }
++ break;
++
++ case IOACCEL2_TMF:
++ for (i = 0; i < dev->nphysical_disks && !match; i++)
++ {
++ match = dev->phys_disk[i]->ioaccel_handle ==
++ le32_to_cpu (ac->it_nexus);
++ }
++ break;
++
++ case 0:
++ match = false;
++ break;
++ default:
++ dev_err (&h->pdev->dev, "unexpected cmd_type: %d\n", c->cmd_type);
++ BUG ();
++ }
++
++ return match;
++}
++
++/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
+diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
+new file mode 100644
+index 000000000..5570c762e
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
+@@ -0,0 +1,58 @@
++/* { dg-do compile} */
++
++#define NULL ((void*)0)
++typedef unsigned long size_t;
++typedef long intptr_t;
++typedef unsigned long uintptr_t;
++typedef long scalar_t__;
++typedef int bool;
++#define false 0
++#define true 1
++
++struct tcpcb
++{
++ int t_state;
++};
++
++struct socket
++{
++ int dummy;
++};
++
++struct proc
++{
++ int dummy;
++};
++
++struct inpcb
++{
++ scalar_t__ inp_lport;
++};
++
++int COMMON_END (int);
++int COMMON_START ();
++int PRU_LISTEN;
++int TCPS_LISTEN;
++int in_pcbbind (struct inpcb *, int *, struct proc *);
++struct inpcb* sotoinpcb (struct socket *);
++
++__attribute__((used)) static void
++tcp_usr_listen (struct socket *so, struct proc *p)
++{
++ int error = 0;
++ struct inpcb *inp = sotoinpcb (so);
++ struct tcpcb *tp;
++
++ COMMON_START ();
++ if (inp->inp_lport == 0)
++ {
++ error = in_pcbbind (inp, NULL, p);
++ }
++ if (error == 0)
++ {
++ tp->t_state = TCPS_LISTEN;
++ }
++ COMMON_END (PRU_LISTEN);
++}
++
++/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_layout" } } */
+diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
+new file mode 100644
+index 000000000..50ab9cc24
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
+@@ -0,0 +1,61 @@
++/* { dg-do compile} */
++
++#define NULL ((void*)0)
++typedef unsigned long size_t;
++typedef long intptr_t;
++typedef unsigned long uintptr_t;
++typedef long scalar_t__;
++typedef int bool;
++#define false 0
++#define true 1
++
++typedef struct TYPE_4__ TYPE_2__;
++typedef struct TYPE_3__ TYPE_1__;
++
++struct TYPE_4__
++{
++ size_t modCount;
++ TYPE_1__ *modList;
++};
++
++struct TYPE_3__
++{
++ void *modDescr;
++ void *modName;
++};
++
++size_t MAX_MODS;
++void *String_Alloc (char *);
++int test_strlen (char *);
++int trap_FD_GetFileList (char *, char *, char *, int);
++TYPE_2__ uiInfo;
++
++__attribute__((used)) static void
++UI_LoadMods ()
++{
++ int numdirs;
++ char dirlist[2048];
++ char *dirptr;
++ char *descptr;
++ int i;
++ int dirlen;
++
++ uiInfo.modCount = 0;
++ numdirs = trap_FD_GetFileList ("$modelist", "", dirlist, sizeof (dirlist));
++ dirptr = dirlist;
++ for (i = 0; i < numdirs; i++)
++ {
++ dirlen = test_strlen (dirptr) + 1;
++ descptr = dirptr + dirlen;
++ uiInfo.modList[uiInfo.modCount].modName = String_Alloc (dirptr);
++ uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc (descptr);
++ dirptr += dirlen + test_strlen (descptr) + 1;
++ uiInfo.modCount++;
++ if (uiInfo.modCount >= MAX_MODS)
++ {
++ break;
++ }
++ }
++}
++
++/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_layout" } } */
+--
+2.27.0.windows.1
+