Analyzes references from toplevel extended assembly.
We cannot perform IPA optimizations with toplevel assembly, so
symtab_node only needs ref_by_asm to know that it should not be removed.
PR ipa/122458
gcc/ChangeLog:
* Makefile.in: Add new file.
* cgraph.h (analyze_toplevel_extended_asm): New.
* cgraphunit.cc (symbol_table::finalize_compilation_unit):
Call analyze_toplevel_extended_asm.
* asm-toplevel.cc: New file.
gcc/lto/ChangeLog:
* lto-common.cc (read_cgraph_and_symbols):
Call analyze_toplevel_extended_asm.
gcc/testsuite/ChangeLog:
* gcc.dg/ipa/pr122458.c: New test.
---
gcc/Makefile.in | 1 +
gcc/asm-toplevel.cc | 67 +++++++++++++++++++++++++++++
gcc/cgraph.h | 7 ++-
gcc/cgraphunit.cc | 2 +
gcc/lto/lto-common.cc | 1 +
gcc/testsuite/gcc.dg/ipa/pr122458.c | 9 ++++
6 files changed, 86 insertions(+), 1 deletion(-)
create mode 100644 gcc/asm-toplevel.cc
create mode 100644 gcc/testsuite/gcc.dg/ipa/pr122458.c
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index d05e15e2b6c..c3f36c5285d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1409,6 +1409,7 @@ OBJS = \
adjust-alignment.o \
alias.o \
alloc-pool.o \
+ asm-toplevel.o \
auto-inc-dec.o \
auto-profile.o \
bb-reorder.o \
diff --git a/gcc/asm-toplevel.cc b/gcc/asm-toplevel.cc
new file mode 100644
index 00000000000..9d7ba934e29
--- /dev/null
+++ b/gcc/asm-toplevel.cc
@@ -0,0 +1,67 @@
+/* Toplevel assembly.
+ Copyright (C) 2025-2025 Free Software Foundation, Inc.
+ Contributed by Michal Jires <[email protected]>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "cgraph.h"
+
+/* Mark symbols in constraints. */
+static tree
+walk_through_constraints (tree* t, int*, void* data)
+{
+ asm_node* anode = (asm_node*) data;
+ if (VAR_OR_FUNCTION_DECL_P (*t))
+ {
+ symtab_node* node;
+ if (!flag_wpa && !flag_ltrans)
+ {
+ node = symtab_node::get_create (*t);
+ node->ref_by_asm = true;
+ }
+ else
+ {
+ node = symtab_node::get (*t);
+ gcc_assert (node);
+ }
+ anode->symbols_referenced.safe_push (node);
+ }
+ return NULL;
+}
+
+/* Analyze constraints of toplevel extended assembly. */
+void
+analyze_toplevel_extended_asm ()
+{
+ asm_node *anode;
+ for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
+ {
+ if (TREE_CODE (anode->asm_str) != ASM_EXPR)
+ continue;
+
+ for (tree l = ASM_INPUTS (anode->asm_str); l; l = TREE_CHAIN (l))
+ walk_tree (&l, walk_through_constraints, (void*) anode, NULL);
+ for (tree l = ASM_OUTPUTS (anode->asm_str); l; l = TREE_CHAIN (l))
+ walk_tree (&l, walk_through_constraints, (void*) anode, NULL);
+ }
+}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 4aed690bac9..036a89da9cb 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -2246,13 +2246,18 @@ private:
struct GTY ((tag ("TOPLEVEL_ASM"))) asm_node: public toplevel_node {
explicit asm_node (tree asm_str)
- : toplevel_node (TOPLEVEL_ASM), next (NULL), asm_str (asm_str)
+ : toplevel_node (TOPLEVEL_ASM), next (NULL), asm_str (asm_str),
+ symbols_referenced ()
{}
/* Next asm node. */
asm_node *next;
/* String for this asm node. */
tree asm_str;
+ /* Vector of referenced symbols used for LTO partitioning.
+ Not populated in flag_ltrans. */
+ vec<symtab_node*> GTY ((skip)) symbols_referenced;
};
+void analyze_toplevel_extended_asm (void);
/* Report whether or not THIS symtab node is a function, aka cgraph_node. */
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index d50ffd270b6..e27bee1309b 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -2581,6 +2581,8 @@ symbol_table::finalize_compilation_unit (void)
if (flag_dump_passes)
dump_passes ();
+ analyze_toplevel_extended_asm ();
+
/* Gimplify and lower all functions, compute reachability and
remove unreachable nodes. */
analyze_functions (/*first_time=*/true);
diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
index 3d35c038916..f5e3c53bbe5 100644
--- a/gcc/lto/lto-common.cc
+++ b/gcc/lto/lto-common.cc
@@ -2998,6 +2998,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char
**fnames)
symtab->dump (dump_file);
}
lto_symtab_merge_symbols ();
+ analyze_toplevel_extended_asm ();
/* Removal of unreachable symbols is needed to make verify_symtab to
pass;
we are still having duplicated comdat groups containing local statics.
We could also just remove them while merging. */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr122458.c
b/gcc/testsuite/gcc.dg/ipa/pr122458.c
new file mode 100644
index 00000000000..bec608ad486
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr122458.c
@@ -0,0 +1,9 @@
+/* PR ipa/122458 */
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+static int foo (void) { return 0; };
+
+asm (".quad %c0" :: "i" (foo));
+
+int main() {}
--
2.51.1