Skip to content

Commit

Permalink
add some array bounds check optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Jun 4, 2014
1 parent 170c2b2 commit 9efe7f7
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 39 deletions.
32 changes: 24 additions & 8 deletions src/backend/el.c
Expand Up @@ -660,8 +660,6 @@ void el_replace_sym(elem *e,symbol *s1,symbol *s2)
* 0 no
*/

#if MARS

int el_appears(elem *e,Symbol *s)
{
symbol_debug(s);
Expand All @@ -688,6 +686,8 @@ int el_appears(elem *e,Symbol *s)
return 0;
}

#if MARS

/*****************************************
* Look for symbol that is a base of addressing mode e.
* Returns:
Expand Down Expand Up @@ -1792,12 +1792,7 @@ int el_noreturn(elem *e)
while (1)
{ elem_debug(e);
switch (e->Eoper)
{ case OPcomma:
if ((result |= el_noreturn(e->E1)) != 0)
break;
e = e->E2;
continue;

{
case OPcall:
case OPucall:
e = e->E1;
Expand All @@ -1809,7 +1804,28 @@ int el_noreturn(elem *e)
result = 1;
break;

case OPandand:
case OPoror:
e = e->E1;
continue;

case OPcolon:
case OPcolon2:
return el_noreturn(e->E1) && el_noreturn(e->E2);

default:
if (EBIN(e))
{
if (el_noreturn(e->E2))
return 1;
e = e->E1;
continue;
}
if (EUNA(e))
{
e = e->E1;
continue;
}
break;
}
break;
Expand Down
128 changes: 100 additions & 28 deletions src/backend/gdag.c
Expand Up @@ -622,7 +622,7 @@ void boolopt()
*/

STATIC void abewalk(elem *n,vec_t ae,vec_t aeval)
{ vec_t aer,aerval;
{
unsigned i,op;
unsigned i1,i2;
elem *t;
Expand All @@ -633,37 +633,104 @@ STATIC void abewalk(elem *n,vec_t ae,vec_t aeval)
/*chkvecdim(exptop);*/
op = n->Eoper;
switch (op)
{ case OPcolon:
case OPcolon2:
/* ae = ae & ael & aer */
/* AEs gened by ael and aer are mutually exclusive */
aer = vec_clone(ae);
aerval = vec_clone(aeval);
{
case OPcond:
{
assert(n->E2->Eoper == OPcolon || n->E2->Eoper == OPcolon2);
abewalk(n->E1,ae,aeval);
goto L1;
abeboolres(n->E1,ae,aeval);
vec_t aer = vec_clone(ae);
vec_t aerval = vec_clone(aeval);
if (el_noreturn(n->E2->E1))
{
abeset(n->E1,aer,aerval,true);
abewalk(n->E2->E1,aer,aerval);
abeset(n->E1,ae,aeval,false);
abewalk(n->E2->E2,ae,aeval);
}
else if (el_noreturn(n->E2->E2))
{
abeset(n->E1,ae,aeval,true);
abewalk(n->E2->E1,ae,aeval);
abeset(n->E1,aer,aerval,false);
abewalk(n->E2->E2,aer,aerval);
}
else
{
/* ae = ae & ael & aer
* AEs gened by ael and aer are mutually exclusive
*/
abeset(n->E1,aer,aerval,true);
abewalk(n->E2->E1,aer,aerval);
abeset(n->E1,ae,aeval,false);
abewalk(n->E2->E2,ae,aeval);

vec_xorass(aerval,aeval);
vec_subass(aer,aerval);
vec_andass(ae,aer);
}
vec_free(aer);
vec_free(aerval);
break;
}

case OPcolon:
case OPcolon2:
assert(0);

case OPandand:
case OPoror:
{
//printf("test1 %p: ", n); WReqn(n); printf("\n");
abewalk(n->E1,ae,aeval);
abeboolres(n->E1,ae,aeval);
/* ae &= aer */
aer = vec_clone(ae);
aerval = vec_clone(aeval);
abeset(n->E1,aer,aerval,(op == OPandand));
L1:
abewalk(n->E2,aer,aerval);
if (!el_noreturn(n->E2))
{ vec_xorass(aerval,aeval);
vec_t aer = vec_clone(ae);
vec_t aerval = vec_clone(aeval);
if (el_noreturn(n->E2))
{
abeset(n->E1,aer,aerval,(op == OPandand));
abewalk(n->E2,aer,aerval);
abeset(n->E1,ae,aeval,(op != OPandand));
}
else
{
/* ae &= aer
*/
abeset(n->E1,aer,aerval,(op == OPandand));
abewalk(n->E2,aer,aerval);

vec_xorass(aerval,aeval);
vec_subass(aer,aerval);
vec_andass(ae,aer);
}

vec_free(aer);
vec_free(aerval);
break;
}

case OPbool:
case OPnot:
abewalk(n->E1,ae,aeval);
abeboolres(n->E1,ae,aeval);
break;

case OPeqeq:
case OPne:
case OPlt:
case OPle:
case OPgt:
case OPge:
case OPunord: case OPlg: case OPleg: case OPule:
case OPul: case OPuge: case OPug: case OPue:
case OPngt: case OPnge: case OPnlt: case OPnle:
case OPord: case OPnlg: case OPnleg: case OPnule:
case OPnul: case OPnuge: case OPnug: case OPnue:
abewalk(n->E1,ae,aeval);
abewalk(n->E2,ae,aeval);
abeboolres(n,ae,aeval);
break;

case OPnegass:
t = Elvalue(n);
if (t->Eoper == OPind)
Expand Down Expand Up @@ -704,9 +771,13 @@ STATIC void abewalk(elem *n,vec_t ae,vec_t aeval)
if (!(s->Sflags & SFLunambig))
vec_subass(ae,starkill);
foreach (i,exptop,ae) /* for each ae elem */
{ register elem *e = expnod[i];
{ elem *e = expnod[i];

if (!e) continue;
#if 1
if (el_appears(e,s))
vec_clearbit(i,ae);
#else
if (OTunary(e->Eoper))
{
if (vec_testbit(e->E1->Eexp,ae))
Expand All @@ -725,6 +796,7 @@ STATIC void abewalk(elem *n,vec_t ae,vec_t aeval)
else
continue;
vec_clearbit(i,ae);
#endif
}
}
else /* else ambiguous definition */
Expand Down Expand Up @@ -774,23 +846,24 @@ STATIC void abewalk(elem *n,vec_t ae,vec_t aeval)
*/

STATIC void abeboolres(elem *n,vec_t ae,vec_t aeval)
{ unsigned i;

{
//printf("abeboolres()[%d %p] ", n->Eexp, expnod[n->Eexp]); WReqn(n); printf("\n");
elem_debug(n);
if (n->Eexp)
if (n->Eexp && expnod[n->Eexp])
{ /* Try to find an equivalent AE, and point to it instead */
assert(expnod[n->Eexp] == n);
unsigned i;
foreach (i,exptop,ae)
{ elem *e = expnod[i];

// Attempt to replace n with e
//dbg_printf("Looking at expnod[%d] = %p\n",i,e);
// Attempt to replace n with the boolean result of e
//printf("Looking at expnod[%d] = %p\n",i,e);
assert(e);
elem_debug(e);
if (n != e && el_match(n,e))
{
#ifdef DEBUG
if (debugc)
//if (debugc)
{ dbg_printf("Elem %p: ",n);
WReqn(n);
dbg_printf(" is replaced by %d\n",vec_testbit(i,aeval) != 0);
Expand All @@ -813,7 +886,7 @@ STATIC void abeboolres(elem *n,vec_t ae,vec_t aeval)

STATIC void abefree(elem *e,vec_t ae)
{
//dbg_printf("abefree %p: "); WReqn(e); dbg_printf("\n");
//printf("abefree [%d %p]: ", e->Eexp, e); WReqn(e); dbg_printf("\n");
assert(e->Eexp);
vec_clearbit(e->Eexp,ae);
expnod[e->Eexp] = NULL;
Expand All @@ -835,14 +908,13 @@ STATIC void abefree(elem *e,vec_t ae)
*/

STATIC void abeset(elem *e,vec_t ae,vec_t aeval,int flag)
{ unsigned i;

{
while (1)
{
i = e->Eexp;
unsigned i = e->Eexp;
if (i && expnod[i])
{
//dbg_printf("abeset for expnod[%d] = %p: ",i,e); WReqn(e); dbg_printf("\n");
//printf("abeset for expnod[%d] = %p: ",i,e); WReqn(e); dbg_printf("\n");
vec_setbit(i,ae);
if (flag)
vec_setbit(i,aeval);
Expand Down
2 changes: 1 addition & 1 deletion src/backend/gflow.c
@@ -1,5 +1,5 @@
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// Copyright (C) 2000-2014 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
Expand Down
2 changes: 1 addition & 1 deletion src/backend/oper.h
Expand Up @@ -215,8 +215,8 @@ enum OPER
OPnullptr, // null pointer
OPasm, /* in-line assembly code */
OPinfo, // attach info (used to attach ctor/dtor
OPhalt, // insert HLT instruction
// info for exception handling)
OPhalt, // insert HLT instruction
OPctor,
OPdtor,
OPmark,
Expand Down
2 changes: 1 addition & 1 deletion src/tocsym.c
Expand Up @@ -650,7 +650,7 @@ Symbol *Module::toModuleArray()

marray = toSymbolX("__array", SCextern, t, "Z");
marray->Sfl = FLextern;
marray->Sflags |= SFLnodebug;
marray->Sflags |= SFLnodebug | SFLexit;
slist_add(marray);
}
return marray;
Expand Down

0 comments on commit 9efe7f7

Please sign in to comment.