1 //===----- HexagonLoopAlign.cpp - Generate loop alignment directives -----===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
8 // Inspect a basic block and if its single basic block loop with a small
9 // number of instructions, set the prefLoopAlignment to 32 bytes (5).
10 //===----------------------------------------------------------------------===//
12 #define DEBUG_TYPE "hexagon-loop-align"
14 #include "HexagonTargetMachine.h"
15 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
16 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
17 #include "llvm/CodeGen/SchedulerRegistry.h"
18 #include "llvm/Support/Debug.h"
23 DisableLoopAlign("disable-hexagon-loop-align", cl::Hidden
,
24 cl::desc("Disable Hexagon loop alignment pass"));
26 static cl::opt
<uint32_t> HVXLoopAlignLimitUB(
27 "hexagon-hvx-loop-align-limit-ub", cl::Hidden
, cl::init(16),
28 cl::desc("Set hexagon hvx loop upper bound align limit"));
30 static cl::opt
<uint32_t> TinyLoopAlignLimitUB(
31 "hexagon-tiny-loop-align-limit-ub", cl::Hidden
, cl::init(16),
32 cl::desc("Set hexagon tiny-core loop upper bound align limit"));
34 static cl::opt
<uint32_t>
35 LoopAlignLimitUB("hexagon-loop-align-limit-ub", cl::Hidden
, cl::init(8),
36 cl::desc("Set hexagon loop upper bound align limit"));
38 static cl::opt
<uint32_t>
39 LoopAlignLimitLB("hexagon-loop-align-limit-lb", cl::Hidden
, cl::init(4),
40 cl::desc("Set hexagon loop lower bound align limit"));
42 static cl::opt
<uint32_t>
43 LoopBndlAlignLimit("hexagon-loop-bundle-align-limit", cl::Hidden
,
45 cl::desc("Set hexagon loop align bundle limit"));
47 static cl::opt
<uint32_t> TinyLoopBndlAlignLimit(
48 "hexagon-tiny-loop-bundle-align-limit", cl::Hidden
, cl::init(8),
49 cl::desc("Set hexagon tiny-core loop align bundle limit"));
51 static cl::opt
<uint32_t>
52 LoopEdgeThreshold("hexagon-loop-edge-threshold", cl::Hidden
, cl::init(7500),
53 cl::desc("Set hexagon loop align edge theshold"));
56 FunctionPass
*createHexagonLoopAlign();
57 void initializeHexagonLoopAlignPass(PassRegistry
&);
62 class HexagonLoopAlign
: public MachineFunctionPass
{
63 const HexagonSubtarget
*HST
= nullptr;
64 const TargetMachine
*HTM
= nullptr;
65 const HexagonInstrInfo
*HII
= nullptr;
69 HexagonLoopAlign() : MachineFunctionPass(ID
) {
70 initializeHexagonLoopAlignPass(*PassRegistry::getPassRegistry());
72 bool shouldBalignLoop(MachineBasicBlock
&BB
, bool AboveThres
);
73 bool isSingleLoop(MachineBasicBlock
&MBB
);
74 bool attemptToBalignSmallLoop(MachineFunction
&MF
, MachineBasicBlock
&MBB
);
76 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
77 AU
.addRequired
<MachineBranchProbabilityInfoWrapperPass
>();
78 AU
.addRequired
<MachineBlockFrequencyInfoWrapperPass
>();
79 MachineFunctionPass::getAnalysisUsage(AU
);
82 StringRef
getPassName() const override
{ return "Hexagon LoopAlign pass"; }
83 bool runOnMachineFunction(MachineFunction
&MF
) override
;
86 char HexagonLoopAlign::ID
= 0;
88 bool HexagonLoopAlign::shouldBalignLoop(MachineBasicBlock
&BB
,
94 for (MachineBasicBlock::instr_iterator II
= BB
.instr_begin(),
98 // End if the instruction is endloop.
99 if (HII
->isEndLoopN(II
->getOpcode()))
101 // Count the number of bundles.
102 if (II
->isBundle()) {
106 // Skip over debug instructions.
107 if (II
->isDebugInstr())
109 // Check if there are any HVX instructions in loop.
110 isVec
|= HII
->isHVXVec(*II
);
111 // Count the number of instructions.
116 dbgs() << "Bundle Count : " << BndlCnt
<< "\n";
117 dbgs() << "Instruction Count : " << InstCnt
<< "\n";
120 unsigned LimitUB
= 0;
121 unsigned LimitBndl
= LoopBndlAlignLimit
;
122 // The conditions in the order of priority.
123 if (HST
->isTinyCore()) {
124 LimitUB
= TinyLoopAlignLimitUB
;
125 LimitBndl
= TinyLoopBndlAlignLimit
;
127 LimitUB
= HVXLoopAlignLimitUB
;
129 LimitUB
= LoopAlignLimitUB
;
131 // if the upper bound is not set to a value, implies we didn't meet
136 return InstCnt
>= LoopAlignLimitLB
&& InstCnt
<= LimitUB
&&
137 BndlCnt
<= LimitBndl
;
140 bool HexagonLoopAlign::isSingleLoop(MachineBasicBlock
&MBB
) {
141 int Succs
= MBB
.succ_size();
142 return (MBB
.isSuccessor(&MBB
) && (Succs
== 2));
145 bool HexagonLoopAlign::attemptToBalignSmallLoop(MachineFunction
&MF
,
146 MachineBasicBlock
&MBB
) {
147 if (!isSingleLoop(MBB
))
150 const MachineBranchProbabilityInfo
*MBPI
=
151 &getAnalysis
<MachineBranchProbabilityInfoWrapperPass
>().getMBPI();
152 const MachineBlockFrequencyInfo
*MBFI
=
153 &getAnalysis
<MachineBlockFrequencyInfoWrapperPass
>().getMBFI();
155 // Compute frequency of back edge,
156 BlockFrequency BlockFreq
= MBFI
->getBlockFreq(&MBB
);
157 BranchProbability BrProb
= MBPI
->getEdgeProbability(&MBB
, &MBB
);
158 BlockFrequency EdgeFreq
= BlockFreq
* BrProb
;
160 dbgs() << "Loop Align Pass:\n";
161 dbgs() << "\tedge with freq(" << EdgeFreq
.getFrequency() << ")\n";
164 bool AboveThres
= EdgeFreq
.getFrequency() > LoopEdgeThreshold
;
165 if (shouldBalignLoop(MBB
, AboveThres
)) {
166 // We found a loop, change its alignment to be 32 (5).
167 MBB
.setAlignment(llvm::Align(1 << 5));
173 // Inspect each basic block, and if its a single BB loop, see if it
174 // meets the criteria for increasing alignment to 32.
176 bool HexagonLoopAlign::runOnMachineFunction(MachineFunction
&MF
) {
178 HST
= &MF
.getSubtarget
<HexagonSubtarget
>();
179 HII
= HST
->getInstrInfo();
180 HTM
= &MF
.getTarget();
182 if (skipFunction(MF
.getFunction()))
184 if (DisableLoopAlign
)
187 // This optimization is performed at
188 // i) -O2 and above, and when the loop has a HVX instruction.
190 if (HST
->useHVXOps()) {
191 if (HTM
->getOptLevel() < CodeGenOptLevel::Default
)
194 if (HTM
->getOptLevel() < CodeGenOptLevel::Aggressive
)
198 bool Changed
= false;
199 for (MachineFunction::iterator MBBi
= MF
.begin(), MBBe
= MF
.end();
200 MBBi
!= MBBe
; ++MBBi
) {
201 MachineBasicBlock
&MBB
= *MBBi
;
202 Changed
|= attemptToBalignSmallLoop(MF
, MBB
);
209 INITIALIZE_PASS(HexagonLoopAlign
, "hexagon-loop-align",
210 "Hexagon LoopAlign pass", false, false)
212 //===----------------------------------------------------------------------===//
213 // Public Constructor Functions
214 //===----------------------------------------------------------------------===//
216 FunctionPass
*llvm::createHexagonLoopAlign() { return new HexagonLoopAlign(); }