aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/example.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-10 12:24:23 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:53 -0700
commitd83a98eabfe4b949d98ecfaf47afc86025091a7f (patch)
treeba56518cf8169d7acc20329be941372fb4d63f3b /example.c
parent88bf1c0b62a84c228f23e484090e6e165c3ccc9c (diff)
downloadsparse-dev-d83a98eabfe4b949d98ecfaf47afc86025091a7f.tar.gz
When fulfilling the output register requirements, don't
be so eager to flush to memory. If we can find the proper target register for the existing pseudo, just turn it into a simple reg-reg move instead. Also, don't worry about dead pseudos - they don't need flushing anyway.
Diffstat (limited to 'example.c')
-rw-r--r--example.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/example.c b/example.c
index b7d8e64e..a54977f8 100644
--- a/example.c
+++ b/example.c
@@ -780,13 +780,31 @@ static void generate_output_storage(struct bb_state *state)
if (out->type == REG_REG) {
struct hardreg *reg = hardregs + out->regno;
pseudo_t p;
+ int flushme = 0;
+
reg->busy = 1000;
FOR_EACH_PTR(reg->contains, p) {
- if (p == entry->pseudo)
- goto ok;
+ struct hardreg *dst;
+ if (p == entry->pseudo) {
+ flushme = -100;
+ continue;
+ }
+ dst = preferred_reg(state, p);
+ if (dst && !dst->busy) {
+ DELETE_CURRENT_PTR(p);
+ output_insn(state, "movl %s,%s", reg->name, dst->name);
+ add_pseudo_reg(state, p, dst);
+ continue;
+ }
+ if (CURRENT_TAG(p) & TAG_DEAD)
+ continue;
+ flushme++;
} END_FOR_EACH_PTR(p);
- flush_reg(state, reg);
-ok: ;
+
+ /* Argh. We did not contain the info we wanted, but something else instead. */
+ if (flushme > 0)
+ flush_reg(state, reg);
+ PACK_PTR_LIST(&reg->contains);
}
} END_FOR_EACH_PTR(entry);