[llvm-commits] [llvm] r137890 - /llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
Devang Patel
dpatel at apple.com
Thu Aug 18 10:24:05 PDT 2011
Nick,
On Aug 17, 2011, at 9:33 PM, Nick Lewycky wrote:
> Devang Patel wrote:
>> Author: dpatel
>> Date: Wed Aug 17 17:49:38 2011
>> New Revision: 137890
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=137890&view=rev
>> Log:
>> Do not use DebugInfoFinder. Extract debug info directly from llvm.dbg.cu named mdnode.
>
> Hi Devang,
>
> This all still crashes on all programs because GCOVProfiling still tries to use SP.getCompileUnit() which is now an assert when called.
>
> How can I tie a function/subprogram to the translation-unit/compile-unit it came from?
Now, compile-unit keeps track of its subprograms (earlier, each subprogram used to keep a pointer to its compile unit). You can use DIcompileUnit::getSubprograms() to get all subprograms in a compile unit. The purpose of this change is to let llvm linker unique debug info MDNodes to significantly reduce memory pressure during LTO.
> The purpose is to ensure that after merging multiple .bc files, we still emit the individual .gcno/.gcda files -- one for each original .o file -- as we would have before.
>
> Nick
>
>>
>> Modified:
>> llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp?rev=137890&r1=137889&r2=137890&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp Wed Aug 17 17:49:38 2011
>> @@ -60,11 +60,11 @@
>> bool runOnModule(Module&M);
>>
>> // Create the GCNO files for the Module based on DebugInfo.
>> - void emitGCNO(DebugInfoFinder&DIF);
>> + void emitGCNO();
>>
>> // Modify the program to track transitions along edges and call into the
>> // profiling runtime to emit .gcda files when run.
>> - bool emitProfileArcs(DebugInfoFinder&DIF);
>> + bool emitProfileArcs();
>>
>> // Get pointers to the functions in the runtime library.
>> Constant *getStartFileFunc();
>> @@ -86,8 +86,7 @@
>>
>> // Add the function to write out all our counters to the global destructor
>> // list.
>> - void insertCounterWriteout(DebugInfoFinder&,
>> - SmallVector<std::pair<GlobalVariable *,
>> + void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *,
>> MDNode *>, 8> &);
>>
>> std::string mangleName(DICompileUnit CU, std::string NewStem);
>> @@ -353,66 +352,66 @@
>> this->M =&M;
>> Ctx =&M.getContext();
>>
>> - DebugInfoFinder DIF;
>> - DIF.processModule(M);
>> -
>> - if (EmitNotes) emitGCNO(DIF);
>> - if (EmitData) return emitProfileArcs(DIF);
>> + if (EmitNotes) emitGCNO();
>> + if (EmitData) return emitProfileArcs();
>> return false;
>> }
>>
>> -void GCOVProfiler::emitGCNO(DebugInfoFinder&DIF) {
>> +void GCOVProfiler::emitGCNO() {
>> DenseMap<const MDNode *, raw_fd_ostream *> GcnoFiles;
>> - for (DebugInfoFinder::iterator I = DIF.compile_unit_begin(),
>> - E = DIF.compile_unit_end(); I != E; ++I) {
>> - // Each compile unit gets its own .gcno file. This means that whether we run
>> - // this pass over the original .o's as they're produced, or run it after
>> - // LTO, we'll generate the same .gcno files.
>> -
>> - DICompileUnit CU(*I);
>> - raw_fd_ostream *&out = GcnoFiles[CU];
>> - std::string ErrorInfo;
>> - out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo,
>> - raw_fd_ostream::F_Binary);
>> - if (!Use402Format)
>> - out->write("oncg*404MVLL", 12);
>> - else
>> - out->write("oncg*204MVLL", 12);
>> - }
>> -
>> - for (DebugInfoFinder::iterator SPI = DIF.subprogram_begin(),
>> - SPE = DIF.subprogram_end(); SPI != SPE; ++SPI) {
>> - DISubprogram SP(*SPI);
>> - raw_fd_ostream *&os = GcnoFiles[SP.getCompileUnit()];
>> -
>> - Function *F = SP.getFunction();
>> - if (!F) continue;
>> - GCOVFunction Func(SP, os, Use402Format);
>> -
>> - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> - GCOVBlock&Block = Func.getBlock(BB);
>> - TerminatorInst *TI = BB->getTerminator();
>> - if (int successors = TI->getNumSuccessors()) {
>> - for (int i = 0; i != successors; ++i) {
>> - Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
>> + NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
>> + if (CU_Nodes) {
>> + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
>> + // Each compile unit gets its own .gcno file. This means that whether we run
>> + // this pass over the original .o's as they're produced, or run it after
>> + // LTO, we'll generate the same .gcno files.
>> +
>> + DICompileUnit CU(CU_Nodes->getOperand(i));
>> + raw_fd_ostream *&out = GcnoFiles[CU];
>> + std::string ErrorInfo;
>> + out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo,
>> + raw_fd_ostream::F_Binary);
>> + if (!Use402Format)
>> + out->write("oncg*404MVLL", 12);
>> + else
>> + out->write("oncg*204MVLL", 12);
>> +
>> + DIArray SPs = CU.getSubprograms();
>> + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
>> + DISubprogram SP(SPs.getElement(i));
>> + if (!SP.Verify()) continue;
>> + raw_fd_ostream *&os = GcnoFiles[SP.getCompileUnit()];
>> +
>> + Function *F = SP.getFunction();
>> + if (!F) continue;
>> + GCOVFunction Func(SP, os, Use402Format);
>> +
>> + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> + GCOVBlock&Block = Func.getBlock(BB);
>> + TerminatorInst *TI = BB->getTerminator();
>> + if (int successors = TI->getNumSuccessors()) {
>> + for (int i = 0; i != successors; ++i) {
>> + Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
>> + }
>> + } else if (isa<ReturnInst>(TI)) {
>> + Block.addEdge(Func.getReturnBlock());
>> + }
>> +
>> + uint32_t Line = 0;
>> + for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
>> + const DebugLoc&Loc = I->getDebugLoc();
>> + if (Loc.isUnknown()) continue;
>> + if (Line == Loc.getLine()) continue;
>> + Line = Loc.getLine();
>> + if (SP != findSubprogram(DIScope(Loc.getScope(*Ctx)))) continue;
>> +
>> + GCOVLines&Lines = Block.getFile(SP.getFilename());
>> + Lines.addLine(Loc.getLine());
>> + }
>> }
>> - } else if (isa<ReturnInst>(TI)) {
>> - Block.addEdge(Func.getReturnBlock());
>> - }
>> -
>> - uint32_t Line = 0;
>> - for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
>> - const DebugLoc&Loc = I->getDebugLoc();
>> - if (Loc.isUnknown()) continue;
>> - if (Line == Loc.getLine()) continue;
>> - Line = Loc.getLine();
>> - if (SP != findSubprogram(DIScope(Loc.getScope(*Ctx)))) continue;
>> -
>> - GCOVLines&Lines = Block.getFile(SP.getFilename());
>> - Lines.addLine(Loc.getLine());
>> + Func.writeOut();
>> }
>> }
>> - Func.writeOut();
>> }
>>
>> for (DenseMap<const MDNode *, raw_fd_ostream *>::iterator
>> @@ -424,104 +423,107 @@
>> }
>> }
>>
>> -bool GCOVProfiler::emitProfileArcs(DebugInfoFinder&DIF) {
>> - if (DIF.subprogram_begin() == DIF.subprogram_end())
>> - return false;
>> -
>> - SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
>> - for (DebugInfoFinder::iterator SPI = DIF.subprogram_begin(),
>> - SPE = DIF.subprogram_end(); SPI != SPE; ++SPI) {
>> - DISubprogram SP(*SPI);
>> - Function *F = SP.getFunction();
>> - if (!F) continue;
>> -
>> - unsigned Edges = 0;
>> - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> - TerminatorInst *TI = BB->getTerminator();
>> - if (isa<ReturnInst>(TI))
>> - ++Edges;
>> - else
>> - Edges += TI->getNumSuccessors();
>> - }
>> -
>> - ArrayType *CounterTy =
>> +bool GCOVProfiler::emitProfileArcs() {
>> + NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
>> + if (!CU_Nodes) return false;
>> +
>> + bool Result = false;
>> + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
>> + DICompileUnit CU(CU_Nodes->getOperand(i));
>> + DIArray SPs = CU.getSubprograms();
>> + SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
>> + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
>> + DISubprogram SP(SPs.getElement(i));
>> + if (!SP.Verify()) continue;
>> + Function *F = SP.getFunction();
>> + if (!F) continue;
>> + if (!Result) Result = true;
>> + unsigned Edges = 0;
>> + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> + TerminatorInst *TI = BB->getTerminator();
>> + if (isa<ReturnInst>(TI))
>> + ++Edges;
>> + else
>> + Edges += TI->getNumSuccessors();
>> + }
>> +
>> + ArrayType *CounterTy =
>> ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
>> - GlobalVariable *Counters =
>> + GlobalVariable *Counters =
>> new GlobalVariable(*M, CounterTy, false,
>> GlobalValue::InternalLinkage,
>> Constant::getNullValue(CounterTy),
>> "__llvm_gcov_ctr", 0, false, 0);
>> - CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
>> -
>> - UniqueVector<BasicBlock *> ComplexEdgePreds;
>> - UniqueVector<BasicBlock *> ComplexEdgeSuccs;
>> -
>> - unsigned Edge = 0;
>> - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> - TerminatorInst *TI = BB->getTerminator();
>> - int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
>> - if (Successors) {
>> - IRBuilder<> Builder(TI);
>> -
>> - if (Successors == 1) {
>> - Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
>> - Edge);
>> - Value *Count = Builder.CreateLoad(Counter);
>> - Count = Builder.CreateAdd(Count,
>> - ConstantInt::get(Type::getInt64Ty(*Ctx),1));
>> - Builder.CreateStore(Count, Counter);
>> - } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
>> - Value *Sel = Builder.CreateSelect(
>> + CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
>> +
>> + UniqueVector<BasicBlock *> ComplexEdgePreds;
>> + UniqueVector<BasicBlock *> ComplexEdgeSuccs;
>> +
>> + unsigned Edge = 0;
>> + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
>> + TerminatorInst *TI = BB->getTerminator();
>> + int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
>> + if (Successors) {
>> + IRBuilder<> Builder(TI);
>> +
>> + if (Successors == 1) {
>> + Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
>> + Edge);
>> + Value *Count = Builder.CreateLoad(Counter);
>> + Count = Builder.CreateAdd(Count,
>> + ConstantInt::get(Type::getInt64Ty(*Ctx),1));
>> + Builder.CreateStore(Count, Counter);
>> + } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
>> + Value *Sel = Builder.CreateSelect(
>> BI->getCondition(),
>> ConstantInt::get(Type::getInt64Ty(*Ctx), Edge),
>> ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1));
>> - SmallVector<Value *, 2> Idx;
>> - Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
>> - Idx.push_back(Sel);
>> - Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
>> - Value *Count = Builder.CreateLoad(Counter);
>> - Count = Builder.CreateAdd(Count,
>> - ConstantInt::get(Type::getInt64Ty(*Ctx),1));
>> - Builder.CreateStore(Count, Counter);
>> - } else {
>> - ComplexEdgePreds.insert(BB);
>> - for (int i = 0; i != Successors; ++i)
>> - ComplexEdgeSuccs.insert(TI->getSuccessor(i));
>> + SmallVector<Value *, 2> Idx;
>> + Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
>> + Idx.push_back(Sel);
>> + Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
>> + Value *Count = Builder.CreateLoad(Counter);
>> + Count = Builder.CreateAdd(Count,
>> + ConstantInt::get(Type::getInt64Ty(*Ctx),1));
>> + Builder.CreateStore(Count, Counter);
>> + } else {
>> + ComplexEdgePreds.insert(BB);
>> + for (int i = 0; i != Successors; ++i)
>> + ComplexEdgeSuccs.insert(TI->getSuccessor(i));
>> + }
>> + Edge += Successors;
>> }
>> - Edge += Successors;
>> }
>> - }
>> -
>> - if (!ComplexEdgePreds.empty()) {
>> - GlobalVariable *EdgeTable =
>> +
>> + if (!ComplexEdgePreds.empty()) {
>> + GlobalVariable *EdgeTable =
>> buildEdgeLookupTable(F, Counters,
>> ComplexEdgePreds, ComplexEdgeSuccs);
>> - GlobalVariable *EdgeState = getEdgeStateValue();
>> -
>> - Type *Int32Ty = Type::getInt32Ty(*Ctx);
>> - for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
>> - IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
>> - Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
>> - }
>> - for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
>> - // call runtime to perform increment
>> - BasicBlock::iterator InsertPt =
>> - ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
>> - IRBuilder<> Builder(InsertPt);
>> - Value *CounterPtrArray =
>> + GlobalVariable *EdgeState = getEdgeStateValue();
>> +
>> + Type *Int32Ty = Type::getInt32Ty(*Ctx);
>> + for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
>> + IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
>> + Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
>> + }
>> + for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
>> + // call runtime to perform increment
>> + BasicBlock::iterator InsertPt =
>> + ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
>> + IRBuilder<> Builder(InsertPt);
>> + Value *CounterPtrArray =
>> Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
>> i * ComplexEdgePreds.size());
>> - Builder.CreateCall2(getIncrementIndirectCounterFunc(),
>> - EdgeState, CounterPtrArray);
>> - // clear the predecessor number
>> - Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
>> + Builder.CreateCall2(getIncrementIndirectCounterFunc(),
>> + EdgeState, CounterPtrArray);
>> + // clear the predecessor number
>> + Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
>> + }
>> }
>> }
>> + insertCounterWriteout(CountersBySP);
>> }
>> -
>> - insertCounterWriteout(DIF, CountersBySP);
>> -
>> - return true;
>> + return Result;
>> }
>>
>> // All edges with successors that aren't branches are "complex", because it
>> @@ -627,7 +629,6 @@
>> }
>>
>> void GCOVProfiler::insertCounterWriteout(
>> - DebugInfoFinder&DIF,
>> SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) {
>> FunctionType *WriteoutFTy =
>> FunctionType::get(Type::getVoidTy(*Ctx), false);
>> @@ -643,29 +644,31 @@
>> Constant *EmitArcs = getEmitArcsFunc();
>> Constant *EndFile = getEndFileFunc();
>>
>> - for (DebugInfoFinder::iterator CUI = DIF.compile_unit_begin(),
>> - CUE = DIF.compile_unit_end(); CUI != CUE; ++CUI) {
>> - DICompileUnit compile_unit(*CUI);
>> - std::string FilenameGcda = mangleName(compile_unit, "gcda");
>> - Builder.CreateCall(StartFile,
>> - Builder.CreateGlobalStringPtr(FilenameGcda));
>> - for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator
>> + NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
>> + if (CU_Nodes) {
>> + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
>> + DICompileUnit compile_unit(CU_Nodes->getOperand(i));
>> + std::string FilenameGcda = mangleName(compile_unit, "gcda");
>> + Builder.CreateCall(StartFile,
>> + Builder.CreateGlobalStringPtr(FilenameGcda));
>> + for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator
>> I = CountersBySP.begin(), E = CountersBySP.end();
>> - I != E; ++I) {
>> - DISubprogram SP(I->second);
>> - intptr_t ident = reinterpret_cast<intptr_t>(I->second);
>> - Builder.CreateCall2(EmitFunction,
>> - ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
>> - Builder.CreateGlobalStringPtr(SP.getName()));
>> -
>> - GlobalVariable *GV = I->first;
>> - unsigned Arcs =
>> + I != E; ++I) {
>> + DISubprogram SP(I->second);
>> + intptr_t ident = reinterpret_cast<intptr_t>(I->second);
>> + Builder.CreateCall2(EmitFunction,
>> + ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
>> + Builder.CreateGlobalStringPtr(SP.getName()));
>> +
>> + GlobalVariable *GV = I->first;
>> + unsigned Arcs =
>> cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
>> - Builder.CreateCall2(EmitArcs,
>> - ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
>> - Builder.CreateConstGEP2_64(GV, 0, 0));
>> + Builder.CreateCall2(EmitArcs,
>> + ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
>> + Builder.CreateConstGEP2_64(GV, 0, 0));
>> + }
>> + Builder.CreateCall(EndFile);
>> }
>> - Builder.CreateCall(EndFile);
>> }
>> Builder.CreateRetVoid();
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
More information about the llvm-commits
mailing list