[llvm] r253484 - [PGO] Value profiling support

Xinliang David Li via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 18 14:46:02 PST 2015


Some of formatting issues are from previous patches. All the problems
mentioned are now fixed.

David


On Wed, Nov 18, 2015 at 1:01 PM, Justin Bogner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> 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
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151118/6fbec9be/attachment-0001.html>


More information about the llvm-commits mailing list