<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">We’re not going to use debug info at all. We’re emitting the counters in the clang front-end. We just need to emit separate info to show how to map those counters to source locations. Mapping to PCs and then using debug info to get from the PCs to the source locations just makes things harder and loses information in the process.<div><br><div><div>On Feb 21, 2014, at 2:57 AM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><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>
</blockquote></div><br></div></body></html>