diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -763,6 +763,9 @@ /* InstrProfile per-function control data alignment. */ #define INSTR_PROF_DATA_ALIGNMENT 8 +/* InstrProfile VNodes alilgnment. */ +#define INSTR_PROF_VNODE_ALIGNMENT 8 + /* The data structure that represents a tracked value by the * value profiler. */ diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h --- a/compiler-rt/lib/profile/InstrProfiling.h +++ b/compiler-rt/lib/profile/InstrProfiling.h @@ -10,6 +10,7 @@ #define PROFILE_INSTRPROFILING_H_ #include "InstrProfilingPort.h" +#include #include #define INSTR_PROF_VISIBILITY COMPILER_RT_VISIBILITY @@ -26,17 +27,21 @@ #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) Type Name; #include "profile/InstrProfData.inc" } __llvm_profile_data; +static_assert(INSTR_PROF_DATA_ALIGNMENT >= _Alignof(__llvm_profile_data), + "INSTR_PROF_DATA_ALIGNMENT is too small"); typedef struct __llvm_profile_header { #define INSTR_PROF_RAW_HEADER(Type, Name, Initializer) Type Name; #include "profile/InstrProfData.inc" } __llvm_profile_header; -typedef struct ValueProfNode * PtrToNodeT; -typedef struct ValueProfNode { +typedef struct ValueProfNode *PtrToNodeT; +typedef struct COMPILER_RT_ALIGNAS(INSTR_PROF_VNODE_ALIGNMENT) ValueProfNode { #define INSTR_PROF_VALUE_NODE(Type, LLVMType, Name, Initializer) Type Name; #include "profile/InstrProfData.inc" } ValueProfNode; +static_assert(INSTR_PROF_VNODE_ALIGNMENT >= _Alignof(ValueProfNode), + "INSTR_PROF_VNODE_ALIGNMENT is too small"); /*! * \brief Return 1 if profile counters are continuously synced to the raw @@ -116,8 +121,7 @@ * structurally the in-process counters. If the profile data in buffer is * not compatible, the interface returns 1 (failure). */ -int __llvm_profile_check_compatibility(const char *Profile, - uint64_t Size); +int __llvm_profile_check_compatibility(const char *Profile, uint64_t Size); /*! * \brief Counts the number of times a target value is seen. @@ -130,7 +134,7 @@ void INSTR_PROF_VALUE_PROF_FUNC( #define VALUE_PROF_FUNC_PARAM(ArgType, ArgName, ArgLLVMType) ArgType ArgName #include "profile/InstrProfData.inc" - ); +); void __llvm_profile_instrument_target_value(uint64_t TargetValue, void *Data, uint32_t CounterIndex, diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -763,6 +763,9 @@ /* InstrProfile per-function control data alignment. */ #define INSTR_PROF_DATA_ALIGNMENT 8 +/* InstrProfile VNodes alilgnment. */ +#define INSTR_PROF_VNODE_ALIGNMENT 8 + /* The data structure that represents a tracked value by the * value profiler. */ 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 @@ -1180,6 +1180,7 @@ Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName()); VNodesVar->setSection( getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat())); + VNodesVar->setAlignment(Align(INSTR_PROF_VNODE_ALIGNMENT)); // VNodesVar is used by runtime but not referenced via relocation by other // sections. Conservatively make it linker retained. UsedVars.push_back(VNodesVar); diff --git a/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll b/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll --- a/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll +++ b/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll @@ -10,10 +10,22 @@ ; RUN: opt < %s -mtriple=mips64-unknown-linux -passes=instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT ; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -vp-static-alloc=false -S | FileCheck %s --check-prefix=DYN - +;; Check that counters have the correct alignments. +; RUN: opt %s -mtriple=powerpc64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN +; RUN: opt %s -mtriple=powerpc-ibm-aix -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN +; RUN: opt %s -mtriple=powerpc64-ibm-aix -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN +; RUN: opt %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN @__profn_foo = private constant [3 x i8] c"foo" @__profn_bar = private constant [3 x i8] c"bar" +; ALIGN: @__profc_foo = private global {{.*}} section "__llvm_prf_cnts",{{.*}} align 8 +; ALIGN: @__profvp_foo = private global {{.*}} section "__llvm_prf_vals",{{.*}} align 8 +; ALIGN: @__profd_foo = private global {{.*}} section "__llvm_prf_data",{{.*}} align 8 +; ALIGN: @__profc_bar = private global {{.*}} section "__llvm_prf_cnts",{{.*}} align 8 +; ALIGN: @__profvp_bar = private global {{.*}} section "__llvm_prf_vals",{{.*}} align 8 +; ALIGN: @__profd_bar = private global {{.*}} section "__llvm_prf_data",{{.*}} align 8 +; ALIGN: @__llvm_prf_vnodes = private global {{.*}} section "__llvm_prf_vnds", align 8 +; ALIGN: @__llvm_prf_nm = private constant {{.*}} section "__llvm_prf_names", align 1 define i32 @foo(ptr ) { call void @llvm.instrprof.increment(ptr @__profn_foo, i64 12884901887, i32 1, i32 0)