summaryrefslogtreecommitdiff
path: root/src/cmd/5g/peep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5g/peep.c')
-rw-r--r--src/cmd/5g/peep.c487
1 files changed, 242 insertions, 245 deletions
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index b6202a882..c78fb3d1c 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -34,59 +34,45 @@
#include "gg.h"
#include "opt.h"
-int xtramodes(Reg*, Adr*);
-int shiftprop(Reg *r);
-void constprop(Adr *c1, Adr *v1, Reg *r);
-void predicate(void);
-int copyau1(Prog *p, Adr *v);
-int isdconst(Addr *a);
+static int xtramodes(Graph*, Flow*, Adr*);
+static int shortprop(Flow *r);
+static int subprop(Flow*);
+static int copyprop(Graph*, Flow*);
+static int copy1(Adr*, Adr*, Flow*, int);
+static int copyas(Adr*, Adr*);
+static int copyau(Adr*, Adr*);
+static int copysub(Adr*, Adr*, Adr*, int);
+static int copysub1(Prog*, Adr*, Adr*, int);
+static Flow* findpre(Flow *r, Adr *v);
+static int copyau1(Prog *p, Adr *v);
+static int isdconst(Addr *a);
+
+static uint32 gactive;
+
+// UNUSED
+int shiftprop(Flow *r);
+void constprop(Adr *c1, Adr *v1, Flow *r);
+void predicate(Graph*);
void
-peep(void)
+peep(Prog *firstp)
{
- Reg *r, *r1, *r2;
- Prog *p, *p1;
+ Flow *r;
+ Graph *g;
+ Prog *p;
int t;
- p1 = nil;
-/*
- * complete R structure
- */
- for(r=firstr; r!=R; r=r1) {
- r1 = r->link;
- if(r1 == R)
- break;
- p = r->prog->link;
- while(p != r1->prog)
- switch(p->as) {
- default:
- r2 = rega();
- r->link = r2;
- r2->link = r1;
-
- r2->prog = p;
- r2->p1 = r;
- r->s1 = r2;
- r2->s1 = r1;
- r1->p1 = r2;
-
- r = r2;
-
- case ADATA:
- case AGLOBL:
- case ANAME:
- case ASIGNAME:
- case ALOCALS:
- case ATYPE:
- p = p->link;
- }
- }
-//dumpit("begin", firstr);
+ g = flowstart(firstp, sizeof(Flow));
+ if(g == nil)
+ return;
+ gactive = 0;
loop1:
+ if(debug['P'] && debug['v'])
+ dumpit("loop1", g->start, 0);
t = 0;
- for(r=firstr; r!=R; r=r->link) {
+ for(r=g->start; r!=nil; r=r->link) {
p = r->prog;
switch(p->as) {
case ASLL:
@@ -102,18 +88,20 @@ loop1:
// }
break;
+ case AMOVB:
+ case AMOVH:
case AMOVW:
case AMOVF:
case AMOVD:
if(regtyp(&p->from))
if(p->from.type == p->to.type)
if(p->scond == C_SCOND_NONE) {
- if(copyprop(r)) {
+ if(copyprop(g, r)) {
excise(r);
t++;
break;
}
- if(subprop(r) && copyprop(r)) {
+ if(subprop(r) && copyprop(g, r)) {
excise(r);
t++;
break;
@@ -121,6 +109,16 @@ loop1:
}
break;
+ case AMOVHS:
+ case AMOVHU:
+ case AMOVBS:
+ case AMOVBU:
+ if(p->from.type == D_REG) {
+ if(shortprop(r))
+ t++;
+ }
+ break;
+
#ifdef NOTDEF
if(p->scond == C_SCOND_NONE)
if(regtyp(&p->to))
@@ -134,8 +132,7 @@ loop1:
if(t)
goto loop1;
-
- for(r=firstr; r!=R; r=r->link) {
+ for(r=g->start; r!=nil; r=r->link) {
p = r->prog;
switch(p->as) {
case AEOR:
@@ -152,42 +149,21 @@ loop1:
p->reg = NREG;
}
break;
-
- case AMOVH:
- case AMOVHU:
- case AMOVB:
- case AMOVBU:
- /*
- * look for MOVB x,R; MOVB R,R
- */
- r1 = r->link;
- if(p->to.type != D_REG)
- break;
- if(r1 == R)
- break;
- p1 = r1->prog;
- if(p1->as != p->as)
- break;
- if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
- break;
- if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
- break;
- excise(r1);
- break;
}
}
- for(r=firstr; r!=R; r=r->link) {
+ for(r=g->start; r!=nil; r=r->link) {
p = r->prog;
switch(p->as) {
case AMOVW:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
if(p->from.type == D_OREG && p->from.offset == 0)
- xtramodes(r, &p->from);
+ xtramodes(g, r, &p->from);
else
if(p->to.type == D_OREG && p->to.offset == 0)
- xtramodes(r, &p->to);
+ xtramodes(g, r, &p->to);
else
continue;
break;
@@ -198,7 +174,7 @@ loop1:
// if(isdconst(&p->from) || p->from.offset != 0)
// continue;
// r2 = r->s1;
-// if(r2 == R)
+// if(r2 == nil)
// continue;
// t = r2->prog->as;
// switch(t) {
@@ -225,8 +201,8 @@ loop1:
// r1 = r;
// do
// r1 = uniqp(r1);
-// while (r1 != R && r1->prog->as == ANOP);
-// if(r1 == R)
+// while (r1 != nil && r1->prog->as == ANOP);
+// if(r1 == nil)
// continue;
// p1 = r1->prog;
// if(p1->to.type != D_REG)
@@ -261,44 +237,9 @@ loop1:
}
}
-// predicate();
-}
+// predicate(g);
-/*
- * uniqp returns a "unique" predecessor to instruction r.
- * If the instruction is the first one or has multiple
- * predecessors due to jump, R is returned.
- */
-Reg*
-uniqp(Reg *r)
-{
- Reg *r1;
-
- r1 = r->p1;
- if(r1 == R) {
- r1 = r->p2;
- if(r1 == R || r1->p2link != R)
- return R;
- } else
- if(r->p2 != R)
- return R;
- return r1;
-}
-
-Reg*
-uniqs(Reg *r)
-{
- Reg *r1;
-
- r1 = r->s1;
- if(r1 == R) {
- r1 = r->s2;
- if(r1 == R)
- return R;
- } else
- if(r->s2 != R)
- return R;
- return r1;
+ flowend(g);
}
int
@@ -326,13 +267,14 @@ regtyp(Adr *a)
* hopefully, then the former or latter MOV
* will be eliminated by copy propagation.
*/
-int
-subprop(Reg *r0)
+static int
+subprop(Flow *r0)
{
Prog *p;
Adr *v1, *v2;
- Reg *r;
+ Flow *r;
int t;
+ ProgInfo info;
p = r0->prog;
v1 = &p->from;
@@ -341,70 +283,34 @@ subprop(Reg *r0)
v2 = &p->to;
if(!regtyp(v2))
return 0;
- for(r=uniqp(r0); r!=R; r=uniqp(r)) {
- if(uniqs(r) == R)
+ for(r=uniqp(r0); r!=nil; r=uniqp(r)) {
+ if(uniqs(r) == nil)
break;
p = r->prog;
- switch(p->as) {
- case ABL:
+ proginfo(&info, p);
+ if(info.flags & Call)
return 0;
+ if((info.flags & CanRegRead) && p->to.type == D_REG) {
+ info.flags |= RegRead;
+ info.flags &= ~(CanRegRead | RightRead);
+ p->reg = p->to.reg;
+ }
+
+ switch(p->as) {
case AMULLU:
case AMULA:
case AMVN:
return 0;
-
- case ACMN:
- case AADD:
- case ASUB:
- case ASBC:
- case ARSB:
- case ASLL:
- case ASRL:
- case ASRA:
- case AORR:
- case AAND:
- case AEOR:
- case AMUL:
- case AMULU:
- case ADIV:
- case ADIVU:
- case AMOD:
- case AMODU:
-
- case AADDD:
- case AADDF:
- case ASUBD:
- case ASUBF:
- case AMULD:
- case AMULF:
- case ADIVD:
- case ADIVF:
- if(p->to.type == v1->type)
- if(p->to.reg == v1->reg)
- if(p->scond == C_SCOND_NONE) {
- if(p->reg == NREG)
- p->reg = p->to.reg;
- goto gotit;
- }
- break;
-
- case AMOVF:
- case AMOVD:
- case AMOVW:
+ }
+
+ if((info.flags & (RightRead|RightWrite)) == RightWrite) {
if(p->to.type == v1->type)
if(p->to.reg == v1->reg)
if(p->scond == C_SCOND_NONE)
goto gotit;
- break;
-
- case AMOVM:
- t = 1<<v2->reg;
- if((p->from.type == D_CONST && (p->from.offset&t)) ||
- (p->to.type == D_CONST && (p->to.offset&t)))
- return 0;
- break;
}
+
if(copyau(&p->from, v2) ||
copyau1(p, v2) ||
copyau(&p->to, v2))
@@ -452,49 +358,48 @@ gotit:
* set v1 F=1
* set v2 return success
*/
-int
-copyprop(Reg *r0)
+static int
+copyprop(Graph *g, Flow *r0)
{
Prog *p;
Adr *v1, *v2;
- Reg *r;
+ USED(g);
p = r0->prog;
v1 = &p->from;
v2 = &p->to;
if(copyas(v1, v2))
return 1;
- for(r=firstr; r!=R; r=r->link)
- r->active = 0;
+ gactive++;
return copy1(v1, v2, r0->s1, 0);
}
-int
-copy1(Adr *v1, Adr *v2, Reg *r, int f)
+static int
+copy1(Adr *v1, Adr *v2, Flow *r, int f)
{
int t;
Prog *p;
- if(r->active) {
+ if(r->active == gactive) {
if(debug['P'])
print("act set; return 1\n");
return 1;
}
- r->active = 1;
+ r->active = gactive;
if(debug['P'])
print("copy %D->%D f=%d\n", v1, v2, f);
- for(; r != R; r = r->s1) {
+ for(; r != nil; r = r->s1) {
p = r->prog;
if(debug['P'])
print("%P", p);
- if(!f && uniqp(r) == R) {
+ if(!f && uniqp(r) == nil) {
f = 1;
if(debug['P'])
print("; merge; f=%d", f);
}
t = copyu(p, v2, A);
switch(t) {
- case 2: /* rar, cant split */
+ case 2: /* rar, can't split */
if(debug['P'])
print("; %Drar; return 0\n", v2);
return 0;
@@ -546,6 +451,7 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
return 1;
}
+// UNUSED
/*
* The idea is to remove redundant constants.
* $c1->v1
@@ -554,17 +460,17 @@ copy1(Adr *v1, Adr *v2, Reg *r, int f)
* The v1->v2 should be eliminated by copy propagation.
*/
void
-constprop(Adr *c1, Adr *v1, Reg *r)
+constprop(Adr *c1, Adr *v1, Flow *r)
{
Prog *p;
if(debug['P'])
print("constprop %D->%D\n", c1, v1);
- for(; r != R; r = r->s1) {
+ for(; r != nil; r = r->s1) {
p = r->prog;
if(debug['P'])
print("%P", p);
- if(uniqp(r) == R) {
+ if(uniqp(r) == nil) {
if(debug['P'])
print("; merge; return\n");
return;
@@ -586,6 +492,65 @@ constprop(Adr *c1, Adr *v1, Reg *r)
}
/*
+ * shortprop eliminates redundant zero/sign extensions.
+ *
+ * MOVBS x, R
+ * <no use R>
+ * MOVBS R, R'
+ *
+ * changed to
+ *
+ * MOVBS x, R
+ * ...
+ * MOVB R, R' (compiled to mov)
+ *
+ * MOVBS above can be a MOVBS, MOVBU, MOVHS or MOVHU.
+ */
+static int
+shortprop(Flow *r)
+{
+ Prog *p, *p1;
+ Flow *r1;
+
+ p = r->prog;
+ r1 = findpre(r, &p->from);
+ if(r1 == nil)
+ return 0;
+
+ p1 = r1->prog;
+ if(p1->as == p->as) {
+ // Two consecutive extensions.
+ goto gotit;
+ }
+
+ if(p1->as == AMOVW && isdconst(&p1->from)
+ && p1->from.offset >= 0 && p1->from.offset < 128) {
+ // Loaded an immediate.
+ goto gotit;
+ }
+
+ return 0;
+
+gotit:
+ if(debug['P'])
+ print("shortprop\n%P\n%P", p1, p);
+ switch(p->as) {
+ case AMOVBS:
+ case AMOVBU:
+ p->as = AMOVB;
+ break;
+ case AMOVHS:
+ case AMOVHU:
+ p->as = AMOVH;
+ break;
+ }
+ if(debug['P'])
+ print(" => %A\n", p->as);
+ return 1;
+}
+
+// UNUSED
+/*
* ASLL x,y,w
* .. (not use w, not set x y w)
* AXXX w,a,b (a != w)
@@ -598,9 +563,9 @@ constprop(Adr *c1, Adr *v1, Reg *r)
*/
#define FAIL(msg) { if(debug['P']) print("\t%s; FAILURE\n", msg); return 0; }
int
-shiftprop(Reg *r)
+shiftprop(Flow *r)
{
- Reg *r1;
+ Flow *r1;
Prog *p, *p1, *p2;
int n, o;
Adr a;
@@ -620,9 +585,9 @@ shiftprop(Reg *r)
for(;;) {
/* find first use of shift result; abort if shift operands or result are changed */
r1 = uniqs(r1);
- if(r1 == R)
+ if(r1 == nil)
FAIL("branch");
- if(uniqp(r1) == R)
+ if(uniqp(r1) == nil)
FAIL("merge");
p1 = r1->prog;
if(debug['P'])
@@ -693,7 +658,7 @@ shiftprop(Reg *r)
if(p1->to.reg != n)
for (;;) {
r1 = uniqs(r1);
- if(r1 == R)
+ if(r1 == nil)
FAIL("inconclusive");
p1 = r1->prog;
if(debug['P'])
@@ -746,40 +711,40 @@ shiftprop(Reg *r)
* before r. It must be a set, and there must be
* a unique path from that instruction to r.
*/
-Reg*
-findpre(Reg *r, Adr *v)
+static Flow*
+findpre(Flow *r, Adr *v)
{
- Reg *r1;
+ Flow *r1;
- for(r1=uniqp(r); r1!=R; r=r1,r1=uniqp(r)) {
+ for(r1=uniqp(r); r1!=nil; r=r1,r1=uniqp(r)) {
if(uniqs(r1) != r)
- return R;
+ return nil;
switch(copyu(r1->prog, v, A)) {
case 1: /* used */
case 2: /* read-alter-rewrite */
- return R;
+ return nil;
case 3: /* set */
case 4: /* set and used */
return r1;
}
}
- return R;
+ return nil;
}
/*
* findinc finds ADD instructions with a constant
* argument which falls within the immed_12 range.
*/
-Reg*
-findinc(Reg *r, Reg *r2, Adr *v)
+static Flow*
+findinc(Flow *r, Flow *r2, Adr *v)
{
- Reg *r1;
+ Flow *r1;
Prog *p;
- for(r1=uniqs(r); r1!=R && r1!=r2; r=r1,r1=uniqs(r)) {
+ for(r1=uniqs(r); r1!=nil && r1!=r2; r=r1,r1=uniqs(r)) {
if(uniqp(r1) != r)
- return R;
+ return nil;
switch(copyu(r1->prog, v, A)) {
case 0: /* not touched */
continue;
@@ -790,14 +755,14 @@ findinc(Reg *r, Reg *r2, Adr *v)
if(p->from.offset > -4096 && p->from.offset < 4096)
return r1;
default:
- return R;
+ return nil;
}
}
- return R;
+ return nil;
}
-int
-nochange(Reg *r, Reg *r2, Prog *p)
+static int
+nochange(Flow *r, Flow *r2, Prog *p)
{
Adr a[3];
int i, n;
@@ -819,7 +784,7 @@ nochange(Reg *r, Reg *r2, Prog *p)
}
if(n == 0)
return 1;
- for(; r!=R && r!=r2; r=uniqs(r)) {
+ for(; r!=nil && r!=r2; r=uniqs(r)) {
p = r->prog;
for(i=0; i<n; i++)
if(copyu(p, &a[i], A) > 1)
@@ -828,10 +793,10 @@ nochange(Reg *r, Reg *r2, Prog *p)
return 1;
}
-int
-findu1(Reg *r, Adr *v)
+static int
+findu1(Flow *r, Adr *v)
{
- for(; r != R; r = r->s1) {
+ for(; r != nil; r = r->s1) {
if(r->active)
return 0;
r->active = 1;
@@ -850,12 +815,12 @@ findu1(Reg *r, Adr *v)
return 0;
}
-int
-finduse(Reg *r, Adr *v)
+static int
+finduse(Graph *g, Flow *r, Adr *v)
{
- Reg *r1;
+ Flow *r1;
- for(r1=firstr; r1!=R; r1=r1->link)
+ for(r1=g->start; r1!=nil; r1=r1->link)
r1->active = 0;
return findu1(r, v);
}
@@ -873,10 +838,10 @@ finduse(Reg *r, Adr *v)
* into
* MOVBU R0<<0(R1),R0
*/
-int
-xtramodes(Reg *r, Adr *a)
+static int
+xtramodes(Graph *g, Flow *r, Adr *a)
{
- Reg *r1, *r2, *r3;
+ Flow *r1, *r2, *r3;
Prog *p, *p1;
Adr v;
@@ -884,7 +849,7 @@ xtramodes(Reg *r, Adr *a)
v = *a;
v.type = D_REG;
r1 = findpre(r, &v);
- if(r1 != R) {
+ if(r1 != nil) {
p1 = r1->prog;
if(p1->to.type == D_REG && p1->to.reg == v.reg)
switch(p1->as) {
@@ -894,12 +859,12 @@ xtramodes(Reg *r, Adr *a)
break;
if(p1->from.type == D_REG ||
(p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
- (p->as != AMOVB || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
+ ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
(p1->from.type == D_CONST &&
p1->from.offset > -4096 && p1->from.offset < 4096))
if(nochange(uniqs(r1), r, p1)) {
if(a != &p->from || v.reg != p->to.reg)
- if (finduse(r->s1, &v)) {
+ if (finduse(g, r->s1, &v)) {
if(p1->reg == NREG || p1->reg == v.reg)
/* pre-indexing */
p->scond |= C_WBIT;
@@ -927,7 +892,7 @@ xtramodes(Reg *r, Adr *a)
break;
case AMOVW:
if(p1->from.type == D_REG)
- if((r2 = findinc(r1, r, &p1->from)) != R) {
+ if((r2 = findinc(r1, r, &p1->from)) != nil) {
for(r3=uniqs(r2); r3->prog->as==ANOP; r3=uniqs(r3))
;
if(r3 == r) {
@@ -936,7 +901,7 @@ xtramodes(Reg *r, Adr *a)
a->reg = p1->to.reg;
a->offset = p1->from.offset;
p->scond |= C_PBIT;
- if(!finduse(r, &r1->prog->to))
+ if(!finduse(g, r, &r1->prog->to))
excise(r1);
excise(r2);
return 1;
@@ -946,7 +911,7 @@ xtramodes(Reg *r, Adr *a)
}
}
if(a != &p->from || a->reg != p->to.reg)
- if((r1 = findinc(r, R, &v)) != R) {
+ if((r1 = findinc(r, nil, &v)) != nil) {
/* post-indexing */
p1 = r1->prog;
a->offset = p1->from.offset;
@@ -971,7 +936,7 @@ copyu(Prog *p, Adr *v, Adr *s)
switch(p->as) {
default:
- print("copyu: cant find %A\n", p->as);
+ print("copyu: can't find %A\n", p->as);
return 2;
case AMOVM:
@@ -1017,8 +982,10 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVF:
case AMOVD:
case AMOVH:
+ case AMOVHS:
case AMOVHU:
case AMOVB:
+ case AMOVBS:
case AMOVBU:
case AMOVFW:
case AMOVWF:
@@ -1089,6 +1056,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case ADIVF:
case ADIVD:
+ case ACHECKNIL: /* read */
case ACMPF: /* read, read, */
case ACMPD:
case ACMP:
@@ -1194,7 +1162,8 @@ copyu(Prog *p, Adr *v, Adr *s)
return 3;
return 0;
- case ALOCALS: /* funny */
+ case APCDATA:
+ case AFUNCDATA:
return 0;
}
}
@@ -1204,7 +1173,7 @@ copyu(Prog *p, Adr *v, Adr *s)
* could be set/use depending on
* semantics
*/
-int
+static int
copyas(Adr *a, Adr *v)
{
@@ -1224,10 +1193,24 @@ copyas(Adr *a, Adr *v)
return 0;
}
+int
+sameaddr(Adr *a, Adr *v)
+{
+ if(a->type != v->type)
+ return 0;
+ if(regtyp(v) && a->reg == v->reg)
+ return 1;
+ if(v->type == D_AUTO || v->type == D_PARAM) {
+ if(v->offset == a->offset)
+ return 1;
+ }
+ return 0;
+}
+
/*
* either direct or indirect
*/
-int
+static int
copyau(Adr *a, Adr *v)
{
@@ -1268,7 +1251,7 @@ copyau(Adr *a, Adr *v)
* ADD r,r,r
* CMP r,r,
*/
-int
+static int
copyau1(Prog *p, Adr *v)
{
@@ -1284,7 +1267,7 @@ copyau1(Prog *p, Adr *v)
return 1;
return 0;
}
- print("copyau1: cant tell %P\n", p);
+ print("copyau1: can't tell %P\n", p);
}
return 0;
}
@@ -1293,7 +1276,7 @@ copyau1(Prog *p, Adr *v)
* substitute s for v in a
* return failure to substitute
*/
-int
+static int
copysub(Adr *a, Adr *v, Adr *s, int f)
{
@@ -1316,7 +1299,7 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
return 0;
}
-int
+static int
copysub1(Prog *p1, Adr *v, Adr *s, int f)
{
@@ -1351,9 +1334,9 @@ struct {
};
typedef struct {
- Reg *start;
- Reg *last;
- Reg *end;
+ Flow *start;
+ Flow *last;
+ Flow *end;
int len;
} Joininfo;
@@ -1373,13 +1356,13 @@ enum {
Keepbranch
};
-int
+static int
isbranch(Prog *p)
{
return (ABEQ <= p->as) && (p->as <= ABLE);
}
-int
+static int
predicable(Prog *p)
{
switch(p->as) {
@@ -1409,7 +1392,7 @@ predicable(Prog *p)
*
* C_SBIT may also have been set explicitly in p->scond.
*/
-int
+static int
modifiescpsr(Prog *p)
{
switch(p->as) {
@@ -1438,8 +1421,8 @@ modifiescpsr(Prog *p)
* Find the maximal chain of instructions starting with r which could
* be executed conditionally
*/
-int
-joinsplit(Reg *r, Joininfo *j)
+static int
+joinsplit(Flow *r, Joininfo *j)
{
j->start = r;
j->last = r;
@@ -1474,8 +1457,8 @@ joinsplit(Reg *r, Joininfo *j)
return Toolong;
}
-Reg*
-successor(Reg *r)
+static Flow*
+successor(Flow *r)
{
if(r->s1)
return r->s1;
@@ -1483,11 +1466,11 @@ successor(Reg *r)
return r->s2;
}
-void
-applypred(Reg *rstart, Joininfo *j, int cond, int branch)
+static void
+applypred(Flow *rstart, Joininfo *j, int cond, int branch)
{
int pred;
- Reg *r;
+ Flow *r;
if(j->len == 0)
return;
@@ -1520,13 +1503,13 @@ applypred(Reg *rstart, Joininfo *j, int cond, int branch)
}
void
-predicate(void)
+predicate(Graph *g)
{
- Reg *r;
+ Flow *r;
int t1, t2;
Joininfo j1, j2;
- for(r=firstr; r!=R; r=r->link) {
+ for(r=g->start; r!=nil; r=r->link) {
if (isbranch(r->prog)) {
t1 = joinsplit(r->s1, &j1);
t2 = joinsplit(r->s2, &j2);
@@ -1549,10 +1532,24 @@ predicate(void)
}
}
-int
+static int
isdconst(Addr *a)
{
if(a->type == D_CONST && a->reg == NREG)
return 1;
return 0;
}
+
+int
+stackaddr(Addr *a)
+{
+ return regtyp(a) && a->reg == REGSP;
+}
+
+int
+smallindir(Addr *a, Addr *reg)
+{
+ return reg->type == D_REG && a->type == D_OREG &&
+ a->reg == reg->reg &&
+ 0 <= a->offset && a->offset < 4096;
+}