aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-08-07 12:18:38 -0700
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>2025-08-10 09:36:48 -0700
commit14ad799ae1545569be158b00865f6f2f951657bd (patch)
tree36be80c5b989543d6c436ba270bc001acb7f9c96 /gcc
parent405f45aae779fe7694e8660cfa828f1cef58b101 (diff)
downloadgcc-14ad799ae1545569be158b00865f6f2f951657bd.zip
gcc-14ad799ae1545569be158b00865f6f2f951657bd.tar.gz
gcc-14ad799ae1545569be158b00865f6f2f951657bd.tar.bz2
varasm: Redo mergeable section support [PR121438]
We increased the switch conversion array decl alignment for better mergeability but it turns out that we increase the alignment on targets which don't support mergeable sections (e.g. NVPTX). Also after the fix for PR 121394, it becomes obvious that we can place any sized into the mergeable section instead of increasing the alignment. This implements that and now also fixes PR 121438 as we don't need to increase the alignment for the mergeable decls that were being created by the C++ front-end. Bootstrapped and tested on x86_64-linux-gnu. PR middle-end/121438 PR middle-end/121444 gcc/ChangeLog: * output.h (MAX_ALIGN_MERGABLE): Rename to ... (MAX_MERGEABLE_BITSIZE): This. * tree-switch-conversion.cc (switch_conversion::build_one_array): Don't increase the alignment. * varasm.cc (mergeable_string_section): Use MAX_MERGEABLE_BITSIZE instead of MAX_ALIGN_MERGABLE. Also replace `/ 8` with `/ BITS_PER_UNIT`. (mergeable_constant_section): Select the mergeable section based on the bitsize rather than the alignment. Make sure the align is less than the entity size. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/output.h4
-rw-r--r--gcc/tree-switch-conversion.cc12
-rw-r--r--gcc/varasm.cc18
3 files changed, 13 insertions, 21 deletions
diff --git a/gcc/output.h b/gcc/output.h
index 51c2d36..835a259 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -545,8 +545,8 @@ extern GTY(()) section *bss_noswitch_section;
extern GTY(()) section *in_section;
extern GTY(()) bool in_cold_section_p;
-/* MAX bit alignment for mergable sections. */
-#define MAX_ALIGN_MERGABLE 256
+/* MAX size for mergeable sections in bits. */
+#define MAX_MERGEABLE_BITSIZE 256
extern section *get_unnamed_section (unsigned int, void (*) (const char *),
const char *);
diff --git a/gcc/tree-switch-conversion.cc b/gcc/tree-switch-conversion.cc
index 04b357f..62eddcd 100644
--- a/gcc/tree-switch-conversion.cc
+++ b/gcc/tree-switch-conversion.cc
@@ -55,7 +55,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "hwint.h"
#include "internal-fn.h"
#include "diagnostic-core.h"
-#include "output.h"
/* ??? For lang_hooks.types.type_for_mode, but is there a word_mode
type in the GIMPLE type system that is language-independent? */
@@ -1031,19 +1030,10 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
TREE_CONSTANT (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_IGNORED_P (decl) = 1;
- /* The decl is mergable since we don't take the address ever and
+ /* The decl is mergeable since we don't take the address ever and
just reading from it. */
DECL_MERGEABLE (decl) = 1;
- /* Increase the alignments as needed. */
- if (tree_to_uhwi (DECL_SIZE (decl)) > DECL_ALIGN (decl))
- {
- unsigned HOST_WIDE_INT s = tree_to_uhwi (DECL_SIZE (decl));
- /* Only support up to the max supported for merging. */
- if (s <= MAX_ALIGN_MERGABLE)
- SET_DECL_ALIGN (decl, HOST_WIDE_INT_1U << ceil_log2 (s));
- }
-
if (offloading_function_p (cfun->decl))
DECL_ATTRIBUTES (decl)
= tree_cons (get_identifier ("omp declare target"), NULL_TREE,
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index ee32cf1..0d78f5b 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -871,7 +871,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
if (HAVE_GAS_SHF_MERGE && flag_merge_constants
&& TREE_CODE (decl) == STRING_CST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
- && align <= MAX_ALIGN_MERGABLE
+ && align <= MAX_MERGEABLE_BITSIZE
&& (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
&& TREE_STRING_LENGTH (decl) == len)
{
@@ -885,7 +885,7 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));
modesize = GET_MODE_BITSIZE (mode);
- if (modesize >= 8 && modesize <= MAX_ALIGN_MERGABLE
+ if (modesize >= 8 && modesize <= MAX_MERGEABLE_BITSIZE
&& (modesize & (modesize - 1)) == 0)
{
if (align < modesize)
@@ -906,8 +906,8 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
if (i == len - unit || (unit == 1 && i == len))
{
sprintf (name, "%s.str%d.%d", prefix,
- modesize / 8, (int) (align / 8));
- flags |= (modesize / 8) | SECTION_MERGE | SECTION_STRINGS;
+ modesize / BITS_PER_UNIT, (int) (align / BITS_PER_UNIT));
+ flags |= (modesize / BITS_PER_UNIT) | SECTION_MERGE | SECTION_STRINGS;
return get_section (name, flags, NULL);
}
}
@@ -923,17 +923,19 @@ mergeable_constant_section (unsigned HOST_WIDE_INT size_bits,
unsigned HOST_WIDE_INT align,
unsigned int flags)
{
+ unsigned HOST_WIDE_INT newsize;
+ newsize = HOST_WIDE_INT_1U << ceil_log2 (size_bits);
if (HAVE_GAS_SHF_MERGE && flag_merge_constants
- && size_bits <= align
+ && newsize <= MAX_MERGEABLE_BITSIZE
&& align >= 8
- && align <= MAX_ALIGN_MERGABLE
+ && align <= newsize
&& (align & (align - 1)) == 0)
{
const char *prefix = function_mergeable_rodata_prefix ();
char *name = (char *) alloca (strlen (prefix) + 30);
- sprintf (name, "%s.cst%d", prefix, (int) (align / 8));
- flags |= (align / 8) | SECTION_MERGE;
+ sprintf (name, "%s.cst%d", prefix, (int) (newsize / BITS_PER_UNIT));
+ flags |= (newsize / BITS_PER_UNIT) | SECTION_MERGE;
return get_section (name, flags, NULL);
}
return readonly_data_section;