From bf153b359e9ce3ebef9bca899eb7ed5bd9045c11 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Thu, 18 Nov 2021 01:45:27 -0800 Subject: 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). --- fold.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'fold.c') diff --git a/fold.c b/fold.c index 50a862e..348e532 100644 --- a/fold.c +++ b/fold.c @@ -496,7 +496,7 @@ foldflt(Con *res, int op, int w, Con *cl, Con *cr) static int opfold(int op, int cls, Con *cl, Con *cr, Fn *fn) { - int nc; + Ref r; Con c; if ((op == Odiv || op == Oudiv @@ -507,13 +507,7 @@ opfold(int op, int cls, Con *cl, Con *cr, Fn *fn) return Bot; } else foldflt(&c, op, cls == Kd, cl, cr); - if (c.type == CBits) - nc = getcon(c.bits.i, fn).val; - else { - nc = fn->ncon; - vgrow(&fn->con, ++fn->ncon); - } + r = newcon(&c, fn); assert(!(cls == Ks || cls == Kd) || c.flt); - fn->con[nc] = c; - return nc; + return r.val; } -- cgit v1.2.3