diff options
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/ProfilingUtils.h | 4 | 
2 files changed, 40 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp b/llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp index b57bbf60a07..26b01e8c2fd 100644 --- a/llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp +++ b/llvm/lib/Transforms/Instrumentation/ProfilingUtils.cpp @@ -121,8 +121,7 @@ void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,    Indices[0] = Constant::getNullValue(Type::getInt32Ty(Context));    Indices[1] = ConstantInt::get(Type::getInt32Ty(Context), CounterNum);    Constant *ElementPtr = -    ConstantExpr::getGetElementPtr(CounterArray, &Indices[0], -                                          Indices.size()); +    ConstantExpr::getGetElementPtr(CounterArray, &Indices[0], Indices.size());    // Load, increment and store the value back.    Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); @@ -131,3 +130,39 @@ void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,                                           "NewFuncCounter", InsertPos);    new StoreInst(NewVal, ElementPtr, InsertPos);  } + +void llvm::InsertProfilingShutdownCall(Function *Callee, Module *Mod) { +  // llvm.global_dtors is an array of type { i32, void ()* }. Prepare those +  // types. +  const Type *GlobalDtorElems[2] = { +    Type::getInt32Ty(Mod->getContext()), +    FunctionType::get(Type::getVoidTy(Mod->getContext()), false)->getPointerTo() +  }; +  const StructType *GlobalDtorElemTy = +      StructType::get(Mod->getContext(), GlobalDtorElems, false); + +  // Construct the new element we'll be adding. +  Constant *Elem[2] = { +    ConstantInt::get(Type::getInt32Ty(Mod->getContext()), 65535), +    ConstantExpr::getBitCast(Callee, GlobalDtorElems[1]) +  }; + +  // If llvm.global_dtors exists, make a copy of the things in its list and +  // delete it, to replace it with one that has a larger array type. +  std::vector<Constant *> dtors; +  if (GlobalVariable *GlobalDtors = Mod->getNamedGlobal("llvm.global_dtors")) { +    ConstantArray *InitList = +        cast<ConstantArray>(GlobalDtors->getInitializer()); +    for (unsigned i = 0, e = InitList->getType()->getNumElements(); i != e; ++i) +      dtors.push_back(cast<Constant>(InitList->getOperand(i))); +    GlobalDtors->eraseFromParent(); +  } + +  // Build up llvm.global_dtors with our new item in it. +  GlobalVariable *GlobalDtors = new GlobalVariable( +      *Mod, ArrayType::get(GlobalDtorElemTy, 1), false, +      GlobalValue::AppendingLinkage, NULL, "llvm.global_dtors"); +  dtors.push_back(ConstantStruct::get(Mod->getContext(), Elem, 2, false)); +  GlobalDtors->setInitializer(ConstantArray::get( +      cast<ArrayType>(GlobalDtors->getType()->getElementType()), dtors)); +} diff --git a/llvm/lib/Transforms/Instrumentation/ProfilingUtils.h b/llvm/lib/Transforms/Instrumentation/ProfilingUtils.h index a76e3576e1c..09b22171ff0 100644 --- a/llvm/lib/Transforms/Instrumentation/ProfilingUtils.h +++ b/llvm/lib/Transforms/Instrumentation/ProfilingUtils.h @@ -18,9 +18,10 @@  #define PROFILINGUTILS_H  namespace llvm { +  class BasicBlock;    class Function;    class GlobalValue; -  class BasicBlock; +  class Module;    class PointerType;    void InsertProfilingInitCall(Function *MainFn, const char *FnName, @@ -29,6 +30,7 @@ namespace llvm {    void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,                                 GlobalValue *CounterArray,                                 bool beginning = true); +  void InsertProfilingShutdownCall(Function *Callee, Module *Mod);  }  #endif  | 

