[llvm-commits] [llvm] r163757 - /llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp

Bill Wendling isanbard at gmail.com
Wed Sep 12 17:09:55 PDT 2012


Author: void
Date: Wed Sep 12 19:09:55 2012
New Revision: 163757

URL: http://llvm.org/viewvc/llvm-project?rev=163757&view=rev
Log:
Introduce the __llvm_gcov_flush function.

This function writes out the current values of the counters and then resets
them. This can be used similarly to the __gcov_flush function to sync the
counters when need be. For instance, in a situation where the application
doesn't exit.
<rdar://problem/12185886>

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=163757&r1=163756&r2=163757&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp Wed Sep 12 19:09:55 2012
@@ -34,6 +34,7 @@
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/PathV2.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetData.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 #include <string>
 #include <utility>
@@ -90,6 +91,7 @@
     // list.
     void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
     void insertIndirectCounterIncrement();
+    void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
 
     std::string mangleName(DICompileUnit CU, const char *NewStem);
 
@@ -100,6 +102,7 @@
 
     Module *M;
     LLVMContext *Ctx;
+    const TargetData *TD;
   };
 }
 
@@ -351,6 +354,7 @@
 
 bool GCOVProfiler::runOnModule(Module &M) {
   this->M = &M;
+  TD = getAnalysisIfAvailable<TargetData>();
   Ctx = &M.getContext();
 
   if (EmitNotes) emitGCNO();
@@ -518,6 +522,7 @@
     }
 
     insertCounterWriteout(CountersBySP);
+    insertFlush(CountersBySP);
   }
 
   if (InsertIndCounterIncrCode)
@@ -630,13 +635,14 @@
 
 void GCOVProfiler::insertCounterWriteout(
     ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
-  FunctionType *WriteoutFTy =
-      FunctionType::get(Type::getVoidTy(*Ctx), false);
-  Function *WriteoutF = Function::Create(WriteoutFTy,
-                                         GlobalValue::InternalLinkage,
-                                         "__llvm_gcov_writeout", M);
+  FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
+  Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
+  if (!WriteoutF)
+    WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
+                                 "__llvm_gcov_writeout", M);
   WriteoutF->setUnnamedAddr(true);
-  BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
+
+  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
   IRBuilder<> Builder(BB);
 
   Constant *StartFile = getStartFileFunc();
@@ -744,3 +750,47 @@
   Builder.SetInsertPoint(Exit);
   Builder.CreateRetVoid();
 }
+
+void GCOVProfiler::
+insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
+  Function *FlushF = M->getFunction("__llvm_gcov_flush");
+  if (!FlushF)
+    FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
+                              "__llvm_gcov_flush", M);
+  else
+    FlushF->setLinkage(GlobalValue::InternalLinkage);
+  FlushF->setUnnamedAddr(true);
+
+  Type *Int8Ty = Type::getInt8Ty(*Ctx);
+  Type *Int64Ty = Type::getInt64Ty(*Ctx);
+  BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
+
+  // Write out the current counters.
+  Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
+  assert(WriteoutF && "Need to create the writeout function first!");
+
+  IRBuilder<> Builder(Entry);
+  Builder.CreateCall(WriteoutF);
+
+  if (TD)
+    // Zero out the counters.
+    for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
+           I = CountersBySP.begin(), E = CountersBySP.end();
+         I != E; ++I) {
+      GlobalVariable *GV = I->first;
+      uint64_t NumBytes = TD->getTypeAllocSize(GV->getType()->getElementType());
+      Builder.CreateMemSet(Builder.CreateConstGEP2_64(GV, 0, 0),
+                           ConstantInt::get(Int8Ty, 0),
+                           ConstantInt::get(Int64Ty, NumBytes), false);
+    }
+
+  Type *RetTy = FlushF->getReturnType();
+  if (RetTy == Type::getVoidTy(*Ctx))
+    Builder.CreateRetVoid();
+  else if (RetTy->isIntegerTy())
+    // Used if __llvm_gcov_flush was implicitly declared.
+    Builder.CreateRet(ConstantInt::get(RetTy, 0));
+  else
+    report_fatal_error("invalid return type for __llvm_gcov_flush");
+}





More information about the llvm-commits mailing list