Fix our -mprofiler-epilogue code.
"The problem is that egcs/gcc-2.95's reorganisation of the prologue and epilogue code to use rtl instead of output_asm_insn() completely broke our hooks. rtl is emitted in a different order, only after optimisation, while output_asm_insn() is emitted immediately. rtl is presumably used so that the prologue and epilogue can be optimised. I couldn't find any good examples to copy. gcc's own FUNCTION_BLOCK_PROFILER still uses output_asm_insn() and seems to be completely broken. One of the XXX comments points to this. IIRC, the hacks here basically arrange to emit magic label names; then when the magic names are output, they are transformed into prologue and epilogue code." Submitted by: bde
This commit is contained in:
parent
e8ddbcd7dc
commit
ca79b6ea7b
@ -103,10 +103,39 @@ Boston, MA 02111-1307, USA. */
|
||||
fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \
|
||||
(PREFIX), (NUM))
|
||||
|
||||
/* This is how to hack on the symbol code of certain relcalcitrant
|
||||
symbols to modify their output in output_pic_addr_const (). */
|
||||
|
||||
#undef ASM_HACK_SYMBOLREF_CODE
|
||||
#define ASM_HACK_SYMBOLREF_CODE(NAME, CODE) \
|
||||
do { \
|
||||
/* Part of hack to avoid writing lots of rtl in \
|
||||
FUNCTION_PROFILER_EPILOGUE (). */ \
|
||||
char *_name = (NAME); \
|
||||
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
|
||||
(CODE) = 'X'; \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME. */
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
|
||||
fprintf ((FILE), "%s%s", (TARGET_UNDERSCORES) ? "_" : "", (NAME))
|
||||
do { \
|
||||
char *_name = (NAME); \
|
||||
/* Hack to avoid writing lots of rtl in \
|
||||
FUNCTION_PROFILER_EPILOGUE (). */ \
|
||||
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
|
||||
{ \
|
||||
if (TARGET_AOUT) \
|
||||
_name++; \
|
||||
if (flag_pic) \
|
||||
fprintf ((FILE), "*%s@GOT(%%ebx)", _name); \
|
||||
else \
|
||||
fprintf ((FILE), "%s", _name); \
|
||||
} \
|
||||
else \
|
||||
fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
@ -416,37 +445,47 @@ do { \
|
||||
/* Tell final.c that we don't need a label passed to mcount. */
|
||||
#define NO_PROFILE_DATA
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
/* Redefine this to not pass an unused label in %edx. */
|
||||
/* Output assembler code to FILE to begin profiling of the current function.
|
||||
LABELNO is an optional label. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
do { \
|
||||
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", \
|
||||
TARGET_AOUT ? "mcount" : ".mcount"); \
|
||||
} \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name); \
|
||||
else \
|
||||
{ \
|
||||
fprintf ((FILE), "\tcall %s\n", TARGET_AOUT ? "mcount" : ".mcount"); \
|
||||
} \
|
||||
}
|
||||
fprintf ((FILE), "\tcall %s\n", _name); \
|
||||
} while (0)
|
||||
|
||||
/* Output assembler code to FILE to end profiling of the current function. */
|
||||
|
||||
#undef FUNCTION_PROFILER_EPILOGUE
|
||||
#define FUNCTION_PROFILER_EPILOGUE(FILE) \
|
||||
{ \
|
||||
#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL) \
|
||||
do { \
|
||||
if (TARGET_PROFILER_EPILOGUE) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", \
|
||||
TARGET_AOUT ? "mexitcount" : ".mexitcount"); \
|
||||
if (DO_RTL) \
|
||||
{ \
|
||||
/* ".mexitcount" is specially handled in \
|
||||
ASM_HACK_SYMBOLREF () so that we don't need to handle \
|
||||
flag_pic or TARGET_AOUT here. */ \
|
||||
rtx xop; \
|
||||
xop = gen_rtx_MEM (FUNCTION_MODE, \
|
||||
gen_rtx_SYMBOL_REF (Pmode, ".mexitcount")); \
|
||||
emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx)); \
|
||||
} \
|
||||
else \
|
||||
fprintf ((FILE), "\tcall %s\n", \
|
||||
TARGET_AOUT ? "mexitcount" : ".mexitcount"); \
|
||||
{ \
|
||||
/* XXX this !DO_RTL case is broken but not actually used. */ \
|
||||
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
|
||||
if (flag_pic) \
|
||||
fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name); \
|
||||
else \
|
||||
fprintf (FILE, "\tcall %s\n", _name); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
@ -103,10 +103,39 @@ Boston, MA 02111-1307, USA. */
|
||||
fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \
|
||||
(PREFIX), (NUM))
|
||||
|
||||
/* This is how to hack on the symbol code of certain relcalcitrant
|
||||
symbols to modify their output in output_pic_addr_const (). */
|
||||
|
||||
#undef ASM_HACK_SYMBOLREF_CODE
|
||||
#define ASM_HACK_SYMBOLREF_CODE(NAME, CODE) \
|
||||
do { \
|
||||
/* Part of hack to avoid writing lots of rtl in \
|
||||
FUNCTION_PROFILER_EPILOGUE (). */ \
|
||||
char *_name = (NAME); \
|
||||
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
|
||||
(CODE) = 'X'; \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME. */
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
|
||||
#undef ASM_OUTPUT_LABELREF
|
||||
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
|
||||
fprintf ((FILE), "%s%s", (TARGET_UNDERSCORES) ? "_" : "", (NAME))
|
||||
do { \
|
||||
char *_name = (NAME); \
|
||||
/* Hack to avoid writing lots of rtl in \
|
||||
FUNCTION_PROFILER_EPILOGUE (). */ \
|
||||
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
|
||||
{ \
|
||||
if (TARGET_AOUT) \
|
||||
_name++; \
|
||||
if (flag_pic) \
|
||||
fprintf ((FILE), "*%s@GOT(%%ebx)", _name); \
|
||||
else \
|
||||
fprintf ((FILE), "%s", _name); \
|
||||
} \
|
||||
else \
|
||||
fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name); \
|
||||
} while (0)
|
||||
|
||||
/* This is how to output an element of a case-vector that is relative.
|
||||
This is only used for PIC code. See comments by the `casesi' insn in
|
||||
@ -416,37 +445,47 @@ do { \
|
||||
/* Tell final.c that we don't need a label passed to mcount. */
|
||||
#define NO_PROFILE_DATA
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry. */
|
||||
/* Redefine this to not pass an unused label in %edx. */
|
||||
/* Output assembler code to FILE to begin profiling of the current function.
|
||||
LABELNO is an optional label. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
{ \
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
do { \
|
||||
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", \
|
||||
TARGET_AOUT ? "mcount" : ".mcount"); \
|
||||
} \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name); \
|
||||
else \
|
||||
{ \
|
||||
fprintf ((FILE), "\tcall %s\n", TARGET_AOUT ? "mcount" : ".mcount"); \
|
||||
} \
|
||||
}
|
||||
fprintf ((FILE), "\tcall %s\n", _name); \
|
||||
} while (0)
|
||||
|
||||
/* Output assembler code to FILE to end profiling of the current function. */
|
||||
|
||||
#undef FUNCTION_PROFILER_EPILOGUE
|
||||
#define FUNCTION_PROFILER_EPILOGUE(FILE) \
|
||||
{ \
|
||||
#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL) \
|
||||
do { \
|
||||
if (TARGET_PROFILER_EPILOGUE) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", \
|
||||
TARGET_AOUT ? "mexitcount" : ".mexitcount"); \
|
||||
if (DO_RTL) \
|
||||
{ \
|
||||
/* ".mexitcount" is specially handled in \
|
||||
ASM_HACK_SYMBOLREF () so that we don't need to handle \
|
||||
flag_pic or TARGET_AOUT here. */ \
|
||||
rtx xop; \
|
||||
xop = gen_rtx_MEM (FUNCTION_MODE, \
|
||||
gen_rtx_SYMBOL_REF (Pmode, ".mexitcount")); \
|
||||
emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx)); \
|
||||
} \
|
||||
else \
|
||||
fprintf ((FILE), "\tcall %s\n", \
|
||||
TARGET_AOUT ? "mexitcount" : ".mexitcount"); \
|
||||
{ \
|
||||
/* XXX this !DO_RTL case is broken but not actually used. */ \
|
||||
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
|
||||
if (flag_pic) \
|
||||
fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name); \
|
||||
else \
|
||||
fprintf (FILE, "\tcall %s\n", _name); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "unsigned int"
|
||||
|
@ -2015,6 +2015,11 @@ ix86_can_use_return_insn_p ()
|
||||
int reglimit = (frame_pointer_needed
|
||||
? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
|
||||
|
||||
#ifdef TARGET_PROFILER_EPILOGUE
|
||||
if (TARGET_PROFILER_EPILOGUE)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef NON_SAVING_SETJMP
|
||||
if (NON_SAVING_SETJMP && current_function_calls_setjmp)
|
||||
return 0;
|
||||
@ -2081,6 +2086,10 @@ ix86_epilogue (do_rtl)
|
||||
if (flag_pic || profile_flag || profile_block_flag)
|
||||
emit_insn (gen_blockage ());
|
||||
|
||||
#ifdef FUNCTION_PROFILER_EPILOGUE
|
||||
FUNCTION_PROFILER_EPILOGUE (asm_out_file, do_rtl);
|
||||
#endif
|
||||
|
||||
/* If we're only restoring one register and sp is not valid then
|
||||
using a move instruction to restore the register since it's
|
||||
less work than reloading sp and popping the register. Otherwise,
|
||||
@ -2216,6 +2225,7 @@ ix86_epilogue (do_rtl)
|
||||
#ifdef FUNCTION_BLOCK_PROFILER_EXIT
|
||||
if (profile_block_flag == 2)
|
||||
{
|
||||
/* XXX this is hosed like FUNCTION_PROFILER_EPILOGUE () was. */
|
||||
FUNCTION_BLOCK_PROFILER_EXIT(file);
|
||||
}
|
||||
#endif
|
||||
@ -2899,6 +2909,9 @@ output_pic_addr_const (file, x, code)
|
||||
|
||||
case SYMBOL_REF:
|
||||
assemble_name (file, XSTR (x, 0));
|
||||
#ifdef ASM_HACK_SYMBOLREF_CODE
|
||||
ASM_HACK_SYMBOLREF_CODE (XSTR (x, 0), code);
|
||||
#endif
|
||||
if (code == 'P' && ! SYMBOL_REF_FLAG (x))
|
||||
fputs ("@PLT", file);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user