259 lines
7.4 KiB
Diff
259 lines
7.4 KiB
Diff
From c6370dc949c39319ef1c31d0b42efc041d27379a Mon Sep 17 00:00:00 2001
|
|
From: huang-xiaoquan <huangxiaoquan1@huawei.com>
|
|
Date: Thu, 8 Jun 2023 11:37:09 +0800
|
|
Subject: [PATCH] [Struct Reorg] Add escape propagate on external functions
|
|
using type
|
|
|
|
External functions may use members of members through structure pointers.
|
|
Therefore, escape propagation of member types of types used by external
|
|
functions is added.
|
|
---
|
|
gcc/ipa-struct-reorg/ipa-struct-reorg.c | 71 +++++++++++++++++--
|
|
gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c | 7 ++
|
|
.../gcc.dg/struct/rf_external_func_types.c | 69 ++++++++++++++++++
|
|
3 files changed, 140 insertions(+), 7 deletions(-)
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/rf_external_func_types.c
|
|
|
|
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
index 7de4fee0e..367bcf210 100644
|
|
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
@@ -1412,6 +1412,7 @@ public:
|
|
srglobal globals;
|
|
srfunction *current_function;
|
|
hash_set <cgraph_node *> safe_functions;
|
|
+ auto_vec<srtype *> ext_func_types;
|
|
|
|
bool done_recording;
|
|
|
|
@@ -1426,6 +1427,7 @@ public:
|
|
void propagate_escape (void);
|
|
void propagate_escape_via_original (void);
|
|
void propagate_escape_via_empty_with_no_original (void);
|
|
+ void propagate_escape_via_ext_func_types (void);
|
|
void analyze_types (void);
|
|
void clear_visited (void);
|
|
bool create_new_types (void);
|
|
@@ -3131,7 +3133,14 @@ ipa_struct_reorg::record_type (tree type)
|
|
return NULL;
|
|
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
- fprintf (dump_file, "Recording new type: %u.\n", typeuid);
|
|
+ {
|
|
+ fprintf (dump_file, "Recording new type: %u.\n", typeuid);
|
|
+ const char *type_name = get_type_name (type);
|
|
+ if (type_name == NULL)
|
|
+ fprintf (dump_file, "Recording new type NULL name\n");
|
|
+ else
|
|
+ fprintf (dump_file, "Recording new type name: %s.\n", type_name);
|
|
+ }
|
|
|
|
type1 = new srtype (type);
|
|
types.safe_push (type1);
|
|
@@ -4478,6 +4487,18 @@ ipa_struct_reorg::maybe_record_call (cgraph_node *node, gcall *stmt)
|
|
gimple_call_arg (stmt, i));
|
|
if (d)
|
|
d->type->mark_escape (escapes, stmt);
|
|
+
|
|
+ if (escapes == escape_external_function
|
|
+ && !gimple_call_builtin_p (stmt, BUILT_IN_MEMSET))
|
|
+ {
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
|
+ {
|
|
+ fprintf (dump_file, "escape_external_function: ");
|
|
+ print_gimple_stmt (dump_file, stmt, 0);
|
|
+ }
|
|
+ if (d)
|
|
+ ext_func_types.safe_push (d->type);
|
|
+ }
|
|
}
|
|
return;
|
|
}
|
|
@@ -5672,6 +5693,35 @@ ipa_struct_reorg::propagate_escape_via_empty_with_no_original (void)
|
|
}
|
|
}
|
|
|
|
+/* Escape propagation is performed on types that escape through external
|
|
+ functions. */
|
|
+
|
|
+void
|
|
+ipa_struct_reorg::propagate_escape_via_ext_func_types (void)
|
|
+{
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
|
+ fprintf (dump_file, "\n propagate_escape_via_ext_func_types: \n\n");
|
|
+ unsigned i = 0;
|
|
+ hash_set<srtype *> visited_types;
|
|
+ while (i < ext_func_types.length ())
|
|
+ {
|
|
+ visited_types.add (ext_func_types[i]);
|
|
+ unsigned j = 0;
|
|
+ srfield * field;
|
|
+ FOR_EACH_VEC_ELT (ext_func_types[i]->fields, j, field)
|
|
+ {
|
|
+ if (field->type)
|
|
+ {
|
|
+ if (!field->type->has_escaped ())
|
|
+ field->type->mark_escape (escape_dependent_type_escapes, NULL);
|
|
+ if (!visited_types.contains (field->type))
|
|
+ ext_func_types.safe_push (field->type);
|
|
+ }
|
|
+ }
|
|
+ i++;
|
|
+ }
|
|
+}
|
|
+
|
|
/* Prune the escaped types and their decls from what was recorded. */
|
|
|
|
void
|
|
@@ -5689,6 +5739,7 @@ ipa_struct_reorg::prune_escaped_types (void)
|
|
{
|
|
propagate_escape_via_original ();
|
|
propagate_escape_via_empty_with_no_original ();
|
|
+ propagate_escape_via_ext_func_types ();
|
|
}
|
|
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
@@ -8242,8 +8293,9 @@ ipa_struct_reorg::rewrite_functions (void)
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
{
|
|
fprintf (dump_file, "\nNo rewrite:\n");
|
|
- dump_function_to_file (current_function_decl, dump_file,
|
|
- dump_flags | TDF_VOPS);
|
|
+ if (current_function_decl)
|
|
+ dump_function_to_file (current_function_decl, dump_file,
|
|
+ dump_flags | TDF_VOPS);
|
|
}
|
|
pop_cfun ();
|
|
}
|
|
@@ -8278,8 +8330,9 @@ ipa_struct_reorg::rewrite_functions (void)
|
|
{
|
|
fprintf (dump_file, "==== Before create decls: %dth_%s ====\n\n",
|
|
i, f->node->name ());
|
|
- dump_function_to_file (current_function_decl, dump_file,
|
|
- dump_flags | TDF_VOPS);
|
|
+ if (current_function_decl)
|
|
+ dump_function_to_file (current_function_decl, dump_file,
|
|
+ dump_flags | TDF_VOPS);
|
|
}
|
|
pop_cfun ();
|
|
}
|
|
@@ -8313,8 +8366,9 @@ ipa_struct_reorg::rewrite_functions (void)
|
|
{
|
|
fprintf (dump_file, "\nBefore rewrite: %dth_%s\n",
|
|
i, f->node->name ());
|
|
- dump_function_to_file (current_function_decl, dump_file,
|
|
- dump_flags | TDF_VOPS);
|
|
+ if (current_function_decl)
|
|
+ dump_function_to_file (current_function_decl, dump_file,
|
|
+ dump_flags | TDF_VOPS);
|
|
fprintf (dump_file, "\n======== Start to rewrite: %dth_%s ========\n",
|
|
i, f->node->name ());
|
|
}
|
|
@@ -8659,6 +8713,9 @@ ipa_struct_reorg::execute (unsigned int opt)
|
|
{
|
|
unsigned int ret = 0;
|
|
|
|
+ if (dump_file)
|
|
+ fprintf (dump_file, "\n\n====== ipa_struct_reorg level %d ======\n\n", opt);
|
|
+
|
|
if (opt != COMPLETE_STRUCT_RELAYOUT)
|
|
{
|
|
current_layout_opt_level = opt;
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c
|
|
index e56bf467b..f9e2cf471 100644
|
|
--- a/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_claw.c
|
|
@@ -42,6 +42,13 @@ 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)
|
|
{
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/rf_external_func_types.c b/gcc/testsuite/gcc.dg/struct/rf_external_func_types.c
|
|
new file mode 100644
|
|
index 000000000..2a9bea783
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/rf_external_func_types.c
|
|
@@ -0,0 +1,69 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-additional-options "-shared" } */
|
|
+
|
|
+#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
|
|
+{
|
|
+ int x;
|
|
+ arc_p arcs, sorted_arcs;
|
|
+ node_p nodes, 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;
|
|
+};
|
|
+
|
|
+extern int bcf_sr_add_reader (network_t *);
|
|
+extern int bcf_hdr_dup (arc_p);
|
|
+
|
|
+int
|
|
+test ()
|
|
+{
|
|
+ network_t *net = (network_t *) calloc (1, 20);
|
|
+
|
|
+ if (!bcf_sr_add_reader(net))
|
|
+ printf("error");
|
|
+ arc_p arc = net->nodes->basic_arc;
|
|
+ if(!bcf_hdr_dup(arc))
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */
|
|
\ No newline at end of file
|
|
--
|
|
2.33.0
|
|
|