https://gcc.gnu.org/g:c8b6ac52adc35d5ed8476fbf774995240de3d490
commit r16-6689-gc8b6ac52adc35d5ed8476fbf774995240de3d490 Author: Michal Jires <[email protected]> Date: Sat Nov 15 19:54:11 2025 +0100 ipa: Analyze toplevel extended assembly 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. Diff: --- gcc/Makefile.in | 1 + gcc/asm-toplevel.cc | 68 +++++++++++++++++++++++++++++++++++++ gcc/cgraph.h | 6 +++- 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(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 4bd05a60cf20..b41cf5df849f 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1416,6 +1416,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 000000000000..336564bb95e0 --- /dev/null +++ b/gcc/asm-toplevel.cc @@ -0,0 +1,68 @@ +/* Toplevel assembly. + Copyright (C) 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 = safe_as_a<asm_node*> (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 f0f31c1487c5..c36020d06168 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -2367,11 +2367,15 @@ private: struct GTY ((tag ("TOPLEVEL_ASM"))) asm_node: public toplevel_node { explicit asm_node (tree asm_str) - : toplevel_node (TOPLEVEL_ASM), asm_str (asm_str) + : toplevel_node (TOPLEVEL_ASM), asm_str (asm_str), symbols_referenced () {} /* 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 8a29cafa0f95..88c1071c8de9 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -2583,6 +2583,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 85d5f72366b6..37888361904c 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 000000000000..bec608ad4865 --- /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() {}
