summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/ia64/ia64.c68
-rw-r--r--gcc/regrename.c11
3 files changed, 80 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 35edc3e63ca..2a0f123370d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2001-01-04 Bernd Schmidt <bernds@redhat.com>
+
+ * regrename.c (regrename_optimize): Don't rename from frame pointer
+ if frame_pointer_needed.
+ (do_replace): Don't set ORIGINAL_REGNO to a hard register number.
+ * config/ia64/ia64.c (emit_all_group_insn_barriers): New function.
+ (ia64_reorg): Use it instead of scheduling if ! optimize.
+ (errata_emit_nops): Properly call asm_noperands.
+ (ia64_sched_reorder): Finish cycle if we see an asm.
+ (ia64_variable_issue): Clear scheduling state after asms.
+
2001-01-04 Neil Booth <neil@daikokuya.demon.co.uk>
* cpp.texi: Update for -MT.
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index d4538664570..82fca4ae10f 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -116,6 +116,7 @@ static void ia64_add_gc_roots PARAMS ((void));
static void ia64_init_machine_status PARAMS ((struct function *));
static void ia64_mark_machine_status PARAMS ((struct function *));
static void emit_insn_group_barriers PARAMS ((FILE *, rtx));
+static void emit_all_insn_group_barriers PARAMS ((FILE *, rtx));
static void emit_predicate_relation_info PARAMS ((void));
static int process_set PARAMS ((FILE *, rtx));
@@ -4450,7 +4451,11 @@ safe_group_barrier_needed_p (insn)
}
/* INSNS is an chain of instructions. Scan the chain, and insert stop bits
- as necessary to eliminate dependendencies. */
+ as necessary to eliminate dependendencies. This function assumes that
+ a final instruction scheduling pass has been run which has already
+ inserted most of the necessary stop bits. This function only inserts
+ new ones at basic block boundaries, since these are invisible to the
+ scheduler. */
static void
emit_insn_group_barriers (dump, insns)
@@ -4505,6 +4510,36 @@ emit_insn_group_barriers (dump, insns)
}
}
}
+
+/* Like emit_insn_group_barriers, but run if no final scheduling pass was run.
+ This function has to emit all necessary group barriers. */
+
+static void
+emit_all_insn_group_barriers (dump, insns)
+ FILE *dump;
+ rtx insns;
+{
+ rtx insn;
+
+ init_insn_group_barriers ();
+
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ && XINT (PATTERN (insn), 1) == 2)
+ init_insn_group_barriers ();
+ else if (INSN_P (insn))
+ {
+ if (group_barrier_needed_p (insn))
+ {
+ emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), insn);
+ init_insn_group_barriers ();
+ group_barrier_needed_p (insn);
+ }
+ }
+ }
+}
static int errata_find_address_regs PARAMS ((rtx *, void *));
static void errata_emit_nops PARAMS ((rtx));
@@ -4567,7 +4602,7 @@ errata_emit_nops (insn)
|| GET_CODE (real_pat) == ASM_INPUT
|| GET_CODE (real_pat) == ADDR_VEC
|| GET_CODE (real_pat) == ADDR_DIFF_VEC
- || asm_noperands (insn) >= 0)
+ || asm_noperands (PATTERN (insn)) >= 0)
return;
/* single_set doesn't work for COND_EXEC insns, so we have to duplicate
@@ -5612,6 +5647,12 @@ ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, reorder_type)
schedule_stop (sched_verbose ? dump : NULL);
sched_data.last_was_stop = 1;
}
+ else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ {
+ /* It must be an asm of some kind. */
+ cycle_end_fill_slots (sched_verbose ? dump : NULL);
+ }
return 1;
}
}
@@ -5811,6 +5852,12 @@ ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
{
if (sched_verbose)
fprintf (dump, "// Ignoring type %s\n", type_names[t]);
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ {
+ /* This must be some kind of asm. Clear the scheduling state. */
+ rotate_two_bundles (sched_verbose ? dump : NULL);
+ }
return 1;
}
@@ -5931,13 +5978,18 @@ ia64_reorg (insns)
find_basic_blocks (insns, max_reg_num (), NULL);
life_analysis (insns, NULL, PROP_DEATH_NOTES);
- ia64_final_schedule = 1;
- schedule_ebbs (rtl_dump_file);
- ia64_final_schedule = 0;
+ if (optimize)
+ {
+ ia64_final_schedule = 1;
+ schedule_ebbs (rtl_dump_file);
+ ia64_final_schedule = 0;
- /* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
- place as they were during scheduling. */
- emit_insn_group_barriers (rtl_dump_file, insns);
+ /* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
+ place as they were during scheduling. */
+ emit_insn_group_barriers (rtl_dump_file, insns);
+ }
+ else
+ emit_all_insn_group_barriers (rtl_dump_file, insns);
fixup_errata ();
emit_predicate_relation_info ();
diff --git a/gcc/regrename.c b/gcc/regrename.c
index bb45f3a2953..ae25e2171fb 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -248,7 +248,13 @@ regrename_optimize ()
}
#endif
- if (fixed_regs[reg] || global_regs[reg])
+ if (fixed_regs[reg] || global_regs[reg]
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
+#else
+ || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
+#endif
+ )
continue;
COPY_HARD_REG_SET (this_unavailable, unavailable);
@@ -351,7 +357,8 @@ do_replace (chain, reg)
{
unsigned int regno = ORIGINAL_REGNO (*chain->loc);
*chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
- ORIGINAL_REGNO (*chain->loc) = regno;
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ ORIGINAL_REGNO (*chain->loc) = regno;
chain = chain->next_use;
}
}