On Tue, Apr 1, 2025 at 12:04 AM Thomas Schwinge <tschwi...@baylibre.com> wrote: > > Hi! > > In Nvidia PTX, "A state space is a storage area with particular > characteristics. All variables reside in some state space. [...]". > These include: > > .const Shared, read-only memory. > .global Global memory, shared by all threads. > > Implemented via 'TARGET_ENCODE_SECTION_INFO', GCC/nvptx then uses > special-cased instructions for accessing the respective memory regions. > > Now, given a 'const' array (with whatever element type; not interesting > here), like: > > extern int * const arr[]; > > ..., for GCC/C compilation, we access this as '.const' memory: GCC/nvptx > 'DATA_AREA_CONST', but for GCC/C++ compilation, we access it as > 'DATA_AREA_GLOBAL', and then fault at run time due to mismatch with the > definition, which actually is '.const' for both C and C++ compilation. > > The difference is, when we get to 'TARGET_ENCODE_SECTION_INFO', that for > C we've got 'TREE_READONLY(decl)', but for C++ we don't.
In C++ there could be runtime initializers for a const qualified object. I think all you need to do is make sure the logic that places the object in .const vs. .global is consistent with the logic deciding how to access it. You could look at the symtab entry for a decl, there's the get_section () method, but I'm not sure we are adjusting this for all objects, it might be just used for comdats. Richard. > > C: > > Breakpoint 3, nvptx_encode_section_info (decl=0x7ffff7824720, > rtl=0x7ffff7843180, first=1) at ../../source-gcc/gcc/config/nvptx/nvptx.cc:468 > 468 { > (gdb) call debug_tree(decl) > <var_decl 0x7ffff7824720 arr > type <array_type 0x7ffff77f7f18 > type <pointer_type 0x7ffff77f7d20 type <integer_type > 0x7ffff76fa5e8 int> > readonly unsigned DI > size <integer_cst 0x7ffff76eb600 constant 64> > unit-size <integer_cst 0x7ffff76eb618 constant 8> > align:64 warn_if_not_align:0 symtab:0 alias-set -1 > canonical-type 0x7ffff77f7d20> > BLK > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7ffff77f7f18> > readonly used public external read BLK > source-gcc/gcc/testsuite/gcc.target/nvptx/const-1-2.c:8:20 > align:64 warn_if_not_align:0 context <translation_unit_decl > 0x7ffff783a100 source-gcc/gcc/testsuite/gcc.target/nvptx/const-1-2.c> > (mem/u/c:BLK (symbol_ref:DI ("arr") <var_decl 0x7ffff7824720 arr>) [1 > arr+0 A64]) chain <function_decl 0x7ffff7819f00 main>> > > Note 'readonly' ('TREE_READONLY') in the third-last line, > and '/u' (RTL 'MEM_READONLY_P') in the last line. > > C++: > > Breakpoint 3, nvptx_encode_section_info (decl=0x7ffff783fa18, > rtl=0x7ffff7844a50, first=1) at ../../source-gcc/gcc/config/nvptx/nvptx.cc:468 > 468 { > (gdb) call debug_tree(decl) > <var_decl 0x7ffff783fa18 arr > type <array_type 0x7ffff782f738 > type <pointer_type 0x7ffff782fe70 type <integer_type > 0x7ffff77015e8 int> > readonly unsigned type_6 DI > size <integer_cst 0x7ffff76eb900 constant 64> > unit-size <integer_cst 0x7ffff76eb918 constant 8> > align:64 warn_if_not_align:0 symtab:0 alias-set -1 > canonical-type 0x7ffff782fe70> > type_6 BLK > align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type > 0x7ffff782f738> > used public external read decl_2 BLK > source-gcc/gcc/testsuite/g++.target/nvptx/const-1-2.C:14:20 > align:64 warn_if_not_align:0 context <translation_unit_decl > 0x7ffff76fe000 source-gcc/gcc/testsuite/g++.target/nvptx/const-1-2.C> > (mem/c:BLK (symbol_ref:DI ("arr") <var_decl 0x7ffff783fa18 arr>) [1 > arr+0 A64]) chain <function_decl 0x7ffff7830600 __cxa_call_terminate>> > > Note no 'readonly' ('!TREE_READONLY') in the third-last line, > and no '/u' (RTL '!MEM_READONLY_P') in the last line. > > Is this difference expected? > > > Now, for example, in 'gcc/config/avr/avr.cc', I found code like: > > tree node0 = node; > > /* For C++, we have to peel arrays in order to get correct > determination of readonlyness. */ > > do > node0 = TREE_TYPE (node0); > while (TREE_CODE (node0) == ARRAY_TYPE); > > if (error_mark_node == node0) > return; > > [...] > > if (!TYPE_READONLY (node0) > && !TREE_READONLY (node)) > { > > That is, in our case, instead of just looking at 'TREE_READONLY (node)', > we need: > > if (TREE_READONLY (node) || TYPE_READONLY (node0)) > [DATA_AREA_CONST] > else > [DATA_AREA_GLOBAL] > > Is this indeed what we have to do? (It would appear to work in the case > analyzed above, but I've not yet checked for other fallout.) > > > Grüße > Thomas