struct elem: add alias this to remove .EV. pt 3

This commit is contained in:
Walter Bright 2024-05-07 15:20:47 -07:00 committed by The Dlang Bot
parent baa3889636
commit d94fa11c90
6 changed files with 734 additions and 734 deletions

View file

@ -39,7 +39,7 @@ enum Aetype { cse, arraybounds }
private __gshared Aetype aetype; private __gshared Aetype aetype;
@trusted @trusted
bool Eunambig(elem* e) { return OTassign(e.Eoper) && e.EV.E1.Eoper == OPvar; } bool Eunambig(elem* e) { return OTassign(e.Eoper) && e.E1.Eoper == OPvar; }
/************************************* /*************************************
* Determine if floating point should be cse'd. * Determine if floating point should be cse'd.
@ -215,13 +215,13 @@ private void aewalk(elem **pn,vec_t ae)
vec_clearbit(i,ae); vec_clearbit(i,ae);
if (OTunary(n.Eoper)) if (OTunary(n.Eoper))
{ {
n = n.EV.E1; n = n.E1;
continue; continue;
} }
else if (OTbinary(n.Eoper)) else if (OTbinary(n.Eoper))
{ {
aeclear(n.EV.E1); aeclear(n.E1);
n = n.EV.E2; n = n.E2;
continue; continue;
} }
break; break;
@ -245,8 +245,8 @@ private void aewalk(elem **pn,vec_t ae)
// ae = ae & ael & aer // ae = ae & ael & aer
// AEs gened by ael and aer are mutually exclusive // AEs gened by ael and aer are mutually exclusive
vec_t aer = vec_clone(ae); vec_t aer = vec_clone(ae);
aewalk(&(n.EV.E1),ae); aewalk(&(n.E1),ae);
aewalk(&(n.EV.E2),aer); aewalk(&(n.E2),aer);
vec_andass(ae,aer); vec_andass(ae,aer);
vec_free(aer); vec_free(aer);
break; break;
@ -255,20 +255,20 @@ private void aewalk(elem **pn,vec_t ae)
case OPandand: case OPandand:
case OPoror: case OPoror:
{ {
aewalk(&(n.EV.E1),ae); aewalk(&(n.E1),ae);
/* ae &= aer */ /* ae &= aer */
vec_t aer = vec_clone(ae); vec_t aer = vec_clone(ae);
aewalk(&(n.EV.E2),aer); aewalk(&(n.E2),aer);
if (el_returns(n.EV.E2)) if (el_returns(n.E2))
vec_andass(ae,aer); vec_andass(ae,aer);
vec_free(aer); vec_free(aer);
break; break;
} }
case OPnegass: case OPnegass:
t = n.EV.E1; t = n.E1;
if (t.Eoper == OPind) if (t.Eoper == OPind)
aewalk(&(t.EV.E1),ae); aewalk(&(t.E1),ae);
break; break;
case OPctor: case OPctor:
@ -288,30 +288,30 @@ private void aewalk(elem **pn,vec_t ae)
{ {
// Don't CSE constants that will turn into // Don't CSE constants that will turn into
// an INC or DEC anyway // an INC or DEC anyway
if (n.EV.E2.Eoper == OPconst && if (n.E2.Eoper == OPconst &&
n.EV.E2.EV.Vint == 1 && n.E2.Vint == 1 &&
(op == OPaddass || op == OPminass || (op == OPaddass || op == OPminass ||
op == OPpostinc || op == OPpostdec) op == OPpostinc || op == OPpostdec)
) )
{ } { }
else else
aewalk(&(n.EV.E2),ae); aewalk(&(n.E2),ae);
} }
if (OTassign(op)) if (OTassign(op))
{ {
t = n.EV.E1; t = n.E1;
if (t.Eoper == OPind) if (t.Eoper == OPind)
aewalk(&(t.EV.E1),ae); aewalk(&(t.E1),ae);
} }
else else
aewalk(&(n.EV.E1),ae); aewalk(&(n.E1),ae);
if (!ERTOL(n)) if (!ERTOL(n))
aewalk(&(n.EV.E2),ae); aewalk(&(n.E2),ae);
} }
else if (OTunary(op)) else if (OTunary(op))
{ {
assert(op != OPnegass); assert(op != OPnegass);
aewalk(&(n.EV.E1),ae); aewalk(&(n.E1),ae);
} }
} }
@ -322,7 +322,7 @@ private void aewalk(elem **pn,vec_t ae)
if (Eunambig(n)) // if unambiguous definition if (Eunambig(n)) // if unambiguous definition
{ {
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
Symbol* s = t.EV.Vsym; Symbol* s = t.Vsym;
if (Symbol_isAffected(*s)) if (Symbol_isAffected(*s))
vec_subass(ae,go.starkill); vec_subass(ae,go.starkill);
for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem
@ -332,18 +332,18 @@ private void aewalk(elem **pn,vec_t ae)
if (!e) continue; if (!e) continue;
if (OTunary(e.Eoper)) if (OTunary(e.Eoper))
{ {
if (vec_testbit(e.EV.E1.Eexp,ae)) if (vec_testbit(e.E1.Eexp,ae))
continue; continue;
} }
else if (OTbinary(e.Eoper)) else if (OTbinary(e.Eoper))
{ {
if (vec_testbit(e.EV.E1.Eexp,ae) && if (vec_testbit(e.E1.Eexp,ae) &&
vec_testbit(e.EV.E2.Eexp,ae)) vec_testbit(e.E2.Eexp,ae))
continue; continue;
} }
else if (e.Eoper == OPvar) else if (e.Eoper == OPvar)
{ {
if (e.EV.Vsym != s) if (e.Vsym != s)
continue; continue;
} }
else else
@ -402,33 +402,33 @@ private elem * delcse(elem **pe)
assert(e.Ecount != 0); assert(e.Ecount != 0);
if (!OTleaf(e.Eoper)) if (!OTleaf(e.Eoper))
{ {
if (e.EV.E1.Ecount == 0xFF-1) if (e.E1.Ecount == 0xFF-1)
{ {
elem *ereplace; elem *ereplace;
ereplace = el_calloc(); ereplace = el_calloc();
el_copy(ereplace,e.EV.E1); el_copy(ereplace,e.E1);
e.EV.E1 = ereplace; e.E1 = ereplace;
ereplace.Ecount = 0; ereplace.Ecount = 0;
} }
else else
{ {
e.EV.E1.Ecount++; e.E1.Ecount++;
debug assert(e.EV.E1.Ecount != 0); debug assert(e.E1.Ecount != 0);
} }
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ {
if (e.EV.E2.Ecount == 0xFF-1) if (e.E2.Ecount == 0xFF-1)
{ {
elem *ereplace; elem *ereplace;
ereplace = el_calloc(); ereplace = el_calloc();
el_copy(ereplace,e.EV.E2); el_copy(ereplace,e.E2);
e.EV.E2 = ereplace; e.E2 = ereplace;
ereplace.Ecount = 0; ereplace.Ecount = 0;
} }
else else
{ {
e.EV.E2.Ecount++; e.E2.Ecount++;
debug assert(e.EV.E2.Ecount != 0); debug assert(e.E2.Ecount != 0);
} }
} }
} }
@ -465,67 +465,67 @@ L1:
if (op == OPind) if (op == OPind)
{ {
bool scaledIndex = I32 || I64; // if scaled index addressing mode support bool scaledIndex = I32 || I64; // if scaled index addressing mode support
elem *e1 = e.EV.E1; elem *e1 = e.E1;
if (e1.Eoper == OPadd && if (e1.Eoper == OPadd &&
e1.Ecount e1.Ecount
) )
{ {
if (scaledIndex) if (scaledIndex)
{ {
e1 = delcse(&e.EV.E1); e1 = delcse(&e.E1);
if (e1.EV.E1.Ecount) // == 1) if (e1.E1.Ecount) // == 1)
delcse(&e1.EV.E1); delcse(&e1.E1);
if (e1.EV.E2.Ecount && e1.EV.E2.Eoper != OPind) if (e1.E2.Ecount && e1.E2.Eoper != OPind)
delcse(&e1.EV.E2); delcse(&e1.E2);
} }
/* *(v +. c) /* *(v +. c)
* *(*pc +. c) * *(*pc +. c)
* The + and the const shouldn't be CSEs. * The + and the const shouldn't be CSEs.
*/ */
else if (e1.EV.E2.Eoper == OPconst && else if (e1.E2.Eoper == OPconst &&
(e1.EV.E1.Eoper == OPvar || (e1.EV.E1.Eoper == OPind && e1.EV.E1.Ety & (mTYconst | mTYimmutable))) (e1.E1.Eoper == OPvar || (e1.E1.Eoper == OPind && e1.E1.Ety & (mTYconst | mTYimmutable)))
) )
{ {
e1 = delcse(&e.EV.E1); e1 = delcse(&e.E1);
} }
} }
/* *(((e <<. 3) + e) + e) /* *(((e <<. 3) + e) + e)
*/ */
if (scaledIndex && e1.Eoper == OPadd && if (scaledIndex && e1.Eoper == OPadd &&
e1.EV.E1.Eoper == OPadd && e1.E1.Eoper == OPadd &&
e1.EV.E1.EV.E1.Ecount && e1.E1.E1.Ecount &&
e1.EV.E1.EV.E1.Eoper == OPshl && e1.E1.E1.Eoper == OPshl &&
e1.EV.E1.EV.E1.EV.E2.Eoper == OPconst && e1.E1.E1.E2.Eoper == OPconst &&
e1.EV.E1.EV.E1.EV.E2.EV.Vuns <= 3 e1.E1.E1.E2.Vuns <= 3
) )
{ {
delcse(&e1.EV.E1.EV.E1); // the <<. operator delcse(&e1.E1.E1); // the <<. operator
} }
/* *(((e << 3) +. e) + e) /* *(((e << 3) +. e) + e)
*/ */
if (scaledIndex && e1.Eoper == OPadd && if (scaledIndex && e1.Eoper == OPadd &&
e1.EV.E1.Eoper == OPadd && e1.E1.Eoper == OPadd &&
e1.EV.E1.Ecount && e1.E1.Ecount &&
e1.EV.E1.EV.E1.Eoper == OPshl && e1.E1.E1.Eoper == OPshl &&
e1.EV.E1.EV.E1.EV.E2.Eoper == OPconst && e1.E1.E1.E2.Eoper == OPconst &&
e1.EV.E1.EV.E1.EV.E2.EV.Vuns <= 3 e1.E1.E1.E2.Vuns <= 3
) )
{ {
delcse(&e1.EV.E1); // the +. operator delcse(&e1.E1); // the +. operator
} }
/* *((e <<. 3) + e) /* *((e <<. 3) + e)
*/ */
else if (scaledIndex && e1.Eoper == OPadd && else if (scaledIndex && e1.Eoper == OPadd &&
e1.EV.E1.Ecount && e1.E1.Ecount &&
e1.EV.E1.Eoper == OPshl && e1.E1.Eoper == OPshl &&
e1.EV.E1.EV.E2.Eoper == OPconst && e1.E1.E2.Eoper == OPconst &&
e1.EV.E1.EV.E2.EV.Vuns <= 3 e1.E1.E2.Vuns <= 3
) )
{ {
delcse(&e1.EV.E1); // the <<. operator delcse(&e1.E1); // the <<. operator
} }
// Remove *e1 where it's a double // Remove *e1 where it's a double
@ -536,24 +536,24 @@ L1:
else if (op == OPu16_32 && I16 && e.Ecount) else if (op == OPu16_32 && I16 && e.Ecount)
e = delcse(pe); e = delcse(pe);
else if (op == OPd_ld && e.EV.E1.Ecount > 0) else if (op == OPd_ld && e.E1.Ecount > 0)
delcse(&e.EV.E1); delcse(&e.E1);
// OPremquo is only worthwhile if its result is used more than once // OPremquo is only worthwhile if its result is used more than once
else if (e.EV.E1.Eoper == OPremquo && else if (e.E1.Eoper == OPremquo &&
(op == OP64_32 || op == OP128_64 || op == OPmsw) && (op == OP64_32 || op == OP128_64 || op == OPmsw) &&
e.EV.E1.Ecount == 0) e.E1.Ecount == 0)
{ // Convert back to OPdiv or OPmod { // Convert back to OPdiv or OPmod
elem *e1 = e.EV.E1; elem *e1 = e.E1;
e.Eoper = (op == OPmsw) ? OPmod : OPdiv; e.Eoper = (op == OPmsw) ? OPmod : OPdiv;
e.EV.E1 = e1.EV.E1; e.E1 = e1.E1;
e.EV.E2 = e1.EV.E2; e.E2 = e1.E2;
e1.EV.E1 = null; e1.E1 = null;
e1.EV.E2 = null; e1.E2 = null;
el_free(e1); el_free(e1);
removecses(&(e.EV.E1)); removecses(&(e.E1));
pe = &(e.EV.E2); pe = &(e.E2);
goto L1; goto L1;
} }
} }
@ -563,18 +563,18 @@ L1:
/* Don't CSE floating stuff if generating */ /* Don't CSE floating stuff if generating */
/* inline 8087 code, the code generator */ /* inline 8087 code, the code generator */
/* can't handle it yet */ /* can't handle it yet */
&& !(tyfloating(e.EV.E1.Ety) && config.inline8087) && !(tyfloating(e.E1.Ety) && config.inline8087)
) )
e = delcse(pe); e = delcse(pe);
if (ERTOL(e)) if (ERTOL(e))
{ {
removecses(&(e.EV.E2)); removecses(&(e.E2));
pe = &(e.EV.E1); pe = &(e.E1);
} }
else else
{ {
removecses(&(e.EV.E1)); removecses(&(e.E1));
pe = &(e.EV.E2); pe = &(e.E2);
} }
goto L1; goto L1;
} }
@ -582,7 +582,7 @@ L1:
{ {
return; return;
} }
pe = &(e.EV.E1); pe = &(e.E1);
goto L1; goto L1;
} }
@ -625,7 +625,7 @@ void boolopt()
if (e) if (e)
{ {
elem_debug(e); elem_debug(e);
if (e.Eoper == OPvar && e.EV.Vsym.Sflags & SFLtrue) if (e.Eoper == OPvar && e.Vsym.Sflags & SFLtrue)
{ {
vec_setbit(i,aevec); vec_setbit(i,aevec);
vec_setbit(i,aevecval); vec_setbit(i,aevecval);
@ -678,34 +678,34 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
{ {
case OPcond: case OPcond:
{ {
assert(n.EV.E2.Eoper == OPcolon || n.EV.E2.Eoper == OPcolon2); assert(n.E2.Eoper == OPcolon || n.E2.Eoper == OPcolon2);
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
abeboolres(n.EV.E1,ae,aeval); abeboolres(n.E1,ae,aeval);
vec_t aer = vec_clone(ae); vec_t aer = vec_clone(ae);
vec_t aerval = vec_clone(aeval); vec_t aerval = vec_clone(aeval);
if (!el_returns(n.EV.E2.EV.E1)) if (!el_returns(n.E2.E1))
{ {
abeset(n.EV.E1,aer,aerval,true); abeset(n.E1,aer,aerval,true);
abewalk(n.EV.E2.EV.E1,aer,aerval); abewalk(n.E2.E1,aer,aerval);
abeset(n.EV.E1,ae,aeval,false); abeset(n.E1,ae,aeval,false);
abewalk(n.EV.E2.EV.E2,ae,aeval); abewalk(n.E2.E2,ae,aeval);
} }
else if (!el_returns(n.EV.E2.EV.E2)) else if (!el_returns(n.E2.E2))
{ {
abeset(n.EV.E1,ae,aeval,true); abeset(n.E1,ae,aeval,true);
abewalk(n.EV.E2.EV.E1,ae,aeval); abewalk(n.E2.E1,ae,aeval);
abeset(n.EV.E1,aer,aerval,false); abeset(n.E1,aer,aerval,false);
abewalk(n.EV.E2.EV.E2,aer,aerval); abewalk(n.E2.E2,aer,aerval);
} }
else else
{ {
/* ae = ae & ael & aer /* ae = ae & ael & aer
* AEs gened by ael and aer are mutually exclusive * AEs gened by ael and aer are mutually exclusive
*/ */
abeset(n.EV.E1,aer,aerval,true); abeset(n.E1,aer,aerval,true);
abewalk(n.EV.E2.EV.E1,aer,aerval); abewalk(n.E2.E1,aer,aerval);
abeset(n.EV.E1,ae,aeval,false); abeset(n.E1,ae,aeval,false);
abewalk(n.EV.E2.EV.E2,ae,aeval); abewalk(n.E2.E2,ae,aeval);
vec_xorass(aerval,aeval); vec_xorass(aerval,aeval);
vec_subass(aer,aerval); vec_subass(aer,aerval);
@ -724,22 +724,22 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
case OPoror: case OPoror:
{ {
//printf("test1 %p: ", n); WReqn(n); printf("\n"); //printf("test1 %p: ", n); WReqn(n); printf("\n");
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
abeboolres(n.EV.E1,ae,aeval); abeboolres(n.E1,ae,aeval);
vec_t aer = vec_clone(ae); vec_t aer = vec_clone(ae);
vec_t aerval = vec_clone(aeval); vec_t aerval = vec_clone(aeval);
if (!el_returns(n.EV.E2)) if (!el_returns(n.E2))
{ {
abeset(n.EV.E1,aer,aerval,(op == OPandand)); abeset(n.E1,aer,aerval,(op == OPandand));
abewalk(n.EV.E2,aer,aerval); abewalk(n.E2,aer,aerval);
abeset(n.EV.E1,ae,aeval,(op != OPandand)); abeset(n.E1,ae,aeval,(op != OPandand));
} }
else else
{ {
/* ae &= aer /* ae &= aer
*/ */
abeset(n.EV.E1,aer,aerval,(op == OPandand)); abeset(n.E1,aer,aerval,(op == OPandand));
abewalk(n.EV.E2,aer,aerval); abewalk(n.E2,aer,aerval);
vec_xorass(aerval,aeval); vec_xorass(aerval,aeval);
vec_subass(aer,aerval); vec_subass(aer,aerval);
@ -753,8 +753,8 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
case OPbool: case OPbool:
case OPnot: case OPnot:
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
abeboolres(n.EV.E1,ae,aeval); abeboolres(n.E1,ae,aeval);
break; break;
case OPeqeq: case OPeqeq:
@ -768,15 +768,15 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
case OPngt: case OPnge: case OPnlt: case OPnle: case OPngt: case OPnge: case OPnlt: case OPnle:
case OPord: case OPnlg: case OPnleg: case OPnule: case OPord: case OPnlg: case OPnleg: case OPnule:
case OPnul: case OPnuge: case OPnug: case OPnue: case OPnul: case OPnuge: case OPnug: case OPnue:
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
abewalk(n.EV.E2,ae,aeval); abewalk(n.E2,ae,aeval);
abeboolres(n,ae,aeval); abeboolres(n,ae,aeval);
break; break;
case OPnegass: case OPnegass:
t = n.EV.E1; t = n.E1;
if (t.Eoper == OPind) if (t.Eoper == OPind)
abewalk(t.EV.E1,ae,aeval); abewalk(t.E1,ae,aeval);
break; break;
case OPasm: case OPasm:
@ -786,19 +786,19 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
default: default:
if (OTbinary(op)) if (OTbinary(op))
{ if (ERTOL(n)) { if (ERTOL(n))
abewalk(n.EV.E2,ae,aeval); abewalk(n.E2,ae,aeval);
if (OTassign(op)) if (OTassign(op))
{ t = n.EV.E1; { t = n.E1;
if (t.Eoper == OPind) if (t.Eoper == OPind)
abewalk(t.EV.E1,ae,aeval); abewalk(t.E1,ae,aeval);
} }
else else
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
if (!ERTOL(n)) if (!ERTOL(n))
abewalk(n.EV.E2,ae,aeval); abewalk(n.E2,ae,aeval);
} }
else if (OTunary(op)) else if (OTunary(op))
abewalk(n.EV.E1,ae,aeval); abewalk(n.E1,ae,aeval);
break; break;
} }
@ -811,7 +811,7 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
Symbol *s; Symbol *s;
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
s = t.EV.Vsym; s = t.Vsym;
if (Symbol_isAffected(*s)) if (Symbol_isAffected(*s))
vec_subass(ae,go.starkill); vec_subass(ae,go.starkill);
for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem for (uint i = 0; (i = cast(uint) vec_index(i, ae)) < go.exptop; ++i) // for each ae elem
@ -831,7 +831,7 @@ private void abewalk(elem *n,vec_t ae,vec_t aeval)
} }
/* GEN the lvalue of an assignment operator */ /* GEN the lvalue of an assignment operator */
uint i1, i2; uint i1, i2;
if (op == OPeq && (i1 = t.Eexp) != 0 && (i2 = n.EV.E2.Eexp) != 0) if (op == OPeq && (i1 = t.Eexp) != 0 && (i2 = n.E2.Eexp) != 0)
{ {
if (vec_testbit(i2,ae)) if (vec_testbit(i2,ae))
{ {
@ -885,7 +885,7 @@ private void abeboolres(elem *n,vec_t ae,vec_t aeval)
} }
abefree(n,ae); abefree(n,ae);
n.EV.Vlong = vec_testbit(i,aeval) != 0; n.Vlong = vec_testbit(i,aeval) != 0;
n.Eoper = OPconst; n.Eoper = OPconst;
n.Ety = TYint; n.Ety = TYint;
go.changes++; go.changes++;
@ -910,13 +910,13 @@ private void abefree(elem *e,vec_t ae)
{ {
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ {
abefree(e.EV.E2,ae); abefree(e.E2,ae);
el_free(e.EV.E2); el_free(e.E2);
e.EV.E2 = null; e.E2 = null;
} }
abefree(e.EV.E1,ae); abefree(e.E1,ae);
el_free(e.EV.E1); el_free(e.E1);
e.EV.E1 = null; e.E1 = null;
} }
} }
@ -943,12 +943,12 @@ private void abeset(elem *e,vec_t ae,vec_t aeval,int flag)
switch (e.Eoper) switch (e.Eoper)
{ case OPnot: { case OPnot:
flag ^= 1; flag ^= 1;
e = e.EV.E1; e = e.E1;
continue; continue;
case OPbool: case OPbool:
case OPeq: case OPeq:
e = e.EV.E1; e = e.E1;
continue; continue;
default: default:

View file

@ -36,7 +36,7 @@ nothrow:
void vec_setclear(size_t b, vec_t vs, vec_t vc) { vec_setbit(b, vs); vec_clearbit(b, vc); } void vec_setclear(size_t b, vec_t vs, vec_t vc) { vec_setbit(b, vs); vec_clearbit(b, vc); }
@trusted @trusted
bool Eunambig(elem* e) { return OTassign(e.Eoper) && e.EV.E1.Eoper == OPvar; } bool Eunambig(elem* e) { return OTassign(e.Eoper) && e.E1.Eoper == OPvar; }
@trusted @trusted
char symbol_isintab(const Symbol* s) { return sytab[s.Sclass] & SCSS; } char symbol_isintab(const Symbol* s) { return sytab[s.Sclass] & SCSS; }
@ -230,17 +230,17 @@ private uint numdefelems(const(elem)* e, ref uint num_unambig_def)
if (OTdef(e.Eoper)) if (OTdef(e.Eoper))
{ {
++n; ++n;
if (OTassign(e.Eoper) && e.EV.E1.Eoper == OPvar) if (OTassign(e.Eoper) && e.E1.Eoper == OPvar)
++num_unambig_def; ++num_unambig_def;
} }
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ {
n += numdefelems(e.EV.E1, num_unambig_def); n += numdefelems(e.E1, num_unambig_def);
e = e.EV.E2; e = e.E2;
} }
else if (OTunary(e.Eoper)) else if (OTunary(e.Eoper))
{ {
e = e.EV.E1; e = e.E1;
} }
else else
break; break;
@ -273,19 +273,19 @@ private void asgdefelems(block *b,elem *n, DefNode[] defnod, ref size_t i)
if (ERTOL(n)) if (ERTOL(n))
{ {
asgdefelems(b,n.EV.E1,defnod,i); asgdefelems(b,n.E1,defnod,i);
n = n.EV.E2; n = n.E2;
continue; continue;
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
asgdefelems(b,n.EV.E2,defnod,i); asgdefelems(b,n.E2,defnod,i);
n = n.EV.E1; n = n.E1;
continue; continue;
} }
else if (OTunary(op)) else if (OTunary(op))
{ {
n = n.EV.E1; n = n.E1;
continue; continue;
} }
break; break;
@ -310,7 +310,7 @@ private void initDNunambigVectors(DefNode[] defnod)
foreach (const i; 0 .. defnod.length) foreach (const i; 0 .. defnod.length)
{ {
elem *e = defnod[i].DNelem; elem *e = defnod[i].DNelem;
if (OTassign(e.Eoper) && e.EV.E1.Eoper == OPvar) if (OTassign(e.Eoper) && e.E1.Eoper == OPvar)
{ {
vec_t v = &go.dnunambig[j] + 2; vec_t v = &go.dnunambig[j] + 2;
assert(vec_dim(v) == 0); assert(vec_dim(v) == 0);
@ -351,11 +351,11 @@ private void initDNunambigVectors(DefNode[] defnod)
private void fillInDNunambig(vec_t v, elem *e, size_t start, DefNode[] defnod) private void fillInDNunambig(vec_t v, elem *e, size_t start, DefNode[] defnod)
{ {
assert(OTassign(e.Eoper)); assert(OTassign(e.Eoper));
elem *t = e.EV.E1; elem *t = e.E1;
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
Symbol *d = t.EV.Vsym; Symbol *d = t.Vsym;
targ_size_t toff = t.EV.Voffset; targ_size_t toff = t.Voffset;
targ_size_t tsize = (e.Eoper == OPstreq) ? type_size(e.ET) : tysize(t.Ety); targ_size_t tsize = (e.Eoper == OPstreq) ? type_size(e.ET) : tysize(t.Ety);
targ_size_t ttop = toff + tsize; targ_size_t ttop = toff + tsize;
@ -371,19 +371,19 @@ private void fillInDNunambig(vec_t v, elem *e, size_t start, DefNode[] defnod)
targ_size_t tn1size; targ_size_t tn1size;
// If not same variable then no overlap // If not same variable then no overlap
tn1 = tn.EV.E1; tn1 = tn.E1;
if (d != tn1.EV.Vsym) if (d != tn1.Vsym)
continue; continue;
tn1size = (tn.Eoper == OPstreq) tn1size = (tn.Eoper == OPstreq)
? type_size(tn.ET) : tysize(tn1.Ety); ? type_size(tn.ET) : tysize(tn1.Ety);
// If t completely overlaps tn1 // If t completely overlaps tn1
if (toff <= tn1.EV.Voffset && tn1.EV.Voffset + tn1size <= ttop) if (toff <= tn1.Voffset && tn1.Voffset + tn1size <= ttop)
{ {
vec_setbit(i, v); vec_setbit(i, v);
} }
// if tn1 completely overlaps t // if tn1 completely overlaps t
if (tn1.EV.Voffset <= toff && ttop <= tn1.EV.Voffset + tn1size) if (tn1.Voffset <= toff && ttop <= tn1.Voffset + tn1size)
{ {
vec_setbit(start, v2); vec_setbit(start, v2);
} }
@ -416,16 +416,16 @@ private void accumrd(vec_t GEN,vec_t KILL,elem *n,uint deftop)
assert(GEN && KILL && n); assert(GEN && KILL && n);
const op = n.Eoper; const op = n.Eoper;
if (OTunary(op)) if (OTunary(op))
accumrd(GEN,KILL,n.EV.E1,deftop); accumrd(GEN,KILL,n.E1,deftop);
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (op == OPcolon || op == OPcolon2) if (op == OPcolon || op == OPcolon2)
{ {
vec_t Gl,Kl,Gr,Kr; vec_t Gl,Kl,Gr,Kr;
rdelem(Gl, Kl, n.EV.E1, deftop); rdelem(Gl, Kl, n.E1, deftop);
rdelem(Gr, Kr, n.EV.E2, deftop); rdelem(Gr, Kr, n.E2, deftop);
switch (el_returns(n.EV.E1) * 2 | int(el_returns(n.EV.E2))) switch (el_returns(n.E1) * 2 | int(el_returns(n.E2)))
{ {
case 3: // E1 and E2 return case 3: // E1 and E2 return
/* GEN = (GEN - Kl) | Gl | /* GEN = (GEN - Kl) | Gl |
@ -475,10 +475,10 @@ private void accumrd(vec_t GEN,vec_t KILL,elem *n,uint deftop)
} }
else if (op == OPandand || op == OPoror) else if (op == OPandand || op == OPoror)
{ {
accumrd(GEN,KILL,n.EV.E1,deftop); accumrd(GEN,KILL,n.E1,deftop);
vec_t Gr,Kr; vec_t Gr,Kr;
rdelem(Gr, Kr, n.EV.E2, deftop); rdelem(Gr, Kr, n.E2, deftop);
if (el_returns(n.EV.E2)) if (el_returns(n.E2))
vec_orass(GEN,Gr); // GEN |= Gr vec_orass(GEN,Gr); // GEN |= Gr
vec_free(Gr); vec_free(Gr);
@ -486,13 +486,13 @@ private void accumrd(vec_t GEN,vec_t KILL,elem *n,uint deftop)
} }
else if (OTrtol(op) && ERTOL(n)) else if (OTrtol(op) && ERTOL(n))
{ {
accumrd(GEN,KILL,n.EV.E2,deftop); accumrd(GEN,KILL,n.E2,deftop);
accumrd(GEN,KILL,n.EV.E1,deftop); accumrd(GEN,KILL,n.E1,deftop);
} }
else else
{ {
accumrd(GEN,KILL,n.EV.E1,deftop); accumrd(GEN,KILL,n.E1,deftop);
accumrd(GEN,KILL,n.EV.E2,deftop); accumrd(GEN,KILL,n.E2,deftop);
} }
} }
@ -687,20 +687,20 @@ private void aecpgenkill(ref GlobalOptimizer go, int flowxx)
if (OTunary(op)) if (OTunary(op))
{ {
n.Eexp = 0; n.Eexp = 0;
n = n.EV.E1; n = n.E1;
continue; continue;
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (ERTOL(n)) if (ERTOL(n))
{ {
asgcpelems(n.EV.E2); asgcpelems(n.E2);
asgcpelems(n.EV.E1); asgcpelems(n.E1);
} }
else else
{ {
asgcpelems(n.EV.E1); asgcpelems(n.E1);
asgcpelems(n.EV.E2); asgcpelems(n.E2);
} }
/* look for elem of the form OPvar=OPvar, where they aren't the /* look for elem of the form OPvar=OPvar, where they aren't the
@ -710,12 +710,12 @@ private void aecpgenkill(ref GlobalOptimizer go, int flowxx)
elem* e1; elem* e1;
elem* e2; elem* e2;
if ((op == OPeq || op == OPstreq) && if ((op == OPeq || op == OPstreq) &&
(e1 = n.EV.E1).Eoper == OPvar && (e1 = n.E1).Eoper == OPvar &&
(e2 = n.EV.E2).Eoper == OPvar && (e2 = n.E2).Eoper == OPvar &&
!((e1.Ety | e2.Ety) & (mTYvolatile | mTYshared)) && !((e1.Ety | e2.Ety) & (mTYvolatile | mTYshared)) &&
(!config.fpxmmregs || (!config.fpxmmregs ||
(!tyfloating(e1.EV.Vsym.Stype.Tty) == !tyfloating(e2.EV.Vsym.Stype.Tty))) && (!tyfloating(e1.Vsym.Stype.Tty) == !tyfloating(e2.Vsym.Stype.Tty))) &&
e1.EV.Vsym != e2.EV.Vsym) e1.Vsym != e2.Vsym)
{ {
n.Eexp = cast(uint)go.expnod.length; n.Eexp = cast(uint)go.expnod.length;
go.expnod.push(n); go.expnod.push(n);
@ -740,7 +740,7 @@ private void aecpgenkill(ref GlobalOptimizer go, int flowxx)
const op = n.Eoper; const op = n.Eoper;
if (OTunary(op)) if (OTunary(op))
{ {
ae = asgaeelems(n.EV.E1); ae = asgaeelems(n.E1);
// Disallow starred references to avoid problems with VBE's // Disallow starred references to avoid problems with VBE's
// being hoisted before tests of an invalid pointer. // being hoisted before tests of an invalid pointer.
if (flowxx == VBE && op == OPind) if (flowxx == VBE && op == OPind)
@ -752,9 +752,9 @@ private void aecpgenkill(ref GlobalOptimizer go, int flowxx)
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (ERTOL(n)) if (ERTOL(n))
ae = asgaeelems(n.EV.E2) & asgaeelems(n.EV.E1); ae = asgaeelems(n.E2) & asgaeelems(n.E1);
else else
ae = asgaeelems(n.EV.E1) & asgaeelems(n.EV.E2); ae = asgaeelems(n.E1) & asgaeelems(n.E2);
} }
else else
ae = true; ae = true;
@ -830,14 +830,14 @@ private void aecpgenkill(ref GlobalOptimizer go, int flowxx)
vec_free(b.Bgen2); vec_free(b.Bgen2);
vec_free(b.Bkill2); vec_free(b.Bkill2);
elem* e; elem* e;
for (e = b.Belem; e.Eoper == OPcomma; e = e.EV.E2) for (e = b.Belem; e.Eoper == OPcomma; e = e.E2)
accumaecp(b.Bgen,b.Bkill,e.EV.E1); accumaecp(b.Bgen,b.Bkill,e.E1);
if (e.Eoper == OPandand || e.Eoper == OPoror) if (e.Eoper == OPandand || e.Eoper == OPoror)
{ {
accumaecp(b.Bgen,b.Bkill,e.EV.E1); accumaecp(b.Bgen,b.Bkill,e.E1);
vec_t Kr = vec_calloc(go.expnod.length); vec_t Kr = vec_calloc(go.expnod.length);
vec_t Gr = vec_calloc(go.expnod.length); vec_t Gr = vec_calloc(go.expnod.length);
accumaecp(Gr,Kr,e.EV.E2); accumaecp(Gr,Kr,e.E2);
// We might or might not have executed E2 // We might or might not have executed E2
// KILL1 = KILL | Kr // KILL1 = KILL | Kr
@ -946,13 +946,13 @@ private void defstarkill()
{ {
const op = n.Eoper; const op = n.Eoper;
assert(op == OPeq || op == OPstreq); assert(op == OPeq || op == OPstreq);
assert(n.EV.E1.Eoper==OPvar && n.EV.E2.Eoper==OPvar); assert(n.E1.Eoper==OPvar && n.E2.Eoper==OPvar);
// Set bit in defkill if either the left or the // Set bit in defkill if either the left or the
// right variable is killed by an ambiguous def. // right variable is killed by an ambiguous def.
if (Symbol_isAffected(*n.EV.E1.EV.Vsym) || if (Symbol_isAffected(*n.E1.Vsym) ||
Symbol_isAffected(*n.EV.E2.EV.Vsym)) Symbol_isAffected(*n.E2.Vsym))
{ {
vec_setbit(i + 1,defkill); vec_setbit(i + 1,defkill);
} }
@ -970,12 +970,12 @@ private void defstarkill()
switch (op) switch (op)
{ {
case OPvar: case OPvar:
if (Symbol_isAffected(*n.EV.Vsym)) if (Symbol_isAffected(*n.Vsym))
vec_setbit(i,defkill); vec_setbit(i,defkill);
break; break;
case OPind: // if a 'starred' ref case OPind: // if a 'starred' ref
if (tybasic(n.EV.E1.Ety) == TYimmutPtr) if (tybasic(n.E1.Ety) == TYimmutPtr)
break; break;
goto case OPstrlen; goto case OPstrlen;
@ -996,18 +996,18 @@ private void defstarkill()
if (OTunary(op)) if (OTunary(op))
{ {
Lunary: Lunary:
if (vec_testbit(n.EV.E1.Eexp,defkill)) if (vec_testbit(n.E1.Eexp,defkill))
vec_setbit(i,defkill); vec_setbit(i,defkill);
if (vec_testbit(n.EV.E1.Eexp,starkill)) if (vec_testbit(n.E1.Eexp,starkill))
vec_setbit(i,starkill); vec_setbit(i,starkill);
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (vec_testbit(n.EV.E1.Eexp,defkill) || if (vec_testbit(n.E1.Eexp,defkill) ||
vec_testbit(n.EV.E2.Eexp,defkill)) vec_testbit(n.E2.Eexp,defkill))
vec_setbit(i,defkill); vec_setbit(i,defkill);
if (vec_testbit(n.EV.E1.Eexp,starkill) || if (vec_testbit(n.E1.Eexp,starkill) ||
vec_testbit(n.EV.E2.Eexp,starkill)) vec_testbit(n.E2.Eexp,starkill))
vec_setbit(i,starkill); vec_setbit(i,starkill);
} }
break; break;
@ -1115,8 +1115,8 @@ private void accumaecpx(elem *n)
case OPcolon2: case OPcolon2:
{ vec_t Gl,Kl,Gr,Kr; { vec_t Gl,Kl,Gr,Kr;
aecpelem(Gl,Kl, n.EV.E1, go.exptop); aecpelem(Gl,Kl, n.E1, go.exptop);
aecpelem(Gr,Kr, n.EV.E2, go.exptop); aecpelem(Gr,Kr, n.E2, go.exptop);
/* KILL |= Kl | Kr */ /* KILL |= Kl | Kr */
/* GEN =((GEN - Kl) | Gl) & */ /* GEN =((GEN - Kl) | Gl) & */
@ -1142,10 +1142,10 @@ private void accumaecpx(elem *n)
case OPoror: case OPoror:
{ vec_t Gr,Kr; { vec_t Gr,Kr;
accumaecpx(n.EV.E1); accumaecpx(n.E1);
aecpelem(Gr,Kr, n.EV.E2, go.exptop); aecpelem(Gr,Kr, n.E2, go.exptop);
if (el_returns(n.EV.E2)) if (el_returns(n.E2))
{ {
// KILL |= Kr // KILL |= Kr
// GEN &= (GEN - Kr) | Gr // GEN &= (GEN - Kr) | Gr
@ -1170,12 +1170,12 @@ private void accumaecpx(elem *n)
case OPeq: case OPeq:
case OPstreq: case OPstreq:
accumaecpx(n.EV.E2); accumaecpx(n.E2);
goto case OPnegass; goto case OPnegass;
case OPnegass: case OPnegass:
accumaecpx(n.EV.E1); accumaecpx(n.E1);
t = n.EV.E1; t = n.E1;
break; break;
case OPvp_fp: case OPvp_fp:
@ -1185,30 +1185,30 @@ private void accumaecpx(elem *n)
break; break;
case OPprefetch: case OPprefetch:
accumaecpx(n.EV.E1); // don't check E2 accumaecpx(n.E1); // don't check E2
break; break;
default: default:
if (OTunary(op)) if (OTunary(op))
{ {
case OPind: // most common unary operator case OPind: // most common unary operator
accumaecpx(n.EV.E1); accumaecpx(n.E1);
debug assert(!OTassign(op)); debug assert(!OTassign(op));
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (OTrtol(op) && ERTOL(n)) if (OTrtol(op) && ERTOL(n))
{ {
accumaecpx(n.EV.E2); accumaecpx(n.E2);
accumaecpx(n.EV.E1); accumaecpx(n.E1);
} }
else else
{ {
accumaecpx(n.EV.E1); accumaecpx(n.E1);
accumaecpx(n.EV.E2); accumaecpx(n.E2);
} }
if (OTassign(op)) // if assignment operator if (OTassign(op)) // if assignment operator
t = n.EV.E1; t = n.E1;
} }
break; break;
} }
@ -1228,7 +1228,7 @@ private void accumaecpx(elem *n)
else /* unambiguous def elem */ else /* unambiguous def elem */
{ {
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
Symbol* s = t.EV.Vsym; // ptr to var being def'd Symbol* s = t.Vsym; // ptr to var being def'd
foreach (uint i; 1 .. go.exptop) // for each ae elem foreach (uint i; 1 .. go.exptop) // for each ae elem
{ {
elem *e = go.expnod[i]; elem *e = go.expnod[i];
@ -1236,7 +1236,7 @@ private void accumaecpx(elem *n)
/* If it could be changed by the definition, */ /* If it could be changed by the definition, */
/* set bit in KILL. */ /* set bit in KILL. */
if (e.EV.E1.EV.Vsym == s || e.EV.E2.EV.Vsym == s) if (e.E1.Vsym == s || e.E2.Vsym == s)
vec_setclear(i,KILL,GEN); vec_setclear(i,KILL,GEN);
} }
} }
@ -1274,7 +1274,7 @@ private void accumaecpx(elem *n)
else /* unambiguous def elem */ else /* unambiguous def elem */
{ {
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
Symbol* s = t.EV.Vsym; // idx of var being def'd Symbol* s = t.Vsym; // idx of var being def'd
if (!(s.Sflags & SFLunambig)) if (!(s.Sflags & SFLunambig))
{ {
vec_orass(KILL,go.starkill); /* kill all 'starred' refs */ vec_orass(KILL,go.starkill); /* kill all 'starred' refs */
@ -1289,18 +1289,18 @@ private void accumaecpx(elem *n)
/* set bit in KILL. */ /* set bit in KILL. */
if (eop == OPvar) if (eop == OPvar)
{ {
if (e.EV.Vsym != s) if (e.Vsym != s)
continue; continue;
} }
else if (OTunary(eop)) else if (OTunary(eop))
{ {
if (!vec_testbit(e.EV.E1.Eexp,KILL)) if (!vec_testbit(e.E1.Eexp,KILL))
continue; continue;
} }
else if (OTbinary(eop)) else if (OTbinary(eop))
{ {
if (!vec_testbit(e.EV.E1.Eexp,KILL) && if (!vec_testbit(e.E1.Eexp,KILL) &&
!vec_testbit(e.EV.E2.Eexp,KILL)) !vec_testbit(e.E2.Eexp,KILL))
continue; continue;
} }
else else
@ -1499,9 +1499,9 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
switch (op) switch (op)
{ {
case OPvar: case OPvar:
if (symbol_isintab(n.EV.Vsym)) if (symbol_isintab(n.Vsym))
{ {
const si = n.EV.Vsym.Ssymnum; const si = n.Vsym.Ssymnum;
assert(cast(uint)si < globsym.length); assert(cast(uint)si < globsym.length);
if (!vec_testbit(si,KILL)) // if not in KILL if (!vec_testbit(si,KILL)) // if not in KILL
@ -1513,8 +1513,8 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPcolon2: case OPcolon2:
{ {
vec_t Gl,Kl,Gr,Kr; vec_t Gl,Kl,Gr,Kr;
lvelem(Gl,Kl, n.EV.E1,ambigsym, globsym.length); lvelem(Gl,Kl, n.E1,ambigsym, globsym.length);
lvelem(Gr,Kr, n.EV.E2,ambigsym, globsym.length); lvelem(Gr,Kr, n.E2,ambigsym, globsym.length);
/* GEN |= (Gl | Gr) - KILL */ /* GEN |= (Gl | Gr) - KILL */
/* KILL |= (Kl & Kr) - GEN */ /* KILL |= (Kl & Kr) - GEN */
@ -1537,8 +1537,8 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPoror: case OPoror:
{ {
vec_t Gr,Kr; vec_t Gr,Kr;
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
lvelem(Gr,Kr, n.EV.E2,ambigsym, globsym.length); lvelem(Gr,Kr, n.E2,ambigsym, globsym.length);
/* GEN |= Gr - KILL */ /* GEN |= Gr - KILL */
/* KILL |= 0 */ /* KILL |= 0 */
@ -1562,14 +1562,14 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPmemcpy: case OPmemcpy:
case OPmemset: case OPmemset:
debug assert(OTrtol(op)); debug assert(OTrtol(op));
accumlv(GEN,KILL,n.EV.E2,ambigsym); accumlv(GEN,KILL,n.E2,ambigsym);
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
goto L1; goto L1;
case OPstrcat: case OPstrcat:
debug assert(!OTrtol(op)); debug assert(!OTrtol(op));
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
accumlv(GEN,KILL,n.EV.E2,ambigsym); accumlv(GEN,KILL,n.E2,ambigsym);
L1: L1:
vec_orass(GEN,ambigsym); vec_orass(GEN,ambigsym);
vec_subass(GEN,KILL); vec_subass(GEN,KILL);
@ -1579,13 +1579,13 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPstreq: case OPstreq:
{ {
/* Avoid GENing the lvalue of an = */ /* Avoid GENing the lvalue of an = */
accumlv(GEN,KILL,n.EV.E2,ambigsym); accumlv(GEN,KILL,n.E2,ambigsym);
const t = n.EV.E1; const t = n.E1;
if (t.Eoper != OPvar) if (t.Eoper != OPvar)
accumlv(GEN,KILL,t.EV.E1,ambigsym); accumlv(GEN,KILL,t.E1,ambigsym);
else /* unambiguous assignment */ else /* unambiguous assignment */
{ {
const s = t.EV.Vsym; const s = t.Vsym;
symbol_debug(s); symbol_debug(s);
uint tsz = tysize(t.Ety); uint tsz = tysize(t.Ety);
@ -1595,7 +1595,7 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
/* if not GENed already, KILL it */ /* if not GENed already, KILL it */
if (symbol_isintab(s) && if (symbol_isintab(s) &&
!vec_testbit(s.Ssymnum,GEN) && !vec_testbit(s.Ssymnum,GEN) &&
t.EV.Voffset == 0 && t.Voffset == 0 &&
tsz == type_size(s.Stype) tsz == type_size(s.Stype)
) )
{ {
@ -1610,8 +1610,8 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPmemcmp: case OPmemcmp:
case OPstrcmp: case OPstrcmp:
case OPbt: // much like OPind case OPbt: // much like OPind
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
accumlv(GEN,KILL,n.EV.E2,ambigsym); accumlv(GEN,KILL,n.E2,ambigsym);
vec_orass(GEN,ambigsym); vec_orass(GEN,ambigsym);
vec_subass(GEN,KILL); vec_subass(GEN,KILL);
break; break;
@ -1620,7 +1620,7 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
case OPucall: case OPucall:
case OPucallns: case OPucallns:
case OPstrlen: case OPstrlen:
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
/* If it was a *p elem, set bits in GEN for all symbols */ /* If it was a *p elem, set bits in GEN for all symbols */
/* it could have referenced, but only if bits in KILL */ /* it could have referenced, but only if bits in KILL */
@ -1633,22 +1633,22 @@ private void accumlv(vec_t GEN, vec_t KILL, const(elem)* n, const vec_t ambigsym
default: default:
if (OTunary(op)) if (OTunary(op))
{ {
n = n.EV.E1; n = n.E1;
continue; continue;
} }
else if (OTrtol(op) && ERTOL(n)) else if (OTrtol(op) && ERTOL(n))
{ {
accumlv(GEN,KILL,n.EV.E2,ambigsym); accumlv(GEN,KILL,n.E2,ambigsym);
/* Note that lvalues of op=,i++,i-- elems */ /* Note that lvalues of op=,i++,i-- elems */
/* are GENed. */ /* are GENed. */
n = n.EV.E1; n = n.E1;
continue; continue;
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
accumlv(GEN,KILL,n.EV.E1,ambigsym); accumlv(GEN,KILL,n.E1,ambigsym);
n = n.EV.E2; n = n.E2;
continue; continue;
} }
break; break;
@ -1764,8 +1764,8 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
{ {
vec_t Gl,Gr,Kl,Kr; vec_t Gl,Gr,Kl,Kr;
aecpelem(Gl,Kl, n.EV.E1, go.exptop); aecpelem(Gl,Kl, n.E1, go.exptop);
aecpelem(Gr,Kr, n.EV.E2, go.exptop); aecpelem(Gr,Kr, n.E2, go.exptop);
/* GEN |=((Gr - Kl) | (Gl - Kr)) - KILL */ /* GEN |=((Gr - Kl) | (Gl - Kr)) - KILL */
vec_subass(Gr,Kl); vec_subass(Gr,Kl);
@ -1788,36 +1788,36 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
case OPandand: case OPandand:
case OPoror: case OPoror:
accumvbe(GEN,KILL,n.EV.E1); accumvbe(GEN,KILL,n.E1);
/* WARNING: just so happens that it works this way. */ /* WARNING: just so happens that it works this way. */
/* Be careful about (b+c)||(b+c) being VBEs, only the */ /* Be careful about (b+c)||(b+c) being VBEs, only the */
/* first should be GENed. Doing things this way instead */ /* first should be GENed. Doing things this way instead */
/* of (GEN |= Gr - KILL) and (KILL |= Kr - GEN) will */ /* of (GEN |= Gr - KILL) and (KILL |= Kr - GEN) will */
/* ensure this. */ /* ensure this. */
accumvbe(GEN,KILL,n.EV.E2); accumvbe(GEN,KILL,n.E2);
break; break;
case OPnegass: case OPnegass:
t = n.EV.E1; t = n.E1;
if (t.Eoper != OPvar) if (t.Eoper != OPvar)
{ {
accumvbe(GEN,KILL,t.EV.E1); accumvbe(GEN,KILL,t.E1);
if (OTbinary(t.Eoper)) if (OTbinary(t.Eoper))
accumvbe(GEN,KILL,t.EV.E2); accumvbe(GEN,KILL,t.E2);
} }
break; break;
case OPcall: case OPcall:
case OPcallns: case OPcallns:
accumvbe(GEN,KILL,n.EV.E2); accumvbe(GEN,KILL,n.E2);
goto case OPucall; goto case OPucall;
case OPucall: case OPucall:
case OPucallns: case OPucallns:
t = n.EV.E1; t = n.E1;
// Do not VBE indirect function calls // Do not VBE indirect function calls
if (t.Eoper == OPind) if (t.Eoper == OPind)
t = t.EV.E1; t = t.E1;
accumvbe(GEN,KILL,t); accumvbe(GEN,KILL,t);
break; break;
@ -1829,22 +1829,22 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
default: default:
if (OTunary(op)) if (OTunary(op))
{ {
t = n.EV.E1; t = n.E1;
accumvbe(GEN,KILL,t); accumvbe(GEN,KILL,t);
} }
else if (ERTOL(n)) else if (ERTOL(n))
{ {
accumvbe(GEN,KILL,n.EV.E2); accumvbe(GEN,KILL,n.E2);
t = n.EV.E1; t = n.E1;
// do not GEN the lvalue of an assignment op // do not GEN the lvalue of an assignment op
if (OTassign(op)) if (OTassign(op))
{ {
t = n.EV.E1; t = n.E1;
if (t.Eoper != OPvar) if (t.Eoper != OPvar)
{ {
accumvbe(GEN,KILL,t.EV.E1); accumvbe(GEN,KILL,t.E1);
if (OTbinary(t.Eoper)) if (OTbinary(t.Eoper))
accumvbe(GEN,KILL,t.EV.E2); accumvbe(GEN,KILL,t.E2);
} }
} }
else else
@ -1855,17 +1855,17 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
/* do not GEN the lvalue of an assignment op */ /* do not GEN the lvalue of an assignment op */
if (OTassign(op)) if (OTassign(op))
{ {
t = n.EV.E1; t = n.E1;
if (t.Eoper != OPvar) if (t.Eoper != OPvar)
{ {
accumvbe(GEN,KILL,t.EV.E1); accumvbe(GEN,KILL,t.E1);
if (OTbinary(t.Eoper)) if (OTbinary(t.Eoper))
accumvbe(GEN,KILL,t.EV.E2); accumvbe(GEN,KILL,t.E2);
} }
} }
else else
accumvbe(GEN,KILL,n.EV.E1); accumvbe(GEN,KILL,n.E1);
accumvbe(GEN,KILL,n.EV.E2); accumvbe(GEN,KILL,n.E2);
} }
break; break;
} }
@ -1920,7 +1920,7 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
else /* unambiguous definition */ else /* unambiguous definition */
{ {
assert(t.Eoper == OPvar); assert(t.Eoper == OPvar);
Symbol* s = t.EV.Vsym; // ptr to var being def'd Symbol* s = t.Vsym; // ptr to var being def'd
if (!(s.Sflags & SFLunambig)) if (!(s.Sflags & SFLunambig))
vec_orass(KILL,go.starkill);/* kill all 'starred' refs */ vec_orass(KILL,go.starkill);/* kill all 'starred' refs */
foreach (uint i; 1 .. go.exptop) // for each vbe elem foreach (uint i; 1 .. go.exptop) // for each vbe elem
@ -1932,18 +1932,18 @@ private void accumvbe(vec_t GEN,vec_t KILL,elem *n)
/* set bit in KILL. */ /* set bit in KILL. */
if (eop == OPvar) if (eop == OPvar)
{ {
if (e.EV.Vsym != s) if (e.Vsym != s)
continue; continue;
} }
else if (OTbinary(eop)) else if (OTbinary(eop))
{ {
if (!vec_testbit(e.EV.E1.Eexp,KILL) && if (!vec_testbit(e.E1.Eexp,KILL) &&
!vec_testbit(e.EV.E2.Eexp,KILL)) !vec_testbit(e.E2.Eexp,KILL))
continue; continue;
} }
else if (OTunary(eop)) else if (OTunary(eop))
{ {
if (!vec_testbit(e.EV.E1.Eexp,KILL)) if (!vec_testbit(e.E1.Eexp,KILL))
continue; continue;
} }
else /* OPconst or OPrelconst or OPstring */ else /* OPconst or OPrelconst or OPstring */

View file

@ -118,13 +118,13 @@ Loop:
switch (op) switch (op)
{ {
case OPcomma: case OPcomma:
local_exp(lt,e.EV.E1,0); local_exp(lt,e.E1,0);
e = e.EV.E2; e = e.E2;
goto Loop; goto Loop;
case OPandand: case OPandand:
case OPoror: case OPoror:
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
lt.setLength(0); // we can do better than this, fix later lt.setLength(0); // we can do better than this, fix later
break; break;
@ -134,9 +134,9 @@ Loop:
break; break;
case OPinfo: case OPinfo:
if (e.EV.E1.Eoper == OPmark) if (e.E1.Eoper == OPmark)
{ lt.setLength(0); { lt.setLength(0);
e = e.EV.E2; e = e.E2;
goto Loop; goto Loop;
} }
goto case_bin; goto case_bin;
@ -150,18 +150,18 @@ Loop:
case OPddtor: case OPddtor:
lt.setLength(0); // don't move expressions across ctor/dtor lt.setLength(0); // don't move expressions across ctor/dtor
// boundaries, it would goof up EH cleanup // boundaries, it would goof up EH cleanup
local_exp(lt,e.EV.E1,0); local_exp(lt,e.E1,0);
lt.setLength(0); lt.setLength(0);
break; break;
case OPeq: case OPeq:
case OPstreq: case OPstreq:
case OPvecsto: case OPvecsto:
e1 = e.EV.E1; e1 = e.E1;
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
if (e1.Eoper == OPvar) if (e1.Eoper == OPvar)
{ {
const s = e1.EV.Vsym; const s = e1.Vsym;
if (s.Sflags & SFLunambig) if (s.Sflags & SFLunambig)
{ local_symdef(lt, s); { local_symdef(lt, s);
if (!goal) if (!goal)
@ -173,9 +173,9 @@ Loop:
else else
{ {
assert(!OTleaf(e1.Eoper)); assert(!OTleaf(e1.Eoper));
local_exp(lt,e1.EV.E1,1); local_exp(lt,e1.E1,1);
if (OTbinary(e1.Eoper)) if (OTbinary(e1.Eoper))
local_exp(lt,e1.EV.E2,1); local_exp(lt,e1.E2,1);
local_ambigdef(lt); local_ambigdef(lt);
} }
break; break;
@ -195,35 +195,35 @@ Loop:
case OPorass: case OPorass:
case OPcmpxchg: case OPcmpxchg:
if (ERTOL(e)) if (ERTOL(e))
{ local_exp(lt,e.EV.E2,1); { local_exp(lt,e.E2,1);
case OPnegass: case OPnegass:
e1 = e.EV.E1; e1 = e.E1;
op1 = e1.Eoper; op1 = e1.Eoper;
if (op1 != OPvar) if (op1 != OPvar)
{ {
local_exp(lt,e1.EV.E1,1); local_exp(lt,e1.E1,1);
if (OTbinary(op1)) if (OTbinary(op1))
local_exp(lt,e1.EV.E2,1); local_exp(lt,e1.E2,1);
} }
else if (lt.length && (op == OPaddass || op == OPxorass)) else if (lt.length && (op == OPaddass || op == OPxorass))
{ {
const s = e1.EV.Vsym; const s = e1.Vsym;
foreach (u; 0 .. lt.length) foreach (u; 0 .. lt.length)
{ {
auto em = lt[u].e; auto em = lt[u].e;
if (em.Eoper == op && if (em.Eoper == op &&
em.EV.E1.EV.Vsym == s && em.E1.Vsym == s &&
tysize(em.Ety) == tysize(e1.Ety) && tysize(em.Ety) == tysize(e1.Ety) &&
!tyfloating(em.Ety) && !tyfloating(em.Ety) &&
em.EV.E1.EV.Voffset == e1.EV.Voffset && em.E1.Voffset == e1.Voffset &&
!el_sideeffect(em.EV.E2) !el_sideeffect(em.E2)
) )
{ // Change (x += a),(x += b) to { // Change (x += a),(x += b) to
// (x + a),(x += a + b) // (x + a),(x += a + b)
go.changes++; go.changes++;
e.EV.E2 = el_bin(opeqtoop(op),e.EV.E2.Ety,em.EV.E2,e.EV.E2); e.E2 = el_bin(opeqtoop(op),e.E2.Ety,em.E2,e.E2);
em.Eoper = cast(ubyte)opeqtoop(op); em.Eoper = cast(ubyte)opeqtoop(op);
em.EV.E2 = el_copytree(em.EV.E2); em.E2 = el_copytree(em.E2);
local_rem(lt, u); local_rem(lt, u);
debug if (debugc) debug if (debugc)
@ -240,29 +240,29 @@ Loop:
} }
else else
{ {
e1 = e.EV.E1; e1 = e.E1;
op1 = e1.Eoper; op1 = e1.Eoper;
if (op1 != OPvar) if (op1 != OPvar)
{ {
local_exp(lt,e1.EV.E1,1); local_exp(lt,e1.E1,1);
if (OTbinary(op1)) if (OTbinary(op1))
local_exp(lt,e1.EV.E2,1); local_exp(lt,e1.E2,1);
} }
if (lt.length) if (lt.length)
{ {
Symbol* s; Symbol* s;
if (op1 == OPvar && if (op1 == OPvar &&
((s = e1.EV.Vsym).Sflags & SFLunambig)) ((s = e1.Vsym).Sflags & SFLunambig))
local_symref(lt, s); local_symref(lt, s);
else else
local_ambigref(lt); local_ambigref(lt);
} }
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
} }
Symbol* s; Symbol* s;
if (op1 == OPvar && if (op1 == OPvar &&
((s = e1.EV.Vsym).Sflags & SFLunambig)) ((s = e1.Vsym).Sflags & SFLunambig))
{ local_symref(lt, s); { local_symref(lt, s);
local_symdef(lt, s); local_symdef(lt, s);
if (op == OPaddass || op == OPxorass) if (op == OPaddass || op == OPxorass)
@ -276,15 +276,15 @@ Loop:
case OPstrlen: case OPstrlen:
case OPind: case OPind:
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
local_ambigref(lt); local_ambigref(lt);
break; break;
case OPstrcmp: case OPstrcmp:
case OPmemcmp: case OPmemcmp:
case OPbt: case OPbt:
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
local_ambigref(lt); local_ambigref(lt);
break; break;
@ -293,21 +293,21 @@ Loop:
case OPstrcat: case OPstrcat:
case OPcall: case OPcall:
case OPcallns: case OPcallns:
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
goto Lrd; goto Lrd;
case OPstrctor: case OPstrctor:
case OPucall: case OPucall:
case OPucallns: case OPucallns:
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
goto Lrd; goto Lrd;
case OPbtc: case OPbtc:
case OPbtr: case OPbtr:
case OPbts: case OPbts:
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
goto Lrd; goto Lrd;
case OPasm: case OPasm:
@ -316,25 +316,25 @@ Loop:
break; break;
case OPmemset: case OPmemset:
local_exp(lt,e.EV.E2,1); local_exp(lt,e.E2,1);
if (e.EV.E1.Eoper == OPvar) if (e.E1.Eoper == OPvar)
{ {
/* Don't want to rearrange (p = get(); p memset 0;) /* Don't want to rearrange (p = get(); p memset 0;)
* as elemxxx() will rearrange it back. * as elemxxx() will rearrange it back.
*/ */
const s = e.EV.E1.EV.Vsym; const s = e.E1.Vsym;
if (s.Sflags & SFLunambig) if (s.Sflags & SFLunambig)
local_symref(lt, s); local_symref(lt, s);
else else
local_ambigref(lt); // ambiguous reference local_ambigref(lt); // ambiguous reference
} }
else else
local_exp(lt,e.EV.E1,1); local_exp(lt,e.E1,1);
local_ambigdef(lt); local_ambigdef(lt);
break; break;
case OPvar: case OPvar:
const s = e.EV.Vsym; const s = e.Vsym;
if (lt.length) if (lt.length)
{ {
// If potential candidate for replacement // If potential candidate for replacement
@ -343,11 +343,11 @@ Loop:
foreach (const u; 0 .. lt.length) foreach (const u; 0 .. lt.length)
{ {
auto em = lt[u].e; auto em = lt[u].e;
if (em.EV.E1.EV.Vsym == s && if (em.E1.Vsym == s &&
(em.Eoper == OPeq || em.Eoper == OPstreq)) (em.Eoper == OPeq || em.Eoper == OPstreq))
{ {
if (tysize(em.Ety) == tysize(e.Ety) && if (tysize(em.Ety) == tysize(e.Ety) &&
em.EV.E1.EV.Voffset == e.EV.Voffset && em.E1.Voffset == e.Voffset &&
((tyfloating(em.Ety) != 0) == (tyfloating(e.Ety) != 0) || ((tyfloating(em.Ety) != 0) == (tyfloating(e.Ety) != 0) ||
/** Hack to fix https://issues.dlang.org/show_bug.cgi?id=10226 /** Hack to fix https://issues.dlang.org/show_bug.cgi?id=10226
* Recognize assignments of float vectors to void16, as used by * Recognize assignments of float vectors to void16, as used by
@ -358,8 +358,8 @@ Loop:
* wrong code. * wrong code.
* Ref: https://issues.dlang.org/show_bug.cgi?id=18034 * Ref: https://issues.dlang.org/show_bug.cgi?id=18034
*/ */
(em.EV.E2.Eoper != OPvecfill || tybasic(e.Ety) == tybasic(em.Ety)) && (em.E2.Eoper != OPvecfill || tybasic(e.Ety) == tybasic(em.Ety)) &&
!local_preserveAssignmentTo(em.EV.E1.Ety)) !local_preserveAssignmentTo(em.E1.Ety))
{ {
debug if (debugc) debug if (debugc)
@ -371,7 +371,7 @@ Loop:
go.changes++; go.changes++;
em.Ety = e.Ety; em.Ety = e.Ety;
el_copy(e,em); el_copy(e,em);
em.EV.E1 = em.EV.E2 = null; em.E1 = em.E2 = null;
em.Eoper = OPconst; em.Eoper = OPconst;
} }
local_rem(lt, u); local_rem(lt, u);
@ -386,9 +386,9 @@ Loop:
break; break;
case OPremquo: case OPremquo:
if (e.EV.E1.Eoper != OPvar) if (e.E1.Eoper != OPvar)
goto case_bin; goto case_bin;
const s = e.EV.E1.EV.Vsym; const s = e.E1.Vsym;
if (lt.length) if (lt.length)
{ {
if (s.Sflags & SFLunambig) if (s.Sflags & SFLunambig)
@ -397,7 +397,7 @@ Loop:
local_ambigref(lt); // ambiguous reference local_ambigref(lt); // ambiguous reference
} }
goal = 1; goal = 1;
e = e.EV.E2; e = e.E2;
goto Loop; goto Loop;
default: default:
@ -409,16 +409,16 @@ Loop:
{ {
const f = lt[u].flags; const f = lt[u].flags;
elem* eu = lt[u].e; elem* eu = lt[u].e;
const s = eu.EV.E1.EV.Vsym; const s = eu.E1.Vsym;
const f1 = local_getflags(e.EV.E1,s); const f1 = local_getflags(e.E1,s);
const f2 = local_getflags(e.EV.E2,s); const f2 = local_getflags(e.E2,s);
if (f1 & f2 & LFsymref || // if both reference or if (f1 & f2 & LFsymref || // if both reference or
(f1 | f2) & LFsymdef || // either define (f1 | f2) & LFsymdef || // either define
f & LFambigref && (f1 | f2) & LFambigdef || f & LFambigref && (f1 | f2) & LFambigdef ||
f & LFambigdef && (f1 | f2) & (LFambigref | LFambigdef) f & LFambigdef && (f1 | f2) & (LFambigref | LFambigdef)
) )
local_rem(lt, u); local_rem(lt, u);
else if (f & LFunambigdef && local_chkrem(e,eu.EV.E2)) else if (f & LFunambigdef && local_chkrem(e,eu.E2))
local_rem(lt, u); local_rem(lt, u);
else else
u++; u++;
@ -426,14 +426,14 @@ Loop:
} }
if (OTunary(e.Eoper)) if (OTunary(e.Eoper))
{ goal = 1; { goal = 1;
e = e.EV.E1; e = e.E1;
goto Loop; goto Loop;
} }
case_bin: case_bin:
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ local_exp(lt,e.EV.E1,1); { local_exp(lt,e.E1,1);
goal = 1; goal = 1;
e = e.EV.E2; e = e.E2;
goto Loop; goto Loop;
} }
break; break;
@ -454,22 +454,22 @@ private bool local_chkrem(const elem* e, const(elem)* eu)
{ {
elem_debug(eu); elem_debug(eu);
const op = eu.Eoper; const op = eu.Eoper;
if (OTassign(op) && eu.EV.E1.Eoper == OPvar) if (OTassign(op) && eu.E1.Eoper == OPvar)
{ {
const s = eu.EV.E1.EV.Vsym; const s = eu.E1.Vsym;
const f1 = local_getflags(e.EV.E1,s); const f1 = local_getflags(e.E1,s);
const f2 = local_getflags(e.EV.E2,s); const f2 = local_getflags(e.E2,s);
if ((f1 | f2) & (LFsymref | LFsymdef)) // if either reference or define if ((f1 | f2) & (LFsymref | LFsymdef)) // if either reference or define
return true; return true;
} }
if (OTbinary(op)) if (OTbinary(op))
{ {
if (local_chkrem(e,eu.EV.E2)) if (local_chkrem(e,eu.E2))
return true; return true;
} }
else if (!OTunary(op)) else if (!OTunary(op))
break; // leaf node break; // leaf node
eu = eu.EV.E1; eu = eu.E1;
} }
return false; return false;
} }
@ -481,15 +481,15 @@ private bool local_chkrem(const elem* e, const(elem)* eu)
private void local_ins(ref Barray!loc_t lt, elem *e) private void local_ins(ref Barray!loc_t lt, elem *e)
{ {
elem_debug(e); elem_debug(e);
if (e.EV.E1.Eoper == OPvar) if (e.E1.Eoper == OPvar)
{ {
const s = e.EV.E1.EV.Vsym; const s = e.E1.Vsym;
symbol_debug(s); symbol_debug(s);
if (s.Sflags & SFLunambig) // if can only be referenced directly if (s.Sflags & SFLunambig) // if can only be referenced directly
{ {
const flags = local_getflags(e.EV.E2,null); const flags = local_getflags(e.E2,null);
if (!(flags & (LFvolatile | LFinp | LFoutp)) && if (!(flags & (LFvolatile | LFinp | LFoutp)) &&
!(e.EV.E1.Ety & (mTYvolatile | mTYshared))) !(e.E1.Ety & (mTYvolatile | mTYshared)))
{ {
// Add e to the candidate array // Add e to the candidate array
//printf("local_ins('%s'), loctop = %d\n",s.Sident.ptr,lt.length); //printf("local_ins('%s'), loctop = %d\n",s.Sident.ptr,lt.length);
@ -526,9 +526,9 @@ private int local_getflags(const(elem)* e, const Symbol* s)
{ {
case OPeq: case OPeq:
case OPstreq: case OPstreq:
if (e.EV.E1.Eoper == OPvar) if (e.E1.Eoper == OPvar)
{ {
const s1 = e.EV.E1.EV.Vsym; const s1 = e.E1.Vsym;
if (s1.Sflags & SFLunambig) if (s1.Sflags & SFLunambig)
flags |= (s1 == s) ? LFsymdef : LFunambigdef; flags |= (s1 == s) ? LFsymdef : LFunambigdef;
else else
@ -552,9 +552,9 @@ private int local_getflags(const(elem)* e, const Symbol* s)
case OPxorass: case OPxorass:
case OPorass: case OPorass:
case OPcmpxchg: case OPcmpxchg:
if (e.EV.E1.Eoper == OPvar) if (e.E1.Eoper == OPvar)
{ {
const s1 = e.EV.E1.EV.Vsym; const s1 = e.E1.Vsym;
if (s1.Sflags & SFLunambig) if (s1.Sflags & SFLunambig)
flags |= (s1 == s) ? LFsymdef | LFsymref flags |= (s1 == s) ? LFsymdef | LFsymref
: LFunambigdef | LFunambigref; : LFunambigdef | LFunambigref;
@ -564,8 +564,8 @@ private int local_getflags(const(elem)* e, const Symbol* s)
else else
flags |= LFambigdef | LFambigref; flags |= LFambigdef | LFambigref;
L1: L1:
flags |= local_getflags(e.EV.E2,s); flags |= local_getflags(e.E2,s);
e = e.EV.E1; e = e.E1;
break; break;
case OPucall: case OPucall:
@ -587,9 +587,9 @@ private int local_getflags(const(elem)* e, const Symbol* s)
break; break;
case OPvar: case OPvar:
if (e.EV.Vsym == s) if (e.Vsym == s)
flags |= LFsymref; flags |= LFsymref;
else if (!(e.EV.Vsym.Sflags & SFLunambig)) else if (!(e.Vsym.Sflags & SFLunambig))
flags |= LFambigref; flags |= LFambigref;
break; break;
@ -616,14 +616,14 @@ private int local_getflags(const(elem)* e, const Symbol* s)
{ {
if (tyfloating(e.Ety)) if (tyfloating(e.Ety))
flags |= LFfloat; flags |= LFfloat;
e = e.EV.E1; e = e.E1;
} }
else if (OTbinary(e.Eoper)) else if (OTbinary(e.Eoper))
{ {
if (tyfloating(e.Ety)) if (tyfloating(e.Ety))
flags |= LFfloat; flags |= LFfloat;
flags |= local_getflags(e.EV.E2,s); flags |= local_getflags(e.E2,s);
e = e.EV.E1; e = e.E1;
} }
else else
break; break;

File diff suppressed because it is too large Load diff

View file

@ -232,28 +232,28 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
if (op == OPcolon || op == OPcolon2) if (op == OPcolon || op == OPcolon2)
{ {
L = vec_clone(IN); L = vec_clone(IN);
switch (el_returns(n.EV.E1) * 2 | el_returns(n.EV.E2)) switch (el_returns(n.E1) * 2 | el_returns(n.E2))
{ {
case 3: // E1 and E2 return case 3: // E1 and E2 return
conpropwalk(n.EV.E1,L); conpropwalk(n.E1,L);
conpropwalk(n.EV.E2,IN); conpropwalk(n.E2,IN);
vec_orass(IN,L); // IN = L | R vec_orass(IN,L); // IN = L | R
break; break;
case 2: // E1 returns case 2: // E1 returns
conpropwalk(n.EV.E1,IN); conpropwalk(n.E1,IN);
conpropwalk(n.EV.E2,L); conpropwalk(n.E2,L);
break; break;
case 1: // E2 returns case 1: // E2 returns
conpropwalk(n.EV.E1,L); conpropwalk(n.E1,L);
conpropwalk(n.EV.E2,IN); conpropwalk(n.E2,IN);
break; break;
case 0: // neither returns case 0: // neither returns
conpropwalk(n.EV.E1,L); conpropwalk(n.E1,L);
vec_copy(L,IN); vec_copy(L,IN);
conpropwalk(n.EV.E2,L); conpropwalk(n.E2,L);
break; break;
default: default:
@ -263,10 +263,10 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
} }
else if (op == OPandand || op == OPoror) else if (op == OPandand || op == OPoror)
{ {
conpropwalk(n.EV.E1,IN); conpropwalk(n.E1,IN);
R = vec_clone(IN); R = vec_clone(IN);
conpropwalk(n.EV.E2,R); conpropwalk(n.E2,R);
if (el_returns(n.EV.E2)) if (el_returns(n.E2))
vec_orass(IN,R); // IN |= R vec_orass(IN,R); // IN |= R
vec_free(R); vec_free(R);
} }
@ -274,15 +274,15 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
goto L3; goto L3;
else if (ERTOL(n)) else if (ERTOL(n))
{ {
conpropwalk(n.EV.E2,IN); conpropwalk(n.E2,IN);
L3: L3:
t = n.EV.E1; t = n.E1;
if (OTassign(op)) if (OTassign(op))
{ {
if (t.Eoper == OPvar) if (t.Eoper == OPvar)
{ {
// Note that the following ignores OPnegass // Note that the following ignores OPnegass
if (OTopeq(op) && sytab[t.EV.Vsym.Sclass] & SCRD) if (OTopeq(op) && sytab[t.Vsym.Sclass] & SCRD)
{ {
Barray!(elem*) rdl; Barray!(elem*) rdl;
listrds(IN,t,null,&rdl); listrds(IN,t,null,&rdl);
@ -293,7 +293,7 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
e = el_copytree(e); e = el_copytree(e);
e.Ety = t.Ety; e.Ety = t.Ety;
n.EV.E2 = el_bin(opeqtoop(op),n.Ety,e,n.EV.E2); n.E2 = el_bin(opeqtoop(op),n.Ety,e,n.E2);
n.Eoper = OPeq; n.Eoper = OPeq;
} }
rdl.dtor(); rdl.dtor();
@ -308,17 +308,17 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
else if (OTbinary(op)) else if (OTbinary(op))
{ {
if (OTassign(op)) if (OTassign(op))
{ t = n.EV.E1; { t = n.E1;
if (t.Eoper != OPvar) if (t.Eoper != OPvar)
conpropwalk(t,IN); conpropwalk(t,IN);
} }
else else
conpropwalk(n.EV.E1,IN); conpropwalk(n.E1,IN);
conpropwalk(n.EV.E2,IN); conpropwalk(n.E2,IN);
} }
// Collect data for subsequent optimizations // Collect data for subsequent optimizations
if (OTbinary(op) && n.EV.E1.Eoper == OPvar && n.EV.E2.Eoper == OPconst) if (OTbinary(op) && n.E1.Eoper == OPvar && n.E2.Eoper == OPconst)
{ {
switch (op) switch (op)
{ {
@ -327,15 +327,15 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
case OPle: case OPle:
case OPge: case OPge:
// Collect compare elems and their rd's in the rellist list // Collect compare elems and their rd's in the rellist list
if (tyintegral(n.EV.E1.Ety) && if (tyintegral(n.E1.Ety) &&
tyintegral(n.EV.E2.Ety) tyintegral(n.E2.Ety)
) )
{ {
//printf("appending to rellist\n"); elem_print(n); //printf("appending to rellist\n"); elem_print(n);
//printf("\trellist IN: "); vec_print(IN); printf("\n"); //printf("\trellist IN: "); vec_print(IN); printf("\n");
auto pdata = eqrelinc.rellist.push(); auto pdata = eqrelinc.rellist.push();
pdata.emplace(n, thisblock); pdata.emplace(n, thisblock);
listrds(IN, n.EV.E1, null, &pdata.rdlist); listrds(IN, n.E1, null, &pdata.rdlist);
} }
break; break;
@ -344,24 +344,24 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
case OPpostinc: case OPpostinc:
case OPpostdec: case OPpostdec:
// Collect increment elems and their rd's in the inclist list // Collect increment elems and their rd's in the inclist list
if (tyintegral(n.EV.E1.Ety)) if (tyintegral(n.E1.Ety))
{ {
//printf("appending to inclist\n"); elem_print(n); //printf("appending to inclist\n"); elem_print(n);
//printf("\tinclist IN: "); vec_print(IN); printf("\n"); //printf("\tinclist IN: "); vec_print(IN); printf("\n");
auto pdata = eqrelinc.inclist.push(); auto pdata = eqrelinc.inclist.push();
pdata.emplace(n, thisblock); pdata.emplace(n, thisblock);
listrds(IN, n.EV.E1, null, &pdata.rdlist); listrds(IN, n.E1, null, &pdata.rdlist);
} }
break; break;
case OPne: case OPne:
case OPeqeq: case OPeqeq:
// Collect compare elems and their rd's in the rellist list // Collect compare elems and their rd's in the rellist list
if (tyintegral(n.EV.E1.Ety) && !tyvector(n.Ety)) if (tyintegral(n.E1.Ety) && !tyvector(n.Ety))
{ //printf("appending to eqeqlist\n"); elem_print(n); { //printf("appending to eqeqlist\n"); elem_print(n);
auto pdata = eqrelinc.eqeqlist.push(); auto pdata = eqrelinc.eqeqlist.push();
pdata.emplace(n, thisblock); pdata.emplace(n, thisblock);
listrds(IN, n.EV.E1, null, &pdata.rdlist); listrds(IN, n.E1, null, &pdata.rdlist);
} }
break; break;
@ -376,9 +376,9 @@ private void constantPropagation(block* thisblock, ref EqRelInc eqrelinc)
/* now we get to the part that checks to see if we can */ /* now we get to the part that checks to see if we can */
/* propagate a constant. */ /* propagate a constant. */
if (op == OPvar && sytab[n.EV.Vsym.Sclass] & SCRD) if (op == OPvar && sytab[n.Vsym.Sclass] & SCRD)
{ {
//printf("const prop: %s\n", n.EV.Vsym.Sident.ptr); //printf("const prop: %s\n", n.Vsym.Sident.ptr);
Barray!(elem*) rdl; Barray!(elem*) rdl;
listrds(IN,n,null,&rdl); listrds(IN,n,null,&rdl);
@ -409,7 +409,7 @@ private void chkrd(elem *n, Barray!(elem*) rdlist)
Symbol *sv; Symbol *sv;
int unambig; int unambig;
sv = n.EV.Vsym; sv = n.Vsym;
assert(sytab[sv.Sclass] & SCRD); assert(sytab[sv.Sclass] & SCRD);
if (sv.Sflags & SFLnord) // if already printed a warning if (sv.Sflags & SFLnord) // if already printed a warning
return; return;
@ -423,9 +423,9 @@ private void chkrd(elem *n, Barray!(elem*) rdlist)
return; return;
if (OTassign(d.Eoper)) if (OTassign(d.Eoper))
{ {
if (d.EV.E1.Eoper == OPvar) if (d.E1.Eoper == OPvar)
{ {
if (d.EV.E1.EV.Vsym == sv) if (d.E1.Vsym == sv)
return; return;
} }
else if (!unambig) else if (!unambig)
@ -514,13 +514,13 @@ private elem * chkprop(elem *n, Barray!(elem*) rdlist)
//printf("checkprop: "); WReqn(n); printf("\n"); //printf("checkprop: "); WReqn(n); printf("\n");
assert(n && n.Eoper == OPvar); assert(n && n.Eoper == OPvar);
elem_debug(n); elem_debug(n);
sv = n.EV.Vsym; sv = n.Vsym;
assert(sytab[sv.Sclass] & SCRD); assert(sytab[sv.Sclass] & SCRD);
nty = n.Ety; nty = n.Ety;
if (!tyscalar(nty)) if (!tyscalar(nty))
goto noprop; goto noprop;
nsize = cast(uint)size(nty); nsize = cast(uint)size(nty);
noff = n.EV.Voffset; noff = n.Voffset;
unambig = sv.Sflags & SFLunambig; unambig = sv.Sflags & SFLunambig;
foreach (d; rdlist) foreach (d; rdlist)
{ {
@ -535,11 +535,11 @@ private elem * chkprop(elem *n, Barray!(elem*) rdlist)
if (OTassign(d.Eoper)) // if assignment elem if (OTassign(d.Eoper)) // if assignment elem
{ {
elem *t = d.EV.E1; elem *t = d.E1;
if (t.Eoper == OPvar) if (t.Eoper == OPvar)
{ {
assert(t.EV.Vsym == sv); assert(t.Vsym == sv);
if (d.Eoper == OPstreq || if (d.Eoper == OPstreq ||
!tyscalar(t.Ety)) !tyscalar(t.Ety))
@ -550,10 +550,10 @@ private elem * chkprop(elem *n, Barray!(elem*) rdlist)
/* Everything must match or we must skip this variable */ /* Everything must match or we must skip this variable */
/* (in case of assigning to overlapping unions, etc.) */ /* (in case of assigning to overlapping unions, etc.) */
if (t.EV.Voffset != noff || if (t.Voffset != noff ||
/* If sizes match, we are ok */ /* If sizes match, we are ok */
size(t.Ety) != nsize && size(t.Ety) != nsize &&
!(d.EV.E2.Eoper == OPconst && size(t.Ety) > nsize && !tyfloating(d.EV.E2.Ety))) !(d.E2.Eoper == OPconst && size(t.Ety) > nsize && !tyfloating(d.E2.Ety)))
goto noprop; goto noprop;
} }
else else
@ -573,15 +573,15 @@ private elem * chkprop(elem *n, Barray!(elem*) rdlist)
goto noprop; /* could be affected */ goto noprop; /* could be affected */
} }
if (d.EV.E2.Eoper == OPconst || d.EV.E2.Eoper == OPrelconst) if (d.E2.Eoper == OPconst || d.E2.Eoper == OPrelconst)
{ {
if (foundelem) /* already found one */ if (foundelem) /* already found one */
{ /* then they must be the same */ { /* then they must be the same */
if (!el_match(foundelem,d.EV.E2)) if (!el_match(foundelem,d.E2))
goto noprop; goto noprop;
} }
else /* else this is it */ else /* else this is it */
foundelem = d.EV.E2; foundelem = d.E2;
} }
else else
goto noprop; goto noprop;
@ -625,11 +625,11 @@ void listrds(vec_t IN,elem *e,vec_t f, Barray!(elem*)* rdlist)
//printf("listrds: "); WReqn(e); printf("\n"); //printf("listrds: "); WReqn(e); printf("\n");
assert(IN); assert(IN);
assert(e.Eoper == OPvar); assert(e.Eoper == OPvar);
s = e.EV.Vsym; s = e.Vsym;
ty = e.Ety; ty = e.Ety;
if (tyscalar(ty)) if (tyscalar(ty))
nsize = cast(uint)size(ty); nsize = cast(uint)size(ty);
noff = e.EV.Voffset; noff = e.Voffset;
unambig = s.Sflags & SFLunambig; unambig = s.Sflags & SFLunambig;
if (f) if (f)
vec_clear(f); vec_clear(f);
@ -641,16 +641,16 @@ void listrds(vec_t IN,elem *e,vec_t f, Barray!(elem*)* rdlist)
if (op == OPasm) // assume ASM elems define everything if (op == OPasm) // assume ASM elems define everything
goto listit; goto listit;
if (OTassign(op)) if (OTassign(op))
{ elem *t = d.EV.E1; { elem *t = d.E1;
if (t.Eoper == OPvar && t.EV.Vsym == s) if (t.Eoper == OPvar && t.Vsym == s)
{ if (op == OPstreq) { if (op == OPstreq)
goto listit; goto listit;
if (!tyscalar(ty) || !tyscalar(t.Ety)) if (!tyscalar(ty) || !tyscalar(t.Ety))
goto listit; goto listit;
// If t does not overlap e, then it doesn't affect things // If t does not overlap e, then it doesn't affect things
if (noff + nsize > t.EV.Voffset && if (noff + nsize > t.Voffset &&
t.EV.Voffset + size(t.Ety) > noff) t.Voffset + size(t.Ety) > noff)
goto listit; // it's an assignment to s goto listit; // it's an assignment to s
} }
else if (t.Eoper != OPvar && !unambig) else if (t.Eoper != OPvar && !unambig)
@ -689,11 +689,11 @@ private void eqeqranges(ref Elemdatas eqeqlist)
foreach (ref rel; eqeqlist) foreach (ref rel; eqeqlist)
{ {
e = rel.pelem; e = rel.pelem;
v = e.EV.E1.EV.Vsym; v = e.E1.Vsym;
if (!(sytab[v.Sclass] & SCRD)) if (!(sytab[v.Sclass] & SCRD))
continue; continue;
sz = tysize(e.EV.E1.Ety); sz = tysize(e.E1.Ety);
c = el_tolong(e.EV.E2); c = el_tolong(e.E2);
result = -1; // result not known yet result = -1; // result not known yet
foreach (erd; rel.rdlist) foreach (erd; rel.rdlist)
@ -704,18 +704,18 @@ private void eqeqranges(ref Elemdatas eqeqlist)
elem_debug(erd); elem_debug(erd);
if (erd.Eoper != OPeq || if (erd.Eoper != OPeq ||
(erd1 = erd.EV.E1).Eoper != OPvar || (erd1 = erd.E1).Eoper != OPvar ||
erd.EV.E2.Eoper != OPconst erd.E2.Eoper != OPconst
) )
goto L1; goto L1;
szrd = tysize(erd1.Ety); szrd = tysize(erd1.Ety);
if (erd1.EV.Voffset + szrd <= e.EV.E1.EV.Voffset || if (erd1.Voffset + szrd <= e.E1.Voffset ||
e.EV.E1.EV.Voffset + sz <= erd1.EV.Voffset) e.E1.Voffset + sz <= erd1.Voffset)
continue; // doesn't affect us, skip it continue; // doesn't affect us, skip it
if (szrd != sz || e.EV.E1.EV.Voffset != erd1.EV.Voffset) if (szrd != sz || e.E1.Voffset != erd1.Voffset)
goto L1; // overlapping - forget it goto L1; // overlapping - forget it
tmp = (c == el_tolong(erd.EV.E2)); tmp = (c == el_tolong(erd.E2));
if (result == -1) if (result == -1)
result = tmp; result = tmp;
else if (result != tmp) else if (result != tmp)
@ -724,9 +724,9 @@ private void eqeqranges(ref Elemdatas eqeqlist)
if (result >= 0) if (result >= 0)
{ {
//printf("replacing with %d\n",result); //printf("replacing with %d\n",result);
el_free(e.EV.E1); el_free(e.E1);
el_free(e.EV.E2); el_free(e.E2);
e.EV.Vint = (e.Eoper == OPeqeq) ? result : result ^ 1; e.Vint = (e.Eoper == OPeqeq) ? result : result ^ 1;
e.Eoper = OPconst; e.Eoper = OPconst;
} }
L1: L1:
@ -765,8 +765,8 @@ private void intranges(ref Elemdatas rellist, ref Elemdatas inclist)
{ {
rb = rel.pblock; rb = rel.pblock;
//printf("rel.pelem: "); WReqn(rel.pelem); printf("\n"); //printf("rel.pelem: "); WReqn(rel.pelem); printf("\n");
assert(rel.pelem.EV.E1.Eoper == OPvar); assert(rel.pelem.E1.Eoper == OPvar);
v = rel.pelem.EV.E1.EV.Vsym; v = rel.pelem.E1.Vsym;
// RD info is only reliable for registers and autos // RD info is only reliable for registers and autos
if (!(sytab[v.Sclass] & SCRD)) if (!(sytab[v.Sclass] & SCRD))
@ -797,10 +797,10 @@ private void intranges(ref Elemdatas rellist, ref Elemdatas inclist)
continue; continue;
/* lvalues should be unambiguous defs */ /* lvalues should be unambiguous defs */
if (rdeq.EV.E1.Eoper != OPvar || rdinc.EV.E1.Eoper != OPvar) if (rdeq.E1.Eoper != OPvar || rdinc.E1.Eoper != OPvar)
continue; continue;
/* rvalues should be constants */ /* rvalues should be constants */
if (rdeq.EV.E2.Eoper != OPconst || rdinc.EV.E2.Eoper != OPconst) if (rdeq.E2.Eoper != OPconst || rdinc.E2.Eoper != OPconst)
continue; continue;
/* Ensure that the only defs reaching the increment elem (rdinc) */ /* Ensure that the only defs reaching the increment elem (rdinc) */
@ -841,12 +841,12 @@ private void intranges(ref Elemdatas rellist, ref Elemdatas inclist)
} }
/* Gather initial, increment, and final values for loop */ /* Gather initial, increment, and final values for loop */
initial = el_tolong(rdeq.EV.E2); initial = el_tolong(rdeq.E2);
increment = el_tolong(rdinc.EV.E2); increment = el_tolong(rdinc.E2);
if (incop == OPpostdec || incop == OPminass) if (incop == OPpostdec || incop == OPminass)
increment = -increment; increment = -increment;
relatop = rel.pelem.Eoper; relatop = rel.pelem.Eoper;
final_ = el_tolong(rel.pelem.EV.E2); final_ = el_tolong(rel.pelem.E2);
//printf("initial = %d, increment = %d, final_ = %d\n",initial,increment,final_); //printf("initial = %d, increment = %d, final_ = %d\n",initial,increment,final_);
/* Determine if we can make the relational an unsigned */ /* Determine if we can make the relational an unsigned */
@ -872,9 +872,9 @@ private void intranges(ref Elemdatas rellist, ref Elemdatas inclist)
) )
{ {
makeuns: makeuns:
if (!tyuns(rel.pelem.EV.E2.Ety)) if (!tyuns(rel.pelem.E2.Ety))
{ {
rel.pelem.EV.E2.Ety = touns(rel.pelem.EV.E2.Ety); rel.pelem.E2.Ety = touns(rel.pelem.E2.Ety);
rel.pelem.Nflags |= NFLtouns; rel.pelem.Nflags |= NFLtouns;
debug debug
@ -893,12 +893,12 @@ private void intranges(ref Elemdatas rellist, ref Elemdatas inclist)
rb.BC == BCiftrue && rb.BC == BCiftrue &&
list_block(rb.Bsucc) == rb && list_block(rb.Bsucc) == rb &&
rb.Belem.Eoper == OPcomma && rb.Belem.Eoper == OPcomma &&
rb.Belem.EV.E1 == rdinc && rb.Belem.E1 == rdinc &&
rb.Belem.EV.E2 == rel.pelem rb.Belem.E2 == rel.pelem
) )
{ {
rel.pelem.Eoper = OPeq; rel.pelem.Eoper = OPeq;
rel.pelem.Ety = rel.pelem.EV.E1.Ety; rel.pelem.Ety = rel.pelem.E1.Ety;
rb.BC = BCgoto; rb.BC = BCgoto;
list_subtract(&rb.Bsucc,rb); list_subtract(&rb.Bsucc,rb);
list_subtract(&rb.Bpred,rb); list_subtract(&rb.Bpred,rb);
@ -946,8 +946,8 @@ public bool findloopparameters(elem* erel, ref elem* rdeq, ref elem* rdinc)
return result; return result;
} }
assert(erel.EV.E1.Eoper == OPvar); assert(erel.E1.Eoper == OPvar);
Symbol* v = erel.EV.E1.EV.Vsym; Symbol* v = erel.E1.Vsym;
// RD info is only reliable for registers and autos // RD info is only reliable for registers and autos
if (!(sytab[v.Sclass] & SCRD)) if (!(sytab[v.Sclass] & SCRD))
@ -1021,14 +1021,14 @@ public bool findloopparameters(elem* erel, ref elem* rdeq, ref elem* rdinc)
} }
// lvalues should be unambiguous defs // lvalues should be unambiguous defs
if (rdeq.Eoper != OPeq || rdeq.EV.E1.Eoper != OPvar || rdinc.EV.E1.Eoper != OPvar) if (rdeq.Eoper != OPeq || rdeq.E1.Eoper != OPvar || rdinc.E1.Eoper != OPvar)
{ {
if (log) printf("\tnot OPvar\n"); if (log) printf("\tnot OPvar\n");
return returnResult(false); return returnResult(false);
} }
// rvalues should be constants // rvalues should be constants
if (rdeq.EV.E2.Eoper != OPconst || rdinc.EV.E2.Eoper != OPconst) if (rdeq.E2.Eoper != OPconst || rdinc.E2.Eoper != OPconst)
{ {
if (log) printf("\tnot OPconst\n"); if (log) printf("\tnot OPconst\n");
return returnResult(false); return returnResult(false);
@ -1163,26 +1163,26 @@ private bool copyPropWalk(elem *n,vec_t IN)
if (op == OPcolon || op == OPcolon2) if (op == OPcolon || op == OPcolon2)
{ {
vec_t L = vec_clone(IN); vec_t L = vec_clone(IN);
cpwalk(n.EV.E1,L); cpwalk(n.E1,L);
cpwalk(n.EV.E2,IN); cpwalk(n.E2,IN);
vec_andass(IN,L); // IN = L & R vec_andass(IN,L); // IN = L & R
vec_free(L); vec_free(L);
} }
else if (op == OPandand || op == OPoror) else if (op == OPandand || op == OPoror)
{ {
cpwalk(n.EV.E1,IN); cpwalk(n.E1,IN);
vec_t L = vec_clone(IN); vec_t L = vec_clone(IN);
cpwalk(n.EV.E2,L); cpwalk(n.E2,L);
vec_andass(IN,L); // IN = L & R vec_andass(IN,L); // IN = L & R
vec_free(L); vec_free(L);
} }
else if (OTunary(op)) else if (OTunary(op))
{ {
t = n.EV.E1; t = n.E1;
if (OTassign(op)) if (OTassign(op))
{ {
if (t.Eoper == OPind) if (t.Eoper == OPind)
cpwalk(t.EV.E1,IN); cpwalk(t.E1,IN);
} }
else if (op == OPctor || op == OPdtor) else if (op == OPctor || op == OPdtor)
{ {
@ -1201,8 +1201,8 @@ private bool copyPropWalk(elem *n,vec_t IN)
} }
else if (OTassign(op)) else if (OTassign(op))
{ {
cpwalk(n.EV.E2,IN); cpwalk(n.E2,IN);
t = n.EV.E1; t = n.E1;
if (t.Eoper == OPind) if (t.Eoper == OPind)
cpwalk(t,IN); cpwalk(t,IN);
else else
@ -1213,13 +1213,13 @@ private bool copyPropWalk(elem *n,vec_t IN)
} }
else if (ERTOL(n)) else if (ERTOL(n))
{ {
cpwalk(n.EV.E2,IN); cpwalk(n.E2,IN);
cpwalk(n.EV.E1,IN); cpwalk(n.E1,IN);
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
cpwalk(n.EV.E1,IN); cpwalk(n.E1,IN);
cpwalk(n.EV.E2,IN); cpwalk(n.E2,IN);
} }
if (OTdef(op)) // if definition elem if (OTdef(op)) // if definition elem
@ -1236,7 +1236,7 @@ private bool copyPropWalk(elem *n,vec_t IN)
/* If this elem could kill the lvalue or the rvalue, */ /* If this elem could kill the lvalue or the rvalue, */
/* Clear bit in IN. */ /* Clear bit in IN. */
v = go.expnod[i].EV.E1.EV.Vsym; v = go.expnod[i].E1.Vsym;
if (ambig) if (ambig)
{ {
if (Symbol_isAffected(*v)) if (Symbol_isAffected(*v))
@ -1244,11 +1244,11 @@ private bool copyPropWalk(elem *n,vec_t IN)
} }
else else
{ {
if (v == t.EV.Vsym) if (v == t.Vsym)
goto clr; goto clr;
} }
v = go.expnod[i].EV.E2.EV.Vsym; v = go.expnod[i].E2.Vsym;
if (ambig) if (ambig)
{ {
if (Symbol_isAffected(*v)) if (Symbol_isAffected(*v))
@ -1256,7 +1256,7 @@ private bool copyPropWalk(elem *n,vec_t IN)
} }
else else
{ {
if (v == t.EV.Vsym) if (v == t.Vsym)
goto clr; goto clr;
} }
continue; continue;
@ -1267,13 +1267,13 @@ private bool copyPropWalk(elem *n,vec_t IN)
/* If this is a copy elem in go.expnod[] */ /* If this is a copy elem in go.expnod[] */
/* Set bit in IN. */ /* Set bit in IN. */
if ((op == OPeq || op == OPstreq) && n.EV.E1.Eoper == OPvar && if ((op == OPeq || op == OPstreq) && n.E1.Eoper == OPvar &&
n.EV.E2.Eoper == OPvar && n.Eexp) n.E2.Eoper == OPvar && n.Eexp)
vec_setbit(n.Eexp,IN); vec_setbit(n.Eexp,IN);
} }
else if (op == OPvar && !nocp) // if reference to variable v else if (op == OPvar && !nocp) // if reference to variable v
{ {
Symbol *v = n.EV.Vsym; Symbol *v = n.Vsym;
//printf("Checking copyprop for '%s', ty=x%x\n", v.Sident.ptr,n.Ety); //printf("Checking copyprop for '%s', ty=x%x\n", v.Sident.ptr,n.Ety);
symbol_debug(v); symbol_debug(v);
@ -1289,28 +1289,28 @@ private bool copyPropWalk(elem *n,vec_t IN)
elem* c = go.expnod[i]; elem* c = go.expnod[i];
assert(c); assert(c);
uint csz = tysize(c.EV.E1.Ety); uint csz = tysize(c.E1.Ety);
if (c.Eoper == OPstreq) if (c.Eoper == OPstreq)
csz = cast(uint)type_size(c.ET); csz = cast(uint)type_size(c.ET);
assert(cast(int)csz >= 0); assert(cast(int)csz >= 0);
//printf(" looking at: ("); WReqn(c); printf("), ty=x%x\n",c.EV.E1.Ety); //printf(" looking at: ("); WReqn(c); printf("), ty=x%x\n",c.E1.Ety);
/* Not only must symbol numbers match, but */ /* Not only must symbol numbers match, but */
/* offsets too (in case of arrays) and sizes */ /* offsets too (in case of arrays) and sizes */
/* (in case of unions). */ /* (in case of unions). */
if (v == c.EV.E1.EV.Vsym && if (v == c.E1.Vsym &&
n.EV.Voffset >= c.EV.E1.EV.Voffset && n.Voffset >= c.E1.Voffset &&
n.EV.Voffset + sz <= c.EV.E1.EV.Voffset + csz) n.Voffset + sz <= c.E1.Voffset + csz)
{ {
if (foundelem) if (foundelem)
{ {
if (c.EV.E2.EV.Vsym != f) if (c.E2.Vsym != f)
goto noprop; goto noprop;
} }
else else
{ {
foundelem = c; foundelem = c;
f = foundelem.EV.E2.EV.Vsym; f = foundelem.E2.Vsym;
} }
} }
} }
@ -1324,11 +1324,11 @@ private bool copyPropWalk(elem *n,vec_t IN)
} }
type *nt = n.ET; type *nt = n.ET;
targ_size_t noffset = n.EV.Voffset; targ_size_t noffset = n.Voffset;
el_copy(n,foundelem.EV.E2); el_copy(n,foundelem.E2);
n.Ety = ty; // retain original type n.Ety = ty; // retain original type
n.ET = nt; n.ET = nt;
n.EV.Voffset += noffset - foundelem.EV.E1.EV.Voffset; n.Voffset += noffset - foundelem.E1.Voffset;
/* original => rewrite /* original => rewrite
* v = f * v = f
@ -1340,7 +1340,7 @@ private bool copyPropWalk(elem *n,vec_t IN)
foreach (j; 1 .. go.exptop) foreach (j; 1 .. go.exptop)
{ {
//printf("go.expnod[%d]: ", j); elem_print(go.expnod[j]); //printf("go.expnod[%d]: ", j); elem_print(go.expnod[j]);
if (go.expnod[j].EV.E2 == n) if (go.expnod[j].E2 == n)
{ {
recalc = true; recalc = true;
break; break;
@ -1405,8 +1405,8 @@ public void rmdeadass()
elem *nv; elem *nv;
n = assnod[j]; n = assnod[j];
nv = n.EV.E1; nv = n.E1;
v = nv.EV.Vsym; v = nv.Vsym;
if (!symbol_isintab(v)) // not considered if (!symbol_isintab(v)) // not considered
continue; continue;
//printf("assnod[%d]: ",j); WReqn(n); printf("\n"); //printf("assnod[%d]: ",j); WReqn(n); printf("\n");
@ -1425,10 +1425,10 @@ public void rmdeadass()
*/ */
if (OTbinary(n.Eoper)) if (OTbinary(n.Eoper))
{ {
elem* e2 = n.EV.E2; elem* e2 = n.E2;
if (e2.Eoper == OPvar && if (e2.Eoper == OPvar &&
config.fpxmmregs && config.fpxmmregs &&
!tyfloating(v.Stype.Tty) != !tyfloating(e2.EV.Vsym.Stype.Tty) !tyfloating(v.Stype.Tty) != !tyfloating(e2.Vsym.Stype.Tty)
) )
continue; continue;
} }
@ -1461,7 +1461,7 @@ public void elimass(elem *n)
switch (n.Eoper) switch (n.Eoper)
{ {
case OPvecsto: case OPvecsto:
n.EV.E2.Eoper = OPcomma; n.E2.Eoper = OPcomma;
goto case OPeq; goto case OPeq;
case OPeq: case OPeq:
@ -1470,10 +1470,10 @@ public void elimass(elem *n)
/* Watch out for (a=b=c) stuff! */ /* Watch out for (a=b=c) stuff! */
/* Don't screw up assnod[]. */ /* Don't screw up assnod[]. */
n.Eoper = OPcomma; n.Eoper = OPcomma;
n.Ety |= n.EV.E2.Ety & (mTYconst | mTYvolatile | mTYimmutable | mTYshared n.Ety |= n.E2.Ety & (mTYconst | mTYvolatile | mTYimmutable | mTYshared
| mTYfar | mTYfar
); );
n.EV.E1.Eoper = OPconst; n.E1.Eoper = OPconst;
break; break;
/* Convert (V op= e) to (V op e) */ /* Convert (V op= e) to (V op e) */
@ -1493,8 +1493,8 @@ public void elimass(elem *n)
case OPpostinc: /* (V i++ c) => V */ case OPpostinc: /* (V i++ c) => V */
case OPpostdec: /* (V i-- c) => V */ case OPpostdec: /* (V i-- c) => V */
e1 = n.EV.E1; e1 = n.E1;
el_free(n.EV.E2); el_free(n.E2);
el_copy(n,e1); el_copy(n,e1);
el_free(e1); el_free(e1);
break; break;
@ -1511,7 +1511,7 @@ public void elimass(elem *n)
case OPcmpxchg: case OPcmpxchg:
n.Eoper = OPcomma; n.Eoper = OPcomma;
n.EV.E2.Eoper = OPcomma; n.E2.Eoper = OPcomma;
break; break;
default: default:
@ -1529,14 +1529,14 @@ public void elimass(elem *n)
private uint numasg(elem *e) private uint numasg(elem *e)
{ {
assert(e); assert(e);
if (OTassign(e.Eoper) && e.EV.E1.Eoper == OPvar) if (OTassign(e.Eoper) && e.E1.Eoper == OPvar)
{ {
e.Nflags |= NFLassign; e.Nflags |= NFLassign;
return 1 + numasg(e.EV.E1) + (OTbinary(e.Eoper) ? numasg(e.EV.E2) : 0); return 1 + numasg(e.E1) + (OTbinary(e.Eoper) ? numasg(e.E2) : 0);
} }
e.Nflags &= ~NFLassign; e.Nflags &= ~NFLassign;
return OTunary(e.Eoper) ? numasg(e.EV.E1) : return OTunary(e.Eoper) ? numasg(e.E1) :
OTbinary(e.Eoper) ? numasg(e.EV.E1) + numasg(e.EV.E2) : 0; OTbinary(e.Eoper) ? numasg(e.E1) + numasg(e.E2) : 0;
} }
/****************************** /******************************
@ -1567,8 +1567,8 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
vec_t Pr = vec_clone(POSS); vec_t Pr = vec_clone(POSS);
vec_t Dl = vec_calloc(vec_numbits(POSS)); vec_t Dl = vec_calloc(vec_numbits(POSS));
vec_t Dr = vec_calloc(vec_numbits(POSS)); vec_t Dr = vec_calloc(vec_numbits(POSS));
accumda(n.EV.E1,Dl,Pl); accumda(n.E1,Dl,Pl);
accumda(n.EV.E2,Dr,Pr); accumda(n.E2,Dr,Pr);
/* D |= P & (Dl & Dr) | ~P & (Dl | Dr) */ /* D |= P & (Dl & Dr) | ~P & (Dl | Dr) */
/* P = P & (Pl & Pr) | ~P & (Pl | Pr) */ /* P = P & (Pl & Pr) | ~P & (Pl | Pr) */
@ -1587,13 +1587,13 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
case OPandand: case OPandand:
case OPoror: case OPoror:
{ {
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
// Substituting into the above equations Pl=P and Dl=0: // Substituting into the above equations Pl=P and Dl=0:
// D |= Dr - P // D |= Dr - P
// P = Pr // P = Pr
vec_t Pr = vec_clone(POSS); vec_t Pr = vec_clone(POSS);
vec_t Dr = vec_calloc(vec_numbits(POSS)); vec_t Dr = vec_calloc(vec_numbits(POSS));
accumda(n.EV.E2,Dr,Pr); accumda(n.E2,Dr,Pr);
vec_subass(Dr,POSS); vec_subass(Dr,POSS);
vec_orass(DEAD,Dr); vec_orass(DEAD,Dr);
vec_copy(POSS,Pr); vec_copy(POSS,Pr);
@ -1603,8 +1603,8 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
case OPvar: case OPvar:
{ {
Symbol *v = n.EV.Vsym; Symbol *v = n.Vsym;
targ_size_t voff = n.EV.Voffset; targ_size_t voff = n.Voffset;
uint vsize = tysize(n.Ety); uint vsize = tysize(n.Ety);
// We have a reference. Clear all bits in POSS that // We have a reference. Clear all bits in POSS that
@ -1612,12 +1612,12 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
foreach (const i; 0 .. assnod.length) foreach (const i; 0 .. assnod.length)
{ {
elem *ti = assnod[i].EV.E1; elem *ti = assnod[i].E1;
if (v == ti.EV.Vsym && if (v == ti.Vsym &&
((vsize == -1 || tysize(ti.Ety) == -1) || ((vsize == -1 || tysize(ti.Ety) == -1) ||
// If symbol references overlap // If symbol references overlap
(voff + vsize > ti.EV.Voffset && (voff + vsize > ti.Voffset &&
ti.EV.Voffset + tysize(ti.Ety) > voff) ti.Voffset + tysize(ti.Ety) > voff)
) )
) )
{ {
@ -1633,8 +1633,8 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
break; break;
case OPbt: case OPbt:
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
vec_subass(POSS,ambigref); // remove possibly refed vec_subass(POSS,ambigref); // remove possibly refed
break; break;
@ -1642,7 +1642,7 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
case OPucall: case OPucall:
case OPucallns: case OPucallns:
case OPvp_fp: case OPvp_fp:
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
vec_subass(POSS,ambigref); // remove possibly refed vec_subass(POSS,ambigref); // remove possibly refed
// assignments from list // assignments from list
// of possibly dead ones // of possibly dead ones
@ -1656,11 +1656,11 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
case OPmemcpy: case OPmemcpy:
case OPstrcpy: case OPstrcpy:
case OPmemset: case OPmemset:
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
goto case OPstrlen; goto case OPstrlen;
case OPstrlen: case OPstrlen:
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
vec_subass(POSS,ambigref); // remove possibly refed vec_subass(POSS,ambigref); // remove possibly refed
// assignments from list // assignments from list
// of possibly dead ones // of possibly dead ones
@ -1669,8 +1669,8 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
case OPstrcat: case OPstrcat:
case OPstrcmp: case OPstrcmp:
case OPmemcmp: case OPmemcmp:
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
vec_subass(POSS,ambigref); // remove possibly refed vec_subass(POSS,ambigref); // remove possibly refed
// assignments from list // assignments from list
// of possibly dead ones // of possibly dead ones
@ -1682,20 +1682,20 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
elem *t; elem *t;
if (ERTOL(n)) if (ERTOL(n))
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
t = n.EV.E1; t = n.E1;
// if not (v = expression) then gen refs of left tree // if not (v = expression) then gen refs of left tree
if (op != OPeq && op != OPstreq) if (op != OPeq && op != OPstreq)
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
else if (OTunary(t.Eoper)) // if (*e = expression) else if (OTunary(t.Eoper)) // if (*e = expression)
accumda(t.EV.E1,DEAD,POSS); accumda(t.E1,DEAD,POSS);
else if (OTbinary(t.Eoper)) else if (OTbinary(t.Eoper))
{ {
accumda(t.EV.E1,DEAD,POSS); accumda(t.E1,DEAD,POSS);
accumda(t.EV.E2,DEAD,POSS); accumda(t.E2,DEAD,POSS);
} }
if (!ERTOL(n) && op != OPnegass) if (!ERTOL(n) && op != OPnegass)
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
// if unambiguous assignment, post all possibilities // if unambiguous assignment, post all possibilities
// to DEAD // to DEAD
@ -1706,7 +1706,7 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
tsz = cast(uint)type_size(n.ET); tsz = cast(uint)type_size(n.ET);
foreach (const i; 0 .. assnod.length) foreach (const i; 0 .. assnod.length)
{ {
elem *ti = assnod[i].EV.E1; elem *ti = assnod[i].E1;
uint tisz = tysize(ti.Ety); uint tisz = tysize(ti.Ety);
if (assnod[i].Eoper == OPstreq) if (assnod[i].Eoper == OPstreq)
@ -1714,11 +1714,11 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
// There may be some problem with this next // There may be some problem with this next
// statement with unions. // statement with unions.
if (ti.EV.Vsym == t.EV.Vsym && if (ti.Vsym == t.Vsym &&
ti.EV.Voffset == t.EV.Voffset && ti.Voffset == t.Voffset &&
tisz == tsz && tisz == tsz &&
!(t.Ety & (mTYvolatile | mTYshared)) && !(t.Ety & (mTYvolatile | mTYshared)) &&
//t.EV.Vsym.Sflags & SFLunambig && //t.Vsym.Sflags & SFLunambig &&
vec_testbit(i,POSS)) vec_testbit(i,POSS))
{ {
vec_setbit(i,DEAD); vec_setbit(i,DEAD);
@ -1735,7 +1735,7 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
// if variable could be referenced by a pointer // if variable could be referenced by a pointer
// or a function call, mark the assignment in // or a function call, mark the assignment in
// ambigref // ambigref
if (!(t.EV.Vsym.Sflags & SFLunambig)) if (!(t.Vsym.Sflags & SFLunambig))
{ {
vec_setbit(i,ambigref); vec_setbit(i,ambigref);
@ -1752,20 +1752,20 @@ private void accumda(elem *n,vec_t DEAD, vec_t POSS)
} }
else if (OTrtol(op)) else if (OTrtol(op))
{ {
accumda(n.EV.E2,DEAD,POSS); accumda(n.E2,DEAD,POSS);
n = n.EV.E1; n = n.E1;
goto LtailRecurse; // accumda(n.EV.E1,DEAD,POSS); goto LtailRecurse; // accumda(n.E1,DEAD,POSS);
} }
else if (OTbinary(op)) else if (OTbinary(op))
{ {
accumda(n.EV.E1,DEAD,POSS); accumda(n.E1,DEAD,POSS);
n = n.EV.E2; n = n.E2;
goto LtailRecurse; // accumda(n.EV.E2,DEAD,POSS); goto LtailRecurse; // accumda(n.E2,DEAD,POSS);
} }
else if (OTunary(op)) else if (OTunary(op))
{ {
n = n.EV.E1; n = n.E1;
goto LtailRecurse; // accumda(n.EV.E1,DEAD,POSS); goto LtailRecurse; // accumda(n.E1,DEAD,POSS);
} }
break; break;
} }
@ -1842,12 +1842,12 @@ public void deadvar()
@trusted @trusted
private void dvwalk(elem *n,uint i) private void dvwalk(elem *n,uint i)
{ {
for (; true; n = n.EV.E1) for (; true; n = n.E1)
{ {
assert(n); assert(n);
if (n.Eoper == OPvar || n.Eoper == OPrelconst) if (n.Eoper == OPvar || n.Eoper == OPrelconst)
{ {
Symbol *s = n.EV.Vsym; Symbol *s = n.Vsym;
s.Sflags &= ~SFLdead; s.Sflags &= ~SFLdead;
if (s.Srange) if (s.Srange)
@ -1856,7 +1856,7 @@ private void dvwalk(elem *n,uint i)
else if (!OTleaf(n.Eoper)) else if (!OTleaf(n.Eoper))
{ {
if (OTbinary(n.Eoper)) if (OTbinary(n.Eoper))
dvwalk(n.EV.E2,i); dvwalk(n.E2,i);
continue; continue;
} }
break; break;

View file

@ -68,7 +68,7 @@ extern (D) private void sliceStructs_Gather(ref const symtab_t symtab, SymInfo[]
{ {
case OPvar: case OPvar:
{ {
const si = e.EV.Vsym.Ssymnum; const si = e.Vsym.Ssymnum;
if (si != SYMIDX.max && sia[si].canSlice) if (si != SYMIDX.max && sia[si].canSlice)
{ {
assert(si < symtab.length); assert(si < symtab.length);
@ -88,7 +88,7 @@ extern (D) private void sliceStructs_Gather(ref const symtab_t symtab, SymInfo[]
foreach (ref ty; sia[si].ty) foreach (ref ty; sia[si].ty)
ty = TYnptr; ty = TYnptr;
const s = e.EV.Vsym; const s = e.Vsym;
const t = s.Stype; const t = s.Stype;
if (tybasic(t.Tty) == TYstruct) if (tybasic(t.Tty) == TYstruct)
{ {
@ -169,13 +169,13 @@ extern (D) private void sliceStructs_Gather(ref const symtab_t symtab, SymInfo[]
if (OTassign(e.Eoper)) if (OTassign(e.Eoper))
{ {
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
sliceStructs_Gather(symtab, sia, e.EV.E2); sliceStructs_Gather(symtab, sia, e.E2);
// Assignment to a whole var will disallow SROA // Assignment to a whole var will disallow SROA
if (e.EV.E1.Eoper == OPvar) if (e.E1.Eoper == OPvar)
{ {
const e1 = e.EV.E1; const e1 = e.E1;
const si = e1.EV.Vsym.Ssymnum; const si = e1.Vsym.Ssymnum;
if (si != SYMIDX.max && sia[si].canSlice) if (si != SYMIDX.max && sia[si].canSlice)
{ {
assert(si < symtab.length); assert(si < symtab.length);
@ -193,23 +193,23 @@ extern (D) private void sliceStructs_Gather(ref const symtab_t symtab, SymInfo[]
// https://github.com/dlang/dmd/pull/8034 // https://github.com/dlang/dmd/pull/8034
else if (!(config.exe & EX_OSX)) else if (!(config.exe & EX_OSX))
{ {
sliceStructs_Gather(symtab, sia, e.EV.E1); sliceStructs_Gather(symtab, sia, e.E1);
} }
} }
return; return;
} }
e = e.EV.E1; e = e.E1;
break; break;
} }
if (OTunary(e.Eoper)) if (OTunary(e.Eoper))
{ {
e = e.EV.E1; e = e.E1;
break; break;
} }
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ {
sliceStructs_Gather(symtab, sia, e.EV.E2); sliceStructs_Gather(symtab, sia, e.E2);
e = e.EV.E1; e = e.E1;
break; break;
} }
return; return;
@ -233,7 +233,7 @@ extern (D) private void sliceStructs_Replace(ref symtab_t symtab, const SymInfo[
{ {
case OPvar: case OPvar:
{ {
Symbol *s = e.EV.Vsym; Symbol *s = e.Vsym;
const si = s.Ssymnum; const si = s.Ssymnum;
//printf("e: %d %d\n", si, sia[si].canSlice); //printf("e: %d %d\n", si, sia[si].canSlice);
//elem_print(e); //elem_print(e);
@ -252,12 +252,12 @@ extern (D) private void sliceStructs_Replace(ref symtab_t symtab, const SymInfo[
el_copy(e2, e); el_copy(e2, e);
Symbol *s1 = symtab[sia[si].si0 + 1]; // +1 for second slice Symbol *s1 = symtab[sia[si].si0 + 1]; // +1 for second slice
e2.Ety = sia[si].ty[1]; e2.Ety = sia[si].ty[1];
e2.EV.Vsym = s1; e2.Vsym = s1;
e2.EV.Voffset = 0; e2.Voffset = 0;
e.Eoper = OPpair; e.Eoper = OPpair;
e.EV.E1 = e1; e.E1 = e1;
e.EV.E2 = e2; e.E2 = e2;
if (tycomplex(e.Ety)) if (tycomplex(e.Ety))
{ {
@ -288,8 +288,8 @@ extern (D) private void sliceStructs_Replace(ref symtab_t symtab, const SymInfo[
else // the nth slice else // the nth slice
{ {
if (log) { printf("slicing slice %d ", n); elem_print(e); } if (log) { printf("slicing slice %d ", n); elem_print(e); }
e.EV.Vsym = symtab[sia[si].si0 + n]; e.Vsym = symtab[sia[si].si0 + n];
e.EV.Voffset -= n * SLICESIZE; e.Voffset -= n * SLICESIZE;
//printf("replaced with:\n"); //printf("replaced with:\n");
//elem_print(e); //elem_print(e);
} }
@ -299,7 +299,7 @@ extern (D) private void sliceStructs_Replace(ref symtab_t symtab, const SymInfo[
case OPrelconst: case OPrelconst:
{ {
Symbol *s = e.EV.Vsym; Symbol *s = e.Vsym;
const si = s.Ssymnum; const si = s.Ssymnum;
//printf("e: %d %d\n", si, sia[si].canSlice); //printf("e: %d %d\n", si, sia[si].canSlice);
//elem_print(e); //elem_print(e);
@ -314,13 +314,13 @@ extern (D) private void sliceStructs_Replace(ref symtab_t symtab, const SymInfo[
default: default:
if (OTunary(e.Eoper)) if (OTunary(e.Eoper))
{ {
e = e.EV.E1; e = e.E1;
break; break;
} }
if (OTbinary(e.Eoper)) if (OTbinary(e.Eoper))
{ {
sliceStructs_Replace(symtab, sia, e.EV.E2); sliceStructs_Replace(symtab, sia, e.E2);
e = e.EV.E1; e = e.E1;
break; break;
} }
return; return;
@ -537,7 +537,7 @@ int nthSlice(const(elem)* e)
/* See if e fits in a slice /* See if e fits in a slice
*/ */
const lwr = e.EV.Voffset; const lwr = e.Voffset;
const upr = lwr + sz; const upr = lwr + sz;
if (0 <= lwr && upr <= sliceSize) if (0 <= lwr && upr <= sliceSize)
return 0; return 0;