diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -1014,9 +1014,17 @@ }; auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); - Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) - ? ConstantExpr::getBitCast(Fn, Int8PtrTy) - : ConstantPointerNull::get(Int8PtrTy); + Constant *FunctionAddr ; + if (shouldRecordFunctionAddr(Fn)) { + // When possible use a private alias to avoid relocations + Constant *Addr = !Fn->isDeclarationForLinker() + ? static_cast(GlobalAlias::create( + GlobalValue::PrivateLinkage, Fn->getName(), Fn)) + : Fn; + FunctionAddr = ConstantExpr::getBitCast(Addr, Int8PtrTy); + } else { + FunctionAddr = ConstantPointerNull::get(Int8PtrTy); + } Constant *Int16ArrayVals[IPVK_Last + 1]; for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) diff --git a/llvm/test/Transforms/PGOProfile/prof_avoid_relocs.ll b/llvm/test/Transforms/PGOProfile/prof_avoid_relocs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/prof_avoid_relocs.ll @@ -0,0 +1,98 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals +; RUN: opt -S -passes=pgo-instr-gen,instrprof < %s | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Test that we use private aliases to reference function addresses inside profile data + +; CHECK: @[[__LLVM_PROFILE_RAW_VERSION:[a-zA-Z0-9_$"\\.-]+]] = hidden constant i64 72057594037927944, comdat +; CHECK: @[[__PROFC_PERFORM_MERGE:[a-zA-Z0-9_$"\\.-]+]] = private global [7 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8 +; CHECK: @[[__PROFD_PERFORM_MERGE:[a-zA-Z0-9_$"\\.-]+]] = private global { i64, i64, i64, ptr, ptr, i32, [2 x i16] } { i64 6162284304386245408, i64 52047013912505467, i64 sub (i64 ptrtoint (ptr @__profc_perform_merge to i64), i64 ptrtoint (ptr @__profd_perform_merge to i64)), ptr @perform_merge.1, ptr null, i32 7, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profc_perform_merge), align 8 +; CHECK: @[[__PROFC_MY_FOO:[a-zA-Z0-9_$"\\.-]+]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8 +; CHECK: @[[__PROFD_MY_FOO:[a-zA-Z0-9_$"\\.-]+]] = private global { i64, i64, i64, ptr, ptr, i32, [2 x i16] } { i64 -7450599261614442455, i64 742261418966908927, i64 sub (i64 ptrtoint (ptr @__profc_my_foo to i64), i64 ptrtoint (ptr @__profd_my_foo to i64)), ptr @my_foo.2, ptr null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profc_my_foo), align 8 +; CHECK: @[[__PROFC_MY_BAR:[a-zA-Z0-9_$"\\.-]+]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8 +; CHECK: @[[__PROFD_MY_BAR:[a-zA-Z0-9_$"\\.-]+]] = private global { i64, i64, i64, ptr, ptr, i32, [2 x i16] } { i64 6915662552355231160, i64 742261418966908927, i64 sub (i64 ptrtoint (ptr @__profc_my_bar to i64), i64 ptrtoint (ptr @__profd_my_bar to i64)), ptr @my_bar.3, ptr null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profc_my_bar), align 8 +; CHECK: @[[__PROFC_MY_BAZ:[a-zA-Z0-9_$"\\.-]+]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat, align 8 +; CHECK: @[[__PROFD_MY_BAZ:[a-zA-Z0-9_$"\\.-]+]] = private global { i64, i64, i64, ptr, ptr, i32, [2 x i16] } { i64 7208794636344905383, i64 742261418966908927, i64 sub (i64 ptrtoint (ptr @__profc_my_baz to i64), i64 ptrtoint (ptr @__profd_my_baz to i64)), ptr @my_baz.4, ptr null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profc_my_baz), align 8 +; CHECK: @[[__LLVM_PRF_NM:[a-zA-Z0-9_$"\\.-]+]] = private constant [36 x i8] c"\22\00perform_merge\01my_foo\01my_bar\01my_baz", section "__llvm_prf_names", align 1 +; CHECK: @[[LLVM_COMPILER_USED:[a-zA-Z0-9_$"\\.-]+]] = appending global [4 x ptr] [ptr @__profd_perform_merge, ptr @__profd_my_foo, ptr @__profd_my_bar, ptr @__profd_my_baz], section "llvm.metadata" +; CHECK: @[[LLVM_USED:[a-zA-Z0-9_$"\\.-]+]] = appending global [1 x ptr] [ptr @__llvm_prf_nm], section "llvm.metadata" +; CHECK: @[[PERFORM_MERGE_1:[a-zA-Z0-9_$"\\.-]+]] = private alias void (ptr, i32, i32, i32, i32), ptr @perform_merge +; CHECK: @[[MY_FOO_2:[a-zA-Z0-9_$"\\.-]+]] = private alias i32 (i32), ptr @my_foo +; CHECK: @[[MY_BAR_3:[a-zA-Z0-9_$"\\.-]+]] = private alias i32 (double), ptr @my_bar +; CHECK: @[[MY_BAZ_4:[a-zA-Z0-9_$"\\.-]+]] = private alias i32 (ptr), ptr @my_baz + +define void @perform_merge(ptr %val, i32 %counter11, i32 %counter12, i32 %counter22, i32 %counter21) { +entry: + br label %while.cond + +while.cond: ; preds = %if.end, %entry + br i1 false, label %land.rhs, label %land.end + +land.rhs: ; preds = %while.cond + br label %land.end + +land.end: ; preds = %land.rhs, %while.cond + br i1 false, label %while.body, label %while.end + +while.body: ; preds = %land.end + br i1 false, label %if.then, label %if.else + +if.then: ; preds = %while.body + br label %if.end + +if.else: ; preds = %while.body + br label %if.end + +if.end: ; preds = %if.else, %if.then + br label %while.cond + +while.end: ; preds = %land.end + br label %while.cond16 + +while.cond16: ; preds = %while.body18, %while.end + br i1 false, label %while.body18, label %while.end25 + +while.body18: ; preds = %while.cond16 + br label %while.cond16 + +while.end25: ; preds = %while.cond16 + br label %while.cond26 + +while.cond26: ; preds = %while.body28, %while.end25 + br i1 false, label %while.body28, label %while.end35 + +while.body28: ; preds = %while.cond26 + br label %while.cond26 + +while.end35: ; preds = %while.cond26 + br label %for.cond + +for.cond: ; preds = %for.inc, %while.end35 + br i1 false, label %for.body, label %for.end + +for.body: ; preds = %for.cond + br label %for.inc + +for.inc: ; preds = %for.body + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} + +define i32 @my_foo(i32 %0) { +entry: + ret i32 0 +} + +define i32 @my_bar(double %d) { +entry: + ret i32 0 +} + +define i32 @my_baz(ptr %str) { +entry: + ret i32 0 +}