diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-10 12:24:23 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:05:53 -0700 |
| commit | d83a98eabfe4b949d98ecfaf47afc86025091a7f (patch) | |
| tree | ba56518cf8169d7acc20329be941372fb4d63f3b /example.c | |
| parent | 88bf1c0b62a84c228f23e484090e6e165c3ccc9c (diff) | |
| download | sparse-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.c | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -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(®->contains); } } END_FOR_EACH_PTR(entry); |
