aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-09 21:30:07 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:50 -0700
commit0e23efe071d25eb48ef2b9f4b952cd11d5d95105 (patch)
tree51eacd408cdfcf2c6525a3f6ce99228764e71ed4
parent6556b643f7a81474fbbbc4ae1b2ee793f36d0c56 (diff)
downloadsparse-dev-0e23efe071d25eb48ef2b9f4b952cd11d5d95105.tar.gz
Don't re-use registers for several different output storages.
We used to be lazy and just assume that if a value was in a register when we exited, we could just use that register. Not so, since now a register can contain multiple pseudos, that may all need different output storages.
-rw-r--r--example.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/example.c b/example.c
index 796e55aa..ad2d8d04 100644
--- a/example.c
+++ b/example.c
@@ -562,21 +562,41 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
show_instruction(insn);
}
-static void write_reg_to_storage(struct bb_state *state, struct hardreg *reg, struct storage *storage)
+static void write_reg_to_storage(struct bb_state *state, struct hardreg *reg, pseudo_t pseudo, struct storage *storage)
{
+ int i;
struct hardreg *out;
switch (storage->type) {
- case REG_UDEF:
- storage->type = REG_REG;
- storage->regno = reg - hardregs;
- return;
case REG_REG:
out = hardregs + storage->regno;
if (reg == out)
return;
printf("\tmovl %s,%s\n", reg->name, out->name);
return;
+ case REG_UDEF:
+ if (reg->busy < 1000) {
+ storage->type = REG_REG;
+ storage->regno = reg - hardregs;
+ reg->busy = 1000;
+ return;
+ }
+
+ /* Try to find a non-busy register.. */
+ for (i = 0; i < REGNO; i++) {
+ out = hardregs + i;
+ if (out->busy)
+ continue;
+ printf("\tmovl %s,%s\n", reg->name, out->name);
+ storage->type = REG_REG;
+ storage->regno = i;
+ reg->busy = 1000;
+ return;
+ }
+
+ /* Fall back on stack allocation ... */
+ alloc_stack(state, storage);
+ /* Fallthroigh */
default:
printf("\tmovl %s,%s\n", reg->name, show_memop(storage));
return;
@@ -627,7 +647,7 @@ static void fill_output(struct bb_state *state, pseudo_t pseudo, struct storage
FOR_EACH_PTR(reg->contains, p) {
if (p == pseudo) {
- write_reg_to_storage(state, reg, out);
+ write_reg_to_storage(state, reg, pseudo, out);
return;
}
} END_FOR_EACH_PTR(p);
@@ -670,6 +690,7 @@ static void generate_output_storage(struct bb_state *state)
if (out->type == REG_REG) {
struct hardreg *reg = hardregs + out->regno;
pseudo_t p;
+ reg->busy = 1000;
FOR_EACH_PTR(reg->contains, p) {
if (p == entry->pseudo)
goto ok;