Re: [PATCH 8/9 v3] lto: Add toplevel simple assembly heuristics
> >
> > I would add a dump file which shows what asm statements made symbol to
> > go global for easier debugging later (I suppose eventually this may get
> > us surprises)
> > > +
> > > + l = 0;
> > > + }
> > > +
> > > + /* Prevent overflow. */
> > > + if (l >= ident_buffer_size)
> > > + {
> > > + ident_buffer_size *= 2;
> > > + ident = (char*) xrealloc (ident, ident_buffer_size);
> >
> > Perhas auto_vec and safe_push would be more readable (and less
> > effecient) way to do this in this millenia?
> > Honza
>
> Changes in v3:
> Applied the suggested changes.
>
> ---
>
> This new pass heuristically detects symbols referenced by toplevel
> assembly to prevent their optimization.
>
> Heuristics is done by comparing identifiers in assembly to known
> symbols.
>
> The pass is split into 2 passes, in LGEN and in WPA.
> There must be one pass for WPA to be able to reference any symbol.
> However in WPA there may be multiple symbols with the same name,
> so we handle those local symbols in LGEN.
>
> gcc/ChangeLog:
>
> * asm-toplevel.cc (mark_fragile_ref_by_asm):
> Add marked_local to handle symbol as local.
> (ipa_asm_heuristics): New.
> (class pass_ipa_asm): New.
> (make_pass_ipa_asm_lgen): New.
> (make_pass_ipa_asm_wpa): New.
> * common.opt: New flto-toplevel-asm-heuristics.
> * passes.def: New asm passes.
> * timevar.def (TV_IPA_LTO_ASM): New.
> * tree-pass.h (make_pass_ipa_asm_lgen): New.
> (make_pass_ipa_asm_wpa): New.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/lto/toplevel-simple-asm-1_0.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-1_1.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-2_0.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-2_1.c: New test.
OK,
Honza
Re: [PATCH 8/9 v3] lto: Add toplevel simple assembly heuristics
WMichal Jires writes:
>>
>> I would add a dump file which shows what asm statements made symbol to
>> go global for easier debugging later (I suppose eventually this may get
>> us surprises)
>> > +
>> > +l = 0;
>> > + }
>> > +
>> > +/* Prevent overflow. */
>> > +if (l >= ident_buffer_size)
>> > + {
>> > +ident_buffer_size *= 2;
>> > +ident = (char*) xrealloc (ident, ident_buffer_size);
>>
>> Perhas auto_vec and safe_push would be more readable (and less
>> effecient) way to do this in this millenia?
>> Honza
>
> Changes in v3:
> Applied the suggested changes.
>
This testcase ICEs with v3 of the series (not checked exactly which
patch, I assume this one):
__asm("");
char main_argv;
$ gcc -flto x.ii
lto1: error: type variant has different ‘TREE_TYPE’
unit-size
align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e0173f0 precision:8 min max
>
QI size unit-size
align:8 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality
domain
unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e017738 precision:64 min max >
DI size unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e017738 precision:64 min max >>
lto1: error: type variant’s ‘TREE_TYPE’
constant 8>
unit-size constant 1>
align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e0173f0 precision:8 min max
>
lto1: error: type’s ‘TREE_TYPE’
constant 8>
unit-size constant 1>
align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e0173f0 precision:8 min max
>
unit-size
align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e0173f0 precision:8 min max
>
QI size unit-size
align:8 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality
domain
unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e017738 precision:64 min max >
DI size unit-size
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ff92e017738 precision:64 min max >>
> ---
>
> This new pass heuristically detects symbols referenced by toplevel
> assembly to prevent their optimization.
>
> Heuristics is done by comparing identifiers in assembly to known
> symbols.
>
> The pass is split into 2 passes, in LGEN and in WPA.
> There must be one pass for WPA to be able to reference any symbol.
> However in WPA there may be multiple symbols with the same name,
> so we handle those local symbols in LGEN.
>
> gcc/ChangeLog:
>
> * asm-toplevel.cc (mark_fragile_ref_by_asm):
> Add marked_local to handle symbol as local.
> (ipa_asm_heuristics): New.
> (class pass_ipa_asm): New.
> (make_pass_ipa_asm_lgen): New.
> (make_pass_ipa_asm_wpa): New.
> * common.opt: New flto-toplevel-asm-heuristics.
> * passes.def: New asm passes.
> * timevar.def (TV_IPA_LTO_ASM): New.
> * tree-pass.h (make_pass_ipa_asm_lgen): New.
> (make_pass_ipa_asm_wpa): New.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/lto/toplevel-simple-asm-1_0.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-1_1.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-2_0.c: New test.
> * gcc.dg/lto/toplevel-simple-asm-2_1.c: New test.
> ---
> gcc/asm-toplevel.cc | 145 +-
> gcc/common.opt| 4 +
> gcc/passes.def| 2 +
> .../gcc.dg/lto/toplevel-simple-asm-1_0.c | 19 +++
> .../gcc.dg/lto/toplevel-simple-asm-1_1.c | 12 ++
> .../gcc.dg/lto/toplevel-simple-asm-2_0.c | 10 ++
> .../gcc.dg/lto/toplevel-simple-asm-2_1.c | 12 ++
> gcc/timevar.def | 1 +
> gcc/tree-pass.h | 2 +
> 9 files changed, 205 insertions(+), 2 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-1_0.c
> create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-1_1.c
> create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-2_0.c
> create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-2_1.c
>
> diff --git a/gcc/asm-toplevel.cc b/gcc/asm-toplevel.cc
> index 576e4b3ba73..5ab5b668d50 100644
> --- a/gcc/asm-toplevel.cc
> +++ b/gcc/asm-toplevel.cc
> @@ -29,11 +29,11 @@ along with GCC; see the file COPYING3. If not see
> /* This symbol must be available and cannot be renamed.
> Marks the symbol and symbols that reference it. */
> static void
> -mark_fragile_ref_by_asm (symtab_node* node)
> +mark_fragile_ref_by_asm (symtab_node* node, bool maybe_local = false)
> {
>node->ref_by_asm = true;
>/* Local symbols must remain in the same partition with their callers. */
> - if (!TREE_PUBLIC (node->decl))
> + if (!TREE_PUBLIC (node->decl) || may
[PATCH 8/9 v3] lto: Add toplevel simple assembly heuristics
>
> I would add a dump file which shows what asm statements made symbol to
> go global for easier debugging later (I suppose eventually this may get
> us surprises)
> > +
> > + l = 0;
> > + }
> > +
> > + /* Prevent overflow. */
> > + if (l >= ident_buffer_size)
> > + {
> > + ident_buffer_size *= 2;
> > + ident = (char*) xrealloc (ident, ident_buffer_size);
>
> Perhas auto_vec and safe_push would be more readable (and less
> effecient) way to do this in this millenia?
> Honza
Changes in v3:
Applied the suggested changes.
---
This new pass heuristically detects symbols referenced by toplevel
assembly to prevent their optimization.
Heuristics is done by comparing identifiers in assembly to known
symbols.
The pass is split into 2 passes, in LGEN and in WPA.
There must be one pass for WPA to be able to reference any symbol.
However in WPA there may be multiple symbols with the same name,
so we handle those local symbols in LGEN.
gcc/ChangeLog:
* asm-toplevel.cc (mark_fragile_ref_by_asm):
Add marked_local to handle symbol as local.
(ipa_asm_heuristics): New.
(class pass_ipa_asm): New.
(make_pass_ipa_asm_lgen): New.
(make_pass_ipa_asm_wpa): New.
* common.opt: New flto-toplevel-asm-heuristics.
* passes.def: New asm passes.
* timevar.def (TV_IPA_LTO_ASM): New.
* tree-pass.h (make_pass_ipa_asm_lgen): New.
(make_pass_ipa_asm_wpa): New.
gcc/testsuite/ChangeLog:
* gcc.dg/lto/toplevel-simple-asm-1_0.c: New test.
* gcc.dg/lto/toplevel-simple-asm-1_1.c: New test.
* gcc.dg/lto/toplevel-simple-asm-2_0.c: New test.
* gcc.dg/lto/toplevel-simple-asm-2_1.c: New test.
---
gcc/asm-toplevel.cc | 145 +-
gcc/common.opt| 4 +
gcc/passes.def| 2 +
.../gcc.dg/lto/toplevel-simple-asm-1_0.c | 19 +++
.../gcc.dg/lto/toplevel-simple-asm-1_1.c | 12 ++
.../gcc.dg/lto/toplevel-simple-asm-2_0.c | 10 ++
.../gcc.dg/lto/toplevel-simple-asm-2_1.c | 12 ++
gcc/timevar.def | 1 +
gcc/tree-pass.h | 2 +
9 files changed, 205 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-1_0.c
create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-1_1.c
create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-2_0.c
create mode 100644 gcc/testsuite/gcc.dg/lto/toplevel-simple-asm-2_1.c
diff --git a/gcc/asm-toplevel.cc b/gcc/asm-toplevel.cc
index 576e4b3ba73..5ab5b668d50 100644
--- a/gcc/asm-toplevel.cc
+++ b/gcc/asm-toplevel.cc
@@ -29,11 +29,11 @@ along with GCC; see the file COPYING3. If not see
/* This symbol must be available and cannot be renamed.
Marks the symbol and symbols that reference it. */
static void
-mark_fragile_ref_by_asm (symtab_node* node)
+mark_fragile_ref_by_asm (symtab_node* node, bool maybe_local = false)
{
node->ref_by_asm = true;
/* Local symbols must remain in the same partition with their callers. */
- if (!TREE_PUBLIC (node->decl))
+ if (!TREE_PUBLIC (node->decl) || maybe_local)
{
unsigned j;
ipa_ref *ref;
@@ -116,3 +116,144 @@ analyze_toplevel_extended_asm ()
walk_tree (&l, walk_through_constraints, (void*) &data, NULL);
}
}
+
+
+/* Checks all toplevel assembly contents and compares them with known symbols.
+ Marks those symbols with relevant flags.
+ Heuristics: Detects anything in assembly that looks like an identifer.
+
+ This pass must be in WPA, otherwise we will not see all possibly referenced
+ symbols - if a symbol is only declared, it will not be in the callgraph if
+ it is only referenced from toplevel assembly.
+ However in WPA there may be multiple symbols with the same identifier.
+ The chosen solution is to handle local symbols in LGEN pass first. */
+
+void
+ipa_asm_heuristics ()
+{
+ hash_map map;
+ asm_node *anode = symtab->first_asm_symbol ();
+ if (!anode)
+return;
+
+ symtab_node* snode;
+ if (flag_wpa)
+{
+ FOR_EACH_SYMBOL (snode)
+ if (TREE_PUBLIC (snode->decl))
+ map.put (snode->asm_name (), snode);
+}
+ else
+{
+ FOR_EACH_SYMBOL (snode)
+ map.put (snode->asm_name (), snode);
+}
+
+ auto_vec ident;
+
+ for (; anode; anode = safe_as_a (anode->next))
+{
+ if (TREE_CODE (anode->asm_str) != STRING_CST)
+ continue;
+
+ const char *asm_str = TREE_STRING_POINTER (anode->asm_str);
+ int asm_len = TREE_STRING_LENGTH (anode->asm_str);
+
+ if (dump_file)
+ fprintf (dump_file, "Searching for symbols in toplevel asm:\n%s\n---\n",
+asm_str);
+
+ for (int i = 0; i < asm_len + 1; ++i)
+ {
+ char c = 0;
+ if (i < asm_len)
+ c = asm_str[i];
+
+ if ('0' <= c && c <= '9')
+
