Skip to content

Commit

Permalink
Merge pull request #5080 from WalterBright/Alloca
Browse files Browse the repository at this point in the history
refactor: use LocalSection for alloca data
  • Loading branch information
yebblies committed Sep 15, 2015
2 parents f79e353 + 2ec35c3 commit d90837d
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 41 deletions.
27 changes: 13 additions & 14 deletions src/backend/cgcod.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ targ_size_t pushoff; // offset of saved registers
bool pushoffuse; // using pushoff
int BPoff; // offset from BP
int EBPtoESP; // add to EBP offset to get ESP offset
targ_size_t AllocaOff; // offset of alloca temporary
LocalSection Para; // section of function parameters
LocalSection Auto; // section of automatics and registers
LocalSection Fast; // section of fastpar
LocalSection EEStack; // offset of SCstack variables from ESP
LocalSection Alloca; // data for alloca() temporary

REGSAVE regsave;

Expand All @@ -81,7 +81,6 @@ bool anyiasm; // !=0 if any inline assembler
char calledafunc; // !=0 if we called a function
char needframe; // if TRUE, then we will need the frame
// pointer (BP for the 8088)
char usedalloca; // if TRUE, then alloca() was called
char gotref; // !=0 if the GOTsym was referenced
unsigned usednteh; // if !=0, then used NT exception handling

Expand Down Expand Up @@ -159,7 +158,6 @@ void codgen()

// if no parameters, assume we don't need a stack frame
needframe = 0;
usedalloca = 0;
gotref = 0;
stackchanged = 0;
stackpush = 0;
Expand All @@ -169,6 +167,7 @@ void codgen()
cgstate.stackclean = 1;
retsym = NULL;

Alloca.init();
regsave.reset();
#if TX86
memset(_8087elems,0,sizeof(_8087elems));
Expand Down Expand Up @@ -686,7 +685,7 @@ code *prolog()
* Auto.size autos and regs
* regsave.off any saved registers
* Foff floating register
* AllocaOff alloca temporary
* Alloca.size alloca temporary
* CSoff common subs
* NDPoff any 8087 saved registers
* monitor context record
Expand Down Expand Up @@ -763,10 +762,10 @@ code *prolog()
else
Foff = regsave.off;

assert(usedalloca != 1);
AllocaOff = alignsection(usedalloca ? (Foff - REGSIZE) : Foff, REGSIZE, bias);
Alloca.alignment = REGSIZE;
Alloca.offset = alignsection(Foff - Alloca.size, Alloca.alignment, bias);

CSoff = alignsection(AllocaOff - cstop * REGSIZE, REGSIZE, bias);
CSoff = alignsection(Alloca.offset - cstop * REGSIZE, REGSIZE, bias);

#if TX86
NDPoff = alignsection(CSoff - NDP::savetop * NDPSAVESIZE, REGSIZE, bias);
Expand Down Expand Up @@ -796,8 +795,8 @@ code *prolog()

localsize = -pushoff;

//printf("AllocaOff = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
//(long long)AllocaOff, (long long)cstop, (long long)CSoff, (long long)NDPoff, (long long)localsize);
//printf("Alloca.offset = x%llx, cstop = x%llx, CSoff = x%llx, NDPoff = x%llx, localsize = x%llx\n",
//(long long)Alloca.offset, (long long)cstop, (long long)CSoff, (long long)NDPoff, (long long)localsize);
assert((targ_ptrdiff_t)localsize >= 0);

// Keep the stack aligned by 8 for any subsequent function calls
Expand Down Expand Up @@ -855,7 +854,7 @@ code *prolog()
xlocalsize >= 0x1000 ||
(usednteh & ~NTEHjmonitor) ||
anyiasm ||
usedalloca
Alloca.size
)
needframe = 1;
}
Expand Down Expand Up @@ -889,19 +888,19 @@ code *prolog()
if (config.flags & CFGstack) // if stack overflow check
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else if (needframe) /* if variables or parameters */
{
if (xlocalsize) /* if any stack offset */
{
cstackadj = prolog_frameadj(tyf, xlocalsize, enter, &pushalloc);
if (usedalloca)
if (Alloca.size)
cstackadj = cat(cstackadj, prolog_setupalloca());
}
else
assert(usedalloca == 0);
assert(Alloca.size == 0);
}
else if (xlocalsize)
{
Expand All @@ -910,7 +909,7 @@ code *prolog()
BPoff += REGSIZE;
}
else
assert((localsize | usedalloca) == 0 || (usednteh & NTEHjmonitor));
assert((localsize | Alloca.size) == 0 || (usednteh & NTEHjmonitor));
EBPtoESP += xlocalsize;
c = cat(c, cstackadj);
}
Expand Down
6 changes: 1 addition & 5 deletions src/backend/cod1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3216,7 +3216,6 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre
c1 = getregs(~s->Sregsaved & (mBP | ALLREGS | mES | XMMREGS));
if (strcmp(s->Sident,"alloca") == 0)
{
#if 1
s = getRtlsym(RTLSYM_ALLOCA);
makeitextern(s);
int areg = CX;
Expand All @@ -3226,10 +3225,7 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre
c1 = genc(c1,0x8D,modregrm(2,areg,BPRM),FLallocatmp,0,0,0); // LEA areg,&localsize[BP]
if (I64)
code_orrex(c1, REX_W);
usedalloca = 2; // new way
#else
usedalloca = 1; // old way
#endif
Alloca.size = REGSIZE;
}
if (sytab[s->Sclass] & SCSS) // if function is on stack (!)
{
Expand Down
21 changes: 7 additions & 14 deletions src/backend/cod3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,7 @@ regm_t cod3_useBP()
config.flags & CFGstack ||
localsize >= 0x100 || // arbitrary value < 0x1000
(usednteh & ~NTEHjmonitor) ||
usedalloca
Alloca.size
)
goto Lcant;
}
Expand Down Expand Up @@ -2874,13 +2874,6 @@ code* prolog_ifunc2(tym_t tyf, tym_t tym, bool pushds)

code* prolog_16bit_windows_farfunc(tym_t* tyf, bool* pushds)
{
#if SCPP
// alloca() can't be because the 'special' parameter won't be at
// a known offset from BP.
if (usedalloca == 1)
synerr(EM_alloca_win); // alloca() can't be in Windows functions
#endif

int wflags = config.wflags;
if (wflags & WFreduced && !(*tyf & mTYexport))
{ // reduced prolog/epilog for non-exported functions
Expand Down Expand Up @@ -3104,7 +3097,7 @@ code* prolog_setupalloca()
// Set up magic parameter for alloca()
// MOV -REGSIZE[BP],localsize - BPoff
code* c = genc(NULL,0xC7,modregrm(2,0,BPRM),
FLconst,AllocaOff + BPoff,
FLconst,Alloca.offset + BPoff,
FLconst,localsize - BPoff);
if (I64)
code_orrex(c, REX_W);
Expand Down Expand Up @@ -3857,7 +3850,7 @@ void epilog(block *b)
goto L4;
}

if (localsize | usedalloca)
if (localsize)
{
c = genc1(c,LEA,modregrm(1,SP,6),FLconst,(targ_uns)-2); /* LEA SP,-2[BP] */
}
Expand All @@ -3877,7 +3870,7 @@ void epilog(block *b)
{
L4:
assert(hasframe);
if (xlocalsize | usedalloca)
if (xlocalsize)
{
if (config.flags2 & CFG2stomp)
{ /* MOV ECX,0xBEAF
Expand Down Expand Up @@ -3919,7 +3912,7 @@ void epilog(block *b)
!(config.target_cpu >= TARGET_80386 && config.flags4 & CFG4speed)
)
c = gen1(c,0xC9); // LEAVE
else if (0 && xlocalsize == REGSIZE && !usedalloca && I32)
else if (0 && xlocalsize == REGSIZE && Alloca.size == 0 && I32)
{ // This doesn't work - I should figure out why
mfuncreg &= ~mask[regx];
c = gen1(c,0x58 + regx); // POP regx
Expand Down Expand Up @@ -4758,7 +4751,7 @@ void assignaddrc(code *c)
c->Iflags |= CFunambig;
goto L2;
case FLallocatmp:
c->IEVpointer1 += AllocaOff + BPoff;
c->IEVpointer1 += Alloca.offset + BPoff;
goto L2;
case FLbprel:
c->IEVpointer1 += s->Soffset;
Expand Down Expand Up @@ -4865,7 +4858,7 @@ void assignaddrc(code *c)
c->IEVpointer2 += Foff + BPoff;
break;
case FLallocatmp:
c->IEVpointer2 += AllocaOff + BPoff;
c->IEVpointer2 += Alloca.offset + BPoff;
break;
case FLbprel:
c->IEVpointer2 += s->Soffset;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/cod5.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void cod5_prol_epi()

if (!(config.flags4 & CFG4optimized) ||
anyiasm ||
usedalloca ||
Alloca.size ||
usednteh ||
tyf & (mTYnaked | mTYloadds) ||
tym == TYifunc ||
Expand Down
4 changes: 2 additions & 2 deletions src/backend/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ extern regm_t FLOATREGS;
extern regm_t FLOATREGS2;
extern regm_t DOUBLEREGS;
extern const char datafl[],stackfl[],segfl[],flinsymtab[];
extern char needframe,usedalloca,gotref;
extern char needframe,gotref;
extern targ_size_t localsize,
funcoffset,
framehandleroffset;
Expand All @@ -199,6 +199,7 @@ extern LocalSection Para;
extern LocalSection Fast;
extern LocalSection Auto;
extern LocalSection EEStack;
extern LocalSection Alloca;
#if TARGET_OSX
extern targ_size_t localgotoffset;
#endif
Expand Down Expand Up @@ -397,7 +398,6 @@ extern targ_size_t pushoff; // offset of saved registers
extern bool pushoffuse; // using pushoff
extern int BPoff; // offset from BP
extern int EBPtoESP; // add to EBP offset to get ESP offset
extern targ_size_t AllocaOff; // offset of alloca temporary

code* prolog_ifunc(tym_t* tyf);
code* prolog_ifunc2(tym_t tyf, tym_t tym, bool pushds);
Expand Down
8 changes: 4 additions & 4 deletions src/backend/nteh.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ unsigned nteh_contextsym_size()
#else
assert(0);
#endif
assert(usedalloca != 1);
}
else if (usednteh & NTEHcpp)
{ sz = 5 * 4; // C++ context record
assert(usedalloca != 1);
{
sz = 5 * 4; // C++ context record
}
else if (usednteh & NTEHpassthru)
{ sz = 1 * 4;
{
sz = 1 * 4;
}
else
sz = 0; // no context record
Expand Down
2 changes: 1 addition & 1 deletion src/eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ symbol *except_gentables()
{
// BUG: alloca() changes the stack size, which is not reflected
// in the fixed eh tables.
if (usedalloca)
if (Alloca.size)
error(NULL, 0, 0, "cannot mix core.std.stdlib.alloca() and exception handling in %s()", funcsym_p->Sident);

char name[13+5+1];
Expand Down

0 comments on commit d90837d

Please sign in to comment.