diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
commit | 071b4126c613881f4cb25b4e5c39032964827f88 (patch) | |
tree | 7ed805786566918630d1d617b1ed8f7310f5fd8e /gcc/varasm.cc | |
parent | 845d23f3ea08ba873197c275a8857eee7edad996 (diff) | |
parent | caa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff) | |
download | gcc-devel/gfortran-test.zip gcc-devel/gfortran-test.tar.gz gcc-devel/gfortran-test.tar.bz2 |
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'gcc/varasm.cc')
-rw-r--r-- | gcc/varasm.cc | 87 |
1 files changed, 69 insertions, 18 deletions
diff --git a/gcc/varasm.cc b/gcc/varasm.cc index 8266282..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 <= 256 + && 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 <= 256 + 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); } } @@ -919,27 +919,59 @@ mergeable_string_section (tree decl ATTRIBUTE_UNUSED, /* Return the section to use for constant merging. */ section * -mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED, - unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED, - unsigned int flags ATTRIBUTE_UNUSED) +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 - && mode != VOIDmode - && mode != BLKmode - && known_le (GET_MODE_BITSIZE (mode), align) + && newsize <= MAX_MERGEABLE_BITSIZE && align >= 8 - && align <= 256 + && 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; } + + +/* Return the section to use for constant merging. Like the above + but the size stored as a tree. */ +static section * +mergeable_constant_section (tree size_bits, + unsigned HOST_WIDE_INT align, + unsigned int flags) +{ + if (!size_bits || !tree_fits_uhwi_p (size_bits)) + return readonly_data_section; + return mergeable_constant_section (tree_to_uhwi (size_bits), align, flags); +} + + +/* Return the section to use for constant merging. Like the above + but given a mode rather than the size. */ + +section * +mergeable_constant_section (machine_mode mode, + unsigned HOST_WIDE_INT align, + unsigned int flags) +{ + /* If the mode is unknown (BLK or VOID), then return a non mergable section. */ + if (mode == BLKmode || mode == VOIDmode) + return readonly_data_section; + unsigned HOST_WIDE_INT size; + if (!GET_MODE_BITSIZE (mode).is_constant (&size)) + return readonly_data_section; + return mergeable_constant_section (size, align, flags); +} + /* Given NAME, a putative register name, discard any customary prefixes. */ @@ -2445,6 +2477,19 @@ assemble_variable_contents (tree decl, const char *name, else /* Leave space for it. */ assemble_zeros (tree_to_uhwi (DECL_SIZE_UNIT (decl))); + /* For mergeable section, make sure the section is zero filled up to + the entity size of the section. */ + if (in_section + && (in_section->common.flags & SECTION_MERGE) + && tree_fits_uhwi_p (DECL_SIZE_UNIT (decl)) + && ((in_section->common.flags & SECTION_ENTSIZE) + > tree_to_uhwi (DECL_SIZE_UNIT (decl)))) + { + unsigned HOST_WIDE_INT entsize, declsize; + entsize = (in_section->common.flags & SECTION_ENTSIZE); + declsize = tree_to_uhwi (DECL_SIZE_UNIT (decl)); + assemble_zeros (entsize - declsize); + } targetm.asm_out.decl_end (); } } @@ -4405,10 +4450,16 @@ output_constant_pool_1 (class constant_descriptor_rtx *desc, /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS sections have proper size. */ - if (align > GET_MODE_BITSIZE (desc->mode) - && in_section - && (in_section->common.flags & SECTION_MERGE)) - assemble_align (align); + if (in_section + && (in_section->common.flags & SECTION_MERGE) + && ((in_section->common.flags & SECTION_ENTSIZE) + > GET_MODE_SIZE (desc->mode))) + { + unsigned HOST_WIDE_INT entsize, constsize; + entsize = (in_section->common.flags & SECTION_ENTSIZE); + constsize = GET_MODE_SIZE (desc->mode); + assemble_zeros (entsize - constsize); + } #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY done: @@ -7453,7 +7504,7 @@ default_elf_select_section (tree decl, int reloc, case SECCAT_RODATA_MERGE_STR_INIT: return mergeable_string_section (DECL_INITIAL (decl), align, 0); case SECCAT_RODATA_MERGE_CONST: - return mergeable_constant_section (DECL_MODE (decl), align, 0); + return mergeable_constant_section (DECL_SIZE (decl), align, 0); case SECCAT_SRODATA: sname = ".sdata2"; break; |