[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