Projects
openEuler:24.03:SP1:Everything
gcc
_service:tar_scm:0022-DFE-Add-Dead-Field-Elimin...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0022-DFE-Add-Dead-Field-Elimination-in-Struct-Reorg.patch of Package gcc
From 9d03b0a7741915e3a0172d60b9c21bf5abbda89e Mon Sep 17 00:00:00 2001 From: Mingchuan Wu <wumingchuan1992@foxmail.com> Date: Mon, 28 Aug 2023 18:11:02 +0800 Subject: [PATCH 22/22] [DFE] Add Dead Field Elimination in Struct-Reorg. We can transform gimple to eliminate fields that are never read and replace the dead fields in stmt by creating a new ssa. --- gcc/common.opt | 4 + gcc/ipa-struct-reorg/ipa-struct-reorg.cc | 240 +++++++++++++++++- gcc/ipa-struct-reorg/ipa-struct-reorg.h | 8 + gcc/opts.cc | 17 ++ gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c | 86 +++++++ .../gcc.dg/struct/dfe_ele_minus_verify.c | 60 +++++ .../gcc.dg/struct/dfe_extr_board_init.c | 77 ++++++ gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c | 84 ++++++ 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_mv_udc_core.c | 82 ++++++ .../gcc.dg/struct/dfe_extr_tcp_usrreq.c | 58 +++++ .../gcc.dg/struct/dfe_extr_ui_main.c | 61 +++++ .../gcc.dg/struct/dfe_mem_ref_offset.c | 58 +++++ .../struct/dfe_mul_layer_ptr_record_bug.c | 30 +++ gcc/testsuite/gcc.dg/struct/dfe_ptr_diff.c | 71 ++++++ .../gcc.dg/struct/dfe_ptr_negate_expr.c | 55 ++++ gcc/testsuite/gcc.dg/struct/dfe_ptr_ptr.c | 55 ++++ gcc/testsuite/gcc.dg/struct/struct-reorg.exp | 4 + .../struct/wo_prof_escape_replace_type.c | 49 ++++ 21 files changed, 1436 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_ele_minus_verify.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_board_init.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c 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_mv_udc_core.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 create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_mem_ref_offset.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_ptr_diff.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_ptr_negate_expr.c create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_ptr_ptr.c create mode 100644 gcc/testsuite/gcc.dg/struct/wo_prof_escape_replace_type.c diff --git a/gcc/common.opt b/gcc/common.opt index 14633c821..8bb735551 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1988,6 +1988,10 @@ fipa-struct-reorg Common Var(flag_ipa_struct_reorg) Init(0) Optimization Perform structure layout optimizations. +fipa-struct-reorg= +Common RejectNegative Joined UInteger Var(struct_layout_optimize_level) Init(0) IntegerRange(0, 3) +-fipa-struct-reorg=[0,1,2,3] adding none, struct-reorg, reorder-fields, dfe optimizations. + fipa-vrp Common Var(flag_ipa_vrp) Optimization Perform IPA Value Range Propagation. diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc index 3e5f9538b..eac5fac7e 100644 --- a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc +++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc @@ -87,6 +87,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "gimple-pretty-print.h" #include "gimple-iterator.h" +#include "gimple-walk.h" #include "cfg.h" #include "ssa.h" #include "tree-dfa.h" @@ -268,10 +269,43 @@ enum srmode STRUCT_REORDER_FIELDS }; +/* Enum the struct layout optimize level, + which should be the same as the option -fstruct-reorg=. */ + +enum struct_layout_opt_level +{ + NONE = 0, + STRUCT_REORG, + STRUCT_REORDER_FIELDS_SLO, + DEAD_FIELD_ELIMINATION +}; + static bool is_result_of_mult (tree arg, tree *num, tree struct_size); static bool isptrptr (tree type); +void get_base (tree &base, tree expr); srmode current_mode; +hash_map<tree, tree> replace_type_map; + +/* Return true if one of these types is created by struct-reorg. */ + +static bool +is_replace_type (tree type1, tree type2) +{ + if (replace_type_map.is_empty ()) + return false; + if (type1 == NULL_TREE || type2 == NULL_TREE) + return false; + tree *type_value = replace_type_map.get (type1); + if (type_value) + if (types_compatible_p (*type_value, type2)) + return true; + type_value = replace_type_map.get (type2); + if (type_value) + if (types_compatible_p (*type_value, type1)) + return true; + return false; +} } // anon namespace @@ -353,7 +387,8 @@ srfield::srfield (tree field, srtype *base) fielddecl (field), base (base), type (NULL), - clusternum (0) + clusternum (0), + field_access (EMPTY_FIELD) { for (int i = 0; i < max_split; i++) newfield[i] = NULL_TREE; @@ -392,6 +427,25 @@ srtype::srtype (tree type) } } +/* Check it if all fields in the RECORD_TYPE are referenced. */ + +bool +srtype::has_dead_field (void) +{ + bool may_dfe = false; + srfield *this_field; + unsigned i; + FOR_EACH_VEC_ELT (fields, i, this_field) + { + if (!(this_field->field_access & READ_FIELD)) + { + may_dfe = true; + break; + } + } + return may_dfe; +} + /* Mark the type as escaping type E at statement STMT. */ void @@ -595,7 +649,17 @@ 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; + { + /* Currently, when the replacement structure type exists, + we only split the replacement structure. */ + 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) @@ -838,6 +902,10 @@ srtype::create_new_type (void) for (unsigned i = 0; i < fields.length (); i++) { srfield *f = fields[i]; + if (current_mode == STRUCT_REORDER_FIELDS + && struct_layout_optimize_level >= DEAD_FIELD_ELIMINATION + && !(f->field_access & READ_FIELD)) + continue; f->create_new_fields (newtype, newfields, newlast); } @@ -856,6 +924,16 @@ srtype::create_new_type (void) warn_padded = save_warn_padded; + if (current_mode == STRUCT_REORDER_FIELDS + && replace_type_map.get (this->newtype[0]) == NULL) + replace_type_map.put (this->newtype[0], this->type); + if (dump_file) + { + if (current_mode == STRUCT_REORDER_FIELDS + && struct_layout_optimize_level >= DEAD_FIELD_ELIMINATION + && has_dead_field ()) + fprintf (dump_file, "Dead field elimination.\n"); + } if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Created %d types:\n", maxclusters); @@ -1269,6 +1347,7 @@ public: void maybe_mark_or_record_other_side (tree side, tree other, gimple *stmt); unsigned execute_struct_relayout (void); + bool remove_dead_field_stmt (tree lhs); }; struct ipa_struct_relayout @@ -3057,6 +3136,119 @@ ipa_struct_reorg::find_vars (gimple *stmt) } } +static HOST_WIDE_INT +get_offset (tree op, HOST_WIDE_INT offset) +{ + switch (TREE_CODE (op)) + { + case COMPONENT_REF: + { + return int_byte_position (TREE_OPERAND (op, 1)); + } + case MEM_REF: + { + return tree_to_uhwi (TREE_OPERAND (op, 1)); + } + default: + return offset; + } + return offset; +} + +/* Record field access. */ +static void +record_field_access (tree type, HOST_WIDE_INT offset, + unsigned access, void *data) +{ + srtype *this_srtype = ((ipa_struct_reorg *)data)->find_type (type); + if (this_srtype == NULL) + return; + srfield *this_srfield = this_srtype->find_field (offset); + if (this_srfield == NULL) + return; + + this_srfield->field_access |= access; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "record field access %d:", access); + print_generic_expr (dump_file, type); + fprintf (dump_file, " field:"); + print_generic_expr (dump_file, this_srfield->fielddecl); + fprintf (dump_file, "\n"); + } + return; + +} + +/* Update field_access in srfield. */ + +static void +update_field_access (tree node, tree op, unsigned access, void *data) +{ + HOST_WIDE_INT offset = 0; + offset = get_offset (op, offset); + tree node_type = inner_type (TREE_TYPE (node)); + record_field_access (node_type, offset, access, data); + tree base = node; + get_base (base, node); + tree base_type = inner_type (TREE_TYPE (base)); + if (!types_compatible_p (base_type, node_type)) + { + record_field_access (base_type, get_offset (node, offset), + access, data); + } + return; +} + +/* A callback for walk_stmt_load_store_ops to visit store. */ + +static bool +find_field_p_store (gimple *stmt ATTRIBUTE_UNUSED, + tree node, tree op, void *data) +{ + update_field_access (node, op, WRITE_FIELD, data); + + return false; +} + +/* A callback for walk_stmt_load_store_ops to visit load. */ + +static bool +find_field_p_load (gimple *stmt ATTRIBUTE_UNUSED, + tree node, tree op, void *data) +{ + update_field_access (node, op, READ_FIELD, data); + + return false; +} + +/* Determine whether the stmt should be deleted. */ + +bool +ipa_struct_reorg::remove_dead_field_stmt (tree lhs) +{ + tree base = NULL_TREE; + bool indirect = false; + srtype *t = NULL; + srfield *f = NULL; + bool realpart = false; + bool imagpart = false; + bool address = false; + bool escape_from_base = false; + if (!get_type_field (lhs, base, indirect, t, f, realpart, imagpart, + address, escape_from_base)) + return false; + if (t ==NULL) + return false; + if (t->newtype[0] == t->type) + return false; + if (f == NULL) + return false; + if (f->newfield[0] == NULL) + return true; + return false; +} + /* Maybe record access of statement for further analaysis. */ void @@ -3078,6 +3270,13 @@ ipa_struct_reorg::maybe_record_stmt (cgraph_node *node, gimple *stmt) default: break; } + if (current_mode == STRUCT_REORDER_FIELDS + && struct_layout_optimize_level >= DEAD_FIELD_ELIMINATION) + { + /* Look for loads and stores. */ + walk_stmt_load_store_ops (stmt, this, find_field_p_load, + find_field_p_store); + } } /* Calculate the multiplier. */ @@ -3368,8 +3567,11 @@ ipa_struct_reorg::maybe_mark_or_record_other_side (tree side, tree other, } else if (type != d->type) { - type->mark_escape (escape_cast_another_ptr, stmt); - d->type->mark_escape (escape_cast_another_ptr, stmt); + if (!is_replace_type (d->type->type, type->type)) + { + type->mark_escape (escape_cast_another_ptr, stmt); + d->type->mark_escape (escape_cast_another_ptr, stmt); + } } /* x_1 = y.x_nodes; void *x; Directly mark the structure pointer type assigned @@ -3949,8 +4151,9 @@ ipa_struct_reorg::check_type_and_push (tree newdecl, srdecl *decl, } /* If we have a non void* or a decl (which is hard to track), then mark the type as escaping. */ - if (!VOID_POINTER_P (TREE_TYPE (newdecl)) - || DECL_P (newdecl)) + if (replace_type_map.get (type->type) == NULL + && (!VOID_POINTER_P (TREE_TYPE (newdecl)) + || DECL_P (newdecl))) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -4216,7 +4419,9 @@ ipa_struct_reorg::check_other_side (srdecl *decl, tree other, gimple *stmt, } srtype *t1 = find_type (inner_type (t)); - if (t1 == type) + /* In the other side check, escape mark is added + when the replacement struct type exists. */ + if (t1 == type || is_replace_type (inner_type (t), type->type)) { /* In Complete Struct Relayout, if lhs type is the same as rhs type, we could return without any harm. */ @@ -5513,6 +5718,27 @@ bool ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi) { bool remove = false; + + if (current_mode == STRUCT_REORDER_FIELDS + && struct_layout_optimize_level >= DEAD_FIELD_ELIMINATION + && remove_dead_field_stmt (gimple_assign_lhs (stmt))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\n rewriting statement (remove): \n"); + print_gimple_stmt (dump_file, stmt, 0); + } + /* 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); + } + } + if (gimple_clobber_p (stmt)) { tree lhs = gimple_assign_lhs (stmt); diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.h b/gcc/ipa-struct-reorg/ipa-struct-reorg.h index 6f85adeb4..719f7b308 100644 --- a/gcc/ipa-struct-reorg/ipa-struct-reorg.h +++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.h @@ -143,6 +143,7 @@ public: bool create_new_type (void); void analyze (void); + bool has_dead_field (void); void mark_escape (escape_type, gimple *stmt); bool has_escaped (void) { @@ -164,6 +165,12 @@ public: } }; +/* Bitflags used for determining if a field + is never accessed, read or written. */ +const unsigned EMPTY_FIELD = 0x0u; +const unsigned READ_FIELD = 0x01u; +const unsigned WRITE_FIELD = 0x02u; + struct srfield { unsigned HOST_WIDE_INT offset; @@ -175,6 +182,7 @@ struct srfield unsigned clusternum; tree newfield[max_split]; + unsigned field_access; /* FIELD_DECL -> bitflag (use for dfe). */ // Constructors srfield (tree field, srtype *base); diff --git a/gcc/opts.cc b/gcc/opts.cc index c3cc2c169..b868d189e 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -2957,6 +2957,23 @@ common_handle_option (struct gcc_options *opts, SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value); break; + case OPT_fipa_struct_reorg_: + /* No break here - do -fipa-struct-reorg processing. */ + /* FALLTHRU. */ + case OPT_fipa_struct_reorg: + opts->x_flag_ipa_struct_reorg = value; + if (value && !opts->x_struct_layout_optimize_level) + { + /* Using the -fipa-struct-reorg option is equivalent to using + -fipa-struct-reorg=1. */ + opts->x_struct_layout_optimize_level = 1; + } + break; + + case OPT_fipa_reorder_fields: + SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_struct_reorg, value); + break; + case OPT_fprofile_generate_: opts->x_profile_data_prefix = xstrdup (arg); value = true; diff --git a/gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c b/gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c new file mode 100644 index 000000000..0c9e384c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->arcs->id = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->arcs->id = net[0]->arcs->id + 2; + stop_arcs->cost = net[0]->arcs->id / 2; + stop_arcs->net_add = net[0]; + printf("stop_arcs->cost = %ld\n", stop_arcs->cost); + net[0]->arcs++; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_ele_minus_verify.c b/gcc/testsuite/gcc.dg/struct/dfe_ele_minus_verify.c new file mode 100644 index 000000000..717fcc386 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_ele_minus_verify.c @@ -0,0 +1,60 @@ +// verify newarc[cmp-1].flow +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[0].id); + for (int i = 1; i < MAX; i++) + { + ap[i-1].id = 500; + } + printf("%d\n", ap[0].id); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_board_init.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_board_init.c new file mode 100644 index 000000000..7723c240b --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_board_init.c @@ -0,0 +1,77 @@ +/* { 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_5__ TYPE_2__; +typedef struct TYPE_4__ TYPE_1__; + +struct TYPE_4__ +{ + int Pin; + int Pull; + int Mode; + int Speed; +}; + +struct TYPE_5__ +{ + int MEMRMP; +}; +typedef TYPE_1__ GPIO_InitTypeDef; + +int BT_RST_PIN; +int BT_RST_PORT; +int CONN_POS10_PIN; +int CONN_POS10_PORT; +int GPIO_HIGH (int, int); +int GPIO_MODE_INPUT; +int GPIO_MODE_OUTPUT_PP; +int GPIO_NOPULL; +int GPIO_PULLUP; +int GPIO_SPEED_FREQ_LOW; +int HAL_GPIO_Init (int, TYPE_1__ *); +scalar_t__ IS_GPIO_RESET (int, int); +TYPE_2__ *SYSCFG; +int __HAL_RCC_GPIOB_CLK_ENABLE (); +int __HAL_RCC_GPIOC_CLK_ENABLE (); + +__attribute__((used)) static void +LBF_DFU_If_Needed (void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + __HAL_RCC_GPIOC_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Pin = BT_RST_PIN; + HAL_GPIO_Init (BT_RST_PORT, &GPIO_InitStruct); + + GPIO_HIGH (BT_RST_PORT, BT_RST_PIN); + __HAL_RCC_GPIOB_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Pin = CONN_POS10_PIN; + HAL_GPIO_Init (CONN_POS10_PORT, &GPIO_InitStruct); + + if (IS_GPIO_RESET (CONN_POS10_PORT, CONN_POS10_PIN)) + { + SYSCFG->MEMRMP = 0x00000001; + asm ( + "LDR R0, =0x000000\n\t" + "LDR SP, [R0, #0]\n\t" + ); + asm ( + "LDR R0, [R0, #0]\n\t" + "BX R0\n\t" + ); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c new file mode 100644 index 000000000..a1feac966 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c @@ -0,0 +1,84 @@ +/* { 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_2__ TYPE_1__; + +struct net_device +{ + struct claw_privbk* ml_priv; +}; +struct clawctl +{ + int linkid; +}; +struct claw_privbk +{ + int system_validate_comp; + TYPE_1__* p_env; + int ctl_bk; +}; +typedef int __u8; +struct TYPE_2__ +{ + scalar_t__ packing; + int api_type; +}; + +int CLAW_DBF_TEXT (int, int, char*); +int CONNECTION_REQUEST; +int HOST_APPL_NAME; +scalar_t__ PACKING_ASK; +scalar_t__ PACK_SEND; +int WS_APPL_NAME_IP_NAME; +int WS_APPL_NAME_PACKED; +int claw_send_control (struct net_device*, int, int, int, int, int, int); +int setup; + +__attribute__((noinline)) int +claw_send_control (struct net_device* net, int a, int b, int c, int d, int e, + int f) +{ + return net->ml_priv->system_validate_comp + a + b + c + d + f; +} + +__attribute__((used)) static int +claw_snd_conn_req (struct net_device *dev, __u8 link) +{ + int rc; + struct claw_privbk *privptr = dev->ml_priv; + struct clawctl *p_ctl; + CLAW_DBF_TEXT (2, setup, "snd_conn"); + rc = 1; + p_ctl = (struct clawctl *)&privptr->ctl_bk; + p_ctl->linkid = link; + if (privptr->system_validate_comp == 0x00) + { + return rc; + } + if (privptr->p_env->packing == PACKING_ASK) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_PACKED, WS_APPL_NAME_PACKED); + } + if (privptr->p_env->packing == PACK_SEND) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_IP_NAME, WS_APPL_NAME_IP_NAME); + } + if (privptr->p_env->packing == 0) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + HOST_APPL_NAME, privptr->p_env->api_type); + } + return rc; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "reorder_fields" } } */ 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..fd1e936ca --- /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 "reorder_fields" } } */ 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..b13d785a9 --- /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 "reorder_fields" } } */ 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..bc28a658a --- /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 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_mv_udc_core.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_mv_udc_core.c new file mode 100644 index 000000000..0a585ac3d --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_mv_udc_core.c @@ -0,0 +1,82 @@ +/* { 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 u32; + +struct mv_udc +{ + TYPE_2__ *op_regs; + TYPE_1__ *ep_dqh; + struct mv_ep *eps; +}; + +struct mv_ep +{ + TYPE_1__ *dqh; + struct mv_udc *udc; +}; + +struct TYPE_4__ +{ + int *epctrlx; +}; + +struct TYPE_3__ +{ + int max_packet_length; + int next_dtd_ptr; +}; + +int EP0_MAX_PKT_SIZE; +int EPCTRL_RX_ENABLE; +int EPCTRL_RX_EP_TYPE_SHIFT; +int EPCTRL_TX_ENABLE; +int EPCTRL_TX_EP_TYPE_SHIFT; +int EP_QUEUE_HEAD_IOS; +int EP_QUEUE_HEAD_MAX_PKT_LEN_POS; +int EP_QUEUE_HEAD_NEXT_TERMINATE; +int USB_ENDPOINT_XFER_CONTROL; +int readl (int *); +int writel (int, int *); + +__attribute__((used)) static void +ep0_reset (struct mv_udc *udc) +{ + struct mv_ep *ep; + u32 epctrlx; + int i = 0; + for (i = 0; i < 2; i++) + { + ep = &udc->eps[i]; + ep->udc = udc; + ep->dqh = &udc->ep_dqh[i]; + ep->dqh->max_packet_length = + (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) + | EP_QUEUE_HEAD_IOS; + ep->dqh->next_dtd_ptr = EP_QUEUE_HEAD_NEXT_TERMINATE; + epctrlx = readl (&udc->op_regs->epctrlx[0]); + if (i) + { + epctrlx |= EPCTRL_TX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_TX_EP_TYPE_SHIFT); + } + else + { + epctrlx |= EPCTRL_RX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_RX_EP_TYPE_SHIFT); + } + writel (epctrlx, &udc->op_regs->epctrlx[0]); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ 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..bddd862fe --- /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 "reorder_fields" } } */ 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..1a06f5eec --- /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 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_mem_ref_offset.c b/gcc/testsuite/gcc.dg/struct/dfe_mem_ref_offset.c new file mode 100644 index 000000000..94eb88d5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_mem_ref_offset.c @@ -0,0 +1,58 @@ +/* Supports the MEM_REF offset. + _1 = MEM[(struct arc *)ap_4 + 72B].flow; + Old rewrite:_1 = ap.reorder.0_8->flow; + New rewrite:_1 = MEM[(struct arc.reorder.0 *)ap.reorder.0_8 + 64B].flow. */ +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + const int MAX = 100; + /* A similar scenario can be reproduced only by using local variables. */ + arc_p ap = NULL; + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c b/gcc/testsuite/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c new file mode 100644 index 000000000..bbf9420d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct T_HASH_ENTRY +{ + unsigned int hash; + unsigned int klen; + char *key; +} iHashEntry; + +typedef struct T_HASH +{ + unsigned int size; + unsigned int fill; + unsigned int keys; + + iHashEntry **array; +} uHash; + +uHash *retval; + +int +main() { + retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_ptr_diff.c b/gcc/testsuite/gcc.dg/struct/dfe_ptr_diff.c new file mode 100644 index 000000000..f706db968 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_ptr_diff.c @@ -0,0 +1,71 @@ +// support POINTER_DIFF_EXPR & NOP_EXPR to avoid +// escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt" +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + arc_t *old_arcs; + node_t *node; + node_t *stop; + size_t off; + network_t* net; + + for( ; node->number < stop->number; node++ ) + { + off = node->basic_arc - old_arcs; + node->basic_arc = (arc_t *)(net->arcs + off); + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 3 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_ptr_negate_expr.c b/gcc/testsuite/gcc.dg/struct/dfe_ptr_negate_expr.c new file mode 100644 index 000000000..963295cb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_ptr_negate_expr.c @@ -0,0 +1,55 @@ +// support NEGATE_EXPR rewriting +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + int64_t susp = 0; + const int MAX = 100; + arc_p ap = (arc_p) calloc(MAX, sizeof(arc_t)); + ap -= susp; + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/dfe_ptr_ptr.c b/gcc/testsuite/gcc.dg/struct/dfe_ptr_ptr.c new file mode 100644 index 000000000..aa10506a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_ptr_ptr.c @@ -0,0 +1,55 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]"; +/* { dg-do compile } */ + +#include <stdio.h> +#include <stdlib.h> + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_t **ap = NULL; + +int +main () +{ + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "reorder_fields" } } */ diff --git a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp index 5a476e8f9..6ccb753b5 100644 --- a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp +++ b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp @@ -43,6 +43,10 @@ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf_*.c]] \ "" "-fipa-reorder-fields -fdump-ipa-all -flto-partition=one -fwhole-program" +# -fipa-struct-reorg=3 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dfe*.c]] \ + "" "-fipa-reorder-fields -fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program" + # All done. torture-finish dg-finish diff --git a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_replace_type.c b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_replace_type.c new file mode 100644 index 000000000..fa8c66b9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_replace_type.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ + +#include <stdlib.h> + +struct AngleDef +{ + double K; + double th0; +}; +typedef struct AngleDef angldef; + +struct bndangdihe +{ + int nbond; + int nangl; + int ndihe; +}; +typedef struct bndangdihe bah; + +struct ambprmtop +{ + double *AnglK; + double *AnglEq; + bah nBAH; + angldef *AParam; + char source[512]; + char eprulesource[512]; +}; +typedef struct ambprmtop prmtop; + +static void OrderBondParameters (prmtop *tp) +{ + int i; + tp->AParam = (angldef *)malloc (tp->nBAH.nangl * sizeof (angldef)); + for (i = 0; i < tp->nBAH.nangl; i++) + { + tp->AParam[i].K = tp->AnglK[i]; + tp->AParam[i].th0 = tp->AnglEq[i]; + } +} + +void main () +{ + prmtop *tp = (prmtop *)malloc (100 * sizeof (prmtop)); + OrderBondParameters (tp); +} + +/*---------------------------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform" "struct_reorg" } } */ -- 2.33.0
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