From 6995e4285b1fd153901fdf9b718c481cd0fdf44f Mon Sep 17 00:00:00 2001 From: obrien Date: Sat, 29 Jan 2000 13:06:33 +0000 Subject: 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 --- contrib/gcc/config/i386/freebsd.h | 85 ++++++++++++++++++++++++--------- contrib/gcc/config/i386/freebsd.h.fixed | 85 ++++++++++++++++++++++++--------- contrib/gcc/config/i386/i386.c | 13 +++++ 3 files changed, 137 insertions(+), 46 deletions(-) (limited to 'contrib/gcc/config') diff --git a/contrib/gcc/config/i386/freebsd.h b/contrib/gcc/config/i386/freebsd.h index 8398733..c1b41a5 100644 --- a/contrib/gcc/config/i386/freebsd.h +++ b/contrib/gcc/config/i386/freebsd.h @@ -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" diff --git a/contrib/gcc/config/i386/freebsd.h.fixed b/contrib/gcc/config/i386/freebsd.h.fixed index 8398733..c1b41a5 100644 --- a/contrib/gcc/config/i386/freebsd.h.fixed +++ b/contrib/gcc/config/i386/freebsd.h.fixed @@ -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" diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c index 08542a0..9eb9582 100644 --- a/contrib/gcc/config/i386/i386.c +++ b/contrib/gcc/config/i386/i386.c @@ -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; -- cgit v1.1