From 2ea844d394a2f1cc1c4cbcb43dbaf068b8dbd9a6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 15 Oct 1997 18:23:23 -0700 Subject: [PATCH] alpha.c (final_prescan_insn): Gut, remove and transform to ... * alpha.c (final_prescan_insn): Gut, remove and transform to ... (alpha_handle_trap_shadows): ... a new function. Handle the entire function in one go. Emit RTL for trapb, instead of printf directly. (alpha_reorg): New function. Call alpha_handle_trap_shadows. (trap_pending): Kill global variable. (output_epilog): Don't call final_prescan_insn. (struct shadow_summary): Elide $31 and $f31; now it fits in a word. * alpha.h (FINAL_PRESCAN_INSN): Remove. (MACHINE_DEPENENT_REORG): Define. * alpha.md (jsr patterns with trapb): Stupid and useless. Kill. (trapb): New insn. From-SVN: r15917 --- gcc/ChangeLog | 14 +++ gcc/config/alpha/alpha.c | 244 +++++++++++++++++++++----------------- gcc/config/alpha/alpha.h | 11 +- gcc/config/alpha/alpha.md | 34 ++---- 4 files changed, 163 insertions(+), 140 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e20e7c3cfcd..368d21281df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +Wed Oct 15 18:21:46 1997 Richard Henderson + + * alpha.c (final_prescan_insn): Gut, remove and transform to ... + (alpha_handle_trap_shadows): ... a new function. Handle the entire + function in one go. Emit RTL for trapb, instead of printf directly. + (alpha_reorg): New function. Call alpha_handle_trap_shadows. + (trap_pending): Kill global variable. + (output_epilog): Don't call final_prescan_insn. + (struct shadow_summary): Elide $31 and $f31; now it fits in a word. + * alpha.h (FINAL_PRESCAN_INSN): Remove. + (MACHINE_DEPENENT_REORG): Define. + * alpha.md (jsr patterns with trapb): Stupid and useless. Kill. + (trapb): New insn. + Wed Oct 15 18:16:05 1997 Richard Henderson Tune Haifa scheduler for Alpha: diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 8990c5b437e..28435f955f7 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -75,10 +75,6 @@ char *alpha_function_name; static int inside_function = FALSE; -/* Non-zero if an instruction that may cause a trap is pending. */ - -static int trap_pending = 0; - /* Nonzero if the current function needs gp. */ int alpha_function_needs_gp; @@ -2599,8 +2595,6 @@ output_epilog (file, size) int fp_offset = 0; int sa_reg; - final_prescan_insn (NULL_RTX, NULL_PTR, 0); - /* If we have a frame pointer, restore SP from it. */ if (frame_pointer_needed) fprintf (file, "\tbis $15,$15,$30\n"); @@ -2791,8 +2785,8 @@ alpha_output_lineno (stream, line) struct shadow_summary { struct { - unsigned long i : 32; /* Mask of int regs */ - unsigned long fp : 32; /* Mask of fp regs */ + unsigned long i : 31; /* Mask of int regs */ + unsigned long fp : 31; /* Mask of fp regs */ unsigned long mem : 1; /* mem == imem | fpmem */ } used, defd; }; @@ -2915,19 +2909,9 @@ summarize_insn (x, sum, set) } } } - -/* This function is executed just prior to the output of assembler code for - INSN to modify the extracted operands so they will be output differently. - - OPVEC is the vector containing the operands extracted from INSN, and - NOPERANDS is the number of elements of the vector which contain meaningful - data for this insn. The contents of this vector are what will be used to - convert the insn template into assembler code, so you can change the - assembler output by changing the contents of the vector. - We use this function to ensure a sufficient number of `trapb' instructions - are in the code when the user requests code with a trap precision of - functions or instructions. +/* Ensure a sufficient number of `trapb' insns are in the code when the user + requests code with a trap precision of functions or instructions. In naive mode, when the user requests a trap-precision of "instruction", a trapb is needed after every instruction that may generate a trap (and after @@ -2953,103 +2937,151 @@ summarize_insn (x, sum, set) (c) Within the trap shadow, no register may be used more than once as a destination register. (This is to make life easier for the trap-handler.) - (d) The trap shadow may not include any branch instructions. - - */ + (d) The trap shadow may not include any branch instructions. */ -void -final_prescan_insn (insn, opvec, noperands) - rtx insn; - rtx *opvec; - int noperands; +static void +alpha_handle_trap_shadows (insns) + rtx insns; { - static struct shadow_summary shadow = {0, 0, 0, 0, 0}; + struct shadow_summary shadow; + int trap_pending, exception_nesting; + rtx i; -#define CLOSE_SHADOW \ - do \ - { \ - fputs ("\ttrapb\n", asm_out_file); \ - trap_pending = 0; \ - bzero ((char *) &shadow, sizeof shadow); \ - } \ - while (0) - - if (alpha_tp == ALPHA_TP_PROG) + if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions) return; - if (trap_pending) - switch (alpha_tp) - { - case ALPHA_TP_FUNC: - /* Generate one trapb before epilogue (indicated by INSN==0) */ - if (insn == 0) - CLOSE_SHADOW; - break; - - case ALPHA_TP_INSN: - if (optimize && insn != 0) - { - struct shadow_summary sum = {0, 0, 0}; - - switch (GET_CODE(insn)) - { - case INSN: - summarize_insn (PATTERN (insn), &sum, 0); - - if ((sum.defd.i & shadow.defd.i) - || (sum.defd.fp & shadow.defd.fp)) - { - /* (c) would be violated */ - CLOSE_SHADOW; - break; - } - - /* Combine shadow with summary of current insn: */ - shadow.used.i |= sum.used.i; - shadow.used.fp |= sum.used.fp; - shadow.used.mem |= sum.used.mem; - shadow.defd.i |= sum.defd.i; - shadow.defd.fp |= sum.defd.fp; - shadow.defd.mem |= sum.defd.mem; - - if ((sum.defd.i & shadow.used.i) - || (sum.defd.fp & shadow.used.fp) - || (sum.defd.mem & shadow.used.mem)) - { - /* (a) would be violated (also takes care of (b)). */ - if (get_attr_trap (insn) == TRAP_YES - && ((sum.defd.i & sum.used.i) - || (sum.defd.fp & sum.used.fp))) + trap_pending = 0; + exception_nesting = 0; + shadow.used.i = 0; + shadow.used.fp = 0; + shadow.used.mem = 0; + shadow.defd = shadow.used; + + for (i = insns; i ; i = NEXT_INSN (i)) + { + if (GET_CODE (i) == NOTE) + { + switch (NOTE_LINE_NUMBER (i)) + { + case NOTE_INSN_EH_REGION_BEG: + exception_nesting++; + if (trap_pending) + goto close_shadow; + break; + + case NOTE_INSN_EH_REGION_END: + exception_nesting--; + if (trap_pending) + goto close_shadow; + break; + + case NOTE_INSN_EPILOGUE_BEG: + if (trap_pending && alpha_tp >= ALPHA_TP_FUNC) + goto close_shadow; + break; + } + } + else if (trap_pending) + { + if (alpha_tp == ALPHA_TP_FUNC) + { + if (GET_CODE (i) == JUMP_INSN + && GET_CODE (PATTERN (i)) == RETURN) + goto close_shadow; + } + else if (alpha_tp == ALPHA_TP_INSN) + { + if (optimize > 0) + { + struct shadow_summary sum; + + sum.used.i = 0; + sum.used.fp = 0; + sum.used.mem = 0; + sum.defd = shadow.used; + + switch (GET_CODE (i)) + { + case INSN: + /* Annoyingly, get_attr_trap will abort on USE. */ + if (GET_CODE (PATTERN (i)) == USE) + break; + + summarize_insn (PATTERN (i), &sum, 0); + + if ((sum.defd.i & shadow.defd.i) + || (sum.defd.fp & shadow.defd.fp)) + { + /* (c) would be violated */ + goto close_shadow; + } + + /* Combine shadow with summary of current insn: */ + shadow.used.i |= sum.used.i; + shadow.used.fp |= sum.used.fp; + shadow.used.mem |= sum.used.mem; + shadow.defd.i |= sum.defd.i; + shadow.defd.fp |= sum.defd.fp; + shadow.defd.mem |= sum.defd.mem; + + if ((sum.defd.i & shadow.used.i) + || (sum.defd.fp & shadow.used.fp) + || (sum.defd.mem & shadow.used.mem)) + { + /* (a) would be violated (also takes care of (b)) */ + if (get_attr_trap (i) == TRAP_YES + && ((sum.defd.i & sum.used.i) + || (sum.defd.fp & sum.used.fp))) + abort (); + + goto close_shadow; + } + break; + + case JUMP_INSN: + case CALL_INSN: + case CODE_LABEL: + goto close_shadow; + + default: abort (); + } + } + else + { + close_shadow: + emit_insn_before (gen_trapb (), i); + trap_pending = 0; + shadow.used.i = 0; + shadow.used.fp = 0; + shadow.used.mem = 0; + shadow.defd = shadow.used; + } + } + } - CLOSE_SHADOW; - break; - } - break; - - case JUMP_INSN: - case CALL_INSN: - case CODE_LABEL: - CLOSE_SHADOW; - break; - - default: - abort (); - } + if (exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC) + if (GET_CODE (i) == INSN + && GET_CODE (PATTERN (i)) != USE + && get_attr_trap (i) == TRAP_YES) + { + if (optimize && !trap_pending) + summarize_insn (PATTERN (i), &shadow, 0); + trap_pending = 1; } - else - CLOSE_SHADOW; - break; - } - - if (insn != 0 && get_attr_trap (insn) == TRAP_YES) - { - if (optimize && !trap_pending && GET_CODE (insn) == INSN) - summarize_insn (PATTERN (insn), &shadow, 0); - trap_pending = 1; } } +/* Machine dependant reorg pass. */ + +void +alpha_reorg (insns) + rtx insns; +{ + alpha_handle_trap_shadows (insns); +} + + /* Check a floating-point value for validity for a particular machine mode. */ static char *float_strings[] = diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 0829c079aec..8c8cf5c45e8 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1463,15 +1463,8 @@ __enable_execute_stack (addr) \ #define ADDRESS_COST(X) 0 -/* Define this if some processing needs to be done immediately before - emitting code for an insn. */ - -extern void final_prescan_insn (); -#define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) \ - final_prescan_insn ((INSN), (OPERANDS), (NOPERANDS)) - -/* Define this if FINAL_PRESCAN_INSN should be called for a CODE_LABEL. */ -#define FINAL_PRESCAN_LABEL +/* Machine-dependent reorg pass. */ +#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X) /* Specify the machine mode that this machine uses for the index in the tablejump instruction. */ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 5f760a563a2..1240d562cd0 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -3279,18 +3279,6 @@ } }") -(define_insn "" - [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) - (match_operand 1 "" "")) - (clobber (reg:DI 27)) - (clobber (reg:DI 26))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN" - "@ - jsr $26,($27),0\;trapb\;ldgp $29,4($26) - bsr $26,%0..ng\;trapb - jsr $26,%0\;trapb\;ldgp $29,4($26)" - [(set_attr "type" "jsr,jsr,ibr")]) - (define_insn "" [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) (match_operand 1 "" "")) @@ -3326,19 +3314,6 @@ ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)" [(set_attr "type" "jsr")]) -(define_insn "" - [(set (match_operand 0 "register_operand" "=rf,rf,rf") - (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i")) - (match_operand 2 "" ""))) - (clobber (reg:DI 27)) - (clobber (reg:DI 26))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN" - "@ - jsr $26,($27),0\;trapb\;ldgp $29,4($26) - bsr $26,%1..ng\;trapb - jsr $26,%1\;trapb\;ldgp $29,4($26)" - [(set_attr "type" "jsr,jsr,ibr")]) - (define_insn "" [(set (match_operand 0 "register_operand" "=rf,rf,rf") (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i")) @@ -4513,3 +4488,12 @@ (clobber (reg:DI 0))] "TARGET_OPEN_VMS" "lda $0,ots$home_args\;ldq $0,8($0)\;jsr $0,ots$home_args") + +;; Close the trap shadow of preceeding instructions. This is generated +;; by alpha_reorg. + +(define_insn "trapb" + [(unspec_volatile [(const_int 0)] 3)] + "" + "trapb" + [(set_attr "type" "misc")]) -- 2.30.2