From 42b3da8ac7d211cbca8a1d9bd18063c9405b2fa8 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sat, 20 Jun 2009 19:11:44 +0200 Subject: [PATCH] Move function codegen data from IrFunction to new FuncGen. This change reduces memory consumption significantly by releasing the memory held by the STL containers that are now inside FuncGen. --- gen/functions.cpp | 3 ++ gen/irstate.h | 2 +- gen/llvmhelpers.cpp | 20 +++++------ gen/statements.cpp | 86 +++++++++++++++++++++++---------------------- ir/irfunction.cpp | 60 ++++++++++++++++--------------- ir/irfunction.h | 81 +++++++++++++++++++++++------------------- ir/irlandingpad.cpp | 10 +++--- 7 files changed, 138 insertions(+), 124 deletions(-) diff --git a/gen/functions.cpp b/gen/functions.cpp index 3fb3cc87..a32e4239 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -774,7 +774,10 @@ void DtoDefineFunction(FuncDeclaration* fd) } // output function body + irfunction->gen = new FuncGen; fd->fbody->toIR(gIR); + delete irfunction->gen; + irfunction->gen = 0; // TODO: clean up this mess diff --git a/gen/irstate.h b/gen/irstate.h index 04d477eb..d56f3fc9 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -182,7 +182,7 @@ struct IRState 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 --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index c664ee67..c61be31f 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -211,8 +211,8 @@ void DtoGoto(Loc loc, Identifier* target, TryFinallyStatement* sourceFinally) } // 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 @@ void EnclosingTryFinally::emitCode(IRState * p) { 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 @@ void DtoEnclosingHandlers(Loc loc, Statement* target) 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 @@ 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"); - 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 --git a/gen/statements.cpp b/gen/statements.cpp index a3868fae..abff984a 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->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 @@ void DoStatement::toIR(IRState* p) 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 @@ void ForStatement::toIR(IRState* p) 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 @@ void ForStatement::toIR(IRState* p) 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 @@ void BreakStatement::toIR(IRState* p) // 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 @@ void BreakStatement::toIR(IRState* p) } 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 @@ void ContinueStatement::toIR(IRState* p) // 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 @@ void ContinueStatement::toIR(IRState* p) } 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 @@ void TryFinallyStatement::toIR(IRState* p) 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 @@ void TryFinallyStatement::toIR(IRState* p) 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 @@ void TryCatchStatement::toIR(IRState* p) 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 @@ void TryCatchStatement::toIR(IRState* p) 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 @@ void SwitchStatement::toIR(IRState* p) 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 @@ void UnrolledLoopStatement::toIR(IRState* p) // 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 @@ void ForeachStatement::toIR(IRState* p) } // 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 @@ void ForeachRangeStatement::toIR(IRState* p) } // 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 @@ void LabelStatement::toIR(IRState* p) } 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 @@ void LabelStatement::toIR(IRState* p) } 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 @@ void SynchronizedStatement::toIR(IRState* p) } // 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 @@ void VolatileStatement::toIR(IRState* p) 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 --git a/ir/irfunction.cpp b/ir/irfunction.cpp index 52197615..c0b29c83 100644 --- a/ir/irfunction.cpp +++ b/ir/irfunction.cpp @@ -93,6 +93,37 @@ void IrFuncTy::getParam(Type* dty, int idx, DValue* val, llvm::Value* lval) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// +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 @@ IrFunction::IrFunction(FuncDeclaration* fd) _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 --git a/ir/irfunction.h b/ir/irfunction.h index 619a7084..02b79fbd 100644 --- a/ir/irfunction.h +++ b/ir/irfunction.h @@ -29,14 +29,58 @@ struct IRTargetScope 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 @@ struct IrFunction : IrBase 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 --git a/ir/irlandingpad.cpp b/ir/irlandingpad.cpp index d0a6280a..e99e6bdd 100644 --- a/ir/irlandingpad.cpp +++ b/ir/irlandingpad.cpp @@ -24,7 +24,7 @@ IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end) #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 @@ IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end) 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 @@ void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB) // 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