# HG changeset patch # User Christian Kamm # Date 1245517924 -7200 # Node ID e07f15c4ab4d7af8a57b32910e71806e5d6c7620 # Parent f86fd3b7728580b80eae42aa37faef9688c5ca5f# Parent e1e93343fc1182102162e96e0fa404552b76b40c Automated merge with http://hg.dsource.org/projects/ldc diff -r f86fd3b77285 -r e07f15c4ab4d gen/functions.cpp --- a/gen/functions.cpp Sat Jun 20 14:28:59 2009 +0200 +++ b/gen/functions.cpp Sat Jun 20 19:12:04 2009 +0200 @@ -774,7 +774,10 @@ } // output function body + irfunction->gen = new FuncGen; fd->fbody->toIR(gIR); + delete irfunction->gen; + irfunction->gen = 0; // TODO: clean up this mess diff -r f86fd3b77285 -r e07f15c4ab4d gen/irstate.h --- a/gen/irstate.h Sat Jun 20 14:28:59 2009 +0200 +++ b/gen/irstate.h Sat Jun 20 19:12:04 2009 +0200 @@ -182,7 +182,7 @@ template llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name) { - llvm::BasicBlock* pad = func()->landingPad; + llvm::BasicBlock* pad = func()->gen->landingPad; if(pad) { // intrinsics don't support invoking and 'nounwind' functions don't need it. diff -r f86fd3b77285 -r e07f15c4ab4d gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Sat Jun 20 14:28:59 2009 +0200 +++ b/gen/llvmhelpers.cpp Sat Jun 20 19:12:04 2009 +0200 @@ -211,8 +211,8 @@ } // find target basic block - std::string labelname = gIR->func()->getScopedLabelName(target->toChars()); - llvm::BasicBlock*& targetBB = gIR->func()->labelToBB[labelname]; + std::string labelname = gIR->func()->gen->getScopedLabelName(target->toChars()); + llvm::BasicBlock*& targetBB = gIR->func()->gen->labelToBB[labelname]; if (targetBB == NULL) targetBB = llvm::BasicBlock::Create("label_" + labelname, gIR->topfunc()); @@ -256,10 +256,10 @@ { if (tf->finalbody) { - llvm::BasicBlock* oldpad = p->func()->landingPad; - p->func()->landingPad = landingPad; + llvm::BasicBlock* oldpad = p->func()->gen->landingPad; + p->func()->gen->landingPad = landingPad; tf->finalbody->toIR(p); - p->func()->landingPad = oldpad; + p->func()->gen->landingPad = oldpad; } } @@ -274,8 +274,8 @@ target = lblstmt->enclosingScopeExit; // figure out up until what handler we need to emit - IrFunction::TargetScopeVec::reverse_iterator targetit = gIR->func()->targetScopes.rbegin(); - IrFunction::TargetScopeVec::reverse_iterator it_end = gIR->func()->targetScopes.rend(); + FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin(); + FuncGen::TargetScopeVec::reverse_iterator it_end = gIR->func()->gen->targetScopes.rend(); while(targetit != it_end) { if (targetit->s == target) { break; @@ -297,14 +297,14 @@ // since the labelstatements possibly inside are private // and might already exist push a label scope - gIR->func()->pushUniqueLabelScope("enclosing"); - IrFunction::TargetScopeVec::reverse_iterator it = gIR->func()->targetScopes.rbegin(); + gIR->func()->gen->pushUniqueLabelScope("enclosing"); + FuncGen::TargetScopeVec::reverse_iterator it = gIR->func()->gen->targetScopes.rbegin(); while (it != targetit) { if (it->enclosinghandler) it->enclosinghandler->emitCode(gIR); ++it; } - gIR->func()->popLabelScope(); + gIR->func()->gen->popLabelScope(); } /****************************************************************************************/ diff -r f86fd3b77285 -r e07f15c4ab4d gen/statements.cpp --- a/gen/statements.cpp Sat Jun 20 14:28:59 2009 +0200 +++ b/gen/statements.cpp Sat Jun 20 19:12:04 2009 +0200 @@ -296,9 +296,9 @@ gIR->scope() = IRScope(whilebodybb,endbb); // while body code - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,whilebb,endbb)); body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // loop if (!gIR->scopereturned()) @@ -332,9 +332,9 @@ gIR->scope() = IRScope(dowhilebb,condbb); // do-while body code - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,condbb,endbb)); body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // branch to condition block llvm::BranchInst::Create(condbb, gIR->scopebb()); @@ -377,7 +377,7 @@ assert(!gIR->scopereturned()); llvm::BranchInst::Create(forbb, gIR->scopebb()); - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,forincbb,endbb)); // replace current scope gIR->scope() = IRScope(forbb,forbodybb); @@ -420,7 +420,7 @@ if (!gIR->scopereturned()) llvm::BranchInst::Create(forbb, gIR->scopebb()); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // rewrite the scope gIR->scope() = IRScope(endbb,oldend); @@ -454,8 +454,8 @@ // find the right break block and jump there bool found = false; - IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); - IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + FuncGen::TargetScopeVec::reverse_iterator it = p->func()->gen->targetScopes.rbegin(); + FuncGen::TargetScopeVec::reverse_iterator it_end = p->func()->gen->targetScopes.rend(); while(it != it_end) { if(it->s == targetLoopStatement) { llvm::BranchInst::Create(it->breakTarget, p->scopebb()); @@ -468,8 +468,8 @@ } else { // find closest scope with a break target - IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); - IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + FuncGen::TargetScopeVec::reverse_iterator it = p->func()->gen->targetScopes.rbegin(); + FuncGen::TargetScopeVec::reverse_iterator it_end = p->func()->gen->targetScopes.rend(); while(it != it_end) { if(it->breakTarget) { break; @@ -509,8 +509,8 @@ // find the right continue block and jump there bool found = false; - IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); - IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + FuncGen::TargetScopeVec::reverse_iterator it = p->func()->gen->targetScopes.rbegin(); + FuncGen::TargetScopeVec::reverse_iterator it_end = p->func()->gen->targetScopes.rend(); while(it != it_end) { if(it->s == targetLoopStatement) { llvm::BranchInst::Create(it->continueTarget, gIR->scopebb()); @@ -523,8 +523,8 @@ } else { // find closest scope with a continue target - IrFunction::TargetScopeVec::reverse_iterator it = p->func()->targetScopes.rbegin(); - IrFunction::TargetScopeVec::reverse_iterator it_end = p->func()->targetScopes.rend(); + FuncGen::TargetScopeVec::reverse_iterator it = p->func()->gen->targetScopes.rbegin(); + FuncGen::TargetScopeVec::reverse_iterator it_end = p->func()->gen->targetScopes.rend(); while(it != it_end) { if(it->continueTarget) { break; @@ -592,10 +592,11 @@ p->scope() = IRScope(landingpadbb, endbb); assert(finalbody); - gIR->func()->landingPadInfo.addFinally(finalbody); - gIR->func()->landingPadInfo.push(landingpadbb); - gIR->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this,gIR->func()->landingPad),NULL,NULL)); - gIR->func()->landingPad = gIR->func()->landingPadInfo.get(); + IRLandingPad& pad = gIR->func()->gen->landingPadInfo; + pad.addFinally(finalbody); + pad.push(landingpadbb); + gIR->func()->gen->targetScopes.push_back(IRTargetScope(this,new EnclosingTryFinally(this,gIR->func()->gen->landingPad),NULL,NULL)); + gIR->func()->gen->landingPad = pad.get(); // // do the try block @@ -609,9 +610,9 @@ if (!p->scopereturned()) llvm::BranchInst::Create(finallybb, p->scopebb()); - gIR->func()->landingPadInfo.pop(); - gIR->func()->landingPad = gIR->func()->landingPadInfo.get(); - gIR->func()->targetScopes.pop_back(); + pad.pop(); + gIR->func()->gen->landingPad = pad.get(); + gIR->func()->gen->targetScopes.pop_back(); // // do finally block @@ -657,14 +658,15 @@ assert(catches); gIR->scope() = IRScope(landingpadbb, endbb); + IRLandingPad& pad = gIR->func()->gen->landingPadInfo; for (int i = 0; i < catches->dim; i++) { Catch *c = (Catch *)catches->data[i]; - gIR->func()->landingPadInfo.addCatch(c, endbb); + pad.addCatch(c, endbb); } - gIR->func()->landingPadInfo.push(landingpadbb); - gIR->func()->landingPad = gIR->func()->landingPadInfo.get(); + pad.push(landingpadbb); + gIR->func()->gen->landingPad = pad.get(); // // do the try block @@ -677,8 +679,8 @@ if (!gIR->scopereturned()) llvm::BranchInst::Create(endbb, p->scopebb()); - gIR->func()->landingPadInfo.pop(); - gIR->func()->landingPad = gIR->func()->landingPadInfo.get(); + pad.pop(); + gIR->func()->gen->landingPad = pad.get(); // rewrite the scope p->scope() = IRScope(endbb,oldend); @@ -863,9 +865,9 @@ assert(body); p->scope() = IRScope(bodybb, endbb); - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,NULL,endbb)); body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); if (!p->scopereturned()) llvm::BranchInst::Create(endbb, p->scopebb()); @@ -984,13 +986,13 @@ // push loop scope // continue goes to next statement, break goes to end - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); // do statement s->toIR(p); // pop loop scope - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // next stmt if (!p->scopereturned()) @@ -1112,10 +1114,10 @@ } // emit body - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); if(body) body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); if (!p->scopereturned()) llvm::BranchInst::Create(nextbb, p->scopebb()); @@ -1208,10 +1210,10 @@ } // emit body - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,nextbb,endbb)); if (body) body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // jump to next iteration if (!p->scopereturned()) @@ -1261,8 +1263,8 @@ } else { - std::string labelname = p->func()->getScopedLabelName(ident->toChars()); - llvm::BasicBlock*& labelBB = p->func()->labelToBB[labelname]; + std::string labelname = p->func()->gen->getScopedLabelName(ident->toChars()); + llvm::BasicBlock*& labelBB = p->func()->gen->labelToBB[labelname]; llvm::BasicBlock* oldend = gIR->scopeend(); if (labelBB != NULL) { @@ -1278,9 +1280,9 @@ } if (statement) { - p->func()->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,NULL,NULL,NULL)); statement->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); } } @@ -1402,9 +1404,9 @@ } // emit body - p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,new EnclosingSynchro(this),NULL,NULL)); body->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // exit lock // no point in a unreachable unlock, terminating statements must insert this themselves. @@ -1436,9 +1438,9 @@ DtoMemoryBarrier(false, true, false, false); // do statement - p->func()->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL)); + p->func()->gen->targetScopes.push_back(IRTargetScope(this,new EnclosingVolatile(this),NULL,NULL)); statement->toIR(p); - p->func()->targetScopes.pop_back(); + p->func()->gen->targetScopes.pop_back(); // no point in a unreachable barrier, terminating statements must insert this themselves. if (statement->blockExit() & BEfallthru) diff -r f86fd3b77285 -r e07f15c4ab4d ir/irfunction.cpp --- a/ir/irfunction.cpp Sat Jun 20 14:28:59 2009 +0200 +++ b/ir/irfunction.cpp Sat Jun 20 19:12:04 2009 +0200 @@ -93,6 +93,37 @@ ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// +FuncGen::FuncGen() +{ + landingPad = NULL; + nextUnique.push(0); +} + +std::string FuncGen::getScopedLabelName(const char* ident) +{ + if(labelScopes.empty()) + return std::string(ident); + + std::string result = "__"; + for(unsigned int i = 0; i < labelScopes.size(); ++i) + result += labelScopes[i] + "_"; + return result + ident; +} + +void FuncGen::pushUniqueLabelScope(const char* name) +{ + std::ostringstream uniquename; + uniquename << name << nextUnique.top()++; + nextUnique.push(0); + labelScopes.push_back(uniquename.str()); +} + +void FuncGen::popLabelScope() +{ + labelScopes.pop_back(); + nextUnique.pop(); +} + IrFunction::IrFunction(FuncDeclaration* fd) { decl = fd; @@ -116,35 +147,6 @@ _arguments = NULL; _argptr = NULL; - - landingPad = NULL; - - nextUnique.push(0); -} - -std::string IrFunction::getScopedLabelName(const char* ident) -{ - if(labelScopes.empty()) - return std::string(ident); - - std::string result = "__"; - for(unsigned int i = 0; i < labelScopes.size(); ++i) - result += labelScopes[i] + "_"; - return result + ident; -} - -void IrFunction::pushUniqueLabelScope(const char* name) -{ - std::ostringstream uniquename; - uniquename << name << nextUnique.top()++; - nextUnique.push(0); - labelScopes.push_back(uniquename.str()); -} - -void IrFunction::popLabelScope() -{ - labelScopes.pop_back(); - nextUnique.pop(); } void IrFunction::setNeverInline() diff -r f86fd3b77285 -r e07f15c4ab4d ir/irfunction.h --- a/ir/irfunction.h Sat Jun 20 14:28:59 2009 +0200 +++ b/ir/irfunction.h Sat Jun 20 19:12:04 2009 +0200 @@ -29,14 +29,58 @@ IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget); }; +struct FuncGen +{ + FuncGen(); + + // pushes a unique label scope of the given name + void pushUniqueLabelScope(const char* name); + // pops a label scope + void popLabelScope(); + + // gets the string under which the label's BB + // is stored in the labelToBB map. + // essentially prefixes ident by the strings in labelScopes + std::string getScopedLabelName(const char* ident); + + // label to basic block lookup + typedef std::map LabelToBBMap; + LabelToBBMap labelToBB; + + // loop blocks + typedef std::vector TargetScopeVec; + TargetScopeVec targetScopes; + + // landing pads for try statements + IRLandingPad landingPadInfo; + llvm::BasicBlock* landingPad; + +private: + // prefix for labels and gotos + // used for allowing labels to be emitted twice + std::vector labelScopes; + + // next unique id stack + std::stack nextUnique; +}; + // represents a function struct IrFunction : IrBase { + // constructor + IrFunction(FuncDeclaration* fd); + + // annotations + void setNeverInline(); + void setAlwaysInline(); + llvm::Function* func; llvm::Instruction* allocapoint; FuncDeclaration* decl; TypeFunction* type; + FuncGen* gen; + bool queued; bool defined; @@ -54,43 +98,6 @@ llvm::Value* _argptr; llvm::DISubprogram diSubprogram; - - // pushes a unique label scope of the given name - void pushUniqueLabelScope(const char* name); - // pops a label scope - void popLabelScope(); - - // gets the string under which the label's BB - // is stored in the labelToBB map. - // essentially prefixes ident by the strings in labelScopes - std::string getScopedLabelName(const char* ident); - - // label to basic block lookup - typedef std::map LabelToBBMap; - LabelToBBMap labelToBB; - - // landing pads for try statements - IRLandingPad landingPadInfo; - llvm::BasicBlock* landingPad; - - // loop blocks - typedef std::vector TargetScopeVec; - TargetScopeVec targetScopes; - - // constructor - IrFunction(FuncDeclaration* fd); - - // annotations - void setNeverInline(); - void setAlwaysInline(); - -private: - // prefix for labels and gotos - // used for allowing labels to be emitted twice - std::vector labelScopes; - - // next unique id stack - std::stack nextUnique; }; #endif diff -r f86fd3b77285 -r e07f15c4ab4d ir/irlandingpad.cpp --- a/ir/irlandingpad.cpp Sat Jun 20 14:28:59 2009 +0200 +++ b/ir/irlandingpad.cpp Sat Jun 20 19:12:04 2009 +0200 @@ -24,7 +24,7 @@ #endif assert(!catchstmt->var->ir.irLocal); catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var); - LLValue* catch_var = gIR->func()->landingPadInfo.getExceptionStorage(); + LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage(); catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type))); } @@ -32,8 +32,8 @@ DtoDeclarationExp(catchstmt->var); // the exception will only be stored in catch_var. copy it over if necessary - if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPadInfo.getExceptionStorage()) { - LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type)); + if(catchstmt->var->ir.irLocal->value != gIR->func()->gen->landingPadInfo.getExceptionStorage()) { + LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type)); DtoStore(exc, catchstmt->var->ir.irLocal->value); } } @@ -172,9 +172,9 @@ // since this may be emitted multiple times // give the labels a new scope - gIR->func()->pushUniqueLabelScope("finally"); + gIR->func()->gen->pushUniqueLabelScope("finally"); rit->finallyBody->toIR(gIR); - gIR->func()->popLabelScope(); + gIR->func()->gen->popLabelScope(); } // otherwise it's a catch and we'll add a switch case else