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).
This commit is contained in:
Michael Forney 2021-11-18 01:45:27 -08:00 committed by Quentin Carbonneaux
parent b0f16dad64
commit bf153b359e
6 changed files with 33 additions and 31 deletions

15
load.c
View file

@ -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;
}
}