namespace llvm {
+class TargetLibraryInfo;
+
/// Instrumentation based profiling lowering pass. This pass lowers
/// the profile instrumented code generated by FE or the IR based
/// instrumentation pass.
InstrProfiling(const InstrProfOptions &Options) : Options(Options) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- bool run(Module &M);
+ bool run(Module &M, const TargetLibraryInfo &TLI);
private:
InstrProfOptions Options;
Module *M;
+ const TargetLibraryInfo *TLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1];
GlobalVariable *RegionCounters;
#include "llvm/Transforms/InstrProfiling.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
return "Frontend instrumentation-based coverage lowering";
}
- bool runOnModule(Module &M) override { return InstrProf.run(M); }
+ bool runOnModule(Module &M) override {
+ return InstrProf.run(M, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI());
+ }
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
}
};
} // anonymous namespace
PreservedAnalyses InstrProfiling::run(Module &M, ModuleAnalysisManager &AM) {
- if (!run(M))
+ auto &TLI = AM.getResult<TargetLibraryAnalysis>(M);
+ if (!run(M, TLI))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
}
char InstrProfilingLegacyPass::ID = 0;
-INITIALIZE_PASS(InstrProfilingLegacyPass, "instrprof",
- "Frontend instrumentation-based coverage lowering.", false,
- false)
+INITIALIZE_PASS_BEGIN(
+ InstrProfilingLegacyPass, "instrprof",
+ "Frontend instrumentation-based coverage lowering.", false, false)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_END(
+ InstrProfilingLegacyPass, "instrprof",
+ "Frontend instrumentation-based coverage lowering.", false, false)
ModulePass *
llvm::createInstrProfilingLegacyPass(const InstrProfOptions &Options) {
return dyn_cast<InstrProfIncrementInst>(Instr);
}
-bool InstrProfiling::run(Module &M) {
+bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
bool MadeChange = false;
this->M = &M;
+ this->TLI = &TLI;
NamesVar = nullptr;
NamesSize = 0;
ProfileDataMap.clear();
return true;
}
-static Constant *getOrInsertValueProfilingCall(Module &M) {
+static Constant *getOrInsertValueProfilingCall(Module &M,
+ const TargetLibraryInfo &TLI) {
LLVMContext &Ctx = M.getContext();
auto *ReturnTy = Type::getVoidTy(M.getContext());
Type *ParamTypes[] = {
};
auto *ValueProfilingCallTy =
FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false);
- return M.getOrInsertFunction(getInstrProfValueProfFuncName(),
- ValueProfilingCallTy);
+ Constant *Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(),
+ ValueProfilingCallTy);
+ if (Function *FunRes = dyn_cast<Function>(Res)) {
+ if (auto AK = TLI.getExtAttrForI32Param(false))
+ FunRes->addAttribute(3, AK);
+ }
+ return Res;
}
void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {
Value *Args[3] = {Ind->getTargetValue(),
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
Builder.getInt32(Index)};
- Ind->replaceAllUsesWith(
- Builder.CreateCall(getOrInsertValueProfilingCall(*M), Args));
+ CallInst *Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, *TLI),
+ Args);
+ if (auto AK = TLI->getExtAttrForI32Param(false))
+ Call->addAttribute(3, AK);
+ Ind->replaceAllUsesWith(Call);
Ind->eraseFromParent();
}
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -vp-static-alloc=true -instrprof -S | FileCheck %s --check-prefix=STATIC
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC
+; RUN: opt < %s -mtriple=powerpc-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC
+; RUN: opt < %s -mtriple=sparc-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC
+; RUN: opt < %s -mtriple=s390x-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT
+; RUN: opt < %s -mtriple=powerpc64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT
+; RUN: opt < %s -mtriple=sparc64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT
+; RUN: opt < %s -mtriple=mips-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT
+; RUN: opt < %s -mtriple=mips64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -vp-static-alloc=false -instrprof -S | FileCheck %s --check-prefix=DYN
; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -vp-static-alloc=false -S | FileCheck %s --check-prefix=DYN
; DYN-NOT: @__profvp_foo
; DYN-NOT: @__llvm_prf_vnodes
+
+; STATIC: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 0)
+; STATIC-EXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 zeroext 0)
+; STATIC-SEXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 signext 0)
+
+; STATIC: declare void @__llvm_profile_instrument_target(i64, i8*, i32)
+; STATIC-EXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 zeroext)
+; STATIC-SEXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 signext)