diff options
| author | Michael Forney <[email protected]> | 2021-11-18 01:45:27 -0800 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2021-11-22 18:07:50 +0100 |
| commit | bf153b359e9ce3ebef9bca899eb7ed5bd9045c11 (patch) | |
| tree | 20857b60dfd9a0f5bb98dee40a1f4b140ba76447 /load.c | |
| parent | b0f16dad64d14f36ffe235b2e9cca96aa3ce35ba (diff) | |
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 'load.c')
| -rw-r--r-- | load.c | 15 |
1 files changed, 7 insertions, 8 deletions
@@ -118,7 +118,8 @@ load(Slice sl, bits msk, Loc *l) { Alias *a; Ref r, r1; - int ld, cls, all, c; + int ld, cls, all; + Con c; ld = (int[]){ [1] = Oloadub, @@ -151,13 +152,11 @@ load(Slice sl, bits msk, Loc *l) break; case ACon: case ASym: - c = curf->ncon++; - vgrow(&curf->con, curf->ncon); - curf->con[c].type = CAddr; - curf->con[c].label = a->label; - curf->con[c].bits.i = a->offset; - curf->con[c].local = 0; - r = CON(c); + c.type = CAddr; + c.label = a->label; + c.bits.i = a->offset; + c.local = 0; + r = newcon(&c, curf); break; } } |
