llvm.org GIT mirror llvm / 8e0778c
Revert r335306 (and r335314) - the Call Graph Profile pass. This is the first pass in the main pipeline to use the legacy PM's ability to run function analyses "on demand". Unfortunately, it turns out there are bugs in that somewhat-hacky approach. At the very least, it leaks memory and doesn't support -debug-pass=Structure. Unclear if there are larger issues or not, but this should get the sanitizer bots back to green by fixing the memory leaks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335320 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 1 year, 2 months ago
16 changed file(s) with 7 addition(s) and 308 deletion(s). Raw diff Collapse all Expand all
3535 protected:
3636 MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =
3737 MCSymbolRefExpr::VK_None;
38 const TargetMachine *TM;
3938
4039 public:
4140 TargetLoweringObjectFileELF() = default;
4241 ~TargetLoweringObjectFileELF() override = default;
43
44 void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
4542
4643 /// Emit Obj-C garbage collection and linker options.
4744 void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
9393 void initializeCFIInstrInserterPass(PassRegistry&);
9494 void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
9595 void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
96 void initializeCGProfilePassPass(PassRegistry&);
9796 void initializeCallGraphDOTPrinterPass(PassRegistry&);
9897 void initializeCallGraphPrinterLegacyPassPass(PassRegistry&);
9998 void initializeCallGraphViewerPass(PassRegistry&);
7979 (void) llvm::createCallGraphDOTPrinterPass();
8080 (void) llvm::createCallGraphViewerPass();
8181 (void) llvm::createCFGSimplificationPass();
82 (void) llvm::createCGProfilePass();
8382 (void) llvm::createCFLAndersAAWrapperPass();
8483 (void) llvm::createCFLSteensAAWrapperPass();
8584 (void) llvm::createStructurizeCFGPass();
186186 ModulePass *createSanitizerCoverageModulePass(
187187 const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
188188
189 ModulePass *createCGProfilePass();
190
191189 /// Calculate what to divide by to scale counts.
192190 ///
193191 /// Given the maximum count, calculate a divisor that will scale all the
9090 // ELF
9191 //===----------------------------------------------------------------------===//
9292
93 void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
94 const TargetMachine &TgtM) {
95 TargetLoweringObjectFile::Initialize(Ctx, TgtM);
96 TM = &TgtM;
97 }
98
9993 void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
10094 Module &M) const {
10195 auto &C = getContext();
121115 StringRef Section;
122116
123117 GetObjCImageInfo(M, Version, Flags, Section);
124 if (!Section.empty()) {
125 auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
126 Streamer.SwitchSection(S);
127 Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
128 Streamer.EmitIntValue(Version, 4);
129 Streamer.EmitIntValue(Flags, 4);
130 Streamer.AddBlankLine();
131 }
132
133 SmallVector ModuleFlags;
134 M.getModuleFlagsMetadata(ModuleFlags);
135
136 MDNode *CFGProfile = nullptr;
137
138 for (const auto &MFE : ModuleFlags) {
139 StringRef Key = MFE.Key->getString();
140 if (Key == "CG Profile") {
141 CFGProfile = cast(MFE.Val);
142 break;
143 }
144 }
145
146 if (!CFGProfile)
118 if (Section.empty())
147119 return;
148120
149 auto GetSym = [this](const MDOperand &MDO) {
150 auto V = cast(MDO);
151 const Function *F = cast(V->getValue());
152 return TM->getSymbol(F);
153 };
154
155 for (const auto &Edge : CFGProfile->operands()) {
156 MDNode *E = cast(Edge);
157 const MCSymbol *From = GetSym(E->getOperand(0));
158 const MCSymbol *To = GetSym(E->getOperand(1));
159 uint64_t Count = cast(E->getOperand(2))
160 ->getValue()
161 ->getUniqueInteger()
162 .getZExtValue();
163 Streamer.emitCGProfileEntry(
164 MCSymbolRefExpr::create(From, MCSymbolRefExpr::VK_None, C),
165 MCSymbolRefExpr::create(To, MCSymbolRefExpr::VK_None, C), Count);
166 }
121 auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
122 Streamer.SwitchSection(S);
123 Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO")));
124 Streamer.EmitIntValue(Version, 4);
125 Streamer.EmitIntValue(Flags, 4);
126 Streamer.AddBlankLine();
167127 }
168128
169129 MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
408408 void visitModuleFlag(const MDNode *Op,
409409 DenseMap &SeenIDs,
410410 SmallVectorImpl &Requirements);
411 void visitModuleFlagCGProfileEntry(const MDOperand &MDO);
412411 void visitFunction(const Function &F);
413412 void visitBasicBlock(BasicBlock &BB);
414413 void visitRangeMetadata(Instruction &I, MDNode *Range, Type *Ty);
14111410 Assert(M.getNamedMetadata("llvm.linker.options"),
14121411 "'Linker Options' named metadata no longer supported");
14131412 }
1414
1415 if (ID->getString() == "CG Profile") {
1416 for (const MDOperand &MDO : cast(Op->getOperand(2))->operands())
1417 visitModuleFlagCGProfileEntry(MDO);
1418 }
1419 }
1420
1421 void Verifier::visitModuleFlagCGProfileEntry(const MDOperand &MDO) {
1422 auto Node = dyn_cast_or_null(MDO);
1423 Assert(Node && Node->getNumOperands() == 3, "expected a MDNode triple", MDO);
1424 auto From = dyn_cast_or_null(Node->getOperand(0));
1425 Assert(From && isa(From->getValue()), "expected a Function",
1426 Node->getOperand(0));
1427 auto To = dyn_cast_or_null(Node->getOperand(1));
1428 Assert(To && isa(To->getValue()), "expected a Function",
1429 Node->getOperand(1));
1430 auto Count = dyn_cast_or_null(Node->getOperand(2));
1431 Assert(Count && Count->getType()->isIntegerTy(),
1432 "expected an integer constant", Node->getOperand(2));
14331413 }
14341414
14351415 /// Return true if this attribute kind only applies to functions.
693693 MPM.add(createConstantMergePass()); // Merge dup global constants
694694 }
695695
696 MPM.add(createCGProfilePass());
697
698696 if (MergeFunctions)
699697 MPM.add(createMergeFunctionsPass());
700698
+0
-110
lib/Transforms/Instrumentation/CGProfile.cpp less more
None //===-- CGProfile.cpp -----------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/MapVector.h"
10 #include "llvm/Analysis/BlockFrequencyInfo.h"
11 #include "llvm/Analysis/BranchProbabilityInfo.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/MDBuilder.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/Transforms/Instrumentation.h"
17
18 #include
19
20 using namespace llvm;
21
22 class CGProfilePass : public ModulePass {
23 public:
24 static char ID;
25
26 CGProfilePass() : ModulePass(ID) {
27 initializeCGProfilePassPass(*PassRegistry::getPassRegistry());
28 }
29
30 StringRef getPassName() const override { return "CGProfilePass"; }
31
32 private:
33 bool runOnModule(Module &M) override;
34 bool addModuleFlags(
35 Module &M,
36 MapVector, uint64_t> &Counts) const;
37
38 void getAnalysisUsage(AnalysisUsage &AU) const override {
39 AU.addRequired();
40 AU.addRequired();
41 }
42 };
43
44 bool CGProfilePass::runOnModule(Module &M) {
45 if (skipModule(M))
46 return false;
47
48 MapVector, uint64_t> Counts;
49
50 for (auto &F : M) {
51 if (F.isDeclaration())
52 continue;
53 getAnalysis(F).getBPI();
54 auto &BFI = getAnalysis(F).getBFI();
55 for (const auto &BB : F) {
56 Optional BBCount = BFI.getBlockProfileCount(&BB);
57 if (!BBCount)
58 continue;
59 for (const auto &I : BB) {
60 auto *CI = dyn_cast(&I);
61 if (!CI)
62 continue;
63 Function *CalledF = CI->getCalledFunction();
64 if (!CalledF || CalledF->isIntrinsic())
65 continue;
66
67 uint64_t &Count = Counts[std::make_pair(&F, CalledF)];
68 Count = SaturatingAdd(Count, *BBCount);
69 }
70 }
71 }
72
73 return addModuleFlags(M, Counts);
74 }
75
76 bool CGProfilePass::addModuleFlags(
77 Module &M,
78 MapVector, uint64_t> &Counts) const {
79 if (Counts.empty())
80 return false;
81
82 LLVMContext &Context = M.getContext();
83 MDBuilder MDB(Context);
84 std::vector Nodes;
85
86 for (auto E : Counts) {
87 SmallVector Vals;
88 Vals.push_back(ValueAsMetadata::get(E.first.first));
89 Vals.push_back(ValueAsMetadata::get(E.first.second));
90 Vals.push_back(MDB.createConstant(
91 ConstantInt::get(Type::getInt64Ty(Context), E.second)));
92 Nodes.push_back(MDNode::get(Context, Vals));
93 }
94
95 M.addModuleFlag(Module::Append, "CG Profile", MDNode::get(Context, Nodes));
96 return true;
97 }
98
99 char CGProfilePass::ID = 0;
100 INITIALIZE_PASS_BEGIN(CGProfilePass, "cg-profile",
101 "Generate profile information from the call graph.",
102 false, false)
103 INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
104 INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
105 INITIALIZE_PASS_END(CGProfilePass, "cg-profile",
106 "Generate profile information from the call graph.", false,
107 false)
108
109 ModulePass *llvm::createCGProfilePass() { return new CGProfilePass(); }
0 add_llvm_library(LLVMInstrumentation
11 AddressSanitizer.cpp
22 BoundsChecking.cpp
3 CGProfile.cpp
43 DataFlowSanitizer.cpp
54 GCOVProfiling.cpp
65 MemorySanitizer.cpp
5959 initializeAddressSanitizerModulePass(Registry);
6060 initializeBoundsCheckingLegacyPassPass(Registry);
6161 initializeGCOVProfilerLegacyPassPass(Registry);
62 initializeCGProfilePassPass(Registry);
6362 initializePGOInstrumentationGenLegacyPassPass(Registry);
6463 initializePGOInstrumentationUseLegacyPassPass(Registry);
6564 initializePGOIndirectCallPromotionLegacyPassPass(Registry);
+0
-28
test/Instrumentation/cgprofile.ll less more
None ; RUN: opt < %s -cg-profile -S | FileCheck %s
1
2 declare void @b()
3
4 define void @a() !prof !1 {
5 call void @b()
6 ret void
7 }
8
9 define void @freq(i1 %cond) !prof !1 {
10 br i1 %cond, label %A, label %B, !prof !2
11 A:
12 call void @a();
13 ret void
14 B:
15 call void @b();
16 ret void
17 }
18
19 !1 = !{!"function_entry_count", i64 32}
20 !2 = !{!"branch_weights", i32 5, i32 10}
21
22 ; CHECK: !llvm.module.flags = !{![[cgprof:[0-9]+]]}
23 ; CHECK: ![[cgprof]] = !{i32 5, !"CG Profile", ![[prof:[0-9]+]]}
24 ; CHECK: ![[prof]] = !{![[e0:[0-9]+]], ![[e1:[0-9]+]], ![[e2:[0-9]+]]}
25 ; CHECK: ![[e0]] = !{void ()* @a, void ()* @b, i64 32}
26 ; CHECK: ![[e1]] = !{void (i1)* @freq, void ()* @a, i64 11}
27 ; CHECK: ![[e2]] = !{void (i1)* @freq, void ()* @b, i64 20}
+0
-50
test/MC/ELF/cgprofile.ll less more
None ; RUN: llc -filetype=asm %s -o - -mtriple x86_64-pc-linux-gnu | FileCheck %s
1 ; RUN: llc -filetype=obj %s -o %t -mtriple x86_64-pc-linux-gnu
2 ; RUN: llvm-readobj -elf-cg-profile %t | FileCheck %s --check-prefix=OBJ
3
4 declare void @b()
5
6 define void @a() {
7 call void @b()
8 ret void
9 }
10
11 define void @freq(i1 %cond) {
12 br i1 %cond, label %A, label %B
13 A:
14 call void @a();
15 ret void
16 B:
17 call void @b();
18 ret void
19 }
20
21 !llvm.module.flags = !{!0}
22
23 !0 = !{i32 5, !"CG Profile", !1}
24 !1 = !{!2, !3, !4}
25 !2 = !{void ()* @a, void ()* @b, i64 32}
26 !3 = !{void (i1)* @freq, void ()* @a, i64 11}
27 !4 = !{void (i1)* @freq, void ()* @b, i64 20}
28
29 ; CHECK: .cg_profile a, b, 32
30 ; CHECK: .cg_profile freq, a, 11
31 ; CHECK: .cg_profile freq, b, 20
32
33 ; OBJ: CGProfile [
34 ; OBJ: CGProfileEntry {
35 ; OBJ: From: a
36 ; OBJ: To: b
37 ; OBJ: Weight: 32
38 ; OBJ: }
39 ; OBJ: CGProfileEntry {
40 ; OBJ: From: freq
41 ; OBJ: To: a
42 ; OBJ: Weight: 11
43 ; OBJ: }
44 ; OBJ: CGProfileEntry {
45 ; OBJ: From: freq
46 ; OBJ: To: b
47 ; OBJ: Weight: 20
48 ; OBJ: }
49 ; OBJ:]
248248 ; CHECK-NEXT: Strip Unused Function Prototypes
249249 ; CHECK-NEXT: Dead Global Elimination
250250 ; CHECK-NEXT: Merge Duplicate Global Constants
251 ; CHECK-NEXT: CGProfilePass
252 ; FIXME: This pass uses the magic "on-demand function analysis" feature of the
253 ; legacy pass manager and doesn't correctly print pass names.
254 ; CHECK-NEXT: Unnamed pass
255251 ; CHECK-NEXT: FunctionPass Manager
256252 ; CHECK-NEXT: Dominator Tree Construction
257253 ; CHECK-NEXT: Natural Loop Information
252252 ; CHECK-NEXT: Strip Unused Function Prototypes
253253 ; CHECK-NEXT: Dead Global Elimination
254254 ; CHECK-NEXT: Merge Duplicate Global Constants
255 ; CHECK-NEXT: CGProfilePass
256 ; FIXME: This pass uses the magic "on-demand function analysis" feature of the
257 ; legacy pass manager and doesn't correctly print pass names.
258 ; CHECK-NEXT: Unnamed pass
259255 ; CHECK-NEXT: FunctionPass Manager
260256 ; CHECK-NEXT: Dominator Tree Construction
261257 ; CHECK-NEXT: Natural Loop Information
234234 ; CHECK-NEXT: Strip Unused Function Prototypes
235235 ; CHECK-NEXT: Dead Global Elimination
236236 ; CHECK-NEXT: Merge Duplicate Global Constants
237 ; CHECK-NEXT: CGProfilePass
238 ; FIXME: This pass uses the magic "on-demand function analysis" feature of the
239 ; legacy pass manager and doesn't correctly print pass names.
240 ; CHECK-NEXT: Unnamed pass
241237 ; CHECK-NEXT: FunctionPass Manager
242238 ; CHECK-NEXT: Dominator Tree Construction
243239 ; CHECK-NEXT: Natural Loop Information
+0
-30
test/Verifier/module-flags-cgprofile.ll less more
None ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
1
2 declare void @b()
3 declare void @a()
4
5 !llvm.module.flags = !{!0}
6
7 !0 = !{i32 5, !"CG Profile", !1}
8 !1 = !{!2, !"", !3, !4, !5, !6, !7, !8}
9 !2 = !{void ()* @a, void ()* @b, i64 32}
10 !3 = !{void ()* @a, void ()* @b}
11 !4 = !{void ()* @a, void ()* @b, i64 32, i64 32}
12 !5 = !{!"a", void ()* @b, i64 32}
13 !6 = !{void ()* @a, !"b", i64 32}
14 !7 = !{void ()* @a, void ()* @b, !""}
15 !8 = !{void ()* @a, void ()* @b, null}
16
17 ; CHECK: expected a MDNode triple
18 ; CHECK: !""
19 ; CHECK: expected a MDNode triple
20 ; CHECK: !3 = !{void ()* @a, void ()* @b}
21 ; CHECK: expected a MDNode triple
22 ; CHECK: !4 = !{void ()* @a, void ()* @b, i64 32, i64 32}
23 ; CHECK: expected a Function
24 ; CHECK: !"a"
25 ; CHECK: expected a Function
26 ; CHECK: !"b"
27 ; CHECK: expected an integer constant
28 ; CHECK: !""
29 ; CHECK: expected an integer constant