Index: lib/profile/InstrProfData.inc =================================================================== --- lib/profile/InstrProfData.inc +++ lib/profile/InstrProfData.inc @@ -153,7 +153,19 @@ VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \ INSTR_PROF_COMMA VALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA +#ifndef VALUE_RANGE_PROF VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) +#else /* VALUE_RANGE_PROF */ +VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) \ + INSTR_PROF_COMMA +VALUE_PROF_FUNC_PARAM(uint32_t, SignedType, Type::getInt32Ty(Ctx)) \ + INSTR_PROF_COMMA +VALUE_PROF_FUNC_PARAM(uint64_t, StartValue, Type::getInt64Ty(Ctx)) \ + INSTR_PROF_COMMA +VALUE_PROF_FUNC_PARAM(uint64_t, SmallTargetValue, Type::getInt64Ty(Ctx)) \ + INSTR_PROF_COMMA +VALUE_PROF_FUNC_PARAM(uint64_t, LargeTargetValue, Type::getInt64Ty(Ctx)) +#endif /*VALUE_RANGE_PROF */ #undef VALUE_PROF_FUNC_PARAM #undef INSTR_PROF_COMMA /* VALUE_PROF_FUNC_PARAM end */ @@ -174,13 +186,15 @@ * name hash and the function address. */ VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0) +/* For memory intrinsic functions size profiling. */ +VALUE_PROF_KIND(IPVK_MemOPSize, 1) /* These two kinds must be the last to be * declared. This is to make sure the string * array created with the template can be * indexed with the kind value. */ VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget) -VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget) +VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize) #undef VALUE_PROF_KIND /* VALUE_PROF_KIND end */ @@ -649,6 +663,9 @@ #define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target #define INSTR_PROF_VALUE_PROF_FUNC_STR \ INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC) +#define INSTR_PROF_VALUE_RANGE_PROF_FUNC __llvm_profile_instrument_range +#define INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR \ + INSTR_PROF_QUOTE(INSTR_PROF_VALUE_RANGE_PROF_FUNC) /* InstrProfile per-function control data alignment. */ #define INSTR_PROF_DATA_ALIGNMENT 8 Index: lib/profile/InstrProfilingValue.c =================================================================== --- lib/profile/InstrProfilingValue.c +++ lib/profile/InstrProfilingValue.c @@ -220,6 +220,40 @@ } /* + * We divide the possible values of TargetValue into the following ranges: + * Range Represent Value + * (-inf, StartVal): StartVal - 1; + * [StartValue, SmallTargetValue] TargetValue + * (SmallTargetalue, LargeTargetValue) SmallTargetValue + 1 + * [LargeTargetValue, +inf) LargetTargetValue + */ +COMPILER_RT_VISIBILITY void +__llvm_profile_instrument_range(uint64_t TargetValue, void *Data, + uint32_t CounterIndex, uint32_t SignedType, + uint64_t StartValue, + uint64_t SmallTargetValue, + uint64_t LargeTargetValue) { + + if (SignedType) { + if ((int64_t) TargetValue >= (int64_t) LargeTargetValue) + TargetValue = LargeTargetValue; + else if ((int64_t) TargetValue > (int64_t) SmallTargetValue) + TargetValue = SmallTargetValue + 1; + else if ((int64_t) TargetValue < (int64_t) StartValue) + TargetValue = StartValue - 1; + } else { + if (TargetValue >= LargeTargetValue) + TargetValue = LargeTargetValue; + else if (TargetValue > SmallTargetValue) + TargetValue = SmallTargetValue + 1; + else if (TargetValue < StartValue) + TargetValue = StartValue - 1; + } + + __llvm_profile_instrument_target(TargetValue, Data, CounterIndex); +} + +/* * A wrapper struct that represents value profile runtime data. * Like InstrProfRecord class which is used by profiling host tools, * ValueProfRuntimeRecord also implements the abstract intefaces defined in