Message ID | CAGWvny=T4xAQ+1S55V8qBD_0-kWzW5w7bgOjsARHCAuG3Hei-g@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | precompute_tls_p target hook in calls.c for AIX TLS (PR 94177) | expand |
On 4/14/2021 3:43 PM, David Edelsohn via Gcc-patches wrote: > AIX uses a compiler-managed TOC for global data, including TLS symbols. > The GCC TOC implementation manages the TOC entries through the > constant pool. > > TLS symbols sometimes require a function call to obtain the TLS base > pointer. The arguments to the TLS call can conflict with arguments to > a normal function call if the TLS symbol is an argument in the normal call. > GCC specifically checks for this situation and precomputes the TLS > arguments, but the mechanism to check for this requirement utilizes > legitimate_constant_p(). The necessary result of legitimate_constant_p() > for correct TOC behavior and for correct TLS argument behavior is in > conflict. > > I have tried multiple approaches to wrap the symbol in UNSPEC and > tweaking legitimate_constant_p definition. The current AIX TOC > implementation is too tied to force_const_mem() and the constant pool. > The calls.c test is tied to both CONST and TLS. I would appreciate > not being told that this is abusing the definition of CONST in GCC or > that I should re-write the TOC implementation. > > This patch adds a new target hook precompute_tls_p() to decide if an > argument should be precomputed regardless of the result from > legitmate_constant_p(). > > If you want to consider this a hack for AIX, fine. > > Bootstrapped on powerpc-ibm-aix7.2.3.0. > > Thanks, David > > * gcc/calls.c (precompute_register_parameters): Additionally test > targetm.precompute_tls_p to pre-compute argument. > * gcc/config/rs6000/aix.h (TARGET_PRECOMPUTE_TLS_P): Define. > * gcc/config/rs6000/rs6000.c (rs6000_aix_precompute_tls_p): New. > * gcc/target.def (precompute_tls_p): New. Not ideal. But I don't see a better way given your research. OK jeff
diff --git a/gcc/calls.c b/gcc/calls.c index ff606204772..883d08ba5f2 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1002,7 +1002,8 @@ precompute_register_parameters (int num_actuals, struct arg_data *args, /* If the value is a non-legitimate constant, force it into a pseudo now. TLS symbols sometimes need a call to resolve. */ if (CONSTANT_P (args[i].value) - && !targetm.legitimate_constant_p (args[i].mode, args[i].value)) + && (!targetm.legitimate_constant_p (args[i].mode, args[i].value) + || targetm.precompute_tls_p (args[i].mode, args[i].value))) args[i].value = force_reg (args[i].mode, args[i].value); /* If we're going to have to load the value by parts, pull the diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 7fccb31307b..b116e1a36bb 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -279,3 +279,4 @@ /* Use standard DWARF numbering for DWARF debugging information. */ #define RS6000_USE_DWARF_NUMBERING +#define TARGET_PRECOMPUTE_TLS_P rs6000_aix_precompute_tls_p diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 48b8efd732b..e2010035ee8 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -9608,7 +9608,8 @@ rs6000_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) != 0) return true; - /* Do not place an ELF TLS symbol in the constant pool. */ + /* Allow AIX TOC TLS symbols in the constant pool, + but not ELF TLS symbols. */ return TARGET_ELF && tls_referenced_p (x); } @@ -25370,6 +25371,18 @@ rs6000_legitimate_constant_p (machine_mode mode, rtx x) return true; } +/* Implement TARGET_PRECOMPUTE_TLS_P. + + On the AIX, TLS symbols are in the TOC, which is maintained in the + constant pool. AIX TOC TLS symbols need to be pre-computed, but + must be considered legitimate constants. */ + +static bool +rs6000_aix_precompute_tls_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) +{ + return tls_referenced_p (x); +} + ^L /* Return TRUE iff the sequence ending in LAST sets the static chain. */ diff --git a/gcc/target.def b/gcc/target.def index d7b94bd8e5d..0ebfb58fa6f 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2715,6 +2715,18 @@ The default definition returns true.", bool, (machine_mode mode, rtx x), hook_bool_mode_rtx_true) +/* True if X is a TLS operand whose value should be pre-computed. */ +DEFHOOK +(precompute_tls_p, + "This hook returns true if @var{x} is a TLS operand on the target\n\ +machine that should be pre-computed when used as the argument in a call.\n\ +You can assume that @var{x} satisfies @code{CONSTANT_P}, so you need not \n\ +check this.\n\ +\n\ +The default definition returns false.", + bool, (machine_mode mode, rtx x), + hook_bool_mode_rtx_false) + /* True if the constant X cannot be placed in the constant pool. */ DEFHOOK (cannot_force_const_mem,