<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><br>
<br>
</div>We may need some additional info.</blockquote><div>What kind of additional info? </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I haven't put a ton of thought into<br>
this, but I'm hoping we can either (a) use debug info as is or add some<br>
extra (valid) debug info to support this, or (b) add an extra<br>
debug-info-like section to instrumented binaries with the information we<br>
need.<br></blockquote><div><br></div><div>I'd try this data format (binary equivalent): </div><div><br></div><div>/path/to/binary/or/dso1 num_counters1</div><div>pc1 counter1</div><div>pc2 counter2<br></div><div>pc3 counter3<br>
</div><div>...</div><div><div>/path/to/binary/or/dso2 num_counters2</div><div>pc1 counter1</div><div>pc2 counter2<br></div><div>pc3 counter3<br></div></div><div>...</div><div><br></div><div>I don't see a straightforward way to produce such data today because individual Instructions do not work as labels.<br>
</div><div>But I think this can be supported in LLVM codegen. </div><div>Here is a *raw* patch with comments, just to get the idea.</div><div><br></div><div><br></div><div><div>Index: lib/CodeGen/CodeGenPGO.cpp</div><div>
===================================================================</div><div>--- lib/CodeGen/CodeGenPGO.cpp (revision 201843)</div><div>+++ lib/CodeGen/CodeGenPGO.cpp (working copy)</div><div>@@ -199,7 +199,8 @@</div><div>
llvm::Type *Args[] = {</div><div> Int8PtrTy, // const char *MangledName</div><div> Int32Ty, // uint32_t NumCounters</div><div>- Int64PtrTy // uint64_t *Counters</div>
<div>+ Int64PtrTy, // uint64_t *Counters</div><div>+ Int64PtrTy // uint64_t *PCs</div><div> };</div><div> llvm::FunctionType *FTy =</div><div> llvm::FunctionType::get(PGOBuilder.getVoidTy(), Args, false);</div>
<div>@@ -209,9 +210,10 @@</div><div> llvm::Constant *MangledName =</div><div> CGM.GetAddrOfConstantCString(CGM.getMangledName(GD), "__llvm_pgo_name");</div><div> MangledName = llvm::ConstantExpr::getBitCast(MangledName, Int8PtrTy);</div>
<div>- PGOBuilder.CreateCall3(EmitFunc, MangledName,</div><div>+ PGOBuilder.CreateCall4(EmitFunc, MangledName,</div><div> PGOBuilder.getInt32(NumRegionCounters),</div><div>- PGOBuilder.CreateBitCast(RegionCounters, Int64PtrTy));</div>
<div>+ PGOBuilder.CreateBitCast(RegionCounters, Int64PtrTy),</div><div>+ PGOBuilder.CreateBitCast(RegionPCs, Int64PtrTy));</div><div> }</div><div> </div><div> llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {</div>
<div>@@ -769,6 +771,13 @@</div><div> llvm::GlobalVariable::PrivateLinkage,</div><div> llvm::Constant::getNullValue(CounterTy),</div><div> "__llvm_pgo_ctr");</div>
<div>+</div><div>+ RegionPCs =</div><div>+ new llvm::GlobalVariable(CGM.getModule(), CounterTy, false,</div><div>+ llvm::GlobalVariable::PrivateLinkage,</div><div>+ llvm::Constant::getNullValue(CounterTy),</div>
<div>+ "__llvm_pgo_pcs");</div><div>+</div><div> }</div><div> </div><div> void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {</div><div>@@ -779,6 +788,21 @@</div>
<div> llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");</div><div> Count = Builder.CreateAdd(Count, Builder.getInt64(1));</div><div> Builder.CreateStore(Count, Addr);</div><div>+ // We should put the PC of the instruction that increments __llvm_pgo_ctr</div>
<div>+ // into __llvm_pgo_pcs, which will be passed to llvm_pgo_emit.</div><div>+ // This patch is wrong in many ways:</div><div>+ // * We pass the PC of the Function instead of the PC of the Instruction,</div><div>+ // because the latter doesn't work like this. We'll need to support</div>
<div>+ // Instructions as labels in LLVM codegen.</div><div>+ // * We actually store the PC on each increment, while we should initialize</div><div>+ // this array at link time (need to refactor this code a bit).</div>
<div>+ //</div><div>+ Builder.CreateStore(</div><div>+ Builder.CreatePointerCast(</div><div>+ cast<llvm::Instruction>(Count)->getParent()->getParent(),</div><div>+ Builder.getInt64Ty() // FIXME: use a better type</div>
<div>+ ),</div><div>+ Builder.CreateConstInBoundsGEP2_64(RegionPCs, 0, Counter));</div><div> }</div><div> </div></div><div><div>Index: lib/CodeGen/CodeGenPGO.h</div><div>===================================================================</div>
<div>--- lib/CodeGen/CodeGenPGO.h (revision 201843)</div><div>+++ lib/CodeGen/CodeGenPGO.h (working copy)</div><div>@@ -59,6 +59,7 @@</div><div> </div><div> unsigned NumRegionCounters;</div><div> llvm::GlobalVariable *RegionCounters;</div>
<div>+ llvm::GlobalVariable *RegionPCs;</div><div> llvm::DenseMap<const Stmt*, unsigned> *RegionCounterMap;</div><div> llvm::DenseMap<const Stmt*, uint64_t> *StmtCountMap;</div><div> std::vector<uint64_t> *RegionCounts;</div>
<div>@@ -66,8 +67,9 @@</div><div> </div><div> public:</div><div> CodeGenPGO(CodeGenModule &CGM)</div><div>- : CGM(CGM), NumRegionCounters(0), RegionCounters(0), RegionCounterMap(0),</div><div>- StmtCountMap(0), RegionCounts(0), CurrentRegionCount(0) {}</div>
<div>+ : CGM(CGM), NumRegionCounters(0), RegionCounters(0), RegionPCs(0),</div><div>+ RegionCounterMap(0), StmtCountMap(0), RegionCounts(0),</div><div>+ CurrentRegionCount(0) {}</div><div> ~CodeGenPGO() {}</div>
<div> </div><div> /// Whether or not we have PGO region data for the current function. This is</div></div><div><br></div><div><br></div><div><br></div><div><br></div><div> </div></div><br></div></div>