[llvm] r253484 - [PGO] Value profiling support
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 18 13:01:41 PST 2015
Betul Buyukkurt via llvm-commits <llvm-commits at lists.llvm.org> writes:
> Author: betulb
> Date: Wed Nov 18 12:14:55 2015
> New Revision: 253484
>
> URL: http://llvm.org/viewvc/llvm-project?rev=253484&view=rev
> Log:
> [PGO] Value profiling support
>
> This change introduces an instrumentation intrinsic instruction for
> value profiling purposes, the lowering of the instrumentation intrinsic
> and raw reader updates. The raw profile data files for llvm-profdata
> testing are updated.
>
>
> Modified:
> llvm/trunk/docs/LangRef.rst
> llvm/trunk/include/llvm/IR/IntrinsicInst.h
> llvm/trunk/include/llvm/IR/Intrinsics.td
> llvm/trunk/include/llvm/ProfileData/InstrProf.h
> llvm/trunk/include/llvm/ProfileData/InstrProfData.inc
> llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> llvm/trunk/lib/ProfileData/InstrProfReader.cpp
> llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
> llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll
> llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll
> llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll
> llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll
> llvm/trunk/test/tools/llvm-profdata/Inputs/c-general.profraw
> llvm/trunk/test/tools/llvm-profdata/c-general.test
> llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test
> llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test
> llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test
> llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test
> llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test
>
> Modified: llvm/trunk/docs/LangRef.rst
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/docs/LangRef.rst (original)
> +++ llvm/trunk/docs/LangRef.rst Wed Nov 18 12:14:55 2015
> @@ -9514,6 +9514,55 @@ structures and the code to increment the
> format that can be written out by a compiler runtime and consumed via
> the ``llvm-profdata`` tool.
>
> +'``llvm.instrprof_value_profile``' Intrinsic
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Syntax:
> +"""""""
> +
> +::
> +
> + declare void @llvm.instrprof_value_profile(i8* <name>, i64 <hash>,
> + i64 <value>, i32 <value_kind>,
> + i32 <index>)
> +
> +Overview:
> +"""""""""
> +
> +The '``llvm.instrprof_value_profile``' intrinsic can be emitted by a
> +frontend for use with instrumentation based profiling. This will be
> +lowered by the ``-instrprof`` pass to find out the target values,
> +instrumented expressions take in a program at runtime.
> +
> +Arguments:
> +""""""""""
> +
> +The first argument is a pointer to a global variable containing the
> +name of the entity being instrumented. ``name`` should generally be the
> +(mangled) function name for a set of counters.
> +
> +The second argument is a hash value that can be used by the consumer
> +of the profile data to detect changes to the instrumented source. It
> +is an error if ``hash`` differs between two instances of
> +``llvm.instrprof_*`` that refer to the same name.
> +
> +The third argument is the value of the expression being profiled. The profiled
> +expression's value should be representable as an unsigned 64-bit value. The
> +fourth argument represents the kind of value profiling that is being done. The
> +supported value profiling kinds are enumerated through the
> +``InstrProfValueKind`` type declared in the
> +``<include/llvm/ProfileData/InstrProf.h>`` header file. The last argument is the
> +index of the instrumented expression within ``name``. It should be >= 0.
> +
> +Semantics:
> +""""""""""
> +
> +This intrinsic represents the point where a call to a runtime routine
> +should be inserted for value profiling of target expressions. ``-instrprof``
> +pass will generate the appropriate data structures and replace the
> +``llvm.instrprof_value_profile`` intrinsic with the call to the profile
> +runtime library with proper arguments.
> +
> Standard C Library Intrinsics
> -----------------------------
>
>
> Modified: llvm/trunk/include/llvm/IR/IntrinsicInst.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/IntrinsicInst.h (original)
> +++ llvm/trunk/include/llvm/IR/IntrinsicInst.h Wed Nov 18 12:14:55 2015
> @@ -372,6 +372,39 @@ namespace llvm {
> return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
> }
> };
> -}
> +
> + /// This represents the llvm.instrprof_value_profile intrinsic.
> + class InstrProfValueProfileInst : public IntrinsicInst {
> + public:
> + static inline bool classof(const IntrinsicInst *I) {
> + return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
> + }
> + static inline bool classof(const Value *V) {
> + return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
> + }
> +
> + GlobalVariable *getName() const {
> + return cast<GlobalVariable>(
> + const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
> + }
> +
> + ConstantInt *getHash() const {
> + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
> + }
> +
> + Value *getTargetValue() const {
> + return cast<Value>(const_cast<Value *>(getArgOperand(2)));
> + }
> +
> + ConstantInt *getValueKind() const {
> + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
> + }
> +
> + // Returns the value site index.
> + ConstantInt *getIndex() const {
> + return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
> + }
> + };
> +} // namespace llvm
>
> #endif
>
> Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
> +++ llvm/trunk/include/llvm/IR/Intrinsics.td Wed Nov 18 12:14:55 2015
> @@ -319,7 +319,15 @@ def int_instrprof_increment : Intrinsic<
> [llvm_ptr_ty, llvm_i64_ty,
> llvm_i32_ty, llvm_i32_ty],
> []>;
> -
> +
> +// A call to profile runtime for value profiling of target expressions
> +// through instrumentation based profiling.
> +def int_instrprof_value_profile : Intrinsic<[],
> + [llvm_ptr_ty, llvm_i64_ty,
> + llvm_i64_ty, llvm_i32_ty,
> + llvm_i32_ty],
> + []>;
> +
> //===------------------- Standard C Library Intrinsics --------------------===//
> //
>
>
> Modified: llvm/trunk/include/llvm/ProfileData/InstrProf.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ProfileData/InstrProf.h (original)
> +++ llvm/trunk/include/llvm/ProfileData/InstrProf.h Wed Nov 18 12:14:55 2015
> @@ -265,7 +265,7 @@ struct InstrProfRecord {
> inline void addValueData(uint32_t ValueKind, uint32_t Site,
> InstrProfValueData *VData, uint32_t N,
> ValueMapType *HashKeys);
> - /// Merge Value Profile ddata from Src record to this record for ValueKind.
> + /// Merge Value Profile data from Src record to this record for ValueKind.
> inline instrprof_error mergeValueProfData(uint32_t ValueKind,
> InstrProfRecord &Src);
>
> @@ -273,6 +273,12 @@ struct InstrProfRecord {
> /// the writer instance.
> inline void updateStrings(InstrProfStringTable *StrTab);
>
> + /// Clear value data entries
> + inline void clearValueData() {
> + for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
> + getValueSitesForKind(Kind).clear();
> + }
> +
> private:
> std::vector<InstrProfValueSiteRecord> IndirectCallSites;
> const std::vector<InstrProfValueSiteRecord> &
> @@ -292,6 +298,7 @@ private:
> const_cast<const InstrProfRecord *>(this)
> ->getValueSitesForKind(ValueKind));
> }
> +
> // Map indirect call target name hash to name string.
> uint64_t remapValue(uint64_t Value, uint32_t ValueKind,
> ValueMapType *HashKeys) {
> @@ -303,9 +310,8 @@ private:
> std::lower_bound(HashKeys->begin(), HashKeys->end(), Value,
> [](const std::pair<uint64_t, const char *> &LHS,
> uint64_t RHS) { return LHS.first < RHS; });
> - assert(Result != HashKeys->end() &&
> - "Hash does not match any known keys\n");
> - Value = (uint64_t)Result->second;
> + if (Result != HashKeys->end())
> + Value = (uint64_t)Result->second;
> break;
> }
> }
> @@ -464,7 +470,7 @@ struct ValueProfData {
> // The number of value profile kinds that has value profile data.
> // In this implementation, a value profile kind is considered to
> // have profile data if the number of value profile sites for the
> - // kind is not zero. More aggressively, the implemnetation can
> + // kind is not zero. More aggressively, the implementation can
> // choose to check the actual data value: if none of the value sites
> // has any profiled values, the kind can be skipped.
> uint32_t NumValueKinds;
> @@ -545,7 +551,7 @@ struct Header {
>
> namespace RawInstrProf {
>
> -const uint64_t Version = 1;
> +const uint64_t Version = 2;
>
> // Magic number to detect file format and endianness.
> // Use 255 at one end, since no UTF-8 file can use that character. Avoid 0,
> @@ -577,7 +583,7 @@ inline uint64_t getMagic<uint32_t>() {
> // compiler-rt/lib/profile/InstrProfiling.h.
> // It should also match the synthesized type in
> // Transforms/Instrumentation/InstrProfiling.cpp:getOrCreateRegionCounters.
> -template <class IntPtrT> struct ProfileData {
> +template <class IntPtrT> struct LLVM_ALIGNAS(8) ProfileData {
> #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Type Name;
> #include "llvm/ProfileData/InstrProfData.inc"
> };
> @@ -594,6 +600,9 @@ struct Header {
> const uint64_t NamesSize;
> const uint64_t CountersDelta;
> const uint64_t NamesDelta;
> + const uint64_t ValueKindLast;
> + const uint64_t ValueDataSize;
> + const uint64_t ValueDataDelta;
> };
>
> } // end namespace RawInstrProf
>
> Modified: llvm/trunk/include/llvm/ProfileData/InstrProfData.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfData.inc?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ProfileData/InstrProfData.inc (original)
> +++ llvm/trunk/include/llvm/ProfileData/InstrProfData.inc Wed Nov 18 12:14:55 2015
> @@ -56,6 +56,12 @@ INSTR_PROF_DATA(const IntPtrT, llvm::Typ
> INSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt64PtrTy(Ctx), CounterPtr, \
> ConstantExpr::getBitCast(CounterPtr, \
> llvm::Type::getInt64PtrTy(Ctx)))
> +INSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), FunctionPointer, \
> + FunctionAddr)
> +INSTR_PROF_DATA(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \
> + ConstantPointerNull::get(Int8PtrTy))
> +INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \
> + ConstantArray::get(Int16ArrayTy, Int16ArrayVals))
> // INSTR_PROF_DATA_END
>
> #ifdef INSTR_PROF_DATA
>
> Modified: llvm/trunk/include/llvm/ProfileData/InstrProfReader.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProfReader.h?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ProfileData/InstrProfReader.h (original)
> +++ llvm/trunk/include/llvm/ProfileData/InstrProfReader.h Wed Nov 18 12:14:55 2015
> @@ -20,10 +20,12 @@
> #include "llvm/ProfileData/InstrProf.h"
> #include "llvm/Support/EndianStream.h"
> #include "llvm/Support/ErrorOr.h"
> +#include "llvm/Support/raw_ostream.h"
> #include "llvm/Support/LineIterator.h"
> #include "llvm/Support/MemoryBuffer.h"
> #include "llvm/Support/OnDiskHashTable.h"
> #include <iterator>
> +#include <map>
Is <map> used? I think this include's left over from an earlier
iteration.
>
> namespace llvm {
>
> @@ -132,15 +134,21 @@ class RawInstrProfReader : public InstrP
> private:
> /// The profile data file contents.
> std::unique_ptr<MemoryBuffer> DataBuffer;
> -
> bool ShouldSwapBytes;
> uint64_t CountersDelta;
> uint64_t NamesDelta;
> + uint64_t ValueDataDelta;
> const RawInstrProf::ProfileData<IntPtrT> *Data;
> const RawInstrProf::ProfileData<IntPtrT> *DataEnd;
> const uint64_t *CountersStart;
> const char *NamesStart;
> + const uint8_t *ValueDataStart;
> const char *ProfileEnd;
> + uint32_t ValueKindLast;
> +
> + // String table for holding a unique copy of all the strings in the profile.
> + InstrProfStringTable StringTable;
> + InstrProfRecord::ValueMapType FunctionPtrToNameMap;
>
> RawInstrProfReader(const RawInstrProfReader &) = delete;
> RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
> @@ -159,10 +167,13 @@ private:
> IntT swap(IntT Int) const {
> return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;
> }
> -
> + inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {
> + return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));
> + }
> std::error_code readName(InstrProfRecord &Record);
> std::error_code readFuncHash(InstrProfRecord &Record);
> std::error_code readRawCounts(InstrProfRecord &Record);
> + std::error_code readValueData(InstrProfRecord &Record);
> bool atEnd() const { return Data == DataEnd; }
> void advanceData() { Data++; }
>
> @@ -174,6 +185,15 @@ private:
> ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
> return NamesStart + Offset;
> }
> + const uint8_t *getValueDataCounts(IntPtrT ValueCountsPtr) const {
> + ptrdiff_t Offset = (swap(ValueCountsPtr) - ValueDataDelta) / sizeof(uint8_t);
> + return ValueDataStart + Offset;
> + }
> + // This accepts an already byte-swapped ValueDataPtr argument.
> + const InstrProfValueData *getValueData(IntPtrT ValueDataPtr) const {
> + ptrdiff_t Offset = (ValueDataPtr - ValueDataDelta) / sizeof(uint8_t);
> + return reinterpret_cast<const InstrProfValueData*>(ValueDataStart + Offset);
Some of the formatting looks a bit off, here and in a few places
elsewhere in the patch. Did you remember to use clang-format?
> + }
> };
>
> typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;
> @@ -303,6 +323,7 @@ private:
> /// Fill Counts with the profile data for the given function name.
> std::error_code getFunctionCounts(StringRef FuncName, uint64_t FuncHash,
> std::vector<uint64_t> &Counts);
> +
> /// Return the maximum of all known function counts.
> uint64_t getMaximumFunctionCount() { return MaxFunctionCount; }
>
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Wed Nov 18 12:14:55 2015
> @@ -5211,7 +5211,8 @@ SelectionDAGBuilder::visitIntrinsicCall(
> }
> case Intrinsic::instrprof_increment:
> llvm_unreachable("instrprof failed to lower an increment");
> -
> + case Intrinsic::instrprof_value_profile:
> + llvm_unreachable("instrprof failed to lower a value profiling call");
> case Intrinsic::localescape: {
> MachineFunction &MF = DAG.getMachineFunction();
> const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo();
>
> Modified: llvm/trunk/lib/ProfileData/InstrProfReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ProfileData/InstrProfReader.cpp (original)
> +++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp Wed Nov 18 12:14:55 2015
> @@ -206,15 +206,21 @@ std::error_code RawInstrProfReader<IntPt
>
> 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())
> @@ -225,8 +231,23 @@ std::error_code RawInstrProfReader<IntPt
> 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();
> }
>
> @@ -234,9 +255,8 @@ 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)
We generally prefer C++ conversions to C-style casts, so I would expect
reinterpret_cast here.
> return error(instrprof_error::malformed);
> -
> return success();
> }
>
> @@ -275,8 +295,54 @@ std::error_code RawInstrProfReader<IntPt
> }
>
> 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)
Similarly here.
> + 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;
> @@ -293,6 +359,9 @@ RawInstrProfReader<IntPtrT>::readNextRec
> 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();
>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp (original)
> +++ llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp Wed Nov 18 12:14:55 2015
> @@ -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;
> @@ -50,7 +49,15 @@ public:
> 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 {
> @@ -77,6 +84,12 @@ private:
> 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);
>
> @@ -118,21 +131,37 @@ bool InstrProfiling::runOnModule(Module
> 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;
>
> @@ -143,6 +172,54 @@ bool InstrProfiling::runOnModule(Module
> 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);
>
> @@ -174,9 +251,10 @@ void InstrProfiling::lowerCoverageData(G
> 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());
> @@ -191,12 +269,25 @@ static std::string getVarName(InstrProfI
> 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
> @@ -225,22 +316,29 @@ InstrProfiling::getOrCreateRegionCounter
> 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());
> @@ -248,6 +346,10 @@ InstrProfiling::getOrCreateRegionCounter
> 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);
>
> @@ -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");
> }
>
>
> Modified: llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll (original)
> +++ llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll Wed Nov 18 12:14:55 2015
> @@ -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
>
>
> Modified: llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll (original)
> +++ llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll Wed Nov 18 12:14:55 2015
> @@ -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
>
> Modified: llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll (original)
> +++ llvm/trunk/test/Instrumentation/InstrProfiling/platform.ll Wed Nov 18 12:14:55 2015
> @@ -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
>
> Modified: llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll (original)
> +++ llvm/trunk/test/Instrumentation/InstrProfiling/profiling.ll Wed Nov 18 12:14:55 2015
> @@ -10,21 +10,21 @@ target triple = "x86_64-apple-macosx10.1
> ; 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)
>
> Modified: llvm/trunk/test/tools/llvm-profdata/Inputs/c-general.profraw
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/Inputs/c-general.profraw?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-profdata/Inputs/c-general.profraw (original) and llvm/trunk/test/tools/llvm-profdata/Inputs/c-general.profraw Wed Nov 18 12:14:55 2015 differ
>
> Modified: llvm/trunk/test/tools/llvm-profdata/c-general.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/c-general.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/c-general.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/c-general.test Wed Nov 18 12:14:55 2015
> @@ -6,7 +6,7 @@ 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
> @@ -14,11 +14,11 @@ RUN: llvm-profdata show %p/Inputs/c-gene
>
> 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
>
> Modified: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-be.test Wed Nov 18 12:14:55 2015
> @@ -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
>
>
> Modified: llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/raw-32-bits-le.test Wed Nov 18 12:14:55 2015
> @@ -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
>
>
> Modified: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-be.test Wed Nov 18 12:14:55 2015
> @@ -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
>
>
> Modified: llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/raw-64-bits-le.test Wed Nov 18 12:14:55 2015
> @@ -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
>
>
> Modified: llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test?rev=253484&r1=253483&r2=253484&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test (original)
> +++ llvm/trunk/test/tools/llvm-profdata/raw-two-profiles.test Wed Nov 18 12:14:55 2015
> @@ -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:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list