History

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).

Michael Forney committed 4 years ago

Commit bf153b31 parent b0f16da6 files · +33 −31Browse files

Unified · Split

6 files
  1. all.h +1 −0
  2. amd64/isel.c +2 −5
  3. fold.c +3 −9
  4. load.c +7 −8
  5. parse.c +1 −9
  6. util.c +19 −0
all.h+1−0
@@ -431,6 +431,7 @@ int clsmerge(short *, short); · 430 unmodified lines
431431 int phicls(int, Tmp *);
432432 Ref newtmp(char *, int, Fn *);
433433 void chuse(Ref, int, Fn *);
434+Ref newcon(Con *, Fn *);
434435 Ref getcon(int64_t, Fn *);
435436 int addcon(Con *, Con *);
436437 void blit(Ref, uint, Ref, uint, Fn *);
amd64/isel.c+2−5
@@ -117,12 +117,9 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) · 116 unmodified lines
117117 m = &fn->mem[r0.val];
118118 if (req(m->base, R))
119119 if (m->offset.type == CAddr) {
120− n = fn->ncon;
121− vgrow(&fn->con, ++fn->ncon);
122− fn->con[n] = m->offset;
123− m->offset.type = CUndef;
124120 r0 = newtmp("isel", Kl, fn);
125− emit(Oaddr, Kl, r0, CON(n), R);
121+ emit(Oaddr, Kl, r0, newcon(&m->offset, fn), R);
122+ m->offset.type = CUndef;
126123 m->base = r0;
127124 }
128125 }
fold.c+3−9
@@ -496,7 +496,7 @@ foldflt(Con *res, int op, int w, Con *cl, Con *cr) · 495 unmodified lines
496496 static int
497497 opfold(int op, int cls, Con *cl, Con *cr, Fn *fn)
498498 {
499− int nc;
499+ Ref r;
500500 Con c;
501501
502502 if ((op == Odiv || op == Oudiv
@@ -507,13 +507,7 @@ opfold(int op, int cls, Con *cl, Con *cr, Fn *fn) · 4 unmodified lines
507507 return Bot;
508508 } else
509509 foldflt(&c, op, cls == Kd, cl, cr);
510− if (c.type == CBits)
511− nc = getcon(c.bits.i, fn).val;
512− else {
513− nc = fn->ncon;
514− vgrow(&fn->con, ++fn->ncon);
515− }
510+ r = newcon(&c, fn);
516511 assert(!(cls == Ks || cls == Kd) || c.flt);
517− fn->con[nc] = c;
518− return nc;
512+ return r.val;
519513 }
load.c+7−8
@@ -118,7 +118,8 @@ load(Slice sl, bits msk, Loc *l) · 117 unmodified lines
118118 {
119119 Alias *a;
120120 Ref r, r1;
121− int ld, cls, all, c;
121+ int ld, cls, all;
122+ Con c;
122123
123124 ld = (int[]){
124125 [1] = Oloadub,
@@ -151,13 +152,11 @@ load(Slice sl, bits msk, Loc *l) · 26 unmodified lines
151152 break;
152153 case ACon:
153154 case ASym:
154− c = curf->ncon++;
155− vgrow(&curf->con, curf->ncon);
156− curf->con[c].type = CAddr;
157− curf->con[c].label = a->label;
158− curf->con[c].bits.i = a->offset;
159− curf->con[c].local = 0;
160− r = CON(c);
155+ c.type = CAddr;
156+ c.label = a->label;
157+ c.bits.i = a->offset;
158+ c.local = 0;
159+ r = newcon(&c, curf);
161160 break;
162161 }
163162 }
parse.c+1−9
@@ -381,7 +381,6 @@ static Ref · 380 unmodified lines
381381 parseref()
382382 {
383383 Con c;
384− int i;
385384
386385 memset(&c, 0, sizeof c);
387386 switch (next()) {
@@ -405,14 +404,7 @@ parseref() · 17 unmodified lines
405404 c.type = CAddr;
406405 c.label = intern(tokval.str);
407406 Look:
408− for (i=0; i<curf->ncon; i++)
409− if (curf->con[i].type == c.type
410− && curf->con[i].bits.i == c.bits.i
411− && curf->con[i].label == c.label)
412− return CON(i);
413− vgrow(&curf->con, ++curf->ncon);
414− curf->con[i] = c;
415− return CON(i);
407+ return newcon(&c, curf);
416408 default:
417409 return R;
418410 }
util.c+19−0
@@ -349,6 +349,25 @@ chuse(Ref r, int du, Fn *fn) · 348 unmodified lines
349349 fn->tmp[r.val].nuse += du;
350350 }
351351
352+Ref
353+newcon(Con *c0, Fn *fn)
354+{
355+ Con *c1;
356+ int i;
357+
358+ for (i=0; i<fn->ncon; i++) {
359+ c1 = &fn->con[i];
360+ if (c0->type == c1->type
361+ && c0->bits.i == c1->bits.i
362+ && c0->label == c1->label
363+ && c0->local == c1->local)
364+ return CON(i);
365+ }
366+ vgrow(&fn->con, ++fn->ncon);
367+ fn->con[i] = *c0;
368+ return CON(i);
369+}
370+
352371 Ref
353372 getcon(int64_t val, Fn *fn)
354373 {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t