-2005-10-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2005-10-24 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-linux.h (NO_PROFILE_COUNTERS): Delete define.
+ (NO_DEFERRED_PROFILE_COUNTERS): Define.
+ * pa.h (NO_PROFILE_COUNTERS): Define.
+ * pa.c (NO_DEFERRED_PROFILE_COUNTERS): Define if not defined.
+ (funcdef_nos): New vector to hold label numbers of deferred profile
+ counters.
+ (output_deferred_profile_counters): New function.
+ (hppa_profile_hook): Push label number onto funcdef_nos.
+ (pa_hpux_file_end): Call output_deferred_profile_counters if
+ NO_DEFERRED_PROFILE_COUNTERS is false.
* pa-protos.h (get_deferred_plabel): New prototype.
* pa.c (get_plabel): Rename to get_deferred_plabel. Return plabel.
static void pa_hpux64_gas_file_start (void) ATTRIBUTE_UNUSED;
static void pa_hpux64_hpas_file_start (void) ATTRIBUTE_UNUSED;
static void output_deferred_plabels (void);
+static void output_deferred_profile_counters (void) ATTRIBUTE_UNUSED;
#ifdef ASM_OUTPUT_EXTERNAL_REAL
static void pa_hpux_file_end (void);
#endif
return get_hard_reg_initial_val (word_mode, PIC_OFFSET_TABLE_REGNUM);
}
+#ifndef NO_DEFERRED_PROFILE_COUNTERS
+#define NO_DEFERRED_PROFILE_COUNTERS 0
+#endif
+
+/* Define heap vector type for funcdef numbers. */
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
+
+/* Vector of funcdef numbers. */
+static VEC(int,heap) *funcdef_nos;
+
+/* Output deferred profile counters. */
+static void
+output_deferred_profile_counters (void)
+{
+ unsigned int i;
+ int align, n;
+
+ if (VEC_empty (int, funcdef_nos))
+ return;
+
+ data_section ();
+ align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+ ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
+
+ for (i = 0; VEC_iterate (int, funcdef_nos, i, n); i++)
+ {
+ targetm.asm_out.internal_label (asm_out_file, "LP", n);
+ assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
+ }
+
+ VEC_free (int, heap, funcdef_nos);
+}
+
void
hppa_profile_hook (int label_no)
{
emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25),
reg, begin_label_rtx, label_rtx));
-#ifndef NO_PROFILE_COUNTERS
+#if !NO_DEFERRED_PROFILE_COUNTERS
{
rtx count_label_rtx, addr, r24;
char count_label_name[16];
+ VEC_safe_push (int, heap, funcdef_nos, label_no);
ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no);
count_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (count_label_name));
unsigned int i;
extern_symbol *p;
+ if (!NO_DEFERRED_PROFILE_COUNTERS)
+ output_deferred_profile_counters ();
+
output_deferred_plabels ();
for (i = 0; VEC_iterate (extern_symbol, extern_symbols, i, p); i++)
/* The profile counter if emitted must come before the prologue. */
#define PROFILE_BEFORE_PROLOGUE 1
+/* We never want final.c to emit profile counters. When profile
+ counters are required, we have to defer emitting them to the end
+ of the current file. */
+#define NO_PROFILE_COUNTERS 1
+
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers.