[llvm] r335306 - [Instrumentation] Add Call Graph Profile pass

Michael Spencer via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 21 19:15:20 PDT 2018


That's fine with me.  Thanks again for looking into this.

On Thu, Jun 21, 2018, 6:56 PM Chandler Carruth <chandlerc at gmail.com> wrote:

> I think I'm going ot have to revert this. I fixed the test failure, but
> this patch is also causing us to leak memory.
>
> The embedded function analysis support in the legacy PM *really* doesn't
> work well. In addition to breaking the '-debug-pass=Structure' output, it
> also appears to leak memory.
>
> You can see the ASan leak reports here:
>
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/6067/
>
> I'm not likely to have energy to debug this nasty part of the legacy PM.
> Personally, I'd suggest just adding this to the new PM and skipping the
> legacy PM. It doesn't seem worth the trouble. We're also *remarkably* close
> to being ready to switch the defaults.
>
> On Thu, Jun 21, 2018 at 4:35 PM Michael J. Spencer via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: mspencer
>> Date: Thu Jun 21 16:31:10 2018
>> New Revision: 335306
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=335306&view=rev
>> Log:
>> [Instrumentation] Add Call Graph Profile pass
>>
>> This patch adds support for generating a call graph profile from Branch
>> Frequency Info.
>>
>> The CGProfile module pass simply gets the block profile count for each BB
>> and scans for call instructions. For each call instruction it adds an edge
>> from the current function to the called function with the current BB block
>> profile count as the weight.
>>
>> After scanning all the functions, it generates an appending module flag
>> containing the data. The format looks like:
>>
>> !llvm.module.flags = !{!0}
>>
>> !0 = !{i32 5, !"CG Profile", !1}
>> !1 = !{!2, !3, !4} ; List of edges
>> !2 = !{void ()* @a, void ()* @b, i64 32} ; Edge from a to b with a weight
>> of 32
>> !3 = !{void (i1)* @freq, void ()* @a, i64 11}
>> !4 = !{void (i1)* @freq, void ()* @b, i64 20}
>>
>> Differential Revision: https://reviews.llvm.org/D48105
>>
>> Added:
>>     llvm/trunk/lib/Transforms/Instrumentation/CGProfile.cpp
>>     llvm/trunk/test/Instrumentation/cgprofile.ll
>>     llvm/trunk/test/MC/ELF/cgprofile.ll
>>     llvm/trunk/test/Verifier/module-flags-cgprofile.ll
>> Modified:
>>     llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
>>     llvm/trunk/include/llvm/InitializePasses.h
>>     llvm/trunk/include/llvm/LinkAllPasses.h
>>     llvm/trunk/include/llvm/Transforms/Instrumentation.h
>>     llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>>     llvm/trunk/lib/IR/Verifier.cpp
>>     llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
>>     llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
>>     llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
>> (original)
>> +++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Thu
>> Jun 21 16:31:10 2018
>> @@ -36,11 +36,14 @@ class TargetLoweringObjectFileELF : publ
>>  protected:
>>    MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =
>>        MCSymbolRefExpr::VK_None;
>> +  const TargetMachine *TM;
>>
>>  public:
>>    TargetLoweringObjectFileELF() = default;
>>    ~TargetLoweringObjectFileELF() override = default;
>>
>> +  void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
>> +
>>    /// Emit Obj-C garbage collection and linker options.
>>    void emitModuleMetadata(MCStreamer &Streamer, Module &M) const
>> override;
>>
>>
>> Modified: llvm/trunk/include/llvm/InitializePasses.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/InitializePasses.h (original)
>> +++ llvm/trunk/include/llvm/InitializePasses.h Thu Jun 21 16:31:10 2018
>> @@ -94,6 +94,7 @@ void initializeCFGViewerLegacyPassPass(P
>>  void initializeCFIInstrInserterPass(PassRegistry&);
>>  void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
>>  void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
>> +void initializeCGProfilePassPass(PassRegistry&);
>>  void initializeCallGraphDOTPrinterPass(PassRegistry&);
>>  void initializeCallGraphPrinterLegacyPassPass(PassRegistry&);
>>  void initializeCallGraphViewerPass(PassRegistry&);
>>
>> Modified: llvm/trunk/include/llvm/LinkAllPasses.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
>> +++ llvm/trunk/include/llvm/LinkAllPasses.h Thu Jun 21 16:31:10 2018
>> @@ -80,6 +80,7 @@ namespace {
>>        (void) llvm::createCallGraphDOTPrinterPass();
>>        (void) llvm::createCallGraphViewerPass();
>>        (void) llvm::createCFGSimplificationPass();
>> +      (void) llvm::createCGProfilePass();
>>        (void) llvm::createCFLAndersAAWrapperPass();
>>        (void) llvm::createCFLSteensAAWrapperPass();
>>        (void) llvm::createStructurizeCFGPass();
>>
>> Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
>> +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Thu Jun 21
>> 16:31:10 2018
>> @@ -187,6 +187,8 @@ struct SanitizerCoverageOptions {
>>  ModulePass *createSanitizerCoverageModulePass(
>>      const SanitizerCoverageOptions &Options =
>> SanitizerCoverageOptions());
>>
>> +ModulePass *createCGProfilePass();
>> +
>>  /// Calculate what to divide by to scale counts.
>>  ///
>>  /// Given the maximum count, calculate a divisor that will scale all the
>>
>> Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Jun 21
>> 16:31:10 2018
>> @@ -91,6 +91,12 @@ static void GetObjCImageInfo(Module &M,
>>  //                                  ELF
>>
>>  //===----------------------------------------------------------------------===//
>>
>> +void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
>> +                                             const TargetMachine &TgtM) {
>> +  TargetLoweringObjectFile::Initialize(Ctx, TgtM);
>> +  TM = &TgtM;
>> +}
>> +
>>  void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer
>> &Streamer,
>>                                                       Module &M) const {
>>    auto &C = getContext();
>> @@ -116,15 +122,49 @@ void TargetLoweringObjectFileELF::emitMo
>>    StringRef Section;
>>
>>    GetObjCImageInfo(M, Version, Flags, Section);
>> -  if (Section.empty())
>> +  if (!Section.empty()) {
>> +    auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS,
>> ELF::SHF_ALLOC);
>> +    Streamer.SwitchSection(S);
>> +
>> Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
>> +    Streamer.EmitIntValue(Version, 4);
>> +    Streamer.EmitIntValue(Flags, 4);
>> +    Streamer.AddBlankLine();
>> +  }
>> +
>> +  SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
>> +  M.getModuleFlagsMetadata(ModuleFlags);
>> +
>> +  MDNode *CFGProfile = nullptr;
>> +
>> +  for (const auto &MFE : ModuleFlags) {
>> +    StringRef Key = MFE.Key->getString();
>> +    if (Key == "CG Profile") {
>> +      CFGProfile = cast<MDNode>(MFE.Val);
>> +      break;
>> +    }
>> +  }
>> +
>> +  if (!CFGProfile)
>>      return;
>>
>> -  auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
>> -  Streamer.SwitchSection(S);
>> -  Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
>> -  Streamer.EmitIntValue(Version, 4);
>> -  Streamer.EmitIntValue(Flags, 4);
>> -  Streamer.AddBlankLine();
>> +  auto GetSym = [this](const MDOperand &MDO) {
>> +    auto V = cast<ValueAsMetadata>(MDO);
>> +    const Function *F = cast<Function>(V->getValue());
>> +    return TM->getSymbol(F);
>> +  };
>> +
>> +  for (const auto &Edge : CFGProfile->operands()) {
>> +    MDNode *E = cast<MDNode>(Edge);
>> +    const MCSymbol *From = GetSym(E->getOperand(0));
>> +    const MCSymbol *To = GetSym(E->getOperand(1));
>> +    uint64_t Count = cast<ConstantAsMetadata>(E->getOperand(2))
>> +                         ->getValue()
>> +                         ->getUniqueInteger()
>> +                         .getZExtValue();
>> +    Streamer.emitCGProfileEntry(
>> +        MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
>> +        MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
>> +  }
>>  }
>>
>>  MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
>>
>> Modified: llvm/trunk/lib/IR/Verifier.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/IR/Verifier.cpp (original)
>> +++ llvm/trunk/lib/IR/Verifier.cpp Thu Jun 21 16:31:10 2018
>> @@ -409,6 +409,7 @@ private:
>>    void visitModuleFlag(const MDNode *Op,
>>                         DenseMap<const MDString *, const MDNode *>
>> &SeenIDs,
>>                         SmallVectorImpl<const MDNode *> &Requirements);
>> +  void visitModuleFlagCGProfileEntry(const MDOperand &MDO);
>>    void visitFunction(const Function &F);
>>    void visitBasicBlock(BasicBlock &BB);
>>    void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
>> @@ -1411,6 +1412,25 @@ Verifier::visitModuleFlag(const MDNode *
>>      Assert(M.getNamedMetadata("llvm.linker.options"),
>>             "'Linker Options' named metadata no longer supported");
>>    }
>> +
>> +  if (ID->getString() == "CG Profile") {
>> +    for (const MDOperand &MDO :
>> cast<MDNode>(Op->getOperand(2))->operands())
>> +      visitModuleFlagCGProfileEntry(MDO);
>> +  }
>> +}
>> +
>> +void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) {
>> +  auto Node = dyn_cast_or_null<MDNode>(MDO);
>> +  Assert(Node && Node->getNumOperands() == 3, "expected a MDNode
>> triple", MDO);
>> +  auto From = dyn_cast_or_null<ValueAsMetadata>(Node->getOperand(0));
>> +  Assert(From && isa<Function>(From->getValue()), "expected a Function",
>> +         Node->getOperand(0));
>> +  auto To = dyn_cast_or_null<ValueAsMetadata>(Node->getOperand(1));
>> +  Assert(To && isa<Function>(To->getValue()), "expected a Function",
>> +         Node->getOperand(1));
>> +  auto Count = dyn_cast_or_null<ConstantAsMetadata>(Node->getOperand(2));
>> +  Assert(Count && Count->getType()->isIntegerTy(),
>> +         "expected an integer constant", Node->getOperand(2));
>>  }
>>
>>  /// Return true if this attribute kind only applies to functions.
>>
>> Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
>> +++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Jun 21
>> 16:31:10 2018
>> @@ -694,6 +694,8 @@ void PassManagerBuilder::populateModuleP
>>      MPM.add(createConstantMergePass());     // Merge dup global constants
>>    }
>>
>> +  MPM.add(createCGProfilePass());
>> +
>>    if (MergeFunctions)
>>      MPM.add(createMergeFunctionsPass());
>>
>>
>> Added: llvm/trunk/lib/Transforms/Instrumentation/CGProfile.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/CGProfile.cpp?rev=335306&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/CGProfile.cpp (added)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/CGProfile.cpp Thu Jun 21
>> 16:31:10 2018
>> @@ -0,0 +1,110 @@
>> +//===-- CGProfile.cpp
>> -----------------------------------------------------===//
>> +//
>> +//                      The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>>
>> +//===----------------------------------------------------------------------===//
>> +
>> +#include "llvm/ADT/MapVector.h"
>> +#include "llvm/Analysis/BlockFrequencyInfo.h"
>> +#include "llvm/Analysis/BranchProbabilityInfo.h"
>> +#include "llvm/IR/Constants.h"
>> +#include "llvm/IR/Instructions.h"
>> +#include "llvm/IR/MDBuilder.h"
>> +#include "llvm/IR/PassManager.h"
>> +#include "llvm/Transforms/Instrumentation.h"
>> +
>> +#include <array>
>> +
>> +using namespace llvm;
>> +
>> +class CGProfilePass : public ModulePass {
>> +public:
>> +  static char ID;
>> +
>> +  CGProfilePass() : ModulePass(ID) {
>> +    initializeCGProfilePassPass(*PassRegistry::getPassRegistry());
>> +  }
>> +
>> +  StringRef getPassName() const override { return "CGProfilePass"; }
>> +
>> +private:
>> +  bool runOnModule(Module &M) override;
>> +  bool addModuleFlags(
>> +      Module &M,
>> +      MapVector<std::pair<Function *, Function *>, uint64_t> &Counts)
>> const;
>> +
>> +  void getAnalysisUsage(AnalysisUsage &AU) const override {
>> +    AU.addRequired<BlockFrequencyInfoWrapperPass>();
>> +    AU.addRequired<BranchProbabilityInfoWrapperPass>();
>> +  }
>> +};
>> +
>> +bool CGProfilePass::runOnModule(Module &M) {
>> +  if (skipModule(M))
>> +    return false;
>> +
>> +  MapVector<std::pair<Function *, Function *>, uint64_t> Counts;
>> +
>> +  for (auto &F : M) {
>> +    if (F.isDeclaration())
>> +      continue;
>> +    getAnalysis<BranchProbabilityInfoWrapperPass>(F).getBPI();
>> +    auto &BFI = getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
>> +    for (const auto &BB : F) {
>> +      Optional<uint64_t> BBCount = BFI.getBlockProfileCount(&BB);
>> +      if (!BBCount)
>> +        continue;
>> +      for (const auto &I : BB) {
>> +        auto *CI = dyn_cast<CallInst>(&I);
>> +        if (!CI)
>> +          continue;
>> +        Function *CalledF = CI->getCalledFunction();
>> +        if (!CalledF || CalledF->isIntrinsic())
>> +          continue;
>> +
>> +        uint64_t &Count = Counts[std::make_pair(&F, CalledF)];
>> +        Count = SaturatingAdd(Count, *BBCount);
>> +      }
>> +    }
>> +  }
>> +
>> +  return addModuleFlags(M, Counts);
>> +}
>> +
>> +bool CGProfilePass::addModuleFlags(
>> +    Module &M,
>> +    MapVector<std::pair<Function *, Function *>, uint64_t> &Counts)
>> const {
>> +  if (Counts.empty())
>> +    return false;
>> +
>> +  LLVMContext &Context = M.getContext();
>> +  MDBuilder MDB(Context);
>> +  std::vector<Metadata *> Nodes;
>> +
>> +  for (auto E : Counts) {
>> +    SmallVector<Metadata *, 3> Vals;
>> +    Vals.push_back(ValueAsMetadata::get(E.first.first));
>> +    Vals.push_back(ValueAsMetadata::get(E.first.second));
>> +    Vals.push_back(MDB.createConstant(
>> +        ConstantInt::get(Type::getInt64Ty(Context), E.second)));
>> +    Nodes.push_back(MDNode::get(Context, Vals));
>> +  }
>> +
>> +  M.addModuleFlag(Module::Append, "CG Profile", MDNode::get(Context,
>> Nodes));
>> +  return true;
>> +}
>> +
>> +char CGProfilePass::ID = 0;
>> +INITIALIZE_PASS_BEGIN(CGProfilePass, "cg-profile",
>> +                      "Generate profile information from the call
>> graph.",
>> +                      false, false)
>> +INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
>> +INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
>> +INITIALIZE_PASS_END(CGProfilePass, "cg-profile",
>> +                    "Generate profile information from the call graph.",
>> false,
>> +                    false)
>> +
>> +ModulePass *llvm::createCGProfilePass() { return new CGProfilePass(); }
>>
>> Modified: llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/CMakeLists.txt Thu Jun 21
>> 16:31:10 2018
>> @@ -1,6 +1,7 @@
>>  add_llvm_library(LLVMInstrumentation
>>    AddressSanitizer.cpp
>>    BoundsChecking.cpp
>> +  CGProfile.cpp
>>    DataFlowSanitizer.cpp
>>    GCOVProfiling.cpp
>>    MemorySanitizer.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=335306&r1=335305&r2=335306&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
>> (original)
>> +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Thu Jun
>> 21 16:31:10 2018
>> @@ -60,6 +60,7 @@ void llvm::initializeInstrumentation(Pas
>>    initializeAddressSanitizerModulePass(Registry);
>>    initializeBoundsCheckingLegacyPassPass(Registry);
>>    initializeGCOVProfilerLegacyPassPass(Registry);
>> +  initializeCGProfilePassPass(Registry);
>>    initializePGOInstrumentationGenLegacyPassPass(Registry);
>>    initializePGOInstrumentationUseLegacyPassPass(Registry);
>>    initializePGOIndirectCallPromotionLegacyPassPass(Registry);
>>
>> Added: llvm/trunk/test/Instrumentation/cgprofile.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/cgprofile.ll?rev=335306&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/Instrumentation/cgprofile.ll (added)
>> +++ llvm/trunk/test/Instrumentation/cgprofile.ll Thu Jun 21 16:31:10 2018
>> @@ -0,0 +1,28 @@
>> +; RUN: opt < %s -cg-profile -S | FileCheck %s
>> +
>> +declare void @b()
>> +
>> +define void @a() !prof !1 {
>> +  call void @b()
>> +  ret void
>> +}
>> +
>> +define void @freq(i1 %cond) !prof !1 {
>> +  br i1 %cond, label %A, label %B, !prof !2
>> +A:
>> +  call void @a();
>> +  ret void
>> +B:
>> +  call void @b();
>> +  ret void
>> +}
>> +
>> +!1 = !{!"function_entry_count", i64 32}
>> +!2 = !{!"branch_weights", i32 5, i32 10}
>> +
>> +; CHECK: !llvm.module.flags = !{![[cgprof:[0-9]+]]}
>> +; CHECK: ![[cgprof]] = !{i32 5, !"CG Profile", ![[prof:[0-9]+]]}
>> +; CHECK: ![[prof]] = !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]]}
>> +; CHECK: ![[e0]] = !{void ()* @a, void ()* @b, i64 32}
>> +; CHECK: ![[e1]] = !{void (i1)* @freq, void ()* @a, i64 11}
>> +; CHECK: ![[e2]] = !{void (i1)* @freq, void ()* @b, i64 20}
>>
>> Added: llvm/trunk/test/MC/ELF/cgprofile.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cgprofile.ll?rev=335306&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/MC/ELF/cgprofile.ll (added)
>> +++ llvm/trunk/test/MC/ELF/cgprofile.ll Thu Jun 21 16:31:10 2018
>> @@ -0,0 +1,50 @@
>> +; RUN: llc -filetype=asm %s -o - -mtriple x86_64-pc-linux-gnu |
>> FileCheck %s
>> +; RUN: llc -filetype=obj %s -o %t -mtriple x86_64-pc-linux-gnu
>> +; RUN: llvm-readobj -elf-cg-profile %t | FileCheck %s --check-prefix=OBJ
>> +
>> +declare void @b()
>> +
>> +define void @a() {
>> +  call void @b()
>> +  ret void
>> +}
>> +
>> +define void @freq(i1 %cond) {
>> +  br i1 %cond, label %A, label %B
>> +A:
>> +  call void @a();
>> +  ret void
>> +B:
>> +  call void @b();
>> +  ret void
>> +}
>> +
>> +!llvm.module.flags = !{!0}
>> +
>> +!0 = !{i32 5, !"CG Profile", !1}
>> +!1 = !{!2, !3, !4}
>> +!2 = !{void ()* @a, void ()* @b, i64 32}
>> +!3 = !{void (i1)* @freq, void ()* @a, i64 11}
>> +!4 = !{void (i1)* @freq, void ()* @b, i64 20}
>> +
>> +; CHECK: .cg_profile a, b, 32
>> +; CHECK: .cg_profile freq, a, 11
>> +; CHECK: .cg_profile freq, b, 20
>> +
>> +; OBJ: CGProfile [
>> +; OBJ:  CGProfileEntry {
>> +; OBJ:    From: a
>> +; OBJ:    To: b
>> +; OBJ:    Weight: 32
>> +; OBJ:  }
>> +; OBJ:  CGProfileEntry {
>> +; OBJ:    From: freq
>> +; OBJ:    To: a
>> +; OBJ:    Weight: 11
>> +; OBJ:  }
>> +; OBJ:  CGProfileEntry {
>> +; OBJ:    From: freq
>> +; OBJ:    To: b
>> +; OBJ:    Weight: 20
>> +; OBJ:  }
>> +; OBJ:]
>>
>> Added: llvm/trunk/test/Verifier/module-flags-cgprofile.ll
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/module-flags-cgprofile.ll?rev=335306&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/Verifier/module-flags-cgprofile.ll (added)
>> +++ llvm/trunk/test/Verifier/module-flags-cgprofile.ll Thu Jun 21
>> 16:31:10 2018
>> @@ -0,0 +1,30 @@
>> +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
>> +
>> +declare void @b()
>> +declare void @a()
>> +
>> +!llvm.module.flags = !{!0}
>> +
>> +!0 = !{i32 5, !"CG Profile", !1}
>> +!1 = !{!2, !"", !3, !4, !5, !6, !7, !8}
>> +!2 = !{void ()* @a, void ()* @b, i64 32}
>> +!3 = !{void ()* @a, void ()* @b}
>> +!4 = !{void ()* @a, void ()* @b, i64 32, i64 32}
>> +!5 = !{!"a", void ()* @b, i64 32}
>> +!6 = !{void ()* @a, !"b", i64 32}
>> +!7 = !{void ()* @a, void ()* @b, !""}
>> +!8 = !{void ()* @a, void ()* @b, null}
>> +
>> +; CHECK: expected a MDNode triple
>> +; CHECK: !""
>> +; CHECK: expected a MDNode triple
>> +; CHECK: !3 = !{void ()* @a, void ()* @b}
>> +; CHECK: expected a MDNode triple
>> +; CHECK: !4 = !{void ()* @a, void ()* @b, i64 32, i64 32}
>> +; CHECK: expected a Function
>> +; CHECK: !"a"
>> +; CHECK: expected a Function
>> +; CHECK: !"b"
>> +; CHECK: expected an integer constant
>> +; CHECK: !""
>> +; CHECK: expected an integer constant
>>
>>
>> _______________________________________________
>> 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/20180621/3225aba8/attachment.html>


More information about the llvm-commits mailing list