+2014-09-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * output.h (get_some_local_dynamic_name): Declare.
+ * final.c (some_local_dynamic_name): New variable.
+ (get_some_local_dynamic_name): New function.
+ (final_end_function): Clear some_local_dynamic_name.
+ * config/alpha/alpha.c (machine_function): Remove some_ld_name.
+ (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
+ (print_operand): Report an error if '%&' is used inappropriately.
+ * config/i386/i386.c (get_some_local_dynamic_name): Delete.
+ (get_some_local_dynamic_name_1): Delete.
+ * config/rs6000/rs6000.c (machine_function): Remove some_ld_name.
+ (rs6000_get_some_local_dynamic_name): Delete.
+ (rs6000_get_some_local_dynamic_name_1): Delete.
+ (print_operand): Report an error if '%&' is used inappropriately.
+ * config/s390/s390.c (machine_function): Remove some_ld_name.
+ (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
+ (print_operand): Assert that get_some_local_dynamic_name is nonnull.
+ * config/sparc/sparc.c: Include rtl-iter.h.
+ (machine_function): Remove some_ld_name.
+ (sparc_print_operand): Report an error if '%&' is used inappropriately.
+ (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Delete.
+
2014-09-03 Richard Henderson <rth@redhat.com>
* config/aarch64/aarch64.c (aarch64_popwb_single_reg): Remove.
struct GTY(()) machine_function
{
- /* For OSF. */
- const char *some_ld_name;
-
/* For flag_reorder_blocks_and_partition. */
rtx gp_save_rtx;
gcc_unreachable ();
}
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in some movdi_er_tlsldm pattern. */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = XSTR (x, 0);
- return 1;
- }
-
- return 0;
-}
-
-static const char *
-get_some_local_dynamic_name (void)
-{
- rtx_insn *insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- gcc_unreachable ();
-}
-
/* Print an operand. Recognize special options, documented below. */
void
break;
case '&':
- assemble_name (file, get_some_local_dynamic_name ());
+ if (const char *name = get_some_local_dynamic_name ())
+ assemble_name (file, name);
+ else
+ output_operand_lossage ("'%%&' used without any "
+ "local dynamic TLS references");
break;
case '/':
}
}
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in some tls_local_dynamic_base
- pattern. */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *)
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = XSTR (x, 0);
- return 1;
- }
-
- return 0;
-}
-
-static const char *
-get_some_local_dynamic_name (void)
-{
- rtx_insn *insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (NONDEBUG_INSN_P (insn)
- && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- return NULL;
-}
-
/* Meaning of CODE:
L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
C -- print opcode suffix for set/cmov insn.
This is added to the cfun structure. */
typedef struct GTY(()) machine_function
{
- /* Some local-dynamic symbol. */
- const char *some_ld_name;
/* Whether the instruction chain has been scanned already. */
int insn_chain_scanned_p;
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
int easy_vector_constant (rtx, enum machine_mode);
static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
-static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
bool, bool);
#if TARGET_MACHO
return i;
}
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in some tls_ld pattern. */
-
-static const char *
-rs6000_get_some_local_dynamic_name (void)
-{
- rtx_insn *insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && for_each_rtx (&PATTERN (insn),
- rs6000_get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- gcc_unreachable ();
-}
-
-/* Helper function for rs6000_get_some_local_dynamic_name. */
-
-static int
-rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF)
- {
- const char *str = XSTR (x, 0);
- if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = str;
- return 1;
- }
- }
-
- return 0;
-}
-
/* Write out a function code label. */
void
return;
case '&':
- assemble_name (file, rs6000_get_some_local_dynamic_name ());
+ if (const char *name = get_some_local_dynamic_name ())
+ assemble_name (file, name);
+ else
+ output_operand_lossage ("'%%&' used without any "
+ "local dynamic TLS references");
return;
default:
/* True if we may need to perform branch splitting. */
bool split_branches_pending_p;
- /* Some local-dynamic TLS symbol name. */
- const char *some_ld_name;
-
bool has_landing_pad_p;
/* True if the current function may contain a tbegin clobbering
fprintf (file, "(%s)", reg_names[REGNO (base)]);
}
-/* See 'get_some_local_dynamic_name'. */
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
- {
- x = get_pool_constant (x);
- return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
- }
-
- if (GET_CODE (x) == SYMBOL_REF
- && tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = XSTR (x, 0);
- return 1;
- }
-
- return 0;
-}
-
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in local-dynamic base patterns. */
-
-static const char *
-get_some_local_dynamic_name (void)
-{
- rtx_insn *insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- gcc_unreachable ();
-}
-
/* Returns -1 if the function should not be made hotpatchable. Otherwise it
returns a number >= 0 that is the desired size of the hotpatch trampoline
in halfwords. */
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
{
fprintf (file, "%s", ":tls_ldcall:");
- assemble_name (file, get_some_local_dynamic_name ());
+ const char *name = get_some_local_dynamic_name ();
+ gcc_assert (name);
+ assemble_name (file, name);
}
else
output_operand_lossage ("invalid reference for 'J' output modifier");
#include "context.h"
#include "wide-int.h"
#include "builtins.h"
+#include "rtl-iter.h"
/* Processor costs */
rtx frame_base_reg;
HOST_WIDE_INT frame_base_offset;
- /* Some local-dynamic TLS symbol name. */
- const char *some_ld_name;
-
/* Number of global or FP registers to be saved (as 4-byte quantities). */
int n_global_fp_regs;
static bool sparc_cannot_force_const_mem (enum machine_mode, rtx);
static rtx sparc_tls_get_addr (void);
static rtx sparc_tls_got (void);
-static const char *get_some_local_dynamic_name (void);
-static int get_some_local_dynamic_name_1 (rtx *, void *);
static int sparc_register_move_cost (enum machine_mode,
reg_class_t, reg_class_t);
static bool sparc_rtx_costs (rtx, int, int, int, int *, bool);
return;
case '&':
/* Print some local dynamic TLS name. */
- assemble_name (file, get_some_local_dynamic_name ());
+ if (const char *name = get_some_local_dynamic_name ())
+ assemble_name (file, name);
+ else
+ output_operand_lossage ("'%%&' used without any "
+ "local dynamic TLS references");
return;
case 'Y':
return ggc_cleared_alloc<machine_function> ();
}
-/* Locate some local-dynamic symbol still in use by this function
- so that we can print its name in local-dynamic base patterns. */
-
-static const char *
-get_some_local_dynamic_name (void)
-{
- rtx_insn *insn;
-
- if (cfun->machine->some_ld_name)
- return cfun->machine->some_ld_name;
-
- for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
- if (INSN_P (insn)
- && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
- return cfun->machine->some_ld_name;
-
- gcc_unreachable ();
-}
-
-static int
-get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
- rtx x = *px;
-
- if (x
- && GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
- {
- cfun->machine->some_ld_name = XSTR (x, 0);
- return 1;
- }
-
- return 0;
-}
-
/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */
reorder_blocks ();
}
+static const char *some_local_dynamic_name;
+
+/* Locate some local-dynamic symbol still in use by this function
+ so that we can print its name in local-dynamic base patterns.
+ Return null if there are no local-dynamic references. */
+
+const char *
+get_some_local_dynamic_name ()
+{
+ subrtx_iterator::array_type array;
+ rtx_insn *insn;
+
+ if (some_local_dynamic_name)
+ return some_local_dynamic_name;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ if (NONDEBUG_INSN_P (insn))
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
+ {
+ const_rtx x = *iter;
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ return some_local_dynamic_name = XSTR (x, 0);
+ if (CONSTANT_POOL_ADDRESS_P (x))
+ iter.substitute (get_pool_constant (x));
+ }
+ }
+
+ return 0;
+}
+
/* Output assembler code for the start of a function,
and initialize some of the variables in this file
for the new function. The label for the function and associated
if (!dwarf2_debug_info_emitted_p (current_function_decl)
&& dwarf2out_do_frame ())
dwarf2out_end_epilogue (last_linenum, last_filename);
+
+ some_local_dynamic_name = 0;
}
\f
any branches of variable length if possible. */
extern void shorten_branches (rtx_insn *);
+const char *get_some_local_dynamic_name ();
+
/* Output assembler code for the start of a function,
and initialize some of the variables in this file
for the new function. The label for the function and associated