Index: lib/Transforms/Instrumentation/GCOVProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -627,111 +627,106 @@ if (!CU_Nodes) return false; bool Result = false; - for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { - SmallVector, 8> CountersBySP; - for (auto &F : M->functions()) { - DISubprogram *SP = F.getSubprogram(); - if (!SP) continue; - if (!functionHasLines(F)) continue; - // TODO: Functions using scope-based EH are currently not supported. - if (isUsingScopeBasedEH(F)) continue; - if (!Result) Result = true; + SmallVector, 8> CountersBySP; + for (auto &F : M->functions()) { + DISubprogram *SP = F.getSubprogram(); + if (!SP) + continue; + if (!functionHasLines(F)) + continue; + // TODO: Functions using scope-based EH are currently not supported. + if (isUsingScopeBasedEH(F)) + continue; + if (!Result) + Result = true; - DenseMap, unsigned> EdgeToCounter; - unsigned Edges = 0; - for (auto &BB : F) { - TerminatorInst *TI = BB.getTerminator(); - if (isa(TI)) { - EdgeToCounter[{&BB, nullptr}] = Edges++; - } else { - for (BasicBlock *Succ : successors(TI)) { - EdgeToCounter[{&BB, Succ}] = Edges++; - } + DenseMap, unsigned> EdgeToCounter; + unsigned Edges = 0; + for (auto &BB : F) { + TerminatorInst *TI = BB.getTerminator(); + if (isa(TI)) { + EdgeToCounter[{&BB, nullptr}] = Edges++; + } else { + for (BasicBlock *Succ : successors(TI)) { + EdgeToCounter[{&BB, Succ}] = Edges++; } } + } - ArrayType *CounterTy = - ArrayType::get(Type::getInt64Ty(*Ctx), Edges); - GlobalVariable *Counters = - new GlobalVariable(*M, CounterTy, false, - GlobalValue::InternalLinkage, - Constant::getNullValue(CounterTy), - "__llvm_gcov_ctr"); - CountersBySP.push_back(std::make_pair(Counters, SP)); + ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(*Ctx), Edges); + GlobalVariable *Counters = new GlobalVariable( + *M, CounterTy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(CounterTy), "__llvm_gcov_ctr"); + CountersBySP.push_back(std::make_pair(Counters, SP)); + + // If a BB has several predecessors, use a PHINode to select + // the correct counter. + for (auto &BB : F) { + const unsigned EdgeCount = std::distance(pred_begin(&BB), pred_end(&BB)); + if (EdgeCount) { + // The phi node must be at the begin of the BB. + IRBuilder<> BuilderForPhi(&*BB.begin()); + Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); + PHINode *Phi = BuilderForPhi.CreatePHI(Int64PtrTy, EdgeCount); + for (BasicBlock *Pred : predecessors(&BB)) { + auto It = EdgeToCounter.find({Pred, &BB}); + assert(It != EdgeToCounter.end()); + const unsigned Edge = It->second; + Value *EdgeCounter = + BuilderForPhi.CreateConstInBoundsGEP2_64(Counters, 0, Edge); + Phi->addIncoming(EdgeCounter, Pred); + } - // If a BB has several predecessors, use a PHINode to select - // the correct counter. - for (auto &BB : F) { - const unsigned EdgeCount = - std::distance(pred_begin(&BB), pred_end(&BB)); - if (EdgeCount) { - // The phi node must be at the begin of the BB. - IRBuilder<> BuilderForPhi(&*BB.begin()); - Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); - PHINode *Phi = BuilderForPhi.CreatePHI(Int64PtrTy, EdgeCount); - for (BasicBlock *Pred : predecessors(&BB)) { - auto It = EdgeToCounter.find({Pred, &BB}); - assert(It != EdgeToCounter.end()); - const unsigned Edge = It->second; - Value *EdgeCounter = - BuilderForPhi.CreateConstInBoundsGEP2_64(Counters, 0, Edge); - Phi->addIncoming(EdgeCounter, Pred); - } + // Skip phis, landingpads. + IRBuilder<> Builder(&*BB.getFirstInsertionPt()); + Value *Count = Builder.CreateLoad(Phi); + Count = Builder.CreateAdd(Count, Builder.getInt64(1)); + Builder.CreateStore(Count, Phi); - // Skip phis, landingpads. - IRBuilder<> Builder(&*BB.getFirstInsertionPt()); - Value *Count = Builder.CreateLoad(Phi); + TerminatorInst *TI = BB.getTerminator(); + if (isa(TI)) { + auto It = EdgeToCounter.find({&BB, nullptr}); + assert(It != EdgeToCounter.end()); + const unsigned Edge = It->second; + Value *Counter = + Builder.CreateConstInBoundsGEP2_64(Counters, 0, Edge); + Value *Count = Builder.CreateLoad(Counter); Count = Builder.CreateAdd(Count, Builder.getInt64(1)); - Builder.CreateStore(Count, Phi); - - TerminatorInst *TI = BB.getTerminator(); - if (isa(TI)) { - auto It = EdgeToCounter.find({&BB, nullptr}); - assert(It != EdgeToCounter.end()); - const unsigned Edge = It->second; - Value *Counter = - Builder.CreateConstInBoundsGEP2_64(Counters, 0, Edge); - Value *Count = Builder.CreateLoad(Counter); - Count = Builder.CreateAdd(Count, Builder.getInt64(1)); - Builder.CreateStore(Count, Counter); - } + Builder.CreateStore(Count, Counter); } } } + } - Function *WriteoutF = insertCounterWriteout(CountersBySP); - Function *FlushF = insertFlush(CountersBySP); + Function *WriteoutF = insertCounterWriteout(CountersBySP); + Function *FlushF = insertFlush(CountersBySP); - // Create a small bit of code that registers the "__llvm_gcov_writeout" to - // be executed at exit and the "__llvm_gcov_flush" function to be executed - // when "__gcov_flush" is called. - FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); - Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, - "__llvm_gcov_init", M); - F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); - F->setLinkage(GlobalValue::InternalLinkage); - F->addFnAttr(Attribute::NoInline); - if (Options.NoRedZone) - F->addFnAttr(Attribute::NoRedZone); - - BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); - IRBuilder<> Builder(BB); - - FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); - Type *Params[] = { - PointerType::get(FTy, 0), - PointerType::get(FTy, 0) - }; - FTy = FunctionType::get(Builder.getVoidTy(), Params, false); - - // Initialize the environment and register the local writeout and flush - // functions. - Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); - Builder.CreateCall(GCOVInit, {WriteoutF, FlushF}); - Builder.CreateRetVoid(); + // Create a small bit of code that registers the "__llvm_gcov_writeout" to + // be executed at exit and the "__llvm_gcov_flush" function to be executed + // when "__gcov_flush" is called. + FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); + Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, + "__llvm_gcov_init", M); + F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); + F->setLinkage(GlobalValue::InternalLinkage); + F->addFnAttr(Attribute::NoInline); + if (Options.NoRedZone) + F->addFnAttr(Attribute::NoRedZone); - appendToGlobalCtors(*M, F, 0); - } + BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); + IRBuilder<> Builder(BB); + + FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); + Type *Params[] = {PointerType::get(FTy, 0), PointerType::get(FTy, 0)}; + FTy = FunctionType::get(Builder.getVoidTy(), Params, false); + + // Initialize the environment and register the local writeout and flush + // functions. + Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); + Builder.CreateCall(GCOVInit, {WriteoutF, FlushF}); + Builder.CreateRetVoid(); + + appendToGlobalCtors(*M, F, 0); return Result; }