903 lines
24 KiB
Diff
903 lines
24 KiB
Diff
|
|
From edd4200e2b3e94d5c124900657b91c22dfe9c557 Mon Sep 17 00:00:00 2001
|
|||
|
|
From: Mingchuan Wu <wumingchuan1992@foxmail.com>
|
|||
|
|
Date: Wed, 15 Jun 2022 16:00:25 +0800
|
|||
|
|
Subject: [PATCH 04/12] [DFE] Add Dead Field Elimination in Struct-Reorg.
|
|||
|
|
|
|||
|
|
We can transform gimple to eliminate fields that are never read
|
|||
|
|
and remove their redundant stmts.
|
|||
|
|
Also we adapted the partial escape_cast_another_ptr for struct relayout.
|
|||
|
|
Add flag -fipa-struct-reorg=3 to enable dead field elimination.
|
|||
|
|
---
|
|||
|
|
gcc/common.opt | 4 +-
|
|||
|
|
gcc/ipa-struct-reorg/ipa-struct-reorg.c | 209 ++++++++++++++++--
|
|||
|
|
gcc/ipa-struct-reorg/ipa-struct-reorg.h | 9 +-
|
|||
|
|
gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c | 86 +++++++
|
|||
|
|
.../gcc.dg/struct/dfe_ele_minus_verify.c | 60 +++++
|
|||
|
|
.../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 | 21 +-
|
|||
|
|
11 files changed, 639 insertions(+), 19 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_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
|
|||
|
|
|
|||
|
|
diff --git a/gcc/common.opt b/gcc/common.opt
|
|||
|
|
index 7fc075d35..b5ea3c7a1 100644
|
|||
|
|
--- a/gcc/common.opt
|
|||
|
|
+++ b/gcc/common.opt
|
|||
|
|
@@ -1884,8 +1884,8 @@ Common Report 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, 2)
|
|||
|
|
--fipa-struct-reorg=[0,1,2] adding none, struct-reorg, reorder-fields optimizations.
|
|||
|
|
+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-extend-auto-profile
|
|||
|
|
Common Report Var(flag_ipa_extend_auto_profile)
|
|||
|
|
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|||
|
|
index 9214ee74a..2fa560239 100644
|
|||
|
|
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|||
|
|
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|||
|
|
@@ -81,6 +81,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"
|
|||
|
|
@@ -238,11 +239,44 @@ enum srmode
|
|||
|
|
STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
+/* 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,
|
|||
|
|
+ DEAD_FIELD_ELIMINATION
|
|||
|
|
+};
|
|||
|
|
+
|
|||
|
|
static bool is_result_of_mult (tree arg, tree *num, tree struct_size);
|
|||
|
|
bool isptrptr (tree type);
|
|||
|
|
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
namespace struct_reorg {
|
|||
|
|
@@ -318,12 +352,13 @@ srfunction::simple_dump (FILE *file)
|
|||
|
|
/* Constructor of FIELD. */
|
|||
|
|
|
|||
|
|
srfield::srfield (tree field, srtype *base)
|
|||
|
|
- : offset(int_byte_position (field)),
|
|||
|
|
+ : offset (int_byte_position (field)),
|
|||
|
|
fieldtype (TREE_TYPE (field)),
|
|||
|
|
fielddecl (field),
|
|||
|
|
- base(base),
|
|||
|
|
- type(NULL),
|
|||
|
|
- clusternum(0)
|
|||
|
|
+ base (base),
|
|||
|
|
+ type (NULL),
|
|||
|
|
+ clusternum (0),
|
|||
|
|
+ field_access (EMPTY_FIELD)
|
|||
|
|
{
|
|||
|
|
for(int i = 0;i < max_split; i++)
|
|||
|
|
newfield[i] = NULL_TREE;
|
|||
|
|
@@ -362,6 +397,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
|
|||
|
|
@@ -833,6 +887,10 @@ srtype::create_new_type (void)
|
|||
|
|
for (unsigned i = 0; i < fields.length (); i++)
|
|||
|
|
{
|
|||
|
|
srfield *f = fields[i];
|
|||
|
|
+ if (current_mode == STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
+ && struct_layout_optimize_level >= DEAD_FIELD_ELIMINATION
|
|||
|
|
+ && !(f->field_access & READ_FIELD))
|
|||
|
|
+ continue;
|
|||
|
|
f->create_new_fields (newtype, newfields, newlast);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@@ -854,6 +912,16 @@ srtype::create_new_type (void)
|
|||
|
|
|
|||
|
|
warn_padded = save_warn_padded;
|
|||
|
|
|
|||
|
|
+ if (current_mode == STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
+ && replace_type_map.get (this->newtype[0]) == NULL)
|
|||
|
|
+ replace_type_map.put (this->newtype[0], this->type);
|
|||
|
|
+ if (dump_file)
|
|||
|
|
+ {
|
|||
|
|
+ if (current_mode == STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
+ && 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);
|
|||
|
|
@@ -1128,12 +1196,12 @@ csrtype::init_type_info (void)
|
|||
|
|
|
|||
|
|
/* Close enough to pad to improve performance.
|
|||
|
|
33~63 should pad to 64 but 33~48 (first half) are too far away, and
|
|||
|
|
- 65~127 should pad to 128 but 65~96 (first half) are too far away. */
|
|||
|
|
+ 65~127 should pad to 128 but 65~80 (first half) are too far away. */
|
|||
|
|
if (old_size > 48 && old_size < 64)
|
|||
|
|
{
|
|||
|
|
new_size = 64;
|
|||
|
|
}
|
|||
|
|
- if (old_size > 96 && old_size < 128)
|
|||
|
|
+ if (old_size > 80 && old_size < 128)
|
|||
|
|
{
|
|||
|
|
new_size = 128;
|
|||
|
|
}
|
|||
|
|
@@ -1272,6 +1340,7 @@ public:
|
|||
|
|
bool has_rewritten_type (srfunction*);
|
|||
|
|
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
|
|||
|
|
@@ -3206,6 +3275,90 @@ 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)
|
|||
|
|
+{
|
|||
|
|
+ srtype *this_srtype = ((ipa_struct_reorg *)data)->find_type (record);
|
|||
|
|
+ if (this_srtype == NULL)
|
|||
|
|
+ return;
|
|||
|
|
+ srfield *this_srfield = this_srtype->find_field (int_byte_position (field));
|
|||
|
|
+ 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, record);
|
|||
|
|
+ fprintf (dump_file, " field:");
|
|||
|
|
+ print_generic_expr (dump_file, field);
|
|||
|
|
+ fprintf (dump_file, "\n");
|
|||
|
|
+ }
|
|||
|
|
+ return;
|
|||
|
|
+}
|
|||
|
|
+
|
|||
|
|
+/* A callback for walk_stmt_load_store_ops to visit store. */
|
|||
|
|
+
|
|||
|
|
+static bool
|
|||
|
|
+find_field_p_store (gimple *, 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);
|
|||
|
|
+
|
|||
|
|
+ return false;
|
|||
|
|
+}
|
|||
|
|
+
|
|||
|
|
+/* A callback for walk_stmt_load_store_ops to visit load. */
|
|||
|
|
+
|
|||
|
|
+static bool
|
|||
|
|
+find_field_p_load (gimple *, 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);
|
|||
|
|
+
|
|||
|
|
+ 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
|
|||
|
|
+ && (f->field_access & WRITE_FIELD))
|
|||
|
|
+ return true;
|
|||
|
|
+ return false;
|
|||
|
|
+}
|
|||
|
|
+
|
|||
|
|
/* Maybe record access of statement for further analaysis. */
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
@@ -3227,6 +3380,13 @@ ipa_struct_reorg::maybe_record_stmt (cgraph_node *node, gimple *stmt)
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
+ if (current_mode == STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
+ && 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. */
|
|||
|
|
@@ -3543,8 +3703,11 @@ ipa_struct_reorg::maybe_mark_or_record_other_side (tree side, tree other, gimple
|
|||
|
|
}
|
|||
|
|
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
|
|||
|
|
@@ -4131,8 +4294,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))
|
|||
|
|
{
|
|||
|
|
@@ -4142,7 +4306,7 @@ ipa_struct_reorg::check_type_and_push (tree newdecl, srdecl *decl,
|
|||
|
|
print_generic_expr (dump_file, TREE_TYPE (newdecl));
|
|||
|
|
fprintf (dump_file, "\n");
|
|||
|
|
}
|
|||
|
|
- type->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
+ type->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
/* At this point there should only be unkown void* ssa names. */
|
|||
|
|
@@ -4465,11 +4629,13 @@ ipa_struct_reorg::check_other_side (srdecl *decl, tree other, gimple *stmt, vec<
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
+ if (!is_replace_type (t1->type, type->type))
|
|||
|
|
+ {
|
|||
|
|
+ if (t1)
|
|||
|
|
+ t1->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
|
|||
|
|
- if (t1)
|
|||
|
|
- t1->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
-
|
|||
|
|
- type->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
+ type->mark_escape (escape_cast_another_ptr, stmt);
|
|||
|
|
+ }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
@@ -5722,6 +5888,19 @@ bool
|
|||
|
|
ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi)
|
|||
|
|
{
|
|||
|
|
bool remove = false;
|
|||
|
|
+
|
|||
|
|
+ if (current_mode == STRUCT_LAYOUT_OPTIMIZE
|
|||
|
|
+ && 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);
|
|||
|
|
+ }
|
|||
|
|
+ return true;
|
|||
|
|
+ }
|
|||
|
|
+
|
|||
|
|
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 54b0dc655..936c0fa6f 100644
|
|||
|
|
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.h
|
|||
|
|
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.h
|
|||
|
|
@@ -142,6 +142,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)
|
|||
|
|
{
|
|||
|
|
@@ -163,6 +164,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;
|
|||
|
|
@@ -174,7 +181,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/testsuite/gcc.dg/struct/dfe_DTE_verify.c b/gcc/testsuite/gcc.dg/struct/dfe_DTE_verify.c
|
|||
|
|
new file mode 100644
|
|||
|
|
index 000000000..4261d2352
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..42d38c63a
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..53583fe82
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..fd675ec2e
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..600e7908b
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..f411364a7
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
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..a4e723763
|
|||
|
|
--- /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 "struct_layout" } } */
|
|||
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
|
|||
|
|
index 67b3ac2d5..ac5585813 100644
|
|||
|
|
--- a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
|
|||
|
|
+++ b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
|
|||
|
|
@@ -64,8 +64,27 @@ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/complete_struct_relayout
|
|||
|
|
"" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
|
|||
|
|
# -fipa-struct-reorg=2
|
|||
|
|
-gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_prof_*.c]] \
|
|||
|
|
"" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_ratio_*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_prof_*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/struct_reorg*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sr_*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/complete_struct_relayout.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+
|
|||
|
|
+# -fipa-struct-reorg=3
|
|||
|
|
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dfe*.c]] \
|
|||
|
|
+ "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program"
|
|||
|
|
+
|
|||
|
|
# All done.
|
|||
|
|
torture-finish
|
|||
|
|
dg-finish
|
|||
|
|
--
|
|||
|
|
2.27.0.windows.1
|
|||
|
|
|