1 //===-- HexagonPeephole.cpp - Hexagon Peephole Optimiztions ---------------===//
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 // This peephole pass optimizes in the following cases.
8 // 1. Optimizes redundant sign extends for the following case
9 // Transform the following pattern
12 // %176 = COPY %170:isub_lo
17 // 2. Optimizes redundant negation of predicates.
18 // %15 = CMPGTrr %6, %2
20 // %16 = NOT_p killed %15
22 // JMP_c killed %16, <%bb.1>, implicit dead %pc
25 // %15 = CMPGTrr %6, %2;
27 // JMP_cNot killed %15, <%bb.1>, implicit dead %pc;
29 // Note: The peephole pass makes the instrucstions like
30 // %170 = SXTW %166 or %16 = NOT_p killed %15
31 // redundant and relies on some form of dead removal instructions, like
32 // DCE or DIE to actually eliminate them.
34 //===----------------------------------------------------------------------===//
37 #include "HexagonTargetMachine.h"
38 #include "llvm/ADT/DenseMap.h"
39 #include "llvm/ADT/Statistic.h"
40 #include "llvm/CodeGen/MachineFunction.h"
41 #include "llvm/CodeGen/MachineFunctionPass.h"
42 #include "llvm/CodeGen/MachineInstrBuilder.h"
43 #include "llvm/CodeGen/MachineRegisterInfo.h"
44 #include "llvm/CodeGen/Passes.h"
45 #include "llvm/CodeGen/TargetInstrInfo.h"
46 #include "llvm/CodeGen/TargetRegisterInfo.h"
47 #include "llvm/IR/Constants.h"
48 #include "llvm/PassSupport.h"
49 #include "llvm/Support/CommandLine.h"
50 #include "llvm/Support/Debug.h"
51 #include "llvm/Support/raw_ostream.h"
52 #include "llvm/Target/TargetMachine.h"
57 #define DEBUG_TYPE "hexagon-peephole"
59 static cl::opt
<bool> DisableHexagonPeephole("disable-hexagon-peephole",
60 cl::Hidden
, cl::ZeroOrMore
, cl::init(false),
61 cl::desc("Disable Peephole Optimization"));
63 static cl::opt
<bool> DisablePNotP("disable-hexagon-pnotp",
64 cl::Hidden
, cl::ZeroOrMore
, cl::init(false),
65 cl::desc("Disable Optimization of PNotP"));
67 static cl::opt
<bool> DisableOptSZExt("disable-hexagon-optszext",
68 cl::Hidden
, cl::ZeroOrMore
, cl::init(true),
69 cl::desc("Disable Optimization of Sign/Zero Extends"));
71 static cl::opt
<bool> DisableOptExtTo64("disable-hexagon-opt-ext-to-64",
72 cl::Hidden
, cl::ZeroOrMore
, cl::init(true),
73 cl::desc("Disable Optimization of extensions to i64."));
76 FunctionPass
*createHexagonPeephole();
77 void initializeHexagonPeepholePass(PassRegistry
&);
81 struct HexagonPeephole
: public MachineFunctionPass
{
82 const HexagonInstrInfo
*QII
;
83 const HexagonRegisterInfo
*QRI
;
84 const MachineRegisterInfo
*MRI
;
88 HexagonPeephole() : MachineFunctionPass(ID
) {
89 initializeHexagonPeepholePass(*PassRegistry::getPassRegistry());
92 bool runOnMachineFunction(MachineFunction
&MF
) override
;
94 StringRef
getPassName() const override
{
95 return "Hexagon optimize redundant zero and size extends";
98 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
99 MachineFunctionPass::getAnalysisUsage(AU
);
104 char HexagonPeephole::ID
= 0;
106 INITIALIZE_PASS(HexagonPeephole
, "hexagon-peephole", "Hexagon Peephole",
109 bool HexagonPeephole::runOnMachineFunction(MachineFunction
&MF
) {
110 if (skipFunction(MF
.getFunction()))
113 QII
= static_cast<const HexagonInstrInfo
*>(MF
.getSubtarget().getInstrInfo());
114 QRI
= MF
.getSubtarget
<HexagonSubtarget
>().getRegisterInfo();
115 MRI
= &MF
.getRegInfo();
117 DenseMap
<unsigned, unsigned> PeepholeMap
;
118 DenseMap
<unsigned, std::pair
<unsigned, unsigned> > PeepholeDoubleRegsMap
;
120 if (DisableHexagonPeephole
) return false;
122 // Loop over all of the basic blocks.
123 for (MachineFunction::iterator MBBb
= MF
.begin(), MBBe
= MF
.end();
124 MBBb
!= MBBe
; ++MBBb
) {
125 MachineBasicBlock
*MBB
= &*MBBb
;
127 PeepholeDoubleRegsMap
.clear();
129 // Traverse the basic block.
130 for (auto I
= MBB
->begin(), E
= MBB
->end(), NextI
= I
; I
!= E
; I
= NextI
) {
131 NextI
= std::next(I
);
132 MachineInstr
&MI
= *I
;
133 // Look for sign extends:
135 if (!DisableOptSZExt
&& MI
.getOpcode() == Hexagon::A2_sxtw
) {
136 assert(MI
.getNumOperands() == 2);
137 MachineOperand
&Dst
= MI
.getOperand(0);
138 MachineOperand
&Src
= MI
.getOperand(1);
139 Register DstReg
= Dst
.getReg();
140 Register SrcReg
= Src
.getReg();
141 // Just handle virtual registers.
142 if (Register::isVirtualRegister(DstReg
) &&
143 Register::isVirtualRegister(SrcReg
)) {
144 // Map the following:
146 // PeepholeMap[170] = %166
147 PeepholeMap
[DstReg
] = SrcReg
;
151 // Look for %170 = COMBINE_ir_V4 (0, %169)
152 // %170:DoublRegs, %169:IntRegs
153 if (!DisableOptExtTo64
&& MI
.getOpcode() == Hexagon::A4_combineir
) {
154 assert(MI
.getNumOperands() == 3);
155 MachineOperand
&Dst
= MI
.getOperand(0);
156 MachineOperand
&Src1
= MI
.getOperand(1);
157 MachineOperand
&Src2
= MI
.getOperand(2);
158 if (Src1
.getImm() != 0)
160 Register DstReg
= Dst
.getReg();
161 Register SrcReg
= Src2
.getReg();
162 PeepholeMap
[DstReg
] = SrcReg
;
165 // Look for this sequence below
166 // %DoubleReg1 = LSRd_ri %DoubleReg0, 32
167 // %IntReg = COPY %DoubleReg1:isub_lo.
169 // %IntReg = COPY %DoubleReg0:isub_hi.
170 if (MI
.getOpcode() == Hexagon::S2_lsr_i_p
) {
171 assert(MI
.getNumOperands() == 3);
172 MachineOperand
&Dst
= MI
.getOperand(0);
173 MachineOperand
&Src1
= MI
.getOperand(1);
174 MachineOperand
&Src2
= MI
.getOperand(2);
175 if (Src2
.getImm() != 32)
177 Register DstReg
= Dst
.getReg();
178 Register SrcReg
= Src1
.getReg();
179 PeepholeDoubleRegsMap
[DstReg
] =
180 std::make_pair(*&SrcReg
, Hexagon::isub_hi
);
183 // Look for P=NOT(P).
184 if (!DisablePNotP
&& MI
.getOpcode() == Hexagon::C2_not
) {
185 assert(MI
.getNumOperands() == 2);
186 MachineOperand
&Dst
= MI
.getOperand(0);
187 MachineOperand
&Src
= MI
.getOperand(1);
188 Register DstReg
= Dst
.getReg();
189 Register SrcReg
= Src
.getReg();
190 // Just handle virtual registers.
191 if (Register::isVirtualRegister(DstReg
) &&
192 Register::isVirtualRegister(SrcReg
)) {
193 // Map the following:
194 // %170 = NOT_xx %166
195 // PeepholeMap[170] = %166
196 PeepholeMap
[DstReg
] = SrcReg
;
201 // %176 = COPY %170:isub_lo
202 if (!DisableOptSZExt
&& MI
.isCopy()) {
203 assert(MI
.getNumOperands() == 2);
204 MachineOperand
&Dst
= MI
.getOperand(0);
205 MachineOperand
&Src
= MI
.getOperand(1);
207 // Make sure we are copying the lower 32 bits.
208 if (Src
.getSubReg() != Hexagon::isub_lo
)
211 Register DstReg
= Dst
.getReg();
212 Register SrcReg
= Src
.getReg();
213 if (Register::isVirtualRegister(DstReg
) &&
214 Register::isVirtualRegister(SrcReg
)) {
215 // Try to find in the map.
216 if (unsigned PeepholeSrc
= PeepholeMap
.lookup(SrcReg
)) {
217 // Change the 1st operand.
219 MI
.addOperand(MachineOperand::CreateReg(PeepholeSrc
, false));
221 DenseMap
<unsigned, std::pair
<unsigned, unsigned> >::iterator DI
=
222 PeepholeDoubleRegsMap
.find(SrcReg
);
223 if (DI
!= PeepholeDoubleRegsMap
.end()) {
224 std::pair
<unsigned,unsigned> PeepholeSrc
= DI
->second
;
226 MI
.addOperand(MachineOperand::CreateReg(
227 PeepholeSrc
.first
, false /*isDef*/, false /*isImp*/,
228 false /*isKill*/, false /*isDead*/, false /*isUndef*/,
229 false /*isEarlyClobber*/, PeepholeSrc
.second
));
235 // Look for Predicated instructions.
238 if (QII
->isPredicated(MI
)) {
239 MachineOperand
&Op0
= MI
.getOperand(0);
240 Register Reg0
= Op0
.getReg();
241 const TargetRegisterClass
*RC0
= MRI
->getRegClass(Reg0
);
242 if (RC0
->getID() == Hexagon::PredRegsRegClassID
) {
243 // Handle instructions that have a prediate register in op0
244 // (most cases of predicable instructions).
245 if (Register::isVirtualRegister(Reg0
)) {
246 // Try to find in the map.
247 if (unsigned PeepholeSrc
= PeepholeMap
.lookup(Reg0
)) {
248 // Change the 1st operand and, flip the opcode.
249 MI
.getOperand(0).setReg(PeepholeSrc
);
250 MRI
->clearKillFlags(PeepholeSrc
);
251 int NewOp
= QII
->getInvertedPredicatedOpcode(MI
.getOpcode());
252 MI
.setDesc(QII
->get(NewOp
));
260 // Handle special instructions.
261 unsigned Op
= MI
.getOpcode();
263 unsigned PR
= 1, S1
= 2, S2
= 3; // Operand indices.
266 case Hexagon::C2_mux
:
267 case Hexagon::C2_muxii
:
270 case Hexagon::C2_muxri
:
271 NewOp
= Hexagon::C2_muxir
;
273 case Hexagon::C2_muxir
:
274 NewOp
= Hexagon::C2_muxri
;
278 Register PSrc
= MI
.getOperand(PR
).getReg();
279 if (unsigned POrig
= PeepholeMap
.lookup(PSrc
)) {
280 BuildMI(*MBB
, MI
.getIterator(), MI
.getDebugLoc(),
281 QII
->get(NewOp
), MI
.getOperand(0).getReg())
283 .add(MI
.getOperand(S2
))
284 .add(MI
.getOperand(S1
));
285 MRI
->clearKillFlags(POrig
);
286 MI
.eraseFromParent();
291 } // if (!DisablePNotP)
298 FunctionPass
*llvm::createHexagonPeephole() {
299 return new HexagonPeephole();