mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Moved IRTargetScopeS from IRState into IrFunction, fixes #240 .
This commit is contained in:
parent
91698fd0a5
commit
367b8da8f4
4 changed files with 71 additions and 57 deletions
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue