aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-04-09 09:09:59 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-04-09 09:09:59 -0400
commit351aa1c1a04f782e11e16efa07a18cdacc71942b (patch)
treef675ca4236de5c9b1a3b5884cb8c267bc624cd21 /gcc
parent46b1c39385d1b94f3adad6add99786924f3801ae (diff)
downloadgcc-351aa1c1a04f782e11e16efa07a18cdacc71942b.zip
gcc-351aa1c1a04f782e11e16efa07a18cdacc71942b.tar.gz
gcc-351aa1c1a04f782e11e16efa07a18cdacc71942b.tar.bz2
(reload_conflicts): Rewrite to clean up and fix numerous bugs; move to
later in file. From-SVN: r7002
Diffstat (limited to 'gcc')
-rw-r--r--gcc/reload1.c156
1 files changed, 62 insertions, 94 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 85960c4..2ff7fd4 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -346,7 +346,6 @@ static int hard_reg_use_compare PROTO((struct hard_reg_n_uses *,
struct hard_reg_n_uses *));
static void order_regs_for_reload PROTO((void));
static void reload_as_needed PROTO((rtx, int));
-static int reloads_conflict PROTO((int, int));
static void forget_old_reloads_1 PROTO((rtx, rtx));
static int reload_reg_class_lower PROTO((short *, short *));
static void mark_reload_reg_in_use PROTO((int, int, enum reload_type,
@@ -356,6 +355,7 @@ static void clear_reload_reg_in_use PROTO((int, int, enum reload_type,
static int reload_reg_free_p PROTO((int, int, enum reload_type));
static int reload_reg_free_before_p PROTO((int, int, enum reload_type));
static int reload_reg_reaches_end_p PROTO((int, int, enum reload_type));
+static int reloads_conflict PROTO((int, int));
static int allocate_reload_reg PROTO((int, rtx, int, int));
static void choose_reload_regs PROTO((rtx, rtx));
static void merge_assigned_reloads PROTO((rtx));
@@ -4066,99 +4066,6 @@ forget_old_reloads_1 (x, ignored)
if (n_reloads == 0 || reg_has_output_reload[regno + nr] == 0)
reg_last_reload_reg[regno + nr] = 0;
}
-
-/* 1 if reload1 and reload2 conflict with each other */
-
-static int
-reloads_conflict (reload1, reload2)
-int reload1, reload2;
-{
- int i;
- enum reload_type reload1_type = reload_when_needed[reload1];
- enum reload_type reload2_type = reload_when_needed[reload2];
- int reload1_opnum = reload_opnum[reload1];
- int reload2_opnum = reload_opnum[reload2];
-
- /* RELOAD_OTHER conflicts with everything. */
-
- if (reload1_type == RELOAD_OTHER
- || reload2_type == RELOAD_OTHER)
- return 1;
-
- switch (reload1_type)
- {
- case RELOAD_FOR_OTHER_ADDRESS:
- if (reload2_type == RELOAD_FOR_OTHER_ADDRESS)
- return 1;
- break;
-
- case RELOAD_FOR_INPUT:
- if (reload2_type == RELOAD_FOR_INSN
- || reload2_type == RELOAD_FOR_OPERAND_ADDRESS
- || reload2_type == RELOAD_FOR_INPUT)
- return 1;
-
- /* RELOAD_FOR_INPUT conflicts with any later
- RELOAD_FOR_INPUT_ADDRESS reloads */
- for (i = reload2_opnum + 1; i < n_reloads; i++)
- if (reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS)
- return 1;
- break;
-
- case RELOAD_FOR_INPUT_ADDRESS:
- if (reload2_type == RELOAD_FOR_INPUT_ADDRESS
- && (reload1_opnum == reload2_opnum))
- return 1;
-
- /* RELOAD_FOR_INPUT_ADDRESS conflicts with any
- earlier RELOAD_FOR_INPUT reloads */
- for (i = 0; i < reload2_opnum; i++)
- if (reload_when_needed[i] == RELOAD_FOR_INPUT)
- return 1;
- break;
-
- case RELOAD_FOR_OUTPUT_ADDRESS:
- if (reload2_type == RELOAD_FOR_OUTPUT_ADDRESS
- && (reload1_opnum == reload2_opnum))
- return 1;
-
- for (i = reload2_opnum; i < n_reloads; i++)
- if (reload_when_needed[i] == RELOAD_FOR_INPUT)
- return 1;
- break;
-
- case RELOAD_FOR_OPERAND_ADDRESS:
- if (reload2_type == RELOAD_FOR_INPUT
- || reload2_type == RELOAD_FOR_INSN
- || reload2_type == RELOAD_FOR_OPERAND_ADDRESS)
- return 1;
- break;
-
- case RELOAD_FOR_OUTPUT:
- if (reload2_type == RELOAD_FOR_INSN
- || reload2_type == RELOAD_FOR_OUTPUT)
- return 1;
-
- for (i = 0; i <= reload2_opnum; i++)
- if (reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS)
- return 1;
- break;
-
- case RELOAD_FOR_INSN:
- if (reload2_type == RELOAD_FOR_INPUT
- || reload2_type == RELOAD_FOR_OUTPUT
- || reload2_type == RELOAD_FOR_INSN
- || reload2_type == RELOAD_FOR_OPERAND_ADDRESS
- || reload2_type == RELOAD_FOR_OTHER_ADDRESS)
- return 1;
- break;
- }
-
- /* No conflict */
- return 0;
-}
-
-
/* For each reload, the mode of the reload register. */
static enum machine_mode reload_mode[MAX_RELOADS];
@@ -4661,6 +4568,67 @@ reload_reg_reaches_end_p (regno, opnum, type)
abort ();
}
+/* Return 1 if the reloads denoted by R1 and R2 cannot share a register.
+ Return 0 otherwise.
+
+ This function uses the same algorithm as reload_reg_free_p above. */
+
+static int
+reloads_conflict (r1, r2)
+ int r1, r2;
+{
+ enum reload_type r1_type = reload_when_needed[r1];
+ enum reload_type r2_type = reload_when_needed[r2];
+ int r1_opnum = reload_opnum[r1];
+ int r2_opnum = reload_opnum[r2];
+
+ /* RELOAD_OTHER conflicts with everything except
+ RELOAD_FOR_OTHER_ADDRESS. */
+
+ if ((r1_type == RELOAD_OTHER && r2_type != RELOAD_FOR_OTHER_ADDRESS)
+ || (r2_type == RELOAD_OTHER && r1_type != RELOAD_FOR_OTHER_ADDRESS))
+ return 1;
+
+ /* Otherwise, check conflicts differently for each type. */
+
+ switch (r1_type)
+ {
+ case RELOAD_FOR_INPUT:
+ return (r2_type == RELOAD_FOR_INSN
+ || r2_type == RELOAD_FOR_OPERAND_ADDRESS
+ || r2_type == RELOAD_FOR_INPUT
+ || (r2_type == RELOAD_FOR_INPUT_ADDRESS && r2_opnum > r1_opnum));
+
+ case RELOAD_FOR_INPUT_ADDRESS:
+ return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum)
+ || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));
+
+ case RELOAD_FOR_OUTPUT_ADDRESS:
+ return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
+ || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum >= r1_opnum));
+
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
+ || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
+
+ case RELOAD_FOR_OUTPUT:
+ return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
+ || (r2_type == RELOAD_FOR_OPERAND_ADDRESS
+ && r2_opnum >= r1_opnum));
+
+ case RELOAD_FOR_INSN:
+ return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
+ || r2_type == RELOAD_FOR_INSN
+ || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
+
+ case RELOAD_FOR_OTHER_ADDRESS:
+ return r2_type == RELOAD_FOR_OTHER_ADDRESS;
+
+ default:
+ abort ();
+ }
+}
+
/* Vector of reload-numbers showing the order in which the reloads should
be processed. */
short reload_order[MAX_RELOADS];