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

Bob Wilson bob.wilson at apple.com
Thu Sep 13 09:19:47 PDT 2012


I'm not seeing the code to read the counter values from the files.  Am I missing that somewhere?  GCC's version of __gcov_flush is designed to let you call it multiple times during a program execution.  Each time it adds the current counters to the values already in the output files, writes the new values out, and zeros the counters again.  It's like fflush() -- you can call it at any point to flush the data out.  That seems like a nice design.

Also, what is the advantage of calling this __llvm_gcov_flush instead of just __gcov_flush?  Since the name of this function is exposed to users, we should keep the same name unless there's a good reason to differ.

On Sep 12, 2012, at 5:09 PM, Bill Wendling <isanbard at gmail.com> wrote:

> 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");
> +}
> 
> 
> _______________________________________________
> 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