diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 48 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.h | 29 |
3 files changed, 48 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8b1268..1b7cde3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +Mon Mar 20 19:53:53 2000 Jim Wilson <wilson@cygnus.com> + + * config/ia64/ia64.c (ia64_expand_prologue): Don't abort if leaf + function uses output registers. Don't save RP for leaf functions. + Do save RP even if no epilogue. + * config/ia64/ia64.h (FIXED_REGISTERS): Unmark in/out registers. + (CALL_USED_REGISTERS): Unmark in registers. + (REG_ALLOC_ORDER): Move out regs up, to near the top. Move in regs up, + to near the middle. + 2000-03-20 Geoff Keating <geoffk@cygnus.com> * config/rs6000/rs6000.md (bunordered): New expander. diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 02938c5..9de15ab 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -775,12 +775,6 @@ save_restore_insns (save_p) /* ??? Get inefficient code when the frame size is larger than can fit in an adds instruction. */ -/* ??? Add support for allocating temporaries from the output registers if - they do not need to live past call instructions. */ - -/* ??? If the function does not return, then we don't need to save the rp - and ar.pfs registers. */ - /* ??? If this is a leaf function, then fp/rp/ar.pfs should be put in the low 32 regs. */ @@ -807,7 +801,7 @@ ia64_expand_prologue () leaf_function = leaf_function_p (); pop_topmost_sequence (); - /* ??? If there is no epilogue, then we don't need some prologue insns. We + /* If there is no epilogue, then we don't need some prologue insns. We need to avoid emitting the dead prologue insns, because flow will complain about them. */ if (optimize) @@ -863,10 +857,6 @@ ia64_expand_prologue () else if (profile_block_flag == 2) outputs = MAX (outputs, 2); - /* Leaf functions should not use any output registers. */ - if (leaf_function && outputs != 0) - abort (); - /* No rotating register support as yet. */ rotates = 0; @@ -874,6 +864,8 @@ ia64_expand_prologue () /* Allocate two extra locals for saving/restoring rp and ar.pfs. Also allocate one local for use as the frame pointer if frame_pointer_needed is true. */ + /* ??? If this is a leaf function, then we aren't using one of these local + registers for the RP anymore. */ locals += 2 + frame_pointer_needed; /* Save these values in global registers for debugging info. */ @@ -925,6 +917,7 @@ ia64_expand_prologue () /* We don't need an alloc instruction if this is a leaf function, and the locals and outputs are both zero sized. Since we have already allocated two locals for rp and ar.pfs, we check for two locals. */ + /* Leaf functions can use output registers as call-clobbered temporaries. */ if (locals == 2 && outputs == 0 && leaf_function) { /* If there is no alloc, but there are input registers used, then we @@ -940,21 +933,36 @@ ia64_expand_prologue () else { ia64_need_regstk = 0; - ia64_arpfs_regno = LOC_REG (locals - 1); - ia64_rp_regno = LOC_REG (locals - 2); - reg_names[RETURN_ADDRESS_REGNUM] = reg_names[ia64_rp_regno]; emit_insn (gen_alloc (gen_rtx_REG (DImode, ia64_arpfs_regno), GEN_INT (inputs), GEN_INT (locals), GEN_INT (outputs), GEN_INT (rotates))); - /* ??? FIXME ??? We don't need to save BR_REG (0) if this is a leaf - function. We also don't need to allocate a local reg for it then. */ - /* ??? Likewise if there is no epilogue. */ - if (epilogue_p) - emit_move_insn (gen_rtx_REG (DImode, ia64_rp_regno), - gen_rtx_REG (DImode, BR_REG (0))); + /* Emit a save of BR_REG (0) if we call other functions. + Do this even if this function doesn't return, as EH + depends on this to be able to unwind the stack. */ + if (! leaf_function) + { + rtx ia64_rp_reg; + + ia64_rp_regno = LOC_REG (locals - 2); + reg_names[RETURN_ADDRESS_REGNUM] = reg_names[ia64_rp_regno]; + + ia64_rp_reg = gen_rtx_REG (DImode, ia64_rp_regno); + insn = emit_move_insn (ia64_rp_reg, gen_rtx_REG (DImode, + BR_REG (0))); + RTX_FRAME_RELATED_P (insn) = 1; + if (! epilogue_p) + { + /* If we don't have an epilogue, then the return value + doesn't appear to be needed and the above store will + appear dead and will elicit a warning from flow. */ + emit_insn (gen_rtx_USE (VOIDmode, ia64_rp_reg)); + } + } + else + ia64_rp_regno = 0; } /* Set up frame pointer and stack pointer. */ diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 5861fb6..dd07ae1 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -577,16 +577,14 @@ while (0) p0: constant true fp: eliminable frame pointer */ -/* The last 16 stacked regs are fixed, because they are reserved for the 8 - input and 8 output registers. */ +/* The last 16 stacked regs are reserved for the 8 input and 8 output + registers. */ /* ??? Must mark the next 3 stacked regs as fixed, because ia64_expand_prologue assumes that three locals are available for fp, b0, and ar.pfs. */ /* ??? Should mark b0 as fixed? */ -/* ??? input and output registers do not have to be marked as fixed. */ - #define FIXED_REGISTERS \ { /* General registers. */ \ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, \ @@ -596,7 +594,7 @@ while (0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ /* Floating-point registers. */ \ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ @@ -622,8 +620,6 @@ while (0) therefore identifies the registers that are not available for general allocation of values that must live across function calls. */ -/* ??? If inputs are not marked as fixed, then they are not call clobbered. */ - #define CALL_USED_REGISTERS \ { /* General registers. */ \ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ @@ -633,7 +629,7 @@ while (0) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \ /* Floating-point registers. */ \ 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ @@ -689,11 +685,6 @@ while (0) /* ??? Should the GR return value registers come before or after the rest of the caller-save GRs? */ -/* ??? Output registers are cheap, because they will be not be saved - by the register engine. They probably should be early in the list. - We need to make them not fixed first though. Similarly, input registers - are callee-saved (RSE) like the stacked locals. */ - #define REG_ALLOC_ORDER \ { \ /* Caller-saved general registers. */ \ @@ -701,6 +692,9 @@ while (0) R_GR (18), R_GR (19), R_GR (20), R_GR (21), R_GR (22), R_GR (23), \ R_GR (24), R_GR (25), R_GR (26), R_GR (27), R_GR (28), R_GR (29), \ R_GR (30), R_GR (31), \ + /* Output registers. */ \ + R_GR (120), R_GR (121), R_GR (122), R_GR (123), R_GR (124), R_GR (125), \ + R_GR (126), R_GR (127), \ /* Caller-saved general registers, also used for return values. */ \ R_GR (8), R_GR (9), R_GR (10), R_GR (11), \ /* addl caller-saved general registers. */ \ @@ -759,6 +753,9 @@ while (0) R_GR (96), R_GR (97), R_GR (98), R_GR (99), R_GR (100), R_GR (101), \ R_GR (102), R_GR (103), R_GR (104), R_GR (105), R_GR (106), R_GR (107), \ R_GR (108), \ + /* Input registers. */ \ + R_GR (112), R_GR (113), R_GR (114), R_GR (115), R_GR (116), R_GR (117), \ + R_GR (118), R_GR (119), \ /* Callee-saved general registers. */ \ R_GR (4), R_GR (5), R_GR (6), R_GR (7), \ /* Callee-saved FP registers. */ \ @@ -773,12 +770,6 @@ while (0) \ /* ??? Stacked registers reserved for fp, rp, and ar.pfs. */ \ R_GR (109), R_GR (110), R_GR (111), \ - /* Input registers. */ \ - R_GR (112), R_GR (113), R_GR (114), R_GR (115), R_GR (116), R_GR (117), \ - R_GR (118), R_GR (119), \ - /* Output registers. */ \ - R_GR (120), R_GR (121), R_GR (122), R_GR (123), R_GR (124), R_GR (125), \ - R_GR (126), R_GR (127), \ \ /* Special general registers. */ \ R_GR (0), R_GR (1), R_GR (12), R_GR (13), \ |