# HG changeset patch # User Frits van Bommel # Date 1243469641 -7200 # Node ID ad999630aa354f98a0b38fc04774f3898c3abf6b # Parent 42bd767ec5a4014fa5a65a43c42638dfea83a48c Teach -dgc2stack to preserve the call graph. This should allow for more efficient execution by the pass manager. diff -r 42bd767ec5a4 -r ad999630aa35 gen/passes/GarbageCollect2Stack.cpp --- a/gen/passes/GarbageCollect2Stack.cpp Thu May 28 00:07:21 2009 +0200 +++ b/gen/passes/GarbageCollect2Stack.cpp Thu May 28 02:14:01 2009 +0200 @@ -30,6 +30,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/IRBuilder.h" #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Target/TargetData.h" @@ -43,24 +44,40 @@ STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas"); STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused"); + +namespace { + struct Analysis { + TargetData& TD; + const Module& M; + CallGraph* CG; + CallGraphNode* CGNode; + + const Type* getTypeFor(Value* typeinfo) const; + }; +} + //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// -void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len) { +void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len, + const Analysis& A) { Dst = B.CreateBitCast(Dst, PointerType::getUnqual(Type::Int8Ty)); Module *M = B.GetInsertBlock()->getParent()->getParent(); const Type* Tys[1]; Tys[0] = Len->getType(); - Value *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1); + Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1); Value *Align = ConstantInt::get(Type::Int32Ty, 1); - B.CreateCall4(MemSet, Dst, Val, Len, Align); + CallSite CS = B.CreateCall4(MemSet, Dst, Val, Len, Align); + if (A.CGNode) + A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet)); } -static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len) { - EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len); +static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len, + const Analysis& A) { + EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len, A); } @@ -69,13 +86,6 @@ //===----------------------------------------------------------------------===// namespace { - struct Analysis { - TargetData& TD; - const Module& M; - - const Type* getTypeFor(Value* typeinfo) const; - }; - class FunctionInfo { protected: const Type* Ty; @@ -174,7 +184,7 @@ // Use the original B to put initialization at the // allocation site. Value* Size = B.CreateMul(TypeSize, arrSize); - EmitMemZero(B, alloca, Size); + EmitMemZero(B, alloca, Size, A); } return alloca; @@ -259,6 +269,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); + AU.addPreserved(); } }; char GarbageCollect2Stack::ID = 0; @@ -284,8 +295,9 @@ KnownFunctions["_d_allocclass"] = &AllocClass; } -static void RemoveCall(Instruction* Inst) { - if (InvokeInst* Invoke = dyn_cast(Inst)) { +static void RemoveCall(CallSite CS, const Analysis& A) { + if (CS.isInvoke()) { + InvokeInst* Invoke = cast(CS.getInstruction()); // If this was an invoke instruction, we need to do some extra // work to preserve the control flow. @@ -296,7 +308,9 @@ BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); } // Remove the runtime call. - Inst->eraseFromParent(); + if (A.CGNode) + A.CGNode->removeCallEdgeFor(CS); + CS.getInstruction()->eraseFromParent(); } /// runOnFunction - Top level algorithm. @@ -306,8 +320,10 @@ TargetData &TD = getAnalysis(); const LoopInfo &LI = getAnalysis(); + CallGraph* CG = getAnalysisIfAvailable(); + CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL; - Analysis A = { TD, *M }; + Analysis A = { TD, *M, CG, CGNode }; BasicBlock& Entry = F.getEntryBlock(); @@ -351,7 +367,7 @@ if (Inst->use_empty() && info->SafeToDelete) { Changed = true; NumDeleted++; - RemoveCall(Inst); + RemoveCall(CS, A); continue; } @@ -374,7 +390,7 @@ newVal = Builder.CreateBitCast(newVal, Inst->getType()); Inst->replaceAllUsesWith(newVal); - RemoveCall(Inst); + RemoveCall(CS, A); } }