From 367b8da8f4004133b00ebb6e2442e1845e49bbd7 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Thu, 26 Mar 2009 18:46:21 +0100 Subject: [PATCH] Moved IRTargetScopeS from IRState into IrFunction, fixes #240 . --- gen/irstate.h | 22 --------------- gen/llvmhelpers.cpp | 13 +++++---- gen/statements.cpp | 68 +++++++++++++++++++++++++-------------------- ir/irfunction.h | 25 +++++++++++++++++ 4 files changed, 71 insertions(+), 57 deletions(-) diff --git a/gen/irstate.h b/gen/irstate.h index ce3e4048..12e64942 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -36,7 +36,6 @@ struct Module; struct TypeStruct; struct BaseClass; struct AnonDeclaration; -struct EnclosingHandler; struct IrModule; @@ -51,23 +50,6 @@ struct IRScope 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 { IRState* state; @@ -159,10 +141,6 @@ struct IRState 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=""); - // loop blocks - typedef std::vector TargetScopeVec; - TargetScopeVec targetScopes; - // 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 // VarDeclaration for __dollar, but I can't see how to get the diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 8195f56d..a6b2463b 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -248,14 +248,16 @@ void DtoEnclosingHandlers(Loc loc, Statement* target) target = lblstmt->enclosingScopeExit; // figure out up until what handler we need to emit - IRState::TargetScopeVec::reverse_iterator targetit; - for (targetit = gIR->targetScopes.rbegin(); targetit != gIR->targetScopes.rend(); ++targetit) { + IrFunction::TargetScopeVec::reverse_iterator targetit = gIR->func()->targetScopes.rbegin(); + IrFunction::TargetScopeVec::reverse_iterator it_end = gIR->func()->targetScopes.rend(); + while(targetit != it_end) { if (targetit->s == target) { break; } + ++targetit; } - if (target && targetit == gIR->targetScopes.rend()) { + if (target && targetit == it_end) { if (lblstmt) error(loc, "cannot goto into try, volatile or synchronized statement at %s", target->loc.toChars()); else @@ -270,10 +272,11 @@ void DtoEnclosingHandlers(Loc loc, Statement* target) // since the labelstatements possibly inside are private // and might already exist push a label scope gIR->func()->pushUniqueLabelScope("enclosing"); - IRState::TargetScopeVec::reverse_iterator it; - for (it = gIR->targetScopes.rbegin(); it != targetit; ++it) { + IrFunction::TargetScopeVec::reverse_iterator it = gIR->func()->targetScopes.rbegin(); + while (it != targetit) { if (it->enclosinghandler) it->enclosinghandler->emitCode(gIR); + ++it; } gIR->func()->popLabelScope(); } diff --git a/gen/statements.cpp b/gen/statements.cpp index 95ad4e7e..b9fc55e4 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -296,9 +296,9 @@ void WhileStatement::toIR(IRState* p) gIR->scope() = IRScope(whilebodybb,endbb); // 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // loop if (!gIR->scopereturned()) @@ -332,9 +332,9 @@ void DoStatement::toIR(IRState* p) gIR->scope() = IRScope(dowhilebb,condbb); // 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // branch to condition block llvm::BranchInst::Create(condbb, gIR->scopebb()); @@ -377,7 +377,7 @@ void ForStatement::toIR(IRState* p) assert(!gIR->scopereturned()); 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 gIR->scope() = IRScope(forbb,forbodybb); @@ -420,7 +420,7 @@ void ForStatement::toIR(IRState* p) if (!gIR->scopereturned()) llvm::BranchInst::Create(forbb, gIR->scopebb()); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // rewrite the scope gIR->scope() = IRScope(endbb,oldend); @@ -454,23 +454,27 @@ void BreakStatement::toIR(IRState* p) // find the right break block and jump there bool found = false; - IRState::TargetScopeVec::reverse_iterator it; - for(it = p->targetScopes.rbegin(); it != p->targetScopes.rend(); ++it) { + IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); + IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + while(it != it_end) { if(it->s == targetLoopStatement) { llvm::BranchInst::Create(it->breakTarget, p->scopebb()); found = true; break; } + ++it; } assert(found); } else { // find closest scope with a break target - IRState::TargetScopeVec::reverse_iterator it; - for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { + IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); + IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + while(it != it_end) { if(it->breakTarget) { break; } + ++it; } DtoEnclosingHandlers(loc, it->s); llvm::BranchInst::Create(it->breakTarget, gIR->scopebb()); @@ -505,23 +509,27 @@ void ContinueStatement::toIR(IRState* p) // find the right continue block and jump there bool found = false; - IRState::TargetScopeVec::reverse_iterator it; - for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { + IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); + IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + while(it != it_end) { if(it->s == targetLoopStatement) { llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); found = true; break; } + ++it; } assert(found); } else { // find closest scope with a continue target - IRState::TargetScopeVec::reverse_iterator it; - for(it = gIR->targetScopes.rbegin(); it != gIR->targetScopes.rend(); ++it) { + IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); + IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + while(it != it_end) { if(it->continueTarget) { break; } + ++it; } DtoEnclosingHandlers(loc, it->s); llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); @@ -593,9 +601,9 @@ void TryFinallyStatement::toIR(IRState* p) p->scope() = IRScope(trybb,finallybb); 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // terminate try BB if (!p->scopereturned()) @@ -851,9 +859,9 @@ void SwitchStatement::toIR(IRState* p) assert(body); 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); if (!p->scopereturned()) llvm::BranchInst::Create(endbb, p->scopebb()); @@ -972,13 +980,13 @@ void UnrolledLoopStatement::toIR(IRState* p) // push loop scope // 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 s->toIR(p); // pop loop scope - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // next stmt if (!p->scopereturned()) @@ -1095,10 +1103,10 @@ void ForeachStatement::toIR(IRState* p) } // emit body - p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); + p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); if(body) body->toIR(p); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); if (!p->scopereturned()) llvm::BranchInst::Create(nextbb, p->scopebb()); @@ -1191,10 +1199,10 @@ void ForeachRangeStatement::toIR(IRState* p) } // emit body - p->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); + p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); if (body) body->toIR(p); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // jump to next iteration if (!p->scopereturned()) @@ -1261,9 +1269,9 @@ void LabelStatement::toIR(IRState* p) } if (statement) { - p->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); + p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); statement->toIR(p); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); } } @@ -1385,9 +1393,9 @@ void SynchronizedStatement::toIR(IRState* p) } // 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // exit lock // 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); // 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); - p->targetScopes.pop_back(); + p->func()->targetScopes.pop_back(); // no point in a unreachable barrier, terminating statements must insert this themselves. if (statement->blockExit() & BEfallthru) diff --git a/ir/irfunction.h b/ir/irfunction.h index bb7543d4..84ebf1a6 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -9,6 +9,26 @@ #include #include +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 struct IrFunction : IrBase { @@ -48,6 +68,11 @@ struct IrFunction : IrBase // landing pads for try statements IRLandingPad landingPad; + // loop blocks + typedef std::vector TargetScopeVec; + TargetScopeVec targetScopes; + + // constructor IrFunction(FuncDeclaration* fd); // annotations