83 changes: 76 additions & 7 deletions llvm/lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,21 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader(

CountersDelta = swap(Header.CountersDelta);
NamesDelta = swap(Header.NamesDelta);
ValueDataDelta = swap(Header.ValueDataDelta);
auto DataSize = swap(Header.DataSize);
auto CountersSize = swap(Header.CountersSize);
auto NamesSize = swap(Header.NamesSize);
auto ValueDataSize = swap(Header.ValueDataSize);
ValueKindLast = swap(Header.ValueKindLast);

auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
auto PaddingSize = getNumPaddingBytes(NamesSize);

ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
ptrdiff_t CountersOffset =
DataOffset + sizeof(RawInstrProf::ProfileData<IntPtrT>) * DataSize;
ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
size_t ProfileSize = NamesOffset + sizeof(char) * NamesSize;
ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
size_t ProfileSize = ValueDataOffset + ValueDataSize;

auto *Start = reinterpret_cast<const char *>(&Header);
if (Start + ProfileSize > DataBuffer->getBufferEnd())
Expand All @@ -225,18 +231,32 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader(
DataEnd = Data + DataSize;
CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
NamesStart = Start + NamesOffset;
ValueDataStart = reinterpret_cast<const uint8_t*>(Start + ValueDataOffset);
ProfileEnd = Start + ProfileSize;

FunctionPtrToNameMap.clear();
for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
const IntPtrT FPtr = swap(I->FunctionPointer);
if (!FPtr)
continue;
StringRef FunctionName(getName(I->NamePtr), swap(I->NameSize));
const char* NameEntryPtr = StringTable.insertString(FunctionName);
FunctionPtrToNameMap.push_back(std::pair<const IntPtrT, const char*>
(FPtr, NameEntryPtr));
}
std::sort(FunctionPtrToNameMap.begin(), FunctionPtrToNameMap.end(), less_first());
FunctionPtrToNameMap.erase(std::unique(FunctionPtrToNameMap.begin(),
FunctionPtrToNameMap.end()),
FunctionPtrToNameMap.end());
return success();
}

template <class IntPtrT>
std::error_code RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) {
Record.Name = StringRef(getName(Data->NamePtr), swap(Data->NameSize));
if (Record.Name.data() < NamesStart ||
Record.Name.data() + Record.Name.size() > DataBuffer->getBufferEnd())
Record.Name.data() + Record.Name.size() > (char*)ValueDataStart)
return error(instrprof_error::malformed);

return success();
}

Expand Down Expand Up @@ -275,8 +295,54 @@ std::error_code RawInstrProfReader<IntPtrT>::readRawCounts(
}

template <class IntPtrT>
std::error_code
RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
std::error_code RawInstrProfReader<IntPtrT>::readValueData(
InstrProfRecord &Record) {

Record.clearValueData();
if (!Data->Values || (ValueDataDelta == 0))
return success();

// Read value data.
uint64_t NumVSites = 0;
for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind)
NumVSites += swap(Data->NumValueSites[Kind]);
NumVSites += getNumPaddingBytes(NumVSites);

auto VDataCounts = makeArrayRef(getValueDataCounts(Data->Values), NumVSites);
// Check bounds.
if (VDataCounts.data() < ValueDataStart ||
VDataCounts.data() + VDataCounts.size() > (const uint8_t *)ProfileEnd)
return error(instrprof_error::malformed);

const InstrProfValueData *VDataPtr =
getValueData(swap(Data->Values) + NumVSites);
for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind) {
NumVSites = swap(Data->NumValueSites[Kind]);
Record.reserveSites(Kind, NumVSites);
for (uint32_t VSite = 0; VSite < NumVSites; ++VSite) {

uint32_t VDataCount = VDataCounts[VSite];
if ((const char *)(VDataPtr + VDataCount) > ProfileEnd)
return error(instrprof_error::malformed);

std::vector<InstrProfValueData> CurrentValues;
CurrentValues.reserve(VDataCount);
for (uint32_t VIndex = 0; VIndex < VDataCount; ++VIndex) {
uint64_t TargetValue = swap(VDataPtr->Value);
uint64_t Count = swap(VDataPtr->Count);
CurrentValues.push_back({TargetValue, Count});
++VDataPtr;
}
Record.addValueData(Kind, VSite, CurrentValues.data(),
VDataCount, &FunctionPtrToNameMap);
}
}
return success();
}

template <class IntPtrT>
std::error_code RawInstrProfReader<IntPtrT>::readNextRecord(
InstrProfRecord &Record) {
if (atEnd())
if (std::error_code EC = readNextHeader(ProfileEnd))
return EC;
Expand All @@ -293,6 +359,9 @@ RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
if (std::error_code EC = readRawCounts(Record))
return EC;

// Read value data and set Record.
if (std::error_code EC = readValueData(Record)) return EC;

// Iterate.
advanceData();
return success();
Expand Down
143 changes: 122 additions & 21 deletions llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
//
//===----------------------------------------------------------------------===//
//
// This pass lowers instrprof_increment intrinsics emitted by a frontend for
// profiling. It also builds the data structures and initialization code needed
// for updating execution counts and emitting the profile at runtime.
// This pass lowers instrprof_* intrinsics emitted by a frontend for profiling.
// It also builds the data structures and initialization code needed for
// updating execution counts and emitting the profile at runtime.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Transforms/Instrumentation.h"

#include "llvm/ADT/Triple.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;
Expand Down Expand Up @@ -50,7 +49,15 @@ class InstrProfiling : public ModulePass {
private:
InstrProfOptions Options;
Module *M;
DenseMap<GlobalVariable *, GlobalVariable *> RegionCounters;
typedef struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last+1];
GlobalVariable* RegionCounters;
GlobalVariable* DataVar;
PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) {
memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last+1));
}
} PerFunctionProfileData;
DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
std::vector<Value *> UsedVars;

bool isMachO() const {
Expand All @@ -77,6 +84,12 @@ class InstrProfiling : public ModulePass {
return getInstrProfCoverageSectionName(isMachO());
}

/// Count the number of instrumented value sites for the function.
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);

/// Replace instrprof_value_profile with a call to runtime library.
void lowerValueProfileInst(InstrProfValueProfileInst *Ins);

/// Replace instrprof_increment with an increment of the appropriate value.
void lowerIncrement(InstrProfIncrementInst *Inc);

Expand Down Expand Up @@ -118,21 +131,37 @@ bool InstrProfiling::runOnModule(Module &M) {
bool MadeChange = false;

this->M = &M;
RegionCounters.clear();
ProfileDataMap.clear();
UsedVars.clear();

// We did not know how many value sites there would be inside
// the instrumented function. This is counting the number of instrumented
// target value sites to enter it as field in the profile data variable.
for (Function &F : M)
for (BasicBlock &BB : F)
for (auto I = BB.begin(), E = BB.end(); I != E;)
if (auto *Inc = dyn_cast<InstrProfIncrementInst>(I++)) {
if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I++))
computeNumValueSiteCounts(Ind);

for (Function &F : M)
for (BasicBlock &BB : F)
for (auto I = BB.begin(), E = BB.end(); I != E;) {
auto Instr = I++;
if (auto *Inc = dyn_cast<InstrProfIncrementInst>(Instr)) {
lowerIncrement(Inc);
MadeChange = true;
} else if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(Instr)) {
lowerValueProfileInst(Ind);
MadeChange = true;
}
}

if (GlobalVariable *Coverage =
M.getNamedGlobal(getCoverageMappingVarName())) {
lowerCoverageData(Coverage);
MadeChange = true;
}

if (!MadeChange)
return false;

Expand All @@ -143,6 +172,54 @@ bool InstrProfiling::runOnModule(Module &M) {
return true;
}

static Constant *getOrInsertValueProfilingCall(Module &M) {
auto *VoidTy = Type::getVoidTy(M.getContext());
auto *VoidPtrTy = Type::getInt8PtrTy(M.getContext());
auto *Int32Ty = Type::getInt32Ty(M.getContext());
auto *Int64Ty = Type::getInt64Ty(M.getContext());
Type *ArgTypes[] = {Int64Ty, VoidPtrTy, Int32Ty};
auto *ValueProfilingCallTy =
FunctionType::get(VoidTy, makeArrayRef(ArgTypes), false);
return M.getOrInsertFunction("__llvm_profile_instrument_target",
ValueProfilingCallTy);
}

void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) {

GlobalVariable *Name = Ind->getName();
uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
uint64_t Index = Ind->getIndex()->getZExtValue();
auto It = ProfileDataMap.find(Name);
if (It == ProfileDataMap.end()) {
PerFunctionProfileData PD;
PD.NumValueSites[ValueKind] = Index + 1;
ProfileDataMap[Name] = PD;
} else if (It->second.NumValueSites[ValueKind] <= Index)
It->second.NumValueSites[ValueKind] = Index + 1;
}

void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) {

GlobalVariable *Name = Ind->getName();
auto It = ProfileDataMap.find(Name);
assert(It != ProfileDataMap.end() && It->second.DataVar &&
"value profiling detected in function with no counter incerement");

GlobalVariable *DataVar = It->second.DataVar;
uint64_t ValueKind = Ind->getValueKind()->getZExtValue();
uint64_t Index = Ind->getIndex()->getZExtValue();
for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind)
Index += It->second.NumValueSites[Kind];

IRBuilder<> Builder(Ind);
Value* Args[3] = {Ind->getTargetValue(),
Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()),
Builder.getInt32(Index)};
Ind->replaceAllUsesWith(
Builder.CreateCall(getOrInsertValueProfilingCall(*M), Args));
Ind->eraseFromParent();
}

void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
GlobalVariable *Counters = getOrCreateRegionCounters(Inc);

Expand Down Expand Up @@ -174,9 +251,10 @@ void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) {
GlobalVariable *Name = cast<GlobalVariable>(V);

// If we have region counters for this name, we've already handled it.
auto It = RegionCounters.find(Name);
if (It != RegionCounters.end())
continue;
auto It = ProfileDataMap.find(Name);
if (It != ProfileDataMap.end())
if (It->second.RegionCounters)
continue;

// Move the name variable to the right section.
Name->setSection(getNameSection());
Expand All @@ -191,12 +269,25 @@ static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix) {
return (Prefix + Name).str();
}

static inline bool shouldRecordFunctionAddr(Function *F) {
// Check the linkage
if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() &&
!F->hasAvailableExternallyLinkage())
return true;
// Check uses of this function for other than direct calls or invokes to it.
return F->hasAddressTaken();
}

GlobalVariable *
InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
GlobalVariable *NamePtr = Inc->getName();
auto It = RegionCounters.find(NamePtr);
if (It != RegionCounters.end())
return It->second;
auto It = ProfileDataMap.find(NamePtr);
PerFunctionProfileData PD;
if (It != ProfileDataMap.end()) {
if (It->second.RegionCounters)
return It->second.RegionCounters;
PD = It->second;
}

// Move the name variable to the right section. Place them in a COMDAT group
// if the associated function is a COMDAT. This will make sure that
Expand Down Expand Up @@ -225,29 +316,40 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
CounterPtr->setAlignment(8);
CounterPtr->setComdat(ProfileVarsComdat);

RegionCounters[Inc->getName()] = CounterPtr;

// Create data variable.

auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
auto *Int16Ty = Type::getInt16Ty(Ctx);
auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1);
Type *DataTypes[] = {
#define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType,
#include "llvm/ProfileData/InstrProfData.inc"
};
auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes));

Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ?
ConstantExpr::getBitCast(Fn, Int8PtrTy) :
ConstantPointerNull::get(Int8PtrTy);

Constant *Int16ArrayVals[IPVK_Last+1];
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]);

Constant *DataVals[] = {
#define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
#include "llvm/ProfileData/InstrProfData.inc"
};

auto *Data = new GlobalVariable(*M, DataTy, true, NamePtr->getLinkage(),
auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(),
ConstantStruct::get(DataTy, DataVals),
getVarName(Inc, getInstrProfDataVarPrefix()));
Data->setVisibility(NamePtr->getVisibility());
Data->setSection(getDataSection());
Data->setAlignment(8);
Data->setComdat(ProfileVarsComdat);

PD.RegionCounters = CounterPtr;
PD.DataVar = Data;
ProfileDataMap[NamePtr] = PD;

// Mark the data variable as used so that it isn't stripped out.
UsedVars.push_back(Data);

Expand Down Expand Up @@ -341,7 +443,6 @@ void InstrProfiling::emitUses() {
LLVMUsed =
new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, MergedVars), "llvm.used");

LLVMUsed->setSection("llvm.metadata");
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Instrumentation/InstrProfiling/PR23499.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ $_Z3barIvEvv = comdat any

; CHECK: @__llvm_profile_name__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", section "{{.*}}__llvm_prf_names", comdat($__llvm_profile_vars__Z3barIvEvv), align 1
; CHECK: @__llvm_profile_counters__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__llvm_profile_vars__Z3barIvEvv), align 8
; CHECK: @__llvm_profile_data__Z3barIvEvv = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__llvm_profile_name__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__llvm_profile_counters__Z3barIvEvv, i32 0, i32 0) }, section "{{.*}}__llvm_prf_data", comdat($__llvm_profile_vars__Z3barIvEvv), align 8
; CHECK: @__llvm_profile_data__Z3barIvEvv = linkonce_odr hidden global { i32, i32, i64, i8*, i64*, i8*, i8*, [1 x i16] } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__llvm_profile_name__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__llvm_profile_counters__Z3barIvEvv, i32 0, i32 0), i8* null, i8* null, [1 x i16] zeroinitializer }, section "{{.*}}__llvm_prf_data", comdat($__llvm_profile_vars__Z3barIvEvv), align 8

declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1

Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Instrumentation/InstrProfiling/linkage.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,28 @@
@__llvm_profile_name_foo_inline = linkonce_odr hidden constant [10 x i8] c"foo_inline"

; COMMON: @__llvm_profile_counters_foo = hidden global
; COMMON: @__llvm_profile_data_foo = hidden constant
; COMMON: @__llvm_profile_data_foo = hidden global
define void @foo() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
}

; COMMON: @__llvm_profile_counters_foo_weak = weak hidden global
; COMMON: @__llvm_profile_data_foo_weak = weak hidden constant
; COMMON: @__llvm_profile_data_foo_weak = weak hidden global
define weak void @foo_weak() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @__llvm_profile_name_foo_weak, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
}

; COMMON: @"__llvm_profile_counters_linkage.ll:foo_internal" = internal global
; COMMON: @"__llvm_profile_data_linkage.ll:foo_internal" = internal constant
; COMMON: @"__llvm_profile_data_linkage.ll:foo_internal" = internal global
define internal void @foo_internal() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"__llvm_profile_name_linkage.ll:foo_internal", i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
}

; COMMON: @__llvm_profile_counters_foo_inline = linkonce_odr hidden global
; COMMON: @__llvm_profile_data_foo_inline = linkonce_odr hidden constant
; COMMON: @__llvm_profile_data_foo_inline = linkonce_odr hidden global
define linkonce_odr void @foo_inline() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__llvm_profile_name_foo_inline, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
Expand Down
9 changes: 5 additions & 4 deletions llvm/test/Instrumentation/InstrProfiling/platform.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
; MACHO: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; ELF: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", align 8

; MACHO: @__llvm_profile_data_foo = hidden constant {{.*}}, section "__DATA,__llvm_prf_data", align 8
; LINUX: @__llvm_profile_data_foo = hidden constant {{.*}}, section "__llvm_prf_data", align 8
; FREEBSD: @__llvm_profile_data_foo = hidden constant {{.*}}, section "__llvm_prf_data", align 8
; SOLARIS: @__llvm_profile_data_foo = hidden constant {{.*}}, section "__llvm_prf_data", align 8
; MACHO: @__llvm_profile_data_foo = hidden {{.*}}, section "__DATA,__llvm_prf_data", align 8
; LINUX: @__llvm_profile_data_foo = hidden {{.*}}, section "__llvm_prf_data", align 8
; FREEBSD: @__llvm_profile_data_foo = hidden {{.*}}, section "__llvm_prf_data", align 8
; SOLARIS: @__llvm_profile_data_foo = hidden {{.*}}, section "__llvm_prf_data", align 8

define void @foo() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Instrumentation/InstrProfiling/profiling.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ target triple = "x86_64-apple-macosx10.10.0"
; CHECK: @baz_prof_name = hidden constant [3 x i8] c"baz", section "__DATA,__llvm_prf_names", align 1

; CHECK: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; CHECK: @__llvm_profile_data_foo = hidden constant {{.*}}, section "__DATA,__llvm_prf_data", align 8
; CHECK: @__llvm_profile_data_foo = hidden {{.*}}, section "__DATA,__llvm_prf_data", align 8
define void @foo() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
}

; CHECK: @__llvm_profile_counters_bar = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; CHECK: @__llvm_profile_data_bar = hidden constant {{.*}}, section "__DATA,__llvm_prf_data", align 8
; CHECK: @__llvm_profile_data_bar = hidden {{.*}}, section "__DATA,__llvm_prf_data", align 8
define void @bar() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @__llvm_profile_name_bar, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
}

; CHECK: @__llvm_profile_counters_baz = hidden global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
; CHECK: @__llvm_profile_data_baz = hidden constant {{.*}}, section "__DATA,__llvm_prf_data", align 8
; CHECK: @__llvm_profile_data_baz = hidden {{.*}}, section "__DATA,__llvm_prf_data", align 8
define void @baz() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @baz_prof_name, i32 0, i32 0), i64 0, i32 3, i32 0)
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @baz_prof_name, i32 0, i32 0), i64 0, i32 3, i32 1)
Expand Down
Binary file modified llvm/test/tools/llvm-profdata/Inputs/c-general.profraw
Binary file not shown.
6 changes: 3 additions & 3 deletions llvm/test/tools/llvm-profdata/c-general.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ REGENERATE: $ SRC=path/to/llvm
REGENERATE: $ CFE=$SRC/tools/clang
REGENERATE: $ TESTDIR=$SRC/test/tools/llvm-profdata
REGENERATE: $ CFE_TESTDIR=$CFE/test/Profile
REGENERATE: $ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/test/Profile/c-general.c
REGENERATE: $ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/c-general.c
REGENERATE: $ LLVM_PROFILE_FILE=$TESTDIR/Inputs/c-general.profraw ./a.out

RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - | FileCheck %s -check-prefix=CHECK
RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - --function=switches | FileCheck %s -check-prefix=SWITCHES -check-prefix=CHECK

SWITCHES-LABEL: Counters:
SWITCHES-NEXT: switches:
SWITCHES-NEXT: Hash: 0x0000000000000013
SWITCHES-NEXT: Hash: 0x2618e4f23f2e8daa
SWITCHES-NEXT: Counters: 19
SWITCHES-NEXT: Function count: 1
SWITCHES-LABEL: Functions shown: 1

CHECK-LABEL: Total functions: 11
CHECK-LABEL: Total functions: 12
CHECK-NEXT: Maximum function count: 1
CHECK-NEXT: Maximum internal block count: 100
13 changes: 11 additions & 2 deletions llvm/test/tools/llvm-profdata/raw-32-bits-be.test
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
RUN: printf '\377lprofR\201' > %t
RUN: printf '\0\0\0\0\0\0\0\1' >> %t
RUN: printf '\0\0\0\0\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\3' >> %t
RUN: printf '\0\0\0\0\0\0\0\6' >> %t
RUN: printf '\0\0\0\0\1\0\0\0' >> %t
RUN: printf '\0\0\0\0\2\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\3' >> %t
RUN: printf '\0\0\0\1' >> %t
RUN: printf '\0\0\0\0\0\0\0\1' >> %t
RUN: printf '\2\0\0\0' >> %t
RUN: printf '\1\0\0\0' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\3' >> %t
RUN: printf '\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\2' >> %t
RUN: printf '\2\0\0\03' >> %t
RUN: printf '\1\0\0\10' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\0\0\0\0\023' >> %t
RUN: printf '\0\0\0\0\0\0\0\067' >> %t
RUN: printf '\0\0\0\0\0\0\0\101' >> %t
RUN: printf 'foobar' >> %t
RUN: printf 'foobar\0\0' >> %t

RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s

Expand Down
13 changes: 11 additions & 2 deletions llvm/test/tools/llvm-profdata/raw-32-bits-le.test
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
RUN: printf '\201Rforpl\377' > %t
RUN: printf '\1\0\0\0\0\0\0\0' >> %t
RUN: printf '\2\0\0\0\0\0\0\0' >> %t
RUN: printf '\2\0\0\0\0\0\0\0' >> %t
RUN: printf '\3\0\0\0\0\0\0\0' >> %t
RUN: printf '\6\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\1\0\0\0\0' >> %t
RUN: printf '\0\0\0\2\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\3\0\0\0' >> %t
RUN: printf '\1\0\0\0' >> %t
RUN: printf '\1\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\2' >> %t
RUN: printf '\0\0\0\1' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\3\0\0\0' >> %t
RUN: printf '\2\0\0\0' >> %t
RUN: printf '\02\0\0\0\0\0\0\0' >> %t
RUN: printf '\03\0\0\2' >> %t
RUN: printf '\10\0\0\1' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\023\0\0\0\0\0\0\0' >> %t
RUN: printf '\067\0\0\0\0\0\0\0' >> %t
RUN: printf '\101\0\0\0\0\0\0\0' >> %t
RUN: printf 'foobar' >> %t
RUN: printf 'foobar\0\0' >> %t

RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s

Expand Down
13 changes: 11 additions & 2 deletions llvm/test/tools/llvm-profdata/raw-64-bits-be.test
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
RUN: printf '\377lprofr\201' > %t
RUN: printf '\0\0\0\0\0\0\0\1' >> %t
RUN: printf '\0\0\0\0\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\3' >> %t
RUN: printf '\0\0\0\0\0\0\0\6' >> %t
RUN: printf '\0\0\0\1\0\4\0\0' >> %t
RUN: printf '\0\0\0\2\0\4\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\3' >> %t
RUN: printf '\0\0\0\1' >> %t
RUN: printf '\0\0\0\0\0\0\0\1' >> %t
RUN: printf '\0\0\0\2\0\4\0\0' >> %t
RUN: printf '\0\0\0\1\0\4\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\3' >> %t
RUN: printf '\0\0\0\2' >> %t
RUN: printf '\0\0\0\0\0\0\0\02' >> %t
RUN: printf '\0\0\0\2\0\4\0\03' >> %t
RUN: printf '\0\0\0\1\0\4\0\10' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\0\0\0\0\0\0\0\023' >> %t
RUN: printf '\0\0\0\0\0\0\0\067' >> %t
RUN: printf '\0\0\0\0\0\0\0\101' >> %t
RUN: printf 'foobar' >> %t
RUN: printf 'foobar\0\0' >> %t

RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s

Expand Down
13 changes: 11 additions & 2 deletions llvm/test/tools/llvm-profdata/raw-64-bits-le.test
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
RUN: printf '\201rforpl\377' > %t
RUN: printf '\1\0\0\0\0\0\0\0' >> %t
RUN: printf '\2\0\0\0\0\0\0\0' >> %t
RUN: printf '\2\0\0\0\0\0\0\0' >> %t
RUN: printf '\3\0\0\0\0\0\0\0' >> %t
RUN: printf '\6\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\4\0\1\0\0\0' >> %t
RUN: printf '\0\0\4\0\2\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\3\0\0\0' >> %t
RUN: printf '\1\0\0\0' >> %t
RUN: printf '\1\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\4\0\2\0\0\0' >> %t
RUN: printf '\0\0\4\0\1\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\03\0\0\0' >> %t
RUN: printf '\02\0\0\0' >> %t
RUN: printf '\02\0\0\0\0\0\0\0' >> %t
RUN: printf '\03\0\4\0\2\0\0\0' >> %t
RUN: printf '\10\0\4\0\1\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t
RUN: printf '\0\0\0\0\0\0\0\0' >> %t

RUN: printf '\023\0\0\0\0\0\0\0' >> %t
RUN: printf '\067\0\0\0\0\0\0\0' >> %t
RUN: printf '\101\0\0\0\0\0\0\0' >> %t
RUN: printf 'foobar' >> %t
RUN: printf 'foobar\0\0' >> %t

RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s

Expand Down
31 changes: 17 additions & 14 deletions llvm/test/tools/llvm-profdata/raw-two-profiles.test
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
RUN: printf '\201rforpl\377' > %t-foo.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\2\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\3\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\4\0\1\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\4\0\2\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw

RUN: printf '\3\0\0\0' >> %t-foo.profraw
RUN: printf '\1\0\0\0' >> %t-foo.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\4\0\2\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\4\0\1\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw

RUN: printf '\023\0\0\0\0\0\0\0' >> %t-foo.profraw
RUN: printf 'foo' >> %t-foo.profraw
RUN: printf 'foo\0\0\0\0\0' >> %t-foo.profraw

RUN: printf '\201rforpl\377' > %t-bar.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\1\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\3\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\6\0\1\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\6\0\2\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw

RUN: printf '\3\0\0\0' >> %t-bar.profraw
RUN: printf '\2\0\0\0' >> %t-bar.profraw
RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\6\0\2\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\6\0\1\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw

RUN: printf '\067\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf '\101\0\0\0\0\0\0\0' >> %t-bar.profraw
RUN: printf 'bar' >> %t-bar.profraw

Versions of the profiles that are padded to eight byte alignment.
RUN: cat %t-foo.profraw > %t-foo-padded.profraw
RUN: printf '\0\0\0\0\0' >> %t-foo-padded.profraw
RUN: cat %t-bar.profraw > %t-bar-padded.profraw
RUN: printf '\0\0\0\0\0' >> %t-bar-padded.profraw

RUN: cat %t-foo-padded.profraw %t-bar.profraw > %t-pad-between.profraw
RUN: cat %t-foo-padded.profraw %t-bar-padded.profraw > %t-pad.profraw
RUN: printf 'bar\0\0\0\0\0' >> %t-bar.profraw

RUN: llvm-profdata show %t-pad-between.profraw -all-functions -counts | FileCheck %s
RUN: cat %t-foo.profraw %t-bar.profraw > %t-pad.profraw
RUN: llvm-profdata show %t-pad.profraw -all-functions -counts | FileCheck %s

CHECK: Counters:
Expand Down