Projects
Mega:23.03
gcc
_service:tar_scm:0042-DFE-Fix-bugs.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0042-DFE-Fix-bugs.patch of Package gcc
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2