aboutsummaryrefslogtreecommitdiff
path: root/load.c
diff options
context:
space:
mode:
authorMichael Forney <[email protected]>2021-11-18 01:45:27 -0800
committerQuentin Carbonneaux <[email protected]>2021-11-22 18:07:50 +0100
commitbf153b359e9ce3ebef9bca899eb7ed5bd9045c11 (patch)
tree20857b60dfd9a0f5bb98dee40a1f4b140ba76447 /load.c
parentb0f16dad64d14f36ffe235b2e9cca96aa3ce35ba (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.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/load.c b/load.c
index 5d61a6c..2e10a35 100644
--- a/load.c
+++ b/load.c
@@ -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;
}
}