Moved IRTargetScopeS from IRState into IrFunction, fixes #240 .

This commit is contained in:
Tomas Lindquist Olsen 2009-03-26 18:46:21 +01:00
parent 91698fd0a5
commit 367b8da8f4
4 changed files with 71 additions and 57 deletions

View file

@ -36,7 +36,6 @@ struct Module;
struct TypeStruct; struct TypeStruct;
struct BaseClass; struct BaseClass;
struct AnonDeclaration; struct AnonDeclaration;
struct EnclosingHandler;
struct IrModule; struct IrModule;
@ -51,23 +50,6 @@ struct IRScope
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e); IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
}; };
// scope statements that can be target of jumps
// includes loops, switch, case, labels
struct IRTargetScope
{
// generating statement
Statement* s;
// the try of a TryFinally that encloses the loop
EnclosingHandler* enclosinghandler;
llvm::BasicBlock* breakTarget;
llvm::BasicBlock* continueTarget;
IRTargetScope();
IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget);
};
struct IRBuilderHelper struct IRBuilderHelper
{ {
IRState* state; IRState* state;
@ -159,10 +141,6 @@ struct IRState
llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name=""); llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name=""); llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name="");
// loop blocks
typedef std::vector<IRTargetScope> TargetScopeVec;
TargetScopeVec targetScopes;
// this holds the array being indexed or sliced so $ will work // this holds the array being indexed or sliced so $ will work
// might be a better way but it works. problem is I only get a // might be a better way but it works. problem is I only get a
// VarDeclaration for __dollar, but I can't see how to get the // VarDeclaration for __dollar, but I can't see how to get the

View file

@ -248,14 +248,16 @@ void DtoEnclosingHandlers(Loc loc, Statement* target)
target = lblstmt->enclosingScopeExit; target = lblstmt->enclosingScopeExit;
// figure out up until what handler we need to emit // figure out up until what handler we need to emit
IRState::TargetScopeVec::reverse_iterator targetit; IrFunction::TargetScopeVec::reverse_iterator targetit = gIR->func()->targetScopes.rbegin();
for (targetit = gIR->targetScopes.rbegin(); targetit != gIR->targetScopes.rend(); ++targetit) { IrFunction::TargetScopeVec::reverse_iterator it_end = gIR->func()->targetScopes.rend();
while(targetit != it_end) {
if (targetit->s == target) { if (targetit->s == target) {
break; break;
} }
++targetit;
} }
if (target && targetit == gIR->targetScopes.rend()) { if (target && targetit == it_end) {
if (lblstmt) if (lblstmt)
error(loc, "cannot goto into try, volatile or synchronized statement at %s", target->loc.toChars()); error(loc, "cannot goto into try, volatile or synchronized statement at %s", target->loc.toChars());
else else
@ -270,10 +272,11 @@ void DtoEnclosingHandlers(Loc loc, Statement* target)
// since the labelstatements possibly inside are private // since the labelstatements possibly inside are private
// and might already exist push a label scope // and might already exist push a label scope
gIR->func()->pushUniqueLabelScope("enclosing"); gIR->func()->pushUniqueLabelScope("enclosing");
IRState::TargetScopeVec::reverse_iterator it; IrFunction::TargetScopeVec::reverse_iterator it = gIR->func()->targetScopes.rbegin();
for (it = gIR->targetScopes.rbegin(); it != targetit; ++it) { while (it != targetit) {
if (it->enclosinghandler) if (it->enclosinghandler)
it->enclosinghandler->emitCode(gIR); it->enclosinghandler->emitCode(gIR);
++it;
} }
gIR->func()->popLabelScope(); gIR->func()->popLabelScope();
} }

View file

@ -296,9 +296,9 @@ void WhileStatement::toIR(IRState* p)
gIR->scope() = IRScope(whilebodybb,endbb); gIR->scope() = IRScope(whilebodybb,endbb);
// while body code // while body code
p->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb));
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// loop // loop
if (!gIR->scopereturned()) if (!gIR->scopereturned())
@ -332,9 +332,9 @@ void DoStatement::toIR(IRState* p)
gIR->scope() = IRScope(dowhilebb,condbb); gIR->scope() = IRScope(dowhilebb,condbb);
// do-while body code // do-while body code
p->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb));
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// branch to condition block // branch to condition block
llvm::BranchInst::Create(condbb, gIR->scopebb()); llvm::BranchInst::Create(condbb, gIR->scopebb());
@ -377,7 +377,7 @@ void ForStatement::toIR(IRState* p)
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
llvm::BranchInst::Create(forbb, gIR->scopebb()); llvm::BranchInst::Create(forbb, gIR->scopebb());
p->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb));
// replace current scope // replace current scope
gIR->scope() = IRScope(forbb,forbodybb); gIR->scope() = IRScope(forbb,forbodybb);
@ -420,7 +420,7 @@ void ForStatement::toIR(IRState* p)
if (!gIR->scopereturned()) if (!gIR->scopereturned())
llvm::BranchInst::Create(forbb, gIR->scopebb()); llvm::BranchInst::Create(forbb, gIR->scopebb());
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// rewrite the scope // rewrite the scope
gIR->scope() = IRScope(endbb,oldend); gIR->scope() = IRScope(endbb,oldend);
@ -454,23 +454,27 @@ void BreakStatement::toIR(IRState* p)
// find the right break block and jump there // find the right break block and jump there
bool found = false; bool found = false;
IRState::TargetScopeVec::reverse_iterator it; IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin();
for(it = p->targetScopes.rbegin(); it != p->targetScopes.rend(); ++it) { IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend();
while(it != it_end) {
if(it->s == targetLoopStatement) { if(it->s == targetLoopStatement) {
llvm::BranchInst::Create(it->breakTarget, p->scopebb()); llvm::BranchInst::Create(it->breakTarget, p->scopebb());
found = true; found = true;
break; break;
} }
++it;
} }
assert(found); assert(found);
} }
else { else {
// find closest scope with a break target // find closest scope with a break target
IRState::TargetScopeVec::reverse_iterator it; IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin();
for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend();
while(it != it_end) {
if(it->breakTarget) { if(it->breakTarget) {
break; break;
} }
++it;
} }
DtoEnclosingHandlers(loc, it->s); DtoEnclosingHandlers(loc, it->s);
llvm::BranchInst::Create(it->breakTarget, gIR->scopebb()); llvm::BranchInst::Create(it->breakTarget, gIR->scopebb());
@ -505,23 +509,27 @@ void ContinueStatement::toIR(IRState* p)
// find the right continue block and jump there // find the right continue block and jump there
bool found = false; bool found = false;
IRState::TargetScopeVec::reverse_iterator it; IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin();
for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend();
while(it != it_end) {
if(it->s == targetLoopStatement) { if(it->s == targetLoopStatement) {
llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); llvm::BranchInst::Create(it->continueTarget, gIR->scopebb());
found = true; found = true;
break; break;
} }
++it;
} }
assert(found); assert(found);
} }
else { else {
// find closest scope with a continue target // find closest scope with a continue target
IRState::TargetScopeVec::reverse_iterator it; IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin();
for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend();
while(it != it_end) {
if(it->continueTarget) { if(it->continueTarget) {
break; break;
} }
++it;
} }
DtoEnclosingHandlers(loc, it->s); DtoEnclosingHandlers(loc, it->s);
llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); llvm::BranchInst::Create(it->continueTarget, gIR->scopebb());
@ -593,9 +601,9 @@ void TryFinallyStatement::toIR(IRState* p)
p->scope() = IRScope(trybb,finallybb); p->scope() = IRScope(trybb,finallybb);
assert(body); assert(body);
p->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL)); p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this),NULL,NULL));
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// terminate try BB // terminate try BB
if (!p->scopereturned()) if (!p->scopereturned())
@ -851,9 +859,9 @@ void SwitchStatement::toIR(IRState* p)
assert(body); assert(body);
p->scope() = IRScope(bodybb, endbb); p->scope() = IRScope(bodybb, endbb);
p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb));
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
if (!p->scopereturned()) if (!p->scopereturned())
llvm::BranchInst::Create(endbb, p->scopebb()); llvm::BranchInst::Create(endbb, p->scopebb());
@ -972,13 +980,13 @@ void UnrolledLoopStatement::toIR(IRState* p)
// push loop scope // push loop scope
// continue goes to next statement, break goes to end // continue goes to next statement, break goes to end
p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
// do statement // do statement
s->toIR(p); s->toIR(p);
// pop loop scope // pop loop scope
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// next stmt // next stmt
if (!p->scopereturned()) if (!p->scopereturned())
@ -1095,10 +1103,10 @@ void ForeachStatement::toIR(IRState* p)
} }
// emit body // emit body
p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
if(body) if(body)
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
if (!p->scopereturned()) if (!p->scopereturned())
llvm::BranchInst::Create(nextbb, p->scopebb()); llvm::BranchInst::Create(nextbb, p->scopebb());
@ -1191,10 +1199,10 @@ void ForeachRangeStatement::toIR(IRState* p)
} }
// emit body // emit body
p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb));
if (body) if (body)
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// jump to next iteration // jump to next iteration
if (!p->scopereturned()) if (!p->scopereturned())
@ -1261,9 +1269,9 @@ void LabelStatement::toIR(IRState* p)
} }
if (statement) { if (statement) {
p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL));
statement->toIR(p); statement->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
} }
} }
@ -1385,9 +1393,9 @@ void SynchronizedStatement::toIR(IRState* p)
} }
// emit body // emit body
p->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL)); p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL));
body->toIR(p); body->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// exit lock // exit lock
// no point in a unreachable unlock, terminating statements must insert this themselves. // no point in a unreachable unlock, terminating statements must insert this themselves.
@ -1419,9 +1427,9 @@ void VolatileStatement::toIR(IRState* p)
DtoMemoryBarrier(false, true, false, false); DtoMemoryBarrier(false, true, false, false);
// do statement // do statement
p->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL)); p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL));
statement->toIR(p); statement->toIR(p);
p->targetScopes.pop_back(); p->func()->targetScopes.pop_back();
// no point in a unreachable barrier, terminating statements must insert this themselves. // no point in a unreachable barrier, terminating statements must insert this themselves.
if (statement->blockExit() & BEfallthru) if (statement->blockExit() & BEfallthru)

View file

@ -9,6 +9,26 @@
#include <stack> #include <stack>
#include <map> #include <map>
struct Statement;
struct EnclosingHandler;
// scope statements that can be target of jumps
// includes loops, switch, case, labels
struct IRTargetScope
{
// generating statement
Statement* s;
// the try of a TryFinally that encloses the loop
EnclosingHandler* enclosinghandler;
llvm::BasicBlock* breakTarget;
llvm::BasicBlock* continueTarget;
IRTargetScope();
IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget);
};
// represents a function // represents a function
struct IrFunction : IrBase struct IrFunction : IrBase
{ {
@ -48,6 +68,11 @@ struct IrFunction : IrBase
// landing pads for try statements // landing pads for try statements
IRLandingPad landingPad; IRLandingPad landingPad;
// loop blocks
typedef std::vector<IRTargetScope> TargetScopeVec;
TargetScopeVec targetScopes;
// constructor
IrFunction(FuncDeclaration* fd); IrFunction(FuncDeclaration* fd);
// annotations // annotations