summaryrefslogtreecommitdiff
path: root/amd64
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-11-18 01:45:27 -0800
committerQuentin Carbonneaux <quentin@c9x.me>2021-11-22 18:07:50 +0100
commitbf153b359e9ce3ebef9bca899eb7ed5bd9045c11 (patch)
tree20857b60dfd9a0f5bb98dee40a1f4b140ba76447 /amd64
parentb0f16dad64d14f36ffe235b2e9cca96aa3ce35ba (diff)
downloadroux-bf153b359e9ce3ebef9bca899eb7ed5bd9045c11.tar.gz
reuse previous address constants in fold()
parseref() has code to reuse address constants, but this is not done in other passes such as fold or isel. Introduce a new function newcon() which takes a Con and returns a Ref for that constant, and use this whenever creating address constants. This is necessary to fix folding of address constants when one operand is already folded. For example, in %a =l add $x, 1 %b =l add %a, 2 %c =w loadw %b %a and %b were folded to $x+1 and $x+3 respectively, but then the second add is visited again since it uses %a. This gets folded to $x+3 as well, but as a new distinct constant. This results in %b getting labeled as bottom instead of either constant, disabling the replacement of %b by a constant in subsequent instructions (such as the loadw).
Diffstat (limited to 'amd64')
-rw-r--r--amd64/isel.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index 607c176..0f4c7a5 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -117,12 +117,9 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
m = &fn->mem[r0.val];
if (req(m->base, R))
if (m->offset.type == CAddr) {
- n = fn->ncon;
- vgrow(&fn->con, ++fn->ncon);
- fn->con[n] = m->offset;
- m->offset.type = CUndef;
r0 = newtmp("isel", Kl, fn);
- emit(Oaddr, Kl, r0, CON(n), R);
+ emit(Oaddr, Kl, r0, newcon(&m->offset, fn), R);
+ m->offset.type = CUndef;
m->base = r0;
}
}