]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa: Analyze toplevel extended assembly
authorMichal Jires <mjires@suse.cz>
Sat, 15 Nov 2025 18:54:11 +0000 (19:54 +0100)
committerMichal Jires <mjires@suse.cz>
Sun, 11 Jan 2026 21:48:54 +0000 (22:48 +0100)
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
gcc/asm-toplevel.cc [new file with mode: 0644]
gcc/cgraph.h
gcc/cgraphunit.cc
gcc/lto/lto-common.cc
gcc/testsuite/gcc.dg/ipa/pr122458.c [new file with mode: 0644]

index 4bd05a60cf2080dfdc81657ba207a56db9c5d431..b41cf5df849fffe82b5c75271c492f437cf698fc 100644 (file)
@@ -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 (file)
index 0000000..336564b
--- /dev/null
@@ -0,0 +1,68 @@
+/* Toplevel assembly.
+   Copyright (C) 2025 Free Software Foundation, Inc.
+   Contributed by Michal Jires <mjires@suse.cz>
+
+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);
+    }
+}
index f0f31c1487c58960b1c5a5f84b4152a2f1c74af2..c36020d061687546dbb411f0addf42dc0a75effd 100644 (file)
@@ -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.  */
 
index 8a29cafa0f959bf83a1129c0da8548fcabf36856..88c1071c8de918e1e5e80953f014cd53dd72c9bc 100644 (file)
@@ -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);
index 85d5f72366b69051c23a5e76c7981f441b5fa9ea..37888361904c47947f455fc92565373b4e613b28 100644 (file)
@@ -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 (file)
index 0000000..bec608a
--- /dev/null
@@ -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() {}