[gcc r15-1062] lto: Skip flag OPT_fltrans_output_list_.

2024-06-06 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:ca43678c3d8aff1b8774e0b05c9a4a42fd271b13

commit r15-1062-gca43678c3d8aff1b8774e0b05c9a4a42fd271b13
Author: Michal Jires 
Date:   Fri Nov 17 21:16:37 2023 +0100

lto: Skip flag OPT_fltrans_output_list_.

Bootstrapped/regtested on x86_64-pc-linux-gnu

gcc/ChangeLog:

* lto-opts.cc (lto_write_options): Skip OPT_fltrans_output_list_.

Diff:
---
 gcc/lto-opts.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/lto-opts.cc b/gcc/lto-opts.cc
index b3d19f8b361..a3a1d110329 100644
--- a/gcc/lto-opts.cc
+++ b/gcc/lto-opts.cc
@@ -152,6 +152,7 @@ lto_write_options (void)
case OPT_fprofile_prefix_map_:
case OPT_fcanon_prefix_map:
case OPT_fwhole_program:
+   case OPT_fltrans_output_list_:
  continue;
 
default:


[gcc r15-1063] lto: Remove random_seed from section name.

2024-06-06 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:346f33e27809ae012696c4731c8ebcec2414dbfb

commit r15-1063-g346f33e27809ae012696c4731c8ebcec2414dbfb
Author: Michal Jires 
Date:   Tue Jan 9 17:49:34 2024 +0100

lto: Remove random_seed from section name.

This patch removes suffixes from section names during LTO linking.

These suffixes were originally added for ld -r to work (PR lto/44992).
They were added to all LTO object files, but are only useful before WPA.
After that they waste space, and if kept random, make LTO caching 
impossible.

Bootstrapped/regtested on x86_64-pc-linux-gnu

gcc/ChangeLog:

* lto-streamer.cc (lto_get_section_name): Remove suffixes after WPA.

gcc/lto/ChangeLog:

* lto-common.cc (lto_section_with_id): Dont load suffix during 
LTRANS.

Diff:
---
 gcc/lto-streamer.cc   | 11 +--
 gcc/lto/lto-common.cc |  7 +++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/lto-streamer.cc b/gcc/lto-streamer.cc
index 8032bbf7108..40ca6b2da1b 100644
--- a/gcc/lto-streamer.cc
+++ b/gcc/lto-streamer.cc
@@ -132,11 +132,18 @@ lto_get_section_name (int section_type, const char *name,
  doesn't confuse the reader with merged sections.
 
  For options don't add a ID, the option reader cannot deal with them
- and merging should be ok here. */
-  if (section_type == LTO_section_opts)
+ and merging should be ok here.
+
+ LTRANS files (output of wpa, input and output of ltrans) are handled
+ directly inside of linker/lto-wrapper, so name uniqueness for external
+ tools is not needed.
+ Randomness would inhibit incremental LTO.  */
+  if (section_type == LTO_section_opts || flag_ltrans)
 strcpy (post, "");
   else if (f != NULL) 
 sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
+  else if (flag_wpa)
+strcpy (post, "");
   else
 sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false)); 
   char *res = concat (section_name_prefix, sep, add, post, NULL);
diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
index 2ce94cc3282..34aa63b179c 100644
--- a/gcc/lto/lto-common.cc
+++ b/gcc/lto/lto-common.cc
@@ -2176,6 +2176,13 @@ lto_section_with_id (const char *name, unsigned 
HOST_WIDE_INT *id)
 
   if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
 return 0;
+
+  if (flag_ltrans)
+{
+  *id = 0;
+  return 1;
+}
+
   s = strrchr (name, '.');
   if (!s)
 return 0;


[gcc r15-1099] lto: Implement cache partitioning

2024-06-07 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:5b6d5a886ee45bb969b4de23528311472b4ab66b

commit r15-1099-g5b6d5a886ee45bb969b4de23528311472b4ab66b
Author: Michal Jires 
Date:   Fri Nov 17 21:17:18 2023 +0100

lto: Implement cache partitioning

This patch implements new cache partitioning. It tries to keep symbols
from single source file together to minimize propagation of divergence.

It starts with symbols already grouped by source files. If reasonably
possible it only either combines several files into one final partition,
or, if a file is large, split the file into several final partitions.

Intermediate representation is partition_set which contains set of
groups of symbols (each group corresponding to original source file) and
number of final partitions this partition_set should split into.

First partition_fixed_split splits partition_set into constant number of
partition_sets with equal number of symbols groups. If for example there
are 39 source files, the resulting partition_sets will contain 10, 10,
10, and 9 source files. This splitting intentionally ignores estimated
instruction counts to minimize propagation of divergence.

Second partition_over_target_split separates too large files and splits
them into individual symbols to be combined back into several smaller
files in next step.

Third partition_binary_split splits partition_set into two halves until
it should be split into only one final partition, at which point the
remaining symbols are joined into one final partition.

Bootstrapped/regtested on x86_64-pc-linux-gnu

gcc/ChangeLog:

* common.opt: Add cache partitioning.
* flag-types.h (enum lto_partition_model): Likewise.

gcc/lto/ChangeLog:

* lto-partition.cc (new_partition): Use new_partition_no_push.
(new_partition_no_push): New.
(free_ltrans_partition): New.
(free_ltrans_partitions): Use free_ltrans_partition.
(join_partitions): New.
(split_partition_into_nodes): New.
(is_partition_reorder): New.
(class partition_set): New.
(distribute_n_partitions): New.
(partition_over_target_split): New.
(partition_binary_split): New.
(partition_fixed_split): New.
(class partitioner_base): New.
(class partitioner_default): New.
(lto_cache_map): New.
* lto-partition.h (lto_cache_map): New.
* lto.cc (do_whole_program_analysis): Use lto_cache_map.

gcc/testsuite/ChangeLog:

* gcc.dg/completion-2.c: Add -flto-partition=cache.

Diff:
---
 gcc/common.opt  |   3 +
 gcc/flag-types.h|   3 +-
 gcc/lto/lto-partition.cc| 605 +++-
 gcc/lto/lto-partition.h |   1 +
 gcc/lto/lto.cc  |   2 +
 gcc/testsuite/gcc.dg/completion-2.c |   1 +
 6 files changed, 605 insertions(+), 10 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index 2c078fdd1f8..f2bc47fdc5e 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2233,6 +2233,9 @@ Enum(lto_partition_model) String(1to1) 
Value(LTO_PARTITION_1TO1)
 EnumValue
 Enum(lto_partition_model) String(max) Value(LTO_PARTITION_MAX)
 
+EnumValue
+Enum(lto_partition_model) String(cache) Value(LTO_PARTITION_CACHE)
+
 flto-partition=
 Common Joined RejectNegative Enum(lto_partition_model) Var(flag_lto_partition) 
Init(LTO_PARTITION_BALANCED)
 Specify the algorithm to partition symbols and vars at linktime.
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 5a2b461fa75..1e497f0bb91 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -396,7 +396,8 @@ enum lto_partition_model {
   LTO_PARTITION_ONE = 1,
   LTO_PARTITION_BALANCED = 2,
   LTO_PARTITION_1TO1 = 3,
-  LTO_PARTITION_MAX = 4
+  LTO_PARTITION_MAX = 4,
+  LTO_PARTITION_CACHE = 5
 };
 
 /* flag_lto_linker_output initialization values.  */
diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
index 19f91e5d660..44b457d0b2a 100644
--- a/gcc/lto/lto-partition.cc
+++ b/gcc/lto/lto-partition.cc
@@ -37,6 +37,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-fnsummary.h"
 #include "lto-partition.h"
 
+#include 
+#include 
+
 vec ltrans_partitions;
 
 static void add_symbol_to_partition (ltrans_partition part, symtab_node *node);
@@ -60,20 +63,41 @@ cmp_partitions_order (const void *a, const void *b)
   return orderb - ordera;
 }
 
-/* Create new partition with name NAME.  */
-
+/* Create new partition with name NAME.
+   Does not push into ltrans_partitions.  */
 static ltrans_partition
-new_partition (const char *name)
+new_partition_no_push (const char *name)
 {
   ltrans_partition part = XCNEW (struct ltrans_partition_def);
   part->encoder = lto_symtab_encoder_new (false);
   part->name = name;
   part->insns = 0;
   

[gcc r15-4977] ipcp don't propagate where not needed

2024-11-06 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:05e70ff9213159dc969a7edefc671d4ad65375f4

commit r15-4977-g05e70ff9213159dc969a7edefc671d4ad65375f4
Author: Michal Jires 
Date:   Thu Oct 24 00:52:28 2024 +0200

ipcp don't propagate where not needed

This patch disables propagation of ipcp information into partitions
where all instances of the node are marked to be inlined.

Motivation:
Incremental LTO needs stable values between compilations to be
effective. This requirement fails with following example:

void heavily_used_function(int);
...
heavily_used_function(__LINE__);

Ipcp creates long list of all __LINE__ arguments, and then
propagates it with every function clone, even though for inlined
functions this information is not useful.

gcc/ChangeLog:

* ipa-prop.cc (write_ipcp_transformation_info): Disable
uneeded value propagation.
* lto-cgraph.cc (lto_symtab_encoder_encode): Default values.
(lto_symtab_encoder_always_inlined_p): New.
(lto_set_symtab_encoder_not_always_inlined): New.
(add_node_to): Set always inlined.
* lto-streamer.h (struct lto_encoder_entry): New field.
(lto_symtab_encoder_always_inlined_p): New.

Diff:
---
 gcc/ipa-prop.cc| 12 +---
 gcc/lto-cgraph.cc  | 47 ++-
 gcc/lto-streamer.h | 11 +++
 3 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index add3a12b5848..599181d0a943 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5405,9 +5405,15 @@ write_ipcp_transformation_info (output_block *ob, 
cgraph_node *node,
   streamer_write_bitpack (&bp);
 }
 
-  streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
-  for (const ipa_vr &parm_vr : ts->m_vr)
-parm_vr.streamer_write (ob);
+  /* If all instances of this node are inlined, ipcp info is not useful.  */
+  if (!lto_symtab_encoder_only_for_inlining_p (encoder, node))
+{
+  streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
+  for (const ipa_vr &parm_vr : ts->m_vr)
+   parm_vr.streamer_write (ob);
+}
+  else
+streamer_write_uhwi (ob, 0);
 }
 
 /* Stream in the aggregate value replacement chain for NODE from IB.  */
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index b1fc694e5624..b18d2b34e468 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -113,7 +113,7 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
 
   if (!encoder->map)
 {
-  lto_encoder_entry entry = {node, false, false, false};
+  lto_encoder_entry entry (node);
 
   ref = encoder->nodes.length ();
   encoder->nodes.safe_push (entry);
@@ -123,7 +123,7 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
   size_t *slot = encoder->map->get (node);
   if (!slot || !*slot)
 {
-  lto_encoder_entry entry = {node, false, false, false};
+  lto_encoder_entry entry (node);
   ref = encoder->nodes.length ();
   if (!slot)
 encoder->map->put (node, ref + 1);
@@ -168,6 +168,15 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t 
encoder,
   return true;
 }
 
+/* Return TRUE if the NODE and its clones are always inlined.  */
+
+bool
+lto_symtab_encoder_only_for_inlining_p (lto_symtab_encoder_t encoder,
+   struct cgraph_node *node)
+{
+  int index = lto_symtab_encoder_lookup (encoder, node);
+  return encoder->nodes[index].only_for_inlining;
+}
 
 /* Return TRUE if we should encode the body of NODE (if any).  */
 
@@ -179,17 +188,6 @@ lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t 
encoder,
   return encoder->nodes[index].body;
 }
 
-/* Specify that we encode the body of NODE in this partition.  */
-
-static void
-lto_set_symtab_encoder_encode_body (lto_symtab_encoder_t encoder,
-   struct cgraph_node *node)
-{
-  int index = lto_symtab_encoder_encode (encoder, node);
-  gcc_checking_assert (encoder->nodes[index].node == node);
-  encoder->nodes[index].body = true;
-}
-
 /* Return TRUE if we should encode initializer of NODE (if any).  */
 
 bool
@@ -797,13 +795,28 @@ output_refs (lto_symtab_encoder_t encoder)
 
 static void
 add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
-bool include_body)
+bool include_body, bool not_inlined)
 {
   if (node->clone_of)
-add_node_to (encoder, node->clone_of, include_body);
+add_node_to (encoder, node->clone_of, include_body, not_inlined);
+
+  int index = lto_symtab_encoder_encode (encoder, node);
+  gcc_checking_assert (encoder->nodes[index].node == node);
+
   if (include_body)
-lto_set_symtab_encoder_encode_body (encoder, node);
-  lto_symtab_encoder_encode (encoder, node);
+encoder->nodes[index].body = true;
+  if (not_inlined)
+encoder->nodes[index].only_for_inlining = false;
+}
+
+/* Add NODE into encoder as well as nodes it is cloned f

[gcc r15-6343] lto: Implement ltrans cache

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:8b1a572840438d0caf3a40cfdebbc55bbc3968f5

commit r15-6343-g8b1a572840438d0caf3a40cfdebbc55bbc3968f5
Author: Michal Jires 
Date:   Fri Nov 17 21:17:11 2023 +0100

lto: Implement ltrans cache

This patch implements Incremental LTO as ltrans cache.

Stored are pairs of ltrans input/output files and input file hash.
File locking is used to allow multiple GCC instances to use to same cache.

Bootstrapped/regtested on x86_64-pc-linux-gnu

gcc/ChangeLog:

* Makefile.in: Add lto-ltrans-cache.o.
* common.opt: New flags for configuring cache.
* lto-opts.cc (lto_write_options): Don't stream the flags.
* lto-wrapper.cc: Use ltrans cache.
* lto-ltrans-cache.cc: New file.
* lto-ltrans-cache.h: New file.

Diff:
---
 gcc/Makefile.in |   5 +-
 gcc/common.opt  |   8 +
 gcc/lto-ltrans-cache.cc | 437 
 gcc/lto-ltrans-cache.h  | 144 
 gcc/lto-opts.cc |   2 +
 gcc/lto-wrapper.cc  | 164 --
 6 files changed, 745 insertions(+), 15 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 61360e06a861..2565870b8123 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1886,7 +1886,7 @@ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) 
$(OBJS-libcommon) \
   $(OBJS-libcommon-target) main.o c-family/cppspec.o \
   $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \
   $(GCOV_TOOL_OBJS) $(GENGTYPE_OBJS) gcc-ar.o gcc-nm.o gcc-ranlib.o \
-  lto-wrapper.o collect-utils.o lockfile.o
+  lto-wrapper.o collect-utils.o lockfile.o lto-ltrans-cache.o
 
 # for anything that is shared use the cc1plus profile data, as that
 # is likely the most exercised during the build
@@ -2548,7 +2548,8 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 CFLAGS-collect2.o += -DTARGET_MACHINE=\"$(target_noncanonical)\" \
@TARGET_SYSTEM_ROOT_DEFINE@
 
-LTO_WRAPPER_OBJS = lto-wrapper.o collect-utils.o ggc-none.o lockfile.o
+LTO_WRAPPER_OBJS = lto-wrapper.o collect-utils.o ggc-none.o lockfile.o \
+  lto-ltrans-cache.o
 
 lto-wrapper$(exeext): $(LTO_WRAPPER_OBJS) libcommon-target.a $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o T$@ \
diff --git a/gcc/common.opt b/gcc/common.opt
index c2803e465c1e..1b72826d44b1 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2239,6 +2239,14 @@ flto=
 Common RejectNegative Joined Var(flag_lto)
 Link-time optimization with number of parallel jobs or jobserver.
 
+flto-incremental=
+Common Joined Var(flag_lto_incremental)
+Enable incremental LTO, with its cache in given directory.
+
+flto-incremental-cache-size=
+Common Joined RejectNegative UInteger Var(flag_lto_incremental_cache_size) 
Init(2048)
+Number of cache entries in incremental LTO after which to prune old entries.
+
 Enum
 Name(lto_partition_model) Type(enum lto_partition_model) UnknownError(unknown 
LTO partitioning model %qs)
 
diff --git a/gcc/lto-ltrans-cache.cc b/gcc/lto-ltrans-cache.cc
new file mode 100644
index ..c3e26f840726
--- /dev/null
+++ b/gcc/lto-ltrans-cache.cc
@@ -0,0 +1,437 @@
+/* File caching.
+   Copyright (C) 2023-2024 Free Software Foundation, Inc.
+
+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
+.  */
+
+#define INCLUDE_ALGORITHM
+#define INCLUDE_STRING
+#define INCLUDE_ARRAY
+#define INCLUDE_MAP
+#define INCLUDE_VECTOR
+#include "config.h"
+#include "system.h"
+#include "sha1.h"
+#include "lto-ltrans-cache.h"
+
+static const checksum_t NULL_CHECKSUM = {
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+/* Computes checksum for given file, returns NULL_CHECKSUM if not
+   possible.  */
+static checksum_t
+file_checksum (char const *filename)
+{
+  FILE *file = fopen (filename, "rb");
+
+  if (!file)
+return NULL_CHECKSUM;
+
+  checksum_t result = NULL_CHECKSUM;
+
+  int ret = sha1_stream (file, &result);
+
+  if (ret)
+result = NULL_CHECKSUM;
+
+  fclose (file);
+
+  return result;
+}
+
+/* Checks identity of two files.  */
+static bool
+files_identical (char const *first_filename, char const *second_filename)
+{
+  bool ret = true;
+
+#if HAVE_MMAP_FILE
+  struct stat st;
+  if (stat (first_filename, &st) < 0 || !S_ISREG (st.st_mode))
+return false;
+  size_t len = st.st_size;
+  if (stat (second_filename, &s

[gcc r15-6344] ipa-strub: Replace cgraph_node order with uid.

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:bad3714b117f6d5c09b3dc8925441ce6745d0a9d

commit r15-6344-gbad3714b117f6d5c09b3dc8925441ce6745d0a9d
Author: Michal Jires 
Date:   Thu Oct 24 02:04:12 2024 +0200

ipa-strub: Replace cgraph_node order with uid.

ipa_strub_set_mode_for_new_functions uses node order as unique ever
increasing identifier. This is better satisfied with uid.
Order loses uniqueness with following patches.

gcc/ChangeLog:
* ipa-strub.cc (ipa_strub_set_mode_for_new_functions): Replace
order with uid.
(pass_ipa_strub_mode::execute): Likewise.

Diff:
---
 gcc/ipa-strub.cc | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
index f6e09cd50b6d..29ba143b4620 100644
--- a/gcc/ipa-strub.cc
+++ b/gcc/ipa-strub.cc
@@ -2257,16 +2257,16 @@ remove_named_attribute_unsharing (const char *name, 
tree *attrs)
 }
 }
 
-/* Record the order of the last cgraph entry whose mode we've already set, so
+/* Record the uid of the last cgraph entry whose mode we've already set, so
that we can perform mode setting incrementally without duplication.  */
-static int last_cgraph_order;
+static int last_cgraph_uid;
 
 /* Set strub modes for functions introduced since the last call.  */
 
 static void
 ipa_strub_set_mode_for_new_functions ()
 {
-  if (symtab->order == last_cgraph_order)
+  if (symtab->cgraph_max_uid == last_cgraph_uid)
 return;
 
   cgraph_node *node;
@@ -2281,13 +2281,13 @@ ipa_strub_set_mode_for_new_functions ()
continue;
 
   /*  Already done.  */
-  if (node->order < last_cgraph_order)
+  if (node->get_uid () < last_cgraph_uid)
continue;
 
   set_strub_mode (node);
 }
 
-  last_cgraph_order = symtab->order;
+  last_cgraph_uid = symtab->cgraph_max_uid;
 }
 
 /* Return FALSE if NODE is a strub context, and TRUE otherwise.  */
@@ -2663,7 +2663,7 @@ pass_ipa_strub::adjust_at_calls_calls (cgraph_node *node)
 unsigned int
 pass_ipa_strub_mode::execute (function *)
 {
-  last_cgraph_order = 0;
+  last_cgraph_uid = 0;
   ipa_strub_set_mode_for_new_functions ();
 
   /* Verify before any inlining or other transformations.  */


[gcc r15-6342] Implement Lockfile.

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:40d197dc81df8b369e454a9e71d1316027ca6e7b

commit r15-6342-g40d197dc81df8b369e454a9e71d1316027ca6e7b
Author: Michal Jires 
Date:   Thu Jun 20 13:24:02 2024 +0200

Implement Lockfile.

This patch implements lockfile used for incremental LTO.

Bootstrapped/regtested on x86_64-pc-linux-gnu

gcc/ChangeLog:

* Makefile.in: Add lockfile.o.
* lockfile.cc: New file.
* lockfile.h: New file.

Diff:
---
 gcc/Makefile.in |   5 ++-
 gcc/lockfile.cc | 136 
 gcc/lockfile.h  |  78 
 3 files changed, 217 insertions(+), 2 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 493ec6a5cb6e..61360e06a861 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1886,7 +1886,7 @@ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) 
$(OBJS-libcommon) \
   $(OBJS-libcommon-target) main.o c-family/cppspec.o \
   $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \
   $(GCOV_TOOL_OBJS) $(GENGTYPE_OBJS) gcc-ar.o gcc-nm.o gcc-ranlib.o \
-  lto-wrapper.o collect-utils.o
+  lto-wrapper.o collect-utils.o lockfile.o
 
 # for anything that is shared use the cc1plus profile data, as that
 # is likely the most exercised during the build
@@ -2548,7 +2548,8 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 CFLAGS-collect2.o += -DTARGET_MACHINE=\"$(target_noncanonical)\" \
@TARGET_SYSTEM_ROOT_DEFINE@
 
-LTO_WRAPPER_OBJS = lto-wrapper.o collect-utils.o ggc-none.o
+LTO_WRAPPER_OBJS = lto-wrapper.o collect-utils.o ggc-none.o lockfile.o
+
 lto-wrapper$(exeext): $(LTO_WRAPPER_OBJS) libcommon-target.a $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o T$@ \
   $(LTO_WRAPPER_OBJS) libcommon-target.a $(LIBS)
diff --git a/gcc/lockfile.cc b/gcc/lockfile.cc
new file mode 100644
index ..8ecb4dc28484
--- /dev/null
+++ b/gcc/lockfile.cc
@@ -0,0 +1,136 @@
+/* File locking.
+   Copyright (C) 2023-2024 Free Software Foundation, Inc.
+
+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
+.  */
+
+#define INCLUDE_STRING
+#include "config.h"
+#include "system.h"
+#include "lockfile.h"
+
+
+/* Unique write lock.  No other lock can be held on this lockfile.
+   Blocking call.  */
+int
+lockfile::lock_write ()
+{
+  fd = open (filename.c_str (), O_RDWR | O_CREAT, 0666);
+  if (fd < 0)
+return -1;
+
+#if HAVE_FCNTL_H
+  struct flock s_flock;
+
+  s_flock.l_whence = SEEK_SET;
+  s_flock.l_start = 0;
+  s_flock.l_len = 0;
+  s_flock.l_pid = getpid ();
+  s_flock.l_type = F_WRLCK;
+
+  while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
+continue;
+#endif
+  return 0;
+}
+
+/* Unique write lock.  No other lock can be held on this lockfile.
+   Only locks if this filelock is not locked by any other process.
+   Return whether locking was successful.  */
+int
+lockfile::try_lock_write ()
+{
+  fd = open (filename.c_str (), O_RDWR | O_CREAT, 0666);
+  if (fd < 0)
+return -1;
+
+#if HAVE_FCNTL_H
+  struct flock s_flock;
+
+  s_flock.l_whence = SEEK_SET;
+  s_flock.l_start = 0;
+  s_flock.l_len = 0;
+  s_flock.l_pid = getpid ();
+  s_flock.l_type = F_WRLCK;
+
+  if (fcntl (fd, F_SETLK, &s_flock) == -1)
+{
+  close (fd);
+  fd = -1;
+  return 1;
+}
+#endif
+  return 0;
+}
+
+/* Shared read lock.  Only read lock can be held concurrently.
+   If write lock is already held by this process, it will be
+   changed to read lock.
+   Blocking call.  */
+int
+lockfile::lock_read ()
+{
+  fd = open (filename.c_str (), O_RDWR | O_CREAT, 0666);
+  if (fd < 0)
+return -1;
+
+#if HAVE_FCNTL_H
+  struct flock s_flock;
+
+  s_flock.l_whence = SEEK_SET;
+  s_flock.l_start = 0;
+  s_flock.l_len = 0;
+  s_flock.l_pid = getpid ();
+  s_flock.l_type = F_RDLCK;
+
+  while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
+continue;
+#endif
+  return 0;
+}
+
+/* Unlock all previously placed locks.  */
+void
+lockfile::unlock ()
+{
+  if (fd < 0)
+{
+#if HAVE_FCNTL_H
+  struct flock s_flock;
+
+  s_flock.l_whence = SEEK_SET;
+  s_flock.l_start = 0;
+  s_flock.l_len = 0;
+  s_flock.l_pid = getpid ();
+  s_flock.l_type = F_UNLCK;
+
+  fcntl (fd, F_SETLK, &s_flock);
+#endif
+  close (fd);
+  fd = -1;
+}
+}
+
+/* Are lockfiles supported?  */
+bool
+lockfile::lockfile_supported ()
+{
+#if HAVE_FCNTL_H
+  return true;

[gcc r15-6346] lto: Remap node order for stability.

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:b47e7eabff260a69b0cf596ca807ebbe6d93a2c2

commit r15-6346-gb47e7eabff260a69b0cf596ca807ebbe6d93a2c2
Author: Michal Jires 
Date:   Thu Oct 24 03:02:55 2024 +0200

lto: Remap node order for stability.

This patch adds remapping of node order for each lto partition.
Resulting order conserves relative order inside partition, but
is independent of outside symbols. So if lto partition contains
identical set of symbols, their remapped order will be stable
between compilations.

This stability is needed for Incremental LTO.

gcc/ChangeLog:

* ipa-devirt.cc (ipa_odr_summary_write):
Add unused argument.
* ipa-fnsummary.cc (ipa_fn_summary_write): Likewise.
* ipa-icf.cc (sem_item_optimizer::write_summary): Likewise.
* ipa-modref.cc (modref_write): Likewise.
* ipa-prop.cc (ipa_prop_write_jump_functions): Likewise.
(ipcp_write_transformation_summaries): Likewise.
* ipa-sra.cc (ipa_sra_write_summary): Likewise.
* lto-cgraph.cc (lto_symtab_encoder_delete): Delete remap.
(lto_output_node): Remap order.
(lto_output_varpool_node): Likewise.
(output_cgraph_opt_summary): Add unused argument.
* lto-streamer-out.cc (produce_symbol_asm): Renamed. Use remapped 
order.
(produce_asm): Rename. New wrapper.
(output_function): Propagate remapped order.
(output_constructor): Likewise.
(copy_function_or_variable): Likewise.
(cmp_int): New.
(create_order_remap): New.
(lto_output): Create remap. Remap order.
* lto-streamer.h (struct lto_symtab_encoder_d): Remap hash_map.
(produce_asm): Add order argument.

Diff:
---
 gcc/ipa-devirt.cc   |  2 +-
 gcc/ipa-fnsummary.cc|  2 +-
 gcc/ipa-icf.cc  |  2 +-
 gcc/ipa-modref.cc   |  4 +--
 gcc/ipa-prop.cc |  4 +--
 gcc/ipa-sra.cc  |  2 +-
 gcc/lto-cgraph.cc   | 10 --
 gcc/lto-streamer-out.cc | 93 ++---
 gcc/lto-streamer.h  |  5 ++-
 9 files changed, 99 insertions(+), 25 deletions(-)

diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index e88e9db781e9..cdd520ba76b8 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -4131,7 +4131,7 @@ ipa_odr_summary_write (void)
   odr_enum_map = NULL;
 }
 
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 6799ffe0b9af..9ed3f151c905 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -5091,7 +5091,7 @@ ipa_fn_summary_write (void)
}
 }
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 
   ipa_prop_write_jump_functions ();
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index 60152e60bc5d..e9c5ae764f0d 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -2216,7 +2216,7 @@ sem_item_optimizer::write_summary (void)
 }
 
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 7449041c102b..e68f434aa101 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -3746,7 +3746,7 @@ modref_write ()
 {
   streamer_write_uhwi (ob, 0);
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
   return;
 }
@@ -3821,7 +3821,7 @@ modref_write ()
}
 }
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 0daa950985b7..0adfd37cac1a 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5430,7 +5430,7 @@ ipa_prop_write_jump_functions (void)
 ipa_write_node_info (ob, node);
 }
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
@@ -5628,7 +5628,7 @@ ipcp_write_transformation_summaries (void)
write_ipcp_transformation_info (ob, cnode, ts);
 }
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
index 04920f2aa8e4..e6a75139eb09 100644
--- a/gcc/ipa-sra.cc
+++ b/gcc/ipa-sra.cc
@@ -2898,7 +2898,7 @@ ipa_sra_write_summary (void)
 isra_write_node_summary (ob, node);
 }
   streamer_write_char_stream (ob->main_stream, 0);
-  produce_asm (ob, NULL);
+  produce_asm (ob);
   destroy_output_block (ob);
 }
 
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index d1d63fd90ea5..14275ed7c42d 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -

[gcc r15-6345] Node clones share order.

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:0895aef01c64c317b489811dbe4ac55f9c13aab3

commit r15-6345-g0895aef01c64c317b489811dbe4ac55f9c13aab3
Author: Michal Jires 
Date:   Thu Oct 24 02:21:00 2024 +0200

Node clones share order.

Symbol order corresponds to the order in source code.
For clones their order is currently arbitrarily chosen as max order++
But it would be more consistent with original purpose to choose clones
order to be shared with the original node order.
This stabilizes clone order for Incremental LTO.

Order is thus no longer unique, but this property is not used outside
of previous patch, where we can use uid.
If total order would be needed, sorting by order and then uid suffices.

gcc/ChangeLog:

* cgraph.h (symbol_table::register_symbol):
Order can be already set.
* cgraphclones.cc (cgraph_node::create_clone):
Reuse order for clones.

Diff:
---
 gcc/cgraph.h| 5 +++--
 gcc/cgraphclones.cc | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 9b4cb6383afc..099fae654da1 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -121,7 +121,7 @@ public:
   used_from_other_partition (false), in_other_partition (false),
   address_taken (false), in_init_priority_hash (false),
   need_lto_streaming (false), offloadable (false), ifunc_resolver (false),
-  order (false), next_sharing_asm_name (NULL),
+  order (-1), next_sharing_asm_name (NULL),
   previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
   alias_target (NULL), lto_file_data (NULL), aux (NULL),
   x_comdat_group (NULL_TREE), x_section (NULL)
@@ -2819,7 +2819,8 @@ symbol_table::register_symbol (symtab_node *node)
 nodes->previous = node;
   nodes = node;
 
-  node->order = order++;
+  if (node->order == -1)
+node->order = order++;
 }
 
 /* Register a top-level asm statement ASM_STR.  */
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 33cab4583348..9f05477cb825 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -401,6 +401,7 @@ cgraph_node::create_clone (tree new_decl, profile_count 
prof_count,
 count = count.combine_with_ipa_count (count.ipa () - prof_count.ipa 
());
 }
   new_node->decl = new_decl;
+  new_node->order = order;
   new_node->register_symbol ();
   new_node->lto_file_data = lto_file_data;
   new_node->analyzed = analyzed;


[gcc r15-6350] ipcp don't propagate where not needed - fix uninit constructor

2024-12-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:bb829ce157f8b466a9635fd96e7a44af9e19bd55

commit r15-6350-gbb829ce157f8b466a9635fd96e7a44af9e19bd55
Author: Michal Jires 
Date:   Wed Dec 18 18:28:46 2024 +0100

ipcp don't propagate where not needed - fix uninit constructor

Removed unitialized empty constructor as was objected.

gcc/ChangeLog:

* lto-cgraph.cc (lto_symtab_encoder_delete_node):
Declare var later when initialized.
* lto-streamer.h (struct lto_encoder_entry):
Remove empty constructor.

Diff:
---
 gcc/lto-cgraph.cc  | 3 +--
 gcc/lto-streamer.h | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 14275ed7c42d..f16c90273f67 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -143,7 +143,6 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t 
encoder,
symtab_node *node)
 {
   int index;
-  lto_encoder_entry last_node;
 
   size_t *slot = encoder->map->get (node);
   if (slot == NULL || !*slot)
@@ -154,7 +153,7 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t 
encoder,
 
   /* Remove from vector. We do this by swapping node with the last element
  of the vector.  */
-  last_node = encoder->nodes.pop ();
+  lto_encoder_entry last_node = encoder->nodes.pop ();
   if (last_node.node != node)
 {
   bool existed = encoder->map->put (last_node.node, index + 1);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 0699c6928d48..0103b60d7420 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -443,8 +443,7 @@ struct lto_stats_d
 /* Entry of LTO symtab encoder.  */
 struct lto_encoder_entry
 {
-  /* Constructors.  */
-  lto_encoder_entry () {}
+  /* Constructor.  */
   lto_encoder_entry (symtab_node* n)
 : node (n), in_partition (false), body (false), only_for_inlining (true),
   initializer (false)


[gcc r15-7024] Fix uniqueness of symtab_node::get_dump_name.

2025-01-18 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:557d1a44ece3b9cf0084a4ebcc2e50875d788393

commit r15-7024-g557d1a44ece3b9cf0084a4ebcc2e50875d788393
Author: Michal Jires 
Date:   Thu Jan 16 14:42:59 2025 +0100

Fix uniqueness of symtab_node::get_dump_name.

symtab_node::get_dump_name uses node order to identify nodes.
Order is no longer unique because of Incremental LTO patches.
This patch moves uid from cgraph_node node to symtab_node,
so get_dump_name can use uid instead and get back unique dump names.

In inlining passes, uid is replaced with more appropriate (more compact
for indexing) summary id.

Bootstrapped/regtested on x86_64-linux.
Ok for trunk?

gcc/ChangeLog:

* cgraph.cc (symbol_table::create_empty):
Move uid to symtab_node.
(test_symbol_table_test): Change expected dump id.
* cgraph.h (struct cgraph_node):
Move uid to symtab_node.
(symbol_table::register_symbol): Likewise.
* dumpfile.cc (test_capture_of_dump_calls):
Change expected dump id.
* ipa-inline.cc (update_caller_keys):
Use summary id instead of uid.
(update_callee_keys): Likewise.
* symtab.cc (symtab_node::get_dump_name):
Use uid instead of order.

gcc/testsuite/ChangeLog:

* gcc.dg/live-patching-1.c: Change expected dump id.
* gcc.dg/live-patching-4.c: Likewise.

Diff:
---
 gcc/cgraph.cc  |  4 ++--
 gcc/cgraph.h   | 25 ++---
 gcc/dumpfile.cc|  8 
 gcc/ipa-inline.cc  |  6 +++---
 gcc/symtab.cc  |  2 +-
 gcc/testsuite/gcc.dg/live-patching-1.c |  2 +-
 gcc/testsuite/gcc.dg/live-patching-4.c |  2 +-
 7 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 83a9b59ef302..d0b19ad850e0 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -290,7 +290,7 @@ cgraph_node *
 symbol_table::create_empty (void)
 {
   cgraph_count++;
-  return new (ggc_alloc ()) cgraph_node (cgraph_max_uid++);
+  return new (ggc_alloc ()) cgraph_node ();
 }
 
 /* Register HOOK to be called with DATA on each removed edge.  */
@@ -4338,7 +4338,7 @@ test_symbol_table_test ()
   /* Verify that the node has order 0 on both iterations,
 and thus that nodes have predictable dump names in selftests.  */
   ASSERT_EQ (node->order, 0);
-  ASSERT_STREQ (node->dump_name (), "test_decl/0");
+  ASSERT_STREQ (node->dump_name (), "test_decl/1");
 }
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 7856d53c9e92..065fcc742e8b 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -124,7 +124,7 @@ public:
   order (-1), next_sharing_asm_name (NULL),
   previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
   alias_target (NULL), lto_file_data (NULL), aux (NULL),
-  x_comdat_group (NULL_TREE), x_section (NULL)
+  x_comdat_group (NULL_TREE), x_section (NULL), m_uid (-1)
   {}
 
   /* Return name.  */
@@ -492,6 +492,12 @@ public:
   /* Perform internal consistency checks, if they are enabled.  */
   static inline void checking_verify_symtab_nodes (void);
 
+  /* Get unique identifier of the node.  */
+  inline int get_uid ()
+  {
+return m_uid;
+  }
+
   /* Type of the symbol.  */
   ENUM_BITFIELD (symtab_type) type : 8;
 
@@ -668,6 +674,9 @@ protected:
  void *data,
  bool include_overwrite);
 private:
+  /* Unique id of the node.  */
+  int m_uid;
+
   /* Workers for set_section.  */
   static bool set_section_from_string (symtab_node *n, void *s);
   static bool set_section_from_node (symtab_node *n, void *o);
@@ -882,7 +891,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public 
symtab_node
   friend class symbol_table;
 
   /* Constructor.  */
-  explicit cgraph_node (int uid)
+  explicit cgraph_node ()
 : symtab_node (SYMTAB_FUNCTION), callees (NULL), callers (NULL),
   indirect_calls (NULL),
   next_sibling_clone (NULL), prev_sibling_clone (NULL), clones (NULL),
@@ -903,7 +912,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public 
symtab_node
   redefined_extern_inline (false), tm_may_enter_irr (false),
   ipcp_clone (false), gc_candidate (false),
   called_by_ifunc_resolver (false), has_omp_variant_constructs (false),
-  m_uid (uid), m_summary_id (-1)
+  m_summary_id (-1)
   {}
 
   /* Remove the node from cgraph and all inline clones inlined into it.
@@ -1304,12 +1313,6 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : 
public symtab_node
 dump_cgraph (stderr);
   }
 
-  /* Get unique identifier of the node.  */
-  inline int get_uid ()
-  {
-return m_uid;
-  }
-
   /* Get summary id of the node.  */
   inline int get_summary_id ()
   {
@@ -1503,8 +1506,6 @@ struct GTY((tag ("SY

[gcc r15-6845] lto: Fix empty fnctl.h build error with MinGW.

2025-01-12 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:89ebb88d1d73ea8f693f2195321b402c31186abe

commit r15-6845-g89ebb88d1d73ea8f693f2195321b402c31186abe
Author: Michal Jires 
Date:   Mon Jan 13 01:58:41 2025 +0100

lto: Fix empty fnctl.h build error with MinGW.

MSYS2+MinGW contains headers without defining expected contents.
This fix checks that the fcntl function is actually defined.

Bootstrapped/regtested on x86_64-linux. Committed as obvious.

gcc/ChangeLog:

* lockfile.cc (LOCKFILE_USE_FCNTL): New.
(lockfile::lock_write): Use LOCKFILE_USE_FCNTL.
(lockfile::try_lock_write): Use LOCKFILE_USE_FCNTL.
(lockfile::lock_read): Use LOCKFILE_USE_FCNTL.
(lockfile::unlock): Use LOCKFILE_USE_FCNTL.
(lockfile::lockfile_supported): Use LOCKFILE_USE_FCNTL.

Diff:
---
 gcc/lockfile.cc | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gcc/lockfile.cc b/gcc/lockfile.cc
index b385c295851f..cecbb86491da 100644
--- a/gcc/lockfile.cc
+++ b/gcc/lockfile.cc
@@ -22,6 +22,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "lockfile.h"
 
+/* fcntl.h may exist without expected contents.  */
+#if HAVE_FCNTL_H && HOST_HAS_F_SETLKW
+#define LOCKFILE_USE_FCNTL 1
+#endif
 
 /* Unique write lock.  No other lock can be held on this lockfile.
Blocking call.  */
@@ -32,7 +36,7 @@ lockfile::lock_write ()
   if (fd < 0)
 return -1;
 
-#if HAVE_FCNTL_H
+#ifdef LOCKFILE_USE_FCNTL
   struct flock s_flock;
 
   s_flock.l_whence = SEEK_SET;
@@ -57,7 +61,7 @@ lockfile::try_lock_write ()
   if (fd < 0)
 return -1;
 
-#if HAVE_FCNTL_H
+#ifdef LOCKFILE_USE_FCNTL
   struct flock s_flock;
 
   s_flock.l_whence = SEEK_SET;
@@ -87,7 +91,7 @@ lockfile::lock_read ()
   if (fd < 0)
 return -1;
 
-#if HAVE_FCNTL_H
+#ifdef LOCKFILE_USE_FCNTL
   struct flock s_flock;
 
   s_flock.l_whence = SEEK_SET;
@@ -108,7 +112,7 @@ lockfile::unlock ()
 {
   if (fd < 0)
 {
-#if HAVE_FCNTL_H
+#ifdef LOCKFILE_USE_FCNTL
   struct flock s_flock;
 
   s_flock.l_whence = SEEK_SET;
@@ -128,7 +132,7 @@ lockfile::unlock ()
 bool
 lockfile::lockfile_supported ()
 {
-#if HAVE_FCNTL_H
+#ifdef LOCKFILE_USE_FCNTL
   return true;
 #else
   return false;


[gcc r15-6846] lto: Pass cache checksum by reference [PR118181]

2025-01-12 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:9100be5741329dfe7bd49d6cf60be1771b9bb3ea

commit r15-6846-g9100be5741329dfe7bd49d6cf60be1771b9bb3ea
Author: Michal Jires 
Date:   Mon Jan 13 02:49:58 2025 +0100

lto: Pass cache checksum by reference [PR118181]

Bootstrapped/regtested on x86_64-linux. Committed as obvious.

PR lto/118181

gcc/ChangeLog:

* lto-ltrans-cache.cc (ltrans_file_cache::create_item):
Pass checksum by reference.
* lto-ltrans-cache.h: Likewise.

Diff:
---
 gcc/lto-ltrans-cache.cc | 2 +-
 gcc/lto-ltrans-cache.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/lto-ltrans-cache.cc b/gcc/lto-ltrans-cache.cc
index 22c0bffaed59..c57775fae851 100644
--- a/gcc/lto-ltrans-cache.cc
+++ b/gcc/lto-ltrans-cache.cc
@@ -309,7 +309,7 @@ ltrans_file_cache::save_cache ()
 
Must be called with creation_lock held to prevent data race.  */
 ltrans_file_cache::item*
-ltrans_file_cache::create_item (checksum_t checksum)
+ltrans_file_cache::create_item (const checksum_t& checksum)
 {
   size_t prefix_len = cache_prefix.size ();
 
diff --git a/gcc/lto-ltrans-cache.h b/gcc/lto-ltrans-cache.h
index b95f63c33357..5fef44bae538 100644
--- a/gcc/lto-ltrans-cache.h
+++ b/gcc/lto-ltrans-cache.h
@@ -108,7 +108,7 @@ private:
  New input/output files are chosen to not collide with other items.
 
  Must be called with creation_lock held to prevent data race.  */
-  item* create_item (checksum_t checksum);
+  item* create_item (const checksum_t& checksum);
 
   /* Prunes oldest unused cache items over limit.
  Must be called with deletion_lock held to prevent data race.  */


[gcc r15-6904] lto: Remove link() to fix build with MinGW [PR118238]

2025-01-14 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:ed1233115c9c60b0174fa99913ba6bd61e81edd7

commit r15-6904-ged1233115c9c60b0174fa99913ba6bd61e81edd7
Author: Michal Jires 
Date:   Mon Jan 13 04:08:03 2025 +0100

lto: Remove link() to fix build with MinGW [PR118238]

I used link() to create cheap copies of Incremental LTO cache contents
to prevent their deletion once linking is finished.
This is unnecessary, since output_files are deleted in our lto-plugin
and not in the linker itself.

Bootstrapped/regtested on x86_64-linux.
lto-wrapper now again builds on MinGW. Though so far I have not setup
MinGW to be able to do full bootstrap.
Ok for trunk?

PR lto/118238

gcc/ChangeLog:

* lto-wrapper.cc (run_gcc): Remove link() copying.

lto-plugin/ChangeLog:

* lto-plugin.c (cleanup_handler):
Keep output_files when using Incremental LTO.
(onload): Detect Incremental LTO.

Diff:
---
 gcc/lto-wrapper.cc  | 34 +-
 lto-plugin/lto-plugin.c |  9 +++--
 2 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/gcc/lto-wrapper.cc b/gcc/lto-wrapper.cc
index f9b2511c38ec..a980b208783a 100644
--- a/gcc/lto-wrapper.cc
+++ b/gcc/lto-wrapper.cc
@@ -1571,6 +1571,8 @@ run_gcc (unsigned argc, char *argv[])
  /* Exists.  */
  if (access (option->arg, W_OK) == 0)
ltrans_cache_dir = option->arg;
+ else
+   fatal_error (input_location, "missing directory: %s", option->arg);
  break;
 
case OPT_flto_incremental_cache_size_:
@@ -2218,39 +2220,13 @@ cont:
{
  for (i = 0; i < nr; ++i)
{
- char *input_name = input_names[i];
- char const *output_name = output_names[i];
-
  ltrans_file_cache::item* item;
- item = ltrans_cache.get_item (input_name);
+ item = ltrans_cache.get_item (input_names[i]);
 
- if (item && !save_temps)
+ if (item)
{
+ /* Ensure LTRANS for this item finished.  */
  item->lock.lock_read ();
- /* Ensure that cached compiled file is not deleted.
-Create copy.  */
-
- obstack_grow (&env_obstack, output_name,
-   strlen (output_name) - 2);
- obstack_grow (&env_obstack, ".cache_copy.XXX.o",
-   sizeof (".cache_copy.XXX.o"));
-
- char* output_name_link = XOBFINISH (&env_obstack, char *);
- char* name_idx = output_name_link + strlen (output_name_link)
-  - strlen ("XXX.o");
-
- /* lto-wrapper can run in parallel and access
-the same partition.  */
- for (int j = 0; ; j++)
-   {
- gcc_assert (j < 1000);
- sprintf (name_idx, "%03d.o", j);
-
- if (link (output_name, output_name_link) != EEXIST)
-   break;
-   }
-
- output_names[i] = output_name_link;
  item->lock.unlock ();
}
}
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index 6bccb56291c5..3d272551fed5 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -214,6 +214,7 @@ static char *ltrans_objects = NULL;
 
 static bool debug;
 static bool save_temps;
+static bool flto_incremental;
 static bool verbose;
 static char nop;
 static char *resolution_file = NULL;
@@ -941,8 +942,9 @@ cleanup_handler (void)
   if (arguments_file_name)
 maybe_unlink (arguments_file_name);
 
-  for (i = 0; i < num_output_files; i++)
-maybe_unlink (output_files[i]);
+  if (!flto_incremental)
+for (i = 0; i < num_output_files; i++)
+  maybe_unlink (output_files[i]);
 
   free_2 ();
   return LDPS_OK;
@@ -1615,6 +1617,9 @@ onload (struct ld_plugin_tv *tv)
   if (strstr (collect_gcc_options, "'-save-temps'"))
save_temps = true;
 
+  if (strstr (collect_gcc_options, "'-flto-incremental="))
+   flto_incremental = true;
+
   if (strstr (collect_gcc_options, "'-v'")
   || strstr (collect_gcc_options, "'--verbose'"))
verbose = true;


[gcc r15-7851] lto: Fix missing cleanup with incremental LTO.

2025-03-06 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:50cd99795268aaaf10705fa876dd4b751453e2f6

commit r15-7851-g50cd99795268aaaf10705fa876dd4b751453e2f6
Author: Michal Jires 
Date:   Thu Mar 6 06:49:20 2025 +0100

lto: Fix missing cleanup with incremental LTO.

Incremental LTO disabled cleanup of output_files since they have to
persist in ltrans cache.
This unintetionally also kept temporary early debug "*.debug.temp.o"
files.

Bootstrapped/regtested on x86_64-linux.
Ok for trunk?

lto-plugin/ChangeLog:

* lto-plugin.c (cleanup_handler): Keep only files in ltrans
cache.

Diff:
---
 lto-plugin/lto-plugin.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index 3d272551fed5..09d5441ecc78 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -945,6 +945,17 @@ cleanup_handler (void)
   if (!flto_incremental)
 for (i = 0; i < num_output_files; i++)
   maybe_unlink (output_files[i]);
+  else
+{
+  /* Keep files in ltrans cache.  */
+  const char* suffix = ".ltrans.o";
+  for (i = 0; i < num_output_files; i++)
+   {
+ int offset = strlen (output_files[i]) - strlen (suffix);
+ if (offset < 0 || strcmp (output_files[i] + offset, suffix))
+   maybe_unlink (output_files[i]);
+   }
+}
 
   free_2 ();
   return LDPS_OK;


[gcc r15-8235] doc: Regenerate common.opt.urls

2025-03-17 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:051ca98a12908b9685d76b4432cff2f8f0f33368

commit r15-8235-g051ca98a12908b9685d76b4432cff2f8f0f33368
Author: Michal Jires 
Date:   Mon Mar 17 17:12:32 2025 +0100

doc: Regenerate common.opt.urls

Regenerating common.opt.urls, which I missed until autobuilder noticed.

gcc/ChangeLog:

* common.opt.urls: Regenerate.

Diff:
---
 gcc/common.opt.urls | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index 79c322bed2b6..ac602631179c 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -935,6 +935,12 @@ UrlSuffix(gcc/Optimize-Options.html#index-flto)
 flto=
 UrlSuffix(gcc/Optimize-Options.html#index-flto)
 
+flto-incremental=
+UrlSuffix(gcc/Optimize-Options.html#index-flto-incremental)
+
+flto-incremental-cache-size=
+UrlSuffix(gcc/Optimize-Options.html#index-flto-incremental-cache-size)
+
 flto-partition=
 UrlSuffix(gcc/Optimize-Options.html#index-flto-partition)


[gcc r15-8087] doc: document Incremental LTO flags

2025-03-17 Thread Michal Jires via Gcc-cvs
https://gcc.gnu.org/g:63e7478db76452d9f7d5bef9704a94480cc28a77

commit r15-8087-g63e7478db76452d9f7d5bef9704a94480cc28a77
Author: Michal Jires 
Date:   Thu Mar 13 16:18:10 2025 +0100

doc: document Incremental LTO flags

This adds missing documentation for LTO flags.

gcc/ChangeLog:

* doc/invoke.texi: (Optimize Options):
Add incremental LTO flags.

Diff:
---
 gcc/doc/invoke.texi | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 768b98dba74c..26b3dd939617 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -601,7 +601,8 @@ Objective-C and Objective-C++ Dialects}.
 -floop-block  -floop-interchange  -floop-strip-mine
 -floop-unroll-and-jam  -floop-nest-optimize
 -floop-parallelize-all  -flra-remat  -flto  -flto-compression-level
--flto-partition=@var{alg}  -fmalloc-dce -fmerge-all-constants
+-flto-partition=@var{alg} -flto-incremental=@var{path}
+-flto-incremental-cache-size=@var{n} -fmalloc-dce -fmerge-all-constants
 -fmerge-constants  -fmodulo-sched  -fmodulo-sched-allow-regmoves
 -fmove-loop-invariants  -fmove-loop-stores  -fno-branch-count-reg
 -fno-defer-pop  -fno-fp-int-builtin-inexact  -fno-function-cse
@@ -15053,8 +15054,10 @@ Specify the partitioning algorithm used by the 
link-time optimizer.
 The value is either @samp{1to1} to specify a partitioning mirroring
 the original source files or @samp{balanced} to specify partitioning
 into equally sized chunks (whenever possible) or @samp{max} to create
-new partition for every symbol where possible.  Specifying @samp{none}
-as an algorithm disables partitioning and streaming completely.
+new partition for every symbol where possible or @samp{cache} to
+balance chunk sizes while keeping related symbols together for better
+caching in incremental LTO.  Specifying @samp{none} as an algorithm
+disables partitioning and streaming completely.
 The default value is @samp{balanced}. While @samp{1to1} can be used
 as an workaround for various code ordering issues, the @samp{max}
 partitioning is intended for internal testing only.
@@ -15062,6 +15065,23 @@ The value @samp{one} specifies that exactly one 
partition should be
 used while the value @samp{none} bypasses partitioning and executes
 the link-time optimization step directly from the WPA phase.
 
+@opindex flto-incremental
+@item -flto-incremental=@var{path}
+Enable incremental LTO, with its cache in given existing directory.
+Can significantly shorten edit-compile cycles with LTO.
+
+When used with LTO (@option{-flto}), the output of translation units
+inside LTO is cached. Cached translation units are likely to be
+encountered again when recompiling with small code changes, leading to
+recompile time reduction.
+
+Multiple GCC instances can use the same cache in parallel.
+
+@opindex flto-incremental-cache-size
+@item -flto-incremental-cache-size=@var{n}
+Specifies number of cache entries in incremental LTO after which to prune
+old entries. This is a soft limit, temporarily there may be more entries.
+
 @opindex flto-compression-level
 @item -flto-compression-level=@var{n}
 This option specifies the level of compression used for intermediate