llvm.org GIT mirror llvm / eec7ef7
Reverted r375254 as it has broken some build bots for a long time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@375375 91177308-0d34-0410-b5e6-96231b3b80d8 Vladimir Vereschaka 1 year, 1 month ago
15 changed file(s) with 20 addition(s) and 661 deletion(s). Raw diff Collapse all Expand all
3737 static char ID;
3838
3939 MachineBlockFrequencyInfo();
40 explicit MachineBlockFrequencyInfo(MachineFunction &F,
41 MachineBranchProbabilityInfo &MBPI,
42 MachineLoopInfo &MLI);
4340 ~MachineBlockFrequencyInfo() override;
4441
4542 void getAnalysisUsage(AnalysisUsage &AU) const override;
8080 static char ID; // Pass ID, replacement for typeid
8181
8282 MachineDominatorTree();
83 explicit MachineDominatorTree(MachineFunction &MF) : MachineFunctionPass(ID) {
84 calculate(MF);
85 }
8683
8784 DomTreeT &getBase() {
8885 if (!DT) DT.reset(new DomTreeT());
112109 }
113110
114111 bool runOnMachineFunction(MachineFunction &F) override;
115
116 void calculate(MachineFunction &F);
117112
118113 bool dominates(const MachineDomTreeNode *A,
119114 const MachineDomTreeNode *B) const {
3636
3737 namespace llvm {
3838
39 class MachineDominatorTree;
4039 // Implementation in LoopInfoImpl.h
4140 class MachineLoop;
4241 extern template class LoopBase;
9190 MachineLoopInfo() : MachineFunctionPass(ID) {
9291 initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
9392 }
94 explicit MachineLoopInfo(MachineDominatorTree &MDT)
95 : MachineFunctionPass(ID) {
96 calculate(MDT);
97 }
9893 MachineLoopInfo(const MachineLoopInfo &) = delete;
9994 MachineLoopInfo &operator=(const MachineLoopInfo &) = delete;
10095
137132
138133 /// Calculate the natural loop information.
139134 bool runOnMachineFunction(MachineFunction &F) override;
140 void calculate(MachineDominatorTree &MDT);
141135
142136 void releaseMemory() override { LI.releaseMemory(); }
143137
+0
-37
include/llvm/CodeGen/MachineSizeOpts.h less more
None //===- MachineSizeOpts.h - machine size optimization ------------*- C++ -*-===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file contains some shared machine IR code size optimization related
9 // code.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_CODEGEN_MACHINE_SIZEOPTS_H
13 #define LLVM_CODEGEN_MACHINE_SIZEOPTS_H
14
15 #include "llvm/Transforms/Utils/SizeOpts.h"
16
17 namespace llvm {
18
19 class ProfileSummaryInfo;
20 class MachineBasicBlock;
21 class MachineBlockFrequencyInfo;
22 class MachineFunction;
23
24 /// Returns true if machine function \p MF is suggested to be size-optimized
25 /// base on the profile.
26 bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI,
27 const MachineBlockFrequencyInfo *BFI);
28 /// Returns true if machine basic block \p MBB is suggested to be size-optimized
29 /// base on the profile.
30 bool shouldOptimizeForSize(const MachineBasicBlock *MBB,
31 ProfileSummaryInfo *PSI,
32 const MachineBlockFrequencyInfo *MBFI);
33
34 } // end namespace llvm
35
36 #endif // LLVM_CODEGEN_MACHINE_SIZEOPTS_H
1212 #ifndef LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
1313 #define LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
1414
15 #include "llvm/Analysis/BlockFrequencyInfo.h"
16 #include "llvm/Analysis/ProfileSummaryInfo.h"
17 #include "llvm/Support/CommandLine.h"
18
19 using namespace llvm;
20
21 extern cl::opt EnablePGSO;
22 extern cl::opt PGSOLargeWorkingSetSizeOnly;
23 extern cl::opt ForcePGSO;
24 extern cl::opt PgsoCutoffInstrProf;
25 extern cl::opt PgsoCutoffSampleProf;
26
2715 namespace llvm {
2816
2917 class BasicBlock;
3119 class Function;
3220 class ProfileSummaryInfo;
3321
34 template
35 bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI,
36 BFIT *BFI) {
37 assert(F);
38 if (!PSI || !BFI || !PSI->hasProfileSummary())
39 return false;
40 if (ForcePGSO)
41 return true;
42 if (!EnablePGSO)
43 return false;
44 if (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()) {
45 // Even if the working set size isn't large, size-optimize cold code.
46 return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI);
47 }
48 return !AdapterT::isFunctionHotInCallGraphNthPercentile(
49 PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
50 F, PSI, *BFI);
51 }
52
53 template
54 bool shouldOptimizeForSizeImpl(const BlockT *BB, ProfileSummaryInfo *PSI,
55 BFIT *BFI) {
56 assert(BB);
57 if (!PSI || !BFI || !PSI->hasProfileSummary())
58 return false;
59 if (ForcePGSO)
60 return true;
61 if (!EnablePGSO)
62 return false;
63 if (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize()) {
64 // Even if the working set size isn't large, size-optimize cold code.
65 return AdapterT::isColdBlock(BB, PSI, BFI);
66 }
67 return !AdapterT::isHotBlockNthPercentile(
68 PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
69 BB, PSI, BFI);
70 }
71
7222 /// Returns true if function \p F is suggested to be size-optimized base on the
7323 /// profile.
74 bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
24 bool shouldOptimizeForSize(Function *F, ProfileSummaryInfo *PSI,
7525 BlockFrequencyInfo *BFI);
76
7726 /// Returns true if basic block \p BB is suggested to be size-optimized base
7827 /// on the profile.
79 bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
28 bool shouldOptimizeForSize(BasicBlock *BB, ProfileSummaryInfo *PSI,
8029 BlockFrequencyInfo *BFI);
8130
8231 } // end namespace llvm
9191 MachineRegisterInfo.cpp
9292 MachineScheduler.cpp
9393 MachineSink.cpp
94 MachineSizeOpts.cpp
9594 MachineSSAUpdater.cpp
9695 MachineTraceMetrics.cpp
9796 MachineVerifier.cpp
171171 initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
172172 }
173173
174 MachineBlockFrequencyInfo::MachineBlockFrequencyInfo(
175 MachineFunction &F,
176 MachineBranchProbabilityInfo &MBPI,
177 MachineLoopInfo &MLI) : MachineFunctionPass(ID) {
178 calculate(F, MBPI, MLI);
179 }
180
181174 MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;
182175
183176 void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
4848 }
4949
5050 bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
51 calculate(F);
52 return false;
53 }
54
55 void MachineDominatorTree::calculate(MachineFunction &F) {
5651 CriticalEdgesToSplit.clear();
5752 NewBBs.clear();
5853 DT.reset(new DomTreeBase());
5954 DT->recalculate(F);
55 return false;
6056 }
6157
6258 MachineDominatorTree::MachineDominatorTree()
3535 char &llvm::MachineLoopInfoID = MachineLoopInfo::ID;
3636
3737 bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
38 calculate(getAnalysis());
38 releaseMemory();
39 LI.analyze(getAnalysis().getBase());
3940 return false;
40 }
41
42 void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
43 releaseMemory();
44 LI.analyze(MDT.getBase());
4541 }
4642
4743 void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+0
-120
lib/CodeGen/MachineSizeOpts.cpp less more
None //===- MachineSizeOpts.cpp - code size optimization related code ----------===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file contains some shared machine IR code size optimization related
9 // code.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/CodeGen/MachineSizeOpts.h"
14 #include "llvm/Analysis/ProfileSummaryInfo.h"
15 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
16
17 using namespace llvm;
18
19 extern cl::opt EnablePGSO;
20 extern cl::opt PGSOLargeWorkingSetSizeOnly;
21 extern cl::opt ForcePGSO;
22 extern cl::opt PgsoCutoffInstrProf;
23 extern cl::opt PgsoCutoffSampleProf;
24
25 namespace machine_size_opts_detail {
26
27 /// Like ProfileSummaryInfo::isColdBlock but for MachineBasicBlock.
28 bool isColdBlock(const MachineBasicBlock *MBB,
29 ProfileSummaryInfo *PSI,
30 const MachineBlockFrequencyInfo *MBFI) {
31 auto Count = MBFI->getBlockProfileCount(MBB);
32 return Count && PSI->isColdCount(*Count);
33 }
34
35 /// Like ProfileSummaryInfo::isHotBlockNthPercentile but for MachineBasicBlock.
36 static bool isHotBlockNthPercentile(int PercentileCutoff,
37 const MachineBasicBlock *MBB,
38 ProfileSummaryInfo *PSI,
39 const MachineBlockFrequencyInfo *MBFI) {
40 auto Count = MBFI->getBlockProfileCount(MBB);
41 return Count && PSI->isHotCountNthPercentile(PercentileCutoff, *Count);
42 }
43
44 /// Like ProfileSummaryInfo::isFunctionColdInCallGraph but for
45 /// MachineFunction.
46 bool isFunctionColdInCallGraph(
47 const MachineFunction *MF,
48 ProfileSummaryInfo *PSI,
49 const MachineBlockFrequencyInfo &MBFI) {
50 if (auto FunctionCount = MF->getFunction().getEntryCount())
51 if (!PSI->isColdCount(FunctionCount.getCount()))
52 return false;
53 for (const auto &MBB : *MF)
54 if (!isColdBlock(&MBB, PSI, &MBFI))
55 return false;
56 return true;
57 }
58
59 /// Like ProfileSummaryInfo::isFunctionHotInCallGraphNthPercentile but for
60 /// MachineFunction.
61 bool isFunctionHotInCallGraphNthPercentile(
62 int PercentileCutoff,
63 const MachineFunction *MF,
64 ProfileSummaryInfo *PSI,
65 const MachineBlockFrequencyInfo &MBFI) {
66 if (auto FunctionCount = MF->getFunction().getEntryCount())
67 if (PSI->isHotCountNthPercentile(PercentileCutoff,
68 FunctionCount.getCount()))
69 return true;
70 for (const auto &MBB : *MF)
71 if (isHotBlockNthPercentile(PercentileCutoff, &MBB, PSI, &MBFI))
72 return true;
73 return false;
74 }
75 } // namespace machine_size_opts_detail
76
77 namespace {
78 struct MachineBasicBlockBFIAdapter {
79 static bool isFunctionColdInCallGraph(const MachineFunction *MF,
80 ProfileSummaryInfo *PSI,
81 const MachineBlockFrequencyInfo &MBFI) {
82 return machine_size_opts_detail::isFunctionColdInCallGraph(MF, PSI, MBFI);
83 }
84 static bool isFunctionHotInCallGraphNthPercentile(
85 int CutOff,
86 const MachineFunction *MF,
87 ProfileSummaryInfo *PSI,
88 const MachineBlockFrequencyInfo &MBFI) {
89 return machine_size_opts_detail::isFunctionHotInCallGraphNthPercentile(
90 CutOff, MF, PSI, MBFI);
91 }
92 static bool isColdBlock(const MachineBasicBlock *MBB,
93 ProfileSummaryInfo *PSI,
94 const MachineBlockFrequencyInfo *MBFI) {
95 return machine_size_opts_detail::isColdBlock(MBB, PSI, MBFI);
96 }
97 static bool isHotBlockNthPercentile(int CutOff,
98 const MachineBasicBlock *MBB,
99 ProfileSummaryInfo *PSI,
100 const MachineBlockFrequencyInfo *MBFI) {
101 return machine_size_opts_detail::isHotBlockNthPercentile(
102 CutOff, MBB, PSI, MBFI);
103 }
104 };
105 } // end anonymous namespace
106
107 bool llvm::shouldOptimizeForSize(const MachineFunction *MF,
108 ProfileSummaryInfo *PSI,
109 const MachineBlockFrequencyInfo *MBFI) {
110 return shouldFuncOptimizeForSizeImpl(
111 MF, PSI, MBFI);
112 }
113
114 bool llvm::shouldOptimizeForSize(const MachineBasicBlock *MBB,
115 ProfileSummaryInfo *PSI,
116 const MachineBlockFrequencyInfo *MBFI) {
117 return shouldOptimizeForSizeImpl(
118 MBB, PSI, MBFI);
119 }
99 //
1010 //===----------------------------------------------------------------------===//
1111
12 #include "llvm/Analysis/BlockFrequencyInfo.h"
13 #include "llvm/Analysis/ProfileSummaryInfo.h"
14 #include "llvm/Support/CommandLine.h"
1215 #include "llvm/Transforms/Utils/SizeOpts.h"
13
1416 using namespace llvm;
1517
16 cl::opt EnablePGSO(
18 static cl::opt ProfileGuidedSizeOpt(
1719 "pgso", cl::Hidden, cl::init(true),
18 cl::desc("Enable the profile guided size optimizations. "));
20 cl::desc("Enable the profile guided size optimization. "));
1921
20 cl::opt PGSOLargeWorkingSetSizeOnly(
21 "pgso-lwss-only", cl::Hidden, cl::init(true),
22 cl::desc("Apply the profile guided size optimizations only "
23 "if the working set size is large (except for cold code.)"));
24
25 cl::opt ForcePGSO(
26 "force-pgso", cl::Hidden, cl::init(false),
27 cl::desc("Force the (profiled-guided) size optimizations. "));
28
29 cl::opt PgsoCutoffInstrProf(
30 "pgso-cutoff-instr-prof", cl::Hidden, cl::init(250000), cl::ZeroOrMore,
31 cl::desc("The profile guided size optimization profile summary cutoff "
32 "for instrumentation profile."));
33
34 cl::opt PgsoCutoffSampleProf(
35 "pgso-cutoff-sample-prof", cl::Hidden, cl::init(800000), cl::ZeroOrMore,
36 cl::desc("The profile guided size optimization profile summary cutoff "
37 "for sample profile."));
38
39 namespace {
40 struct BasicBlockBFIAdapter {
41 static bool isFunctionColdInCallGraph(const Function *F,
42 ProfileSummaryInfo *PSI,
43 BlockFrequencyInfo &BFI) {
44 return PSI->isFunctionColdInCallGraph(F, BFI);
45 }
46 static bool isFunctionHotInCallGraphNthPercentile(int CutOff,
47 const Function *F,
48 ProfileSummaryInfo *PSI,
49 BlockFrequencyInfo &BFI) {
50 return PSI->isFunctionHotInCallGraphNthPercentile(CutOff, F, BFI);
51 }
52 static bool isColdBlock(const BasicBlock *BB,
53 ProfileSummaryInfo *PSI,
54 BlockFrequencyInfo *BFI) {
55 return PSI->isColdBlock(BB, BFI);
56 }
57 static bool isHotBlockNthPercentile(int CutOff,
58 const BasicBlock *BB,
59 ProfileSummaryInfo *PSI,
60 BlockFrequencyInfo *BFI) {
61 return PSI->isHotBlockNthPercentile(CutOff, BB, BFI);
62 }
63 };
64 } // end anonymous namespace
65
66 bool llvm::shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
22 bool llvm::shouldOptimizeForSize(Function *F, ProfileSummaryInfo *PSI,
6723 BlockFrequencyInfo *BFI) {
68 return shouldFuncOptimizeForSizeImpl(F, PSI, BFI);
24 assert(F);
25 if (!PSI || !BFI || !PSI->hasProfileSummary())
26 return false;
27 return ProfileGuidedSizeOpt && PSI->isFunctionColdInCallGraph(F, *BFI);
6928 }
7029
71 bool llvm::shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
30 bool llvm::shouldOptimizeForSize(BasicBlock *BB, ProfileSummaryInfo *PSI,
7231 BlockFrequencyInfo *BFI) {
73 return shouldOptimizeForSizeImpl(BB, PSI, BFI);
32 assert(BB);
33 if (!PSI || !BFI || !PSI->hasProfileSummary())
34 return false;
35 return ProfileGuidedSizeOpt && PSI->isColdBlock(BB, BFI);
7436 }
1818 MachineInstrBundleIteratorTest.cpp
1919 MachineInstrTest.cpp
2020 MachineOperandTest.cpp
21 MachineSizeOptsTest.cpp
2221 ScalableVectorMVTsTest.cpp
2322 TypeTraitsTest.cpp
2423 TargetOptionsTest.cpp
+0
-234
unittests/CodeGen/MachineSizeOptsTest.cpp less more
None //===- MachineSizeOptsTest.cpp --------------------------------------------===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/CodeGen/MachineSizeOpts.h"
9 #include "llvm/Analysis/ProfileSummaryInfo.h"
10 #include "llvm/Analysis/BlockFrequencyInfo.h"
11 #include "llvm/Analysis/BranchProbabilityInfo.h"
12 #include "llvm/Analysis/LoopInfo.h"
13 #include "llvm/CodeGen/MIRParser/MIRParser.h"
14 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
15 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
16 #include "llvm/CodeGen/MachineDominators.h"
17 #include "llvm/CodeGen/MachineLoopInfo.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 #include "llvm/Support/TargetRegistry.h"
20 #include "llvm/Support/TargetSelect.h"
21 #include "llvm/Target/TargetMachine.h"
22 #include "gtest/gtest.h"
23
24 using namespace llvm;
25
26 namespace {
27
28 std::unique_ptr createTargetMachine() {
29 auto TT(Triple::normalize("x86_64--"));
30 std::string Error;
31 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
32 return std::unique_ptr(static_cast(
33 TheTarget->createTargetMachine(TT, "", "", TargetOptions(), None, None,
34 CodeGenOpt::Default)));
35 }
36
37 class MachineSizeOptsTest : public testing::Test {
38 protected:
39 static const char* MIRString;
40 LLVMContext Context;
41 std::unique_ptr TM;
42 std::unique_ptr MMI;
43 std::unique_ptr Parser;
44 std::unique_ptr M;
45 struct BFIData {
46 std::unique_ptr MDT;
47 std::unique_ptr MLI;
48 std::unique_ptr MBPI;
49 std::unique_ptr MBFI;
50 BFIData(MachineFunction &MF) {
51 MDT.reset(new MachineDominatorTree(MF));
52 MLI.reset(new MachineLoopInfo(*MDT));
53 MBPI.reset(new MachineBranchProbabilityInfo());
54 MBFI.reset(new MachineBlockFrequencyInfo(MF, *MBPI, *MLI));
55 }
56 MachineBlockFrequencyInfo *get() { return MBFI.get(); }
57 };
58
59 static void SetUpTestCase() {
60 InitializeAllTargets();
61 InitializeAllTargetMCs();
62 }
63
64 void SetUp() override {
65 TM = createTargetMachine();
66 std::unique_ptr MBuffer =
67 MemoryBuffer::getMemBuffer(MIRString);
68 Parser = createMIRParser(std::move(MBuffer), Context);
69 if (!Parser)
70 report_fatal_error("null MIRParser");
71 M = Parser->parseIRModule();
72 if (!M)
73 report_fatal_error("parseIRModule failed");
74 M->setTargetTriple(TM->getTargetTriple().getTriple());
75 M->setDataLayout(TM->createDataLayout());
76 MMI = std::make_unique(TM.get());
77 if (Parser->parseMachineFunctions(*M, *MMI.get()))
78 report_fatal_error("parseMachineFunctions failed");
79 }
80
81 MachineFunction *getMachineFunction(Module *M, StringRef Name) {
82 auto F = M->getFunction(Name);
83 if (!F)
84 report_fatal_error("null Function");
85 auto &MF = MMI->getOrCreateMachineFunction(*F);
86 return &MF;
87 }
88 };
89
90 TEST_F(MachineSizeOptsTest, Test) {
91 MachineFunction *F = getMachineFunction(M.get(), "f");
92 ASSERT_TRUE(F != nullptr);
93 MachineFunction *G = getMachineFunction(M.get(), "g");
94 ASSERT_TRUE(G != nullptr);
95 MachineFunction *H = getMachineFunction(M.get(), "h");
96 ASSERT_TRUE(H != nullptr);
97 ProfileSummaryInfo PSI = ProfileSummaryInfo(*M.get());
98 ASSERT_TRUE(PSI.hasProfileSummary());
99 BFIData BFID_F(*F);
100 BFIData BFID_G(*G);
101 BFIData BFID_H(*H);
102 MachineBlockFrequencyInfo *MBFI_F = BFID_F.get();
103 MachineBlockFrequencyInfo *MBFI_G = BFID_G.get();
104 MachineBlockFrequencyInfo *MBFI_H = BFID_H.get();
105 MachineBasicBlock &BB0 = F->front();
106 auto iter = BB0.succ_begin();
107 MachineBasicBlock *BB1 = *iter;
108 iter++;
109 MachineBasicBlock *BB2 = *iter;
110 iter++;
111 ASSERT_TRUE(iter == BB0.succ_end());
112 MachineBasicBlock *BB3 = *BB1->succ_begin();
113 ASSERT_TRUE(BB3 == *BB2->succ_begin());
114 EXPECT_FALSE(shouldOptimizeForSize(F, &PSI, MBFI_F));
115 EXPECT_TRUE(shouldOptimizeForSize(G, &PSI, MBFI_G));
116 EXPECT_FALSE(shouldOptimizeForSize(H, &PSI, MBFI_H));
117 EXPECT_FALSE(shouldOptimizeForSize(&BB0, &PSI, MBFI_F));
118 EXPECT_FALSE(shouldOptimizeForSize(BB1, &PSI, MBFI_F));
119 EXPECT_TRUE(shouldOptimizeForSize(BB2, &PSI, MBFI_F));
120 EXPECT_FALSE(shouldOptimizeForSize(BB3, &PSI, MBFI_F));
121 }
122
123 const char* MachineSizeOptsTest::MIRString = R"MIR(
124 --- |
125 define i32 @g(i32 %x) !prof !14 {
126 ret i32 0
127 }
128
129 define i32 @h(i32 %x) !prof !15 {
130 ret i32 0
131 }
132
133 define i32 @f(i32 %x) !prof !16 {
134 bb0:
135 %y1 = icmp eq i32 %x, 0
136 br i1 %y1, label %bb1, label %bb2, !prof !17
137
138 bb1: ; preds = %bb0
139 %z1 = call i32 @g(i32 %x)
140 br label %bb3
141
142 bb2: ; preds = %bb0
143 %z2 = call i32 @h(i32 %x)
144 br label %bb3
145
146 bb3: ; preds = %bb2, %bb1
147 %y2 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]
148 ret i32 %y2
149 }
150
151 !llvm.module.flags = !{!0}
152
153 !0 = !{i32 1, !"ProfileSummary", !1}
154 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
155 !2 = !{!"ProfileFormat", !"InstrProf"}
156 !3 = !{!"TotalCount", i64 10000}
157 !4 = !{!"MaxCount", i64 10}
158 !5 = !{!"MaxInternalCount", i64 1}
159 !6 = !{!"MaxFunctionCount", i64 1000}
160 !7 = !{!"NumCounts", i64 3}
161 !8 = !{!"NumFunctions", i64 3}
162 !9 = !{!"DetailedSummary", !10}
163 !10 = !{!11, !12, !13}
164 !11 = !{i32 10000, i64 1000, i32 1}
165 !12 = !{i32 999000, i64 300, i32 3}
166 !13 = !{i32 999999, i64 5, i32 10}
167 !14 = !{!"function_entry_count", i64 1}
168 !15 = !{!"function_entry_count", i64 100}
169 !16 = !{!"function_entry_count", i64 400}
170 !17 = !{!"branch_weights", i32 100, i32 1}
171
172 ...
173 ---
174 name: g
175 body: |
176 bb.0:
177 %1:gr32 = MOV32r0 implicit-def dead $eflags
178 $eax = COPY %1
179 RET 0, $eax
180
181 ...
182 ---
183 name: h
184 body: |
185 bb.0:
186 %1:gr32 = MOV32r0 implicit-def dead $eflags
187 $eax = COPY %1
188 RET 0, $eax
189
190 ...
191 ---
192 name: f
193 tracksRegLiveness: true
194 body: |
195 bb.0:
196 successors: %bb.1(0x7ebb907a), %bb.2(0x01446f86)
197 liveins: $edi
198
199 %1:gr32 = COPY $edi
200 TEST32rr %1, %1, implicit-def $eflags
201 JCC_1 %bb.2, 5, implicit $eflags
202 JMP_1 %bb.1
203
204 bb.1:
205 successors: %bb.3(0x80000000)
206
207 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
208 $edi = COPY %1
209 CALL64pcrel32 @g, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
210 ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
211 %5:gr32 = COPY $eax
212 %4:gr32 = MOV32r0 implicit-def dead $eflags
213 JMP_1 %bb.3
214
215 bb.2:
216 successors: %bb.3(0x80000000)
217
218 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
219 $edi = COPY %1
220 CALL64pcrel32 @h, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
221 ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
222 %3:gr32 = COPY $eax
223 %2:gr32 = MOV32ri 1
224
225 bb.3:
226 %0:gr32 = PHI %2, %bb.2, %4, %bb.1
227 $eax = COPY %0
228 RET 0, $eax
229
230 ...
231 )MIR";
232
233 } // anonymous namespace
1313 FunctionComparatorTest.cpp
1414 IntegerDivisionTest.cpp
1515 LocalTest.cpp
16 SizeOptsTest.cpp
1716 SSAUpdaterBulkTest.cpp
1817 UnrollLoopTest.cpp
1918 ValueMapperTest.cpp
+0
-129
unittests/Transforms/Utils/SizeOptsTest.cpp less more
None //===- SizeOptsTest.cpp - SizeOpts unit tests -----------------------------===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Transforms/Utils/SizeOpts.h"
9 #include "llvm/Analysis/ProfileSummaryInfo.h"
10 #include "llvm/Analysis/BlockFrequencyInfo.h"
11 #include "llvm/Analysis/BranchProbabilityInfo.h"
12 #include "llvm/Analysis/LoopInfo.h"
13 #include "llvm/AsmParser/Parser.h"
14 #include "llvm/IR/BasicBlock.h"
15 #include "llvm/IR/Dominators.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/FormatVariadic.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "gtest/gtest.h"
22
23 using namespace llvm;
24
25 namespace {
26
27 class SizeOptsTest : public testing::Test {
28 protected:
29 static const char* IRString;
30 LLVMContext C;
31 std::unique_ptr M;
32 struct BFIData {
33 std::unique_ptr DT;
34 std::unique_ptr LI;
35 std::unique_ptr BPI;
36 std::unique_ptr BFI;
37 BFIData(Function &F) {
38 DT.reset(new DominatorTree(F));
39 LI.reset(new LoopInfo(*DT));
40 BPI.reset(new BranchProbabilityInfo(F, *LI));
41 BFI.reset(new BlockFrequencyInfo(F, *BPI, *LI));
42 }
43 BlockFrequencyInfo *get() { return BFI.get(); }
44 };
45
46 void SetUp() override {
47 SMDiagnostic Err;
48 M = parseAssemblyString(IRString, Err, C);
49 }
50 };
51
52 TEST_F(SizeOptsTest, Test) {
53 Function *F = M->getFunction("f");
54 Function *G = M->getFunction("g");
55 Function *H = M->getFunction("h");
56
57 ProfileSummaryInfo PSI(*M.get());
58 BFIData BFID_F(*F);
59 BFIData BFID_G(*G);
60 BFIData BFID_H(*H);
61 BlockFrequencyInfo *BFI_F = BFID_F.get();
62 BlockFrequencyInfo *BFI_G = BFID_G.get();
63 BlockFrequencyInfo *BFI_H = BFID_H.get();
64 BasicBlock &BB0 = F->getEntryBlock();
65 BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0);
66 BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1);
67 BasicBlock *BB3 = BB1->getSingleSuccessor();
68
69 EXPECT_TRUE(PSI.hasProfileSummary());
70 EXPECT_FALSE(shouldOptimizeForSize(F, &PSI, BFI_F));
71 EXPECT_TRUE(shouldOptimizeForSize(G, &PSI, BFI_G));
72 EXPECT_FALSE(shouldOptimizeForSize(H, &PSI, BFI_H));
73 EXPECT_FALSE(shouldOptimizeForSize(&BB0, &PSI, BFI_F));
74 EXPECT_FALSE(shouldOptimizeForSize(BB1, &PSI, BFI_F));
75 EXPECT_TRUE(shouldOptimizeForSize(BB2, &PSI, BFI_F));
76 EXPECT_FALSE(shouldOptimizeForSize(BB3, &PSI, BFI_F));
77 }
78
79 const char* SizeOptsTest::IRString = R"IR(
80 define i32 @g(i32 %x) !prof !14 {
81 ret i32 0
82 }
83
84 define i32 @h(i32 %x) !prof !15 {
85 ret i32 0
86 }
87
88 define i32 @f(i32 %x) !prof !16 {
89 bb0:
90 %y1 = icmp eq i32 %x, 0
91 br i1 %y1, label %bb1, label %bb2, !prof !17
92
93 bb1: ; preds = %bb0
94 %z1 = call i32 @g(i32 %x)
95 br label %bb3
96
97 bb2: ; preds = %bb0
98 %z2 = call i32 @h(i32 %x)
99 br label %bb3
100
101 bb3: ; preds = %bb2, %bb1
102 %y2 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]
103 ret i32 %y2
104 }
105
106 !llvm.module.flags = !{!0}
107
108 !0 = !{i32 1, !"ProfileSummary", !1}
109 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
110 !2 = !{!"ProfileFormat", !"InstrProf"}
111 !3 = !{!"TotalCount", i64 10000}
112 !4 = !{!"MaxCount", i64 10}
113 !5 = !{!"MaxInternalCount", i64 1}
114 !6 = !{!"MaxFunctionCount", i64 1000}
115 !7 = !{!"NumCounts", i64 3}
116 !8 = !{!"NumFunctions", i64 3}
117 !9 = !{!"DetailedSummary", !10}
118 !10 = !{!11, !12, !13}
119 !11 = !{i32 10000, i64 1000, i32 1}
120 !12 = !{i32 999000, i64 300, i32 3}
121 !13 = !{i32 999999, i64 5, i32 10}
122 !14 = !{!"function_entry_count", i64 1}
123 !15 = !{!"function_entry_count", i64 100}
124 !16 = !{!"function_entry_count", i64 400}
125 !17 = !{!"branch_weights", i32 100, i32 1}
126 )IR";
127
128 } // end anonymous namespace