public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Michael Matz <matz@suse.de>
To: binutils@sourceware.org
Subject: [PATCH 1/8] section-select: Lazily resolve section matches
Date: Fri, 25 Nov 2022 16:44:54 +0000 (UTC)	[thread overview]
Message-ID: <alpine.LSU.2.20.2211251644290.24878@wotan.suse.de> (raw)
In-Reply-To: <cover.1669391757.git.matz@suse.de>

and remember the results.  Before this the order of section matching
is basically:

  foreach script-wild-stmt S
    foreach pattern P of S
      foreach inputfile I
        foreach section S of I
	  match S against P
	    if match: do action for S

And this process is done three or four times: for each top-level call to
walk_wild() or wild(), that is: check_input_sections, lang_gc_sections,
lang_find_relro_sections and of course map_input_to_output_sections.

So we iterate over all sections of all files many many times (for each
glob).  Reality is a bit more complicated (some special glob types don't
need the full iteration over all sections, only over all files), but
that's the gist of it.

For future work this shuffles the whole ordering a bit by lazily doing
the matching process and memoizing results, trading a little memory for
a 75% speedup of the overall section selection process.

This lazy resolution introduces a problem with sections added late
that's corrected in the next patch.
---
 ld/ldlang.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 ld/ldlang.h | 12 ++++++++
 2 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 81a6aeb7a89..c92ebd472f4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1072,8 +1072,27 @@ walk_wild_file (lang_wild_statement_type *s,
     }
 }
 
+static lang_statement_union_type *
+new_statement (enum statement_enum type,
+	       size_t size,
+	       lang_statement_list_type *list);
 static void
-walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
+add_matching_callback (lang_wild_statement_type *ptr,
+		       struct wildcard_list *sec,
+		       asection *section,
+		       lang_input_statement_type *file,
+		       void *data ATTRIBUTE_UNUSED)
+{
+  lang_input_matcher_type *new_section;
+  /* Add a section reference to the list.  */
+  new_section = new_stat (lang_input_matcher, &ptr->matching_sections);
+  new_section->section = section;
+  new_section->pattern = sec;
+  new_section->input_stmt = file;
+}
+
+static void
+walk_wild_resolve (lang_wild_statement_type *s)
 {
   const char *file_spec = s->filename;
   char *p;
@@ -1083,6 +1102,66 @@ walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
       /* Perform the iteration over all files in the list.  */
       LANG_FOR_EACH_INPUT_STATEMENT (f)
 	{
+	  //printf("XXX   %s\n", f->filename);
+	  walk_wild_file (s, f, add_matching_callback, NULL);
+	}
+    }
+  else if ((p = archive_path (file_spec)) != NULL)
+    {
+      LANG_FOR_EACH_INPUT_STATEMENT (f)
+	{
+	  if (input_statement_is_archive_path (file_spec, p, f))
+	    walk_wild_file (s, f, add_matching_callback, NULL);
+	}
+    }
+  else if (wildcardp (file_spec))
+    {
+      LANG_FOR_EACH_INPUT_STATEMENT (f)
+	{
+	  if (fnmatch (file_spec, f->filename, 0) == 0)
+	    walk_wild_file (s, f, add_matching_callback, NULL);
+	}
+    }
+  else
+    {
+      lang_input_statement_type *f;
+
+      /* Perform the iteration over a single file.  */
+      f = lookup_name (file_spec);
+      if (f)
+	walk_wild_file (s, f, add_matching_callback, NULL);
+    }
+}
+
+static void
+walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
+{
+  const char *file_spec = s->filename;
+  //char *p;
+
+  if (!s->resolved)
+    {
+      //printf("XXX %s\n", file_spec ? file_spec : "<null>");
+      walk_wild_resolve (s);
+      s->resolved = true;
+    }
+
+    {
+      lang_statement_union_type *l;
+      for (l = s->matching_sections.head; l; l = l->header.next)
+	{
+	  (*callback) (s, l->input_matcher.pattern, l->input_matcher.section, l->input_matcher.input_stmt, data);
+	}
+      return;
+    }
+
+#if 0
+  if (file_spec == NULL)
+    {
+      /* Perform the iteration over all files in the list.  */
+      LANG_FOR_EACH_INPUT_STATEMENT (f)
+	{
+	  printf("XXX   %s\n", f->filename);
 	  walk_wild_file (s, f, callback, data);
 	}
     }
@@ -1111,6 +1190,7 @@ walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
       if (f)
 	walk_wild_file (s, f, callback, data);
     }
+#endif
 }
 
 /* lang_for_each_statement walks the parse tree and calls the provided
@@ -1982,6 +2062,8 @@ insert_os_after (lang_output_section_statement_type *after)
 	case lang_group_statement_enum:
 	case lang_insert_statement_enum:
 	  continue;
+	case lang_input_matcher_enum:
+	  FAIL ();
 	}
       break;
     }
@@ -4347,6 +4429,8 @@ map_input_to_output_sections
 	  break;
 	case lang_insert_statement_enum:
 	  break;
+	case lang_input_matcher_enum:
+	  FAIL ();
 	}
     }
 }
@@ -8343,6 +8427,8 @@ lang_add_wild (struct wildcard_spec *filespec,
   new_stmt->section_list = section_list;
   new_stmt->keep_sections = keep_sections;
   lang_list_init (&new_stmt->children);
+  new_stmt->resolved = false;
+  lang_list_init (&new_stmt->matching_sections);
   analyze_walk_wild_section_handler (new_stmt);
 }
 
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 713c5282b55..50ad64ce057 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -76,6 +76,7 @@ enum statement_enum
   lang_fill_statement_enum,
   lang_group_statement_enum,
   lang_input_section_enum,
+  lang_input_matcher_enum,
   lang_input_statement_enum,
   lang_insert_statement_enum,
   lang_output_section_statement_enum,
@@ -335,6 +336,14 @@ typedef struct
   void *pattern;
 } lang_input_section_type;
 
+typedef struct
+{
+  lang_statement_header_type header;
+  asection *section;
+  void *pattern;
+  lang_input_statement_type *input_stmt;
+} lang_input_matcher_type;
+
 struct map_symbol_def {
   struct bfd_link_hash_entry *entry;
   struct map_symbol_def *next;
@@ -389,6 +398,8 @@ struct lang_wild_statement_struct
   bool keep_sections;
   lang_statement_list_type children;
   struct name_list *exclude_name_list;
+  lang_statement_list_type matching_sections;
+  bool resolved;
 
   walk_wild_section_handler_t walk_wild_section_handler;
   struct wildcard_list *handler_data[4];
@@ -440,6 +451,7 @@ typedef union lang_statement_union
   lang_fill_statement_type fill_statement;
   lang_group_statement_type group_statement;
   lang_input_section_type input_section;
+  lang_input_matcher_type input_matcher;
   lang_input_statement_type input_statement;
   lang_insert_statement_type insert_statement;
   lang_output_section_statement_type output_section_statement;
-- 
2.36.1


       reply	other threads:[~2022-11-25 16:44 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1669391757.git.matz@suse.de>
2022-11-25 16:44 ` Michael Matz [this message]
2022-11-25 16:46 ` [PATCH 2/8] section-select: Deal with sections added late Michael Matz
2022-11-25 16:47 ` [PATCH 3/8] section-select: Implement a prefix-tree Michael Matz
2022-11-25 16:55 ` [PATCH 4/8] section-select: Completely rebuild matches Michael Matz
2022-11-28  1:57   ` Alan Modra
2022-11-28 14:24     ` Michael Matz
2022-11-29 12:22       ` Alan Modra
2022-11-29 13:23         ` Michael Matz
2022-11-25 16:55 ` [PATCH 5/8] section-select: Remove unused code Michael Matz
2022-11-25 16:55 ` [PATCH 6/8] section-select: Cleanup Michael Matz
2022-11-25 16:57 ` [PATCH 7/8] section-select: Remove bfd_max_section_id again Michael Matz
2022-11-25 16:58 ` [PATCH 8/8] section-select: Fix exclude-file-3 Michael Matz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LSU.2.20.2211251644290.24878@wotan.suse.de \
    --to=matz@suse.de \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).