1*9880d681SAndroid Build Coastguard Worker //===-- LanaiInstrInfo.cpp - Lanai Instruction Information ------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Lanai implementation of the TargetInstrInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "Lanai.h"
15*9880d681SAndroid Build Coastguard Worker #include "LanaiInstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "LanaiMachineFunctionInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "LanaiTargetMachine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker using namespace llvm;
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
29*9880d681SAndroid Build Coastguard Worker #include "LanaiGenInstrInfo.inc"
30*9880d681SAndroid Build Coastguard Worker
LanaiInstrInfo()31*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::LanaiInstrInfo()
32*9880d681SAndroid Build Coastguard Worker : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
33*9880d681SAndroid Build Coastguard Worker RegisterInfo() {}
34*9880d681SAndroid Build Coastguard Worker
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,const DebugLoc & DL,unsigned DestinationRegister,unsigned SourceRegister,bool KillSource) const35*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
36*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Position,
37*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL,
38*9880d681SAndroid Build Coastguard Worker unsigned DestinationRegister,
39*9880d681SAndroid Build Coastguard Worker unsigned SourceRegister,
40*9880d681SAndroid Build Coastguard Worker bool KillSource) const {
41*9880d681SAndroid Build Coastguard Worker if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {
42*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Impossible reg-to-reg copy");
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)
46*9880d681SAndroid Build Coastguard Worker .addReg(SourceRegister, getKillRegState(KillSource))
47*9880d681SAndroid Build Coastguard Worker .addImm(0);
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,unsigned SourceRegister,bool IsKill,int FrameIndex,const TargetRegisterClass * RegisterClass,const TargetRegisterInfo * RegisterInfo) const50*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::storeRegToStackSlot(
51*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
52*9880d681SAndroid Build Coastguard Worker unsigned SourceRegister, bool IsKill, int FrameIndex,
53*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RegisterClass,
54*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *RegisterInfo) const {
55*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
56*9880d681SAndroid Build Coastguard Worker if (Position != MBB.end()) {
57*9880d681SAndroid Build Coastguard Worker DL = Position->getDebugLoc();
58*9880d681SAndroid Build Coastguard Worker }
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
61*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Can't store this register to stack slot");
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, Position, DL, get(Lanai::SW_RI))
64*9880d681SAndroid Build Coastguard Worker .addReg(SourceRegister, getKillRegState(IsKill))
65*9880d681SAndroid Build Coastguard Worker .addFrameIndex(FrameIndex)
66*9880d681SAndroid Build Coastguard Worker .addImm(0)
67*9880d681SAndroid Build Coastguard Worker .addImm(LPAC::ADD);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,unsigned DestinationRegister,int FrameIndex,const TargetRegisterClass * RegisterClass,const TargetRegisterInfo * RegisterInfo) const70*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::loadRegFromStackSlot(
71*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
72*9880d681SAndroid Build Coastguard Worker unsigned DestinationRegister, int FrameIndex,
73*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RegisterClass,
74*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *RegisterInfo) const {
75*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
76*9880d681SAndroid Build Coastguard Worker if (Position != MBB.end()) {
77*9880d681SAndroid Build Coastguard Worker DL = Position->getDebugLoc();
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
81*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Can't load this register from stack slot");
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)
84*9880d681SAndroid Build Coastguard Worker .addFrameIndex(FrameIndex)
85*9880d681SAndroid Build Coastguard Worker .addImm(0)
86*9880d681SAndroid Build Coastguard Worker .addImm(LPAC::ADD);
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker
areMemAccessesTriviallyDisjoint(MachineInstr & MIa,MachineInstr & MIb,AliasAnalysis * AA) const89*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr &MIa,
90*9880d681SAndroid Build Coastguard Worker MachineInstr &MIb,
91*9880d681SAndroid Build Coastguard Worker AliasAnalysis *AA) const {
92*9880d681SAndroid Build Coastguard Worker assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
93*9880d681SAndroid Build Coastguard Worker assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
96*9880d681SAndroid Build Coastguard Worker MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
97*9880d681SAndroid Build Coastguard Worker return false;
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker // Retrieve the base register, offset from the base register and width. Width
100*9880d681SAndroid Build Coastguard Worker // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
101*9880d681SAndroid Build Coastguard Worker // base registers are identical, and the offset of a lower memory access +
102*9880d681SAndroid Build Coastguard Worker // the width doesn't overlap the offset of a higher memory access,
103*9880d681SAndroid Build Coastguard Worker // then the memory accesses are different.
104*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = &getRegisterInfo();
105*9880d681SAndroid Build Coastguard Worker unsigned BaseRegA = 0, BaseRegB = 0;
106*9880d681SAndroid Build Coastguard Worker int64_t OffsetA = 0, OffsetB = 0;
107*9880d681SAndroid Build Coastguard Worker unsigned int WidthA = 0, WidthB = 0;
108*9880d681SAndroid Build Coastguard Worker if (getMemOpBaseRegImmOfsWidth(MIa, BaseRegA, OffsetA, WidthA, TRI) &&
109*9880d681SAndroid Build Coastguard Worker getMemOpBaseRegImmOfsWidth(MIb, BaseRegB, OffsetB, WidthB, TRI)) {
110*9880d681SAndroid Build Coastguard Worker if (BaseRegA == BaseRegB) {
111*9880d681SAndroid Build Coastguard Worker int LowOffset = std::min(OffsetA, OffsetB);
112*9880d681SAndroid Build Coastguard Worker int HighOffset = std::max(OffsetA, OffsetB);
113*9880d681SAndroid Build Coastguard Worker int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
114*9880d681SAndroid Build Coastguard Worker if (LowOffset + LowWidth <= HighOffset)
115*9880d681SAndroid Build Coastguard Worker return true;
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker return false;
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
expandPostRAPseudo(MachineInstr & MI) const121*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
122*9880d681SAndroid Build Coastguard Worker return false;
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker
getOppositeCondition(LPCC::CondCode CC)125*9880d681SAndroid Build Coastguard Worker static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC) {
126*9880d681SAndroid Build Coastguard Worker switch (CC) {
127*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_T: // true
128*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_F;
129*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_F: // false
130*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_T;
131*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_HI: // high
132*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_LS;
133*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LS: // low or same
134*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_HI;
135*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_CC: // carry cleared
136*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_CS;
137*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_CS: // carry set
138*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_CC;
139*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_NE: // not equal
140*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_EQ;
141*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_EQ: // equal
142*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_NE;
143*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_VC: // oVerflow cleared
144*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_VS;
145*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_VS: // oVerflow set
146*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_VC;
147*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_PL: // plus (note: 0 is "minus" too here)
148*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_MI;
149*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_MI: // minus
150*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_PL;
151*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_GE: // greater than or equal
152*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_LT;
153*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LT: // less than
154*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_GE;
155*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_GT: // greater than
156*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_LE;
157*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LE: // less than or equal
158*9880d681SAndroid Build Coastguard Worker return LPCC::ICC_GT;
159*9880d681SAndroid Build Coastguard Worker default:
160*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid condtional code");
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const165*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
166*9880d681SAndroid Build Coastguard Worker return std::make_pair(TF, 0u);
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const170*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
171*9880d681SAndroid Build Coastguard Worker using namespace LanaiII;
172*9880d681SAndroid Build Coastguard Worker static const std::pair<unsigned, const char *> TargetFlags[] = {
173*9880d681SAndroid Build Coastguard Worker {MO_ABS_HI, "lanai-hi"},
174*9880d681SAndroid Build Coastguard Worker {MO_ABS_LO, "lanai-lo"},
175*9880d681SAndroid Build Coastguard Worker {MO_NO_FLAG, "lanai-nf"}};
176*9880d681SAndroid Build Coastguard Worker return makeArrayRef(TargetFlags);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker
analyzeCompare(const MachineInstr & MI,unsigned & SrcReg,unsigned & SrcReg2,int & CmpMask,int & CmpValue) const179*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
180*9880d681SAndroid Build Coastguard Worker unsigned &SrcReg2, int &CmpMask,
181*9880d681SAndroid Build Coastguard Worker int &CmpValue) const {
182*9880d681SAndroid Build Coastguard Worker switch (MI.getOpcode()) {
183*9880d681SAndroid Build Coastguard Worker default:
184*9880d681SAndroid Build Coastguard Worker break;
185*9880d681SAndroid Build Coastguard Worker case Lanai::SFSUB_F_RI_LO:
186*9880d681SAndroid Build Coastguard Worker case Lanai::SFSUB_F_RI_HI:
187*9880d681SAndroid Build Coastguard Worker SrcReg = MI.getOperand(0).getReg();
188*9880d681SAndroid Build Coastguard Worker SrcReg2 = 0;
189*9880d681SAndroid Build Coastguard Worker CmpMask = ~0;
190*9880d681SAndroid Build Coastguard Worker CmpValue = MI.getOperand(1).getImm();
191*9880d681SAndroid Build Coastguard Worker return true;
192*9880d681SAndroid Build Coastguard Worker case Lanai::SFSUB_F_RR:
193*9880d681SAndroid Build Coastguard Worker SrcReg = MI.getOperand(0).getReg();
194*9880d681SAndroid Build Coastguard Worker SrcReg2 = MI.getOperand(1).getReg();
195*9880d681SAndroid Build Coastguard Worker CmpMask = ~0;
196*9880d681SAndroid Build Coastguard Worker CmpValue = 0;
197*9880d681SAndroid Build Coastguard Worker return true;
198*9880d681SAndroid Build Coastguard Worker }
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker return false;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker // isRedundantFlagInstr - check whether the first instruction, whose only
204*9880d681SAndroid Build Coastguard Worker // purpose is to update flags, can be made redundant.
205*9880d681SAndroid Build Coastguard Worker // * SFSUB_F_RR can be made redundant by SUB_RI if the operands are the same.
206*9880d681SAndroid Build Coastguard Worker // * SFSUB_F_RI can be made redundant by SUB_I if the operands are the same.
isRedundantFlagInstr(MachineInstr * CmpI,unsigned SrcReg,unsigned SrcReg2,int ImmValue,MachineInstr * OI)207*9880d681SAndroid Build Coastguard Worker inline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,
208*9880d681SAndroid Build Coastguard Worker unsigned SrcReg2, int ImmValue,
209*9880d681SAndroid Build Coastguard Worker MachineInstr *OI) {
210*9880d681SAndroid Build Coastguard Worker if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&
211*9880d681SAndroid Build Coastguard Worker OI->getOpcode() == Lanai::SUB_R &&
212*9880d681SAndroid Build Coastguard Worker ((OI->getOperand(1).getReg() == SrcReg &&
213*9880d681SAndroid Build Coastguard Worker OI->getOperand(2).getReg() == SrcReg2) ||
214*9880d681SAndroid Build Coastguard Worker (OI->getOperand(1).getReg() == SrcReg2 &&
215*9880d681SAndroid Build Coastguard Worker OI->getOperand(2).getReg() == SrcReg)))
216*9880d681SAndroid Build Coastguard Worker return true;
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&
219*9880d681SAndroid Build Coastguard Worker OI->getOpcode() == Lanai::SUB_I_LO) ||
220*9880d681SAndroid Build Coastguard Worker (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&
221*9880d681SAndroid Build Coastguard Worker OI->getOpcode() == Lanai::SUB_I_HI)) &&
222*9880d681SAndroid Build Coastguard Worker OI->getOperand(1).getReg() == SrcReg &&
223*9880d681SAndroid Build Coastguard Worker OI->getOperand(2).getImm() == ImmValue)
224*9880d681SAndroid Build Coastguard Worker return true;
225*9880d681SAndroid Build Coastguard Worker return false;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker
flagSettingOpcodeVariant(unsigned OldOpcode)228*9880d681SAndroid Build Coastguard Worker inline static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {
229*9880d681SAndroid Build Coastguard Worker switch (OldOpcode) {
230*9880d681SAndroid Build Coastguard Worker case Lanai::ADD_I_HI:
231*9880d681SAndroid Build Coastguard Worker return Lanai::ADD_F_I_HI;
232*9880d681SAndroid Build Coastguard Worker case Lanai::ADD_I_LO:
233*9880d681SAndroid Build Coastguard Worker return Lanai::ADD_F_I_LO;
234*9880d681SAndroid Build Coastguard Worker case Lanai::ADD_R:
235*9880d681SAndroid Build Coastguard Worker return Lanai::ADD_F_R;
236*9880d681SAndroid Build Coastguard Worker case Lanai::ADDC_I_HI:
237*9880d681SAndroid Build Coastguard Worker return Lanai::ADDC_F_I_HI;
238*9880d681SAndroid Build Coastguard Worker case Lanai::ADDC_I_LO:
239*9880d681SAndroid Build Coastguard Worker return Lanai::ADDC_F_I_LO;
240*9880d681SAndroid Build Coastguard Worker case Lanai::ADDC_R:
241*9880d681SAndroid Build Coastguard Worker return Lanai::ADDC_F_R;
242*9880d681SAndroid Build Coastguard Worker case Lanai::AND_I_HI:
243*9880d681SAndroid Build Coastguard Worker return Lanai::AND_F_I_HI;
244*9880d681SAndroid Build Coastguard Worker case Lanai::AND_I_LO:
245*9880d681SAndroid Build Coastguard Worker return Lanai::AND_F_I_LO;
246*9880d681SAndroid Build Coastguard Worker case Lanai::AND_R:
247*9880d681SAndroid Build Coastguard Worker return Lanai::AND_F_R;
248*9880d681SAndroid Build Coastguard Worker case Lanai::OR_I_HI:
249*9880d681SAndroid Build Coastguard Worker return Lanai::OR_F_I_HI;
250*9880d681SAndroid Build Coastguard Worker case Lanai::OR_I_LO:
251*9880d681SAndroid Build Coastguard Worker return Lanai::OR_F_I_LO;
252*9880d681SAndroid Build Coastguard Worker case Lanai::OR_R:
253*9880d681SAndroid Build Coastguard Worker return Lanai::OR_F_R;
254*9880d681SAndroid Build Coastguard Worker case Lanai::SL_I:
255*9880d681SAndroid Build Coastguard Worker return Lanai::SL_F_I;
256*9880d681SAndroid Build Coastguard Worker case Lanai::SRL_R:
257*9880d681SAndroid Build Coastguard Worker return Lanai::SRL_F_R;
258*9880d681SAndroid Build Coastguard Worker case Lanai::SA_I:
259*9880d681SAndroid Build Coastguard Worker return Lanai::SA_F_I;
260*9880d681SAndroid Build Coastguard Worker case Lanai::SRA_R:
261*9880d681SAndroid Build Coastguard Worker return Lanai::SRA_F_R;
262*9880d681SAndroid Build Coastguard Worker case Lanai::SUB_I_HI:
263*9880d681SAndroid Build Coastguard Worker return Lanai::SUB_F_I_HI;
264*9880d681SAndroid Build Coastguard Worker case Lanai::SUB_I_LO:
265*9880d681SAndroid Build Coastguard Worker return Lanai::SUB_F_I_LO;
266*9880d681SAndroid Build Coastguard Worker case Lanai::SUB_R:
267*9880d681SAndroid Build Coastguard Worker return Lanai::SUB_F_R;
268*9880d681SAndroid Build Coastguard Worker case Lanai::SUBB_I_HI:
269*9880d681SAndroid Build Coastguard Worker return Lanai::SUBB_F_I_HI;
270*9880d681SAndroid Build Coastguard Worker case Lanai::SUBB_I_LO:
271*9880d681SAndroid Build Coastguard Worker return Lanai::SUBB_F_I_LO;
272*9880d681SAndroid Build Coastguard Worker case Lanai::SUBB_R:
273*9880d681SAndroid Build Coastguard Worker return Lanai::SUBB_F_R;
274*9880d681SAndroid Build Coastguard Worker case Lanai::XOR_I_HI:
275*9880d681SAndroid Build Coastguard Worker return Lanai::XOR_F_I_HI;
276*9880d681SAndroid Build Coastguard Worker case Lanai::XOR_I_LO:
277*9880d681SAndroid Build Coastguard Worker return Lanai::XOR_F_I_LO;
278*9880d681SAndroid Build Coastguard Worker case Lanai::XOR_R:
279*9880d681SAndroid Build Coastguard Worker return Lanai::XOR_F_R;
280*9880d681SAndroid Build Coastguard Worker default:
281*9880d681SAndroid Build Coastguard Worker return Lanai::NOP;
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker
optimizeCompareInstr(MachineInstr & CmpInstr,unsigned SrcReg,unsigned SrcReg2,int CmpMask,int CmpValue,const MachineRegisterInfo * MRI) const285*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::optimizeCompareInstr(
286*9880d681SAndroid Build Coastguard Worker MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
287*9880d681SAndroid Build Coastguard Worker int CmpValue, const MachineRegisterInfo *MRI) const {
288*9880d681SAndroid Build Coastguard Worker // Get the unique definition of SrcReg.
289*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
290*9880d681SAndroid Build Coastguard Worker if (!MI)
291*9880d681SAndroid Build Coastguard Worker return false;
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker // Get ready to iterate backward from CmpInstr.
294*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I = CmpInstr, E = MI,
295*9880d681SAndroid Build Coastguard Worker B = CmpInstr.getParent()->begin();
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker // Early exit if CmpInstr is at the beginning of the BB.
298*9880d681SAndroid Build Coastguard Worker if (I == B)
299*9880d681SAndroid Build Coastguard Worker return false;
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker // There are two possible candidates which can be changed to set SR:
302*9880d681SAndroid Build Coastguard Worker // One is MI, the other is a SUB instruction.
303*9880d681SAndroid Build Coastguard Worker // * For SFSUB_F_RR(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
304*9880d681SAndroid Build Coastguard Worker // * For SFSUB_F_RI(r1, CmpValue), we are looking for SUB(r1, CmpValue).
305*9880d681SAndroid Build Coastguard Worker MachineInstr *Sub = nullptr;
306*9880d681SAndroid Build Coastguard Worker if (SrcReg2 != 0)
307*9880d681SAndroid Build Coastguard Worker // MI is not a candidate to transform into a flag setting instruction.
308*9880d681SAndroid Build Coastguard Worker MI = nullptr;
309*9880d681SAndroid Build Coastguard Worker else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
310*9880d681SAndroid Build Coastguard Worker // Conservatively refuse to convert an instruction which isn't in the same
311*9880d681SAndroid Build Coastguard Worker // BB as the comparison. Don't return if SFSUB_F_RI and CmpValue != 0 as Sub
312*9880d681SAndroid Build Coastguard Worker // may still be a candidate.
313*9880d681SAndroid Build Coastguard Worker if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)
314*9880d681SAndroid Build Coastguard Worker MI = nullptr;
315*9880d681SAndroid Build Coastguard Worker else
316*9880d681SAndroid Build Coastguard Worker return false;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker // Check that SR isn't set between the comparison instruction and the
320*9880d681SAndroid Build Coastguard Worker // instruction we want to change while searching for Sub.
321*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = &getRegisterInfo();
322*9880d681SAndroid Build Coastguard Worker for (--I; I != E; --I) {
323*9880d681SAndroid Build Coastguard Worker const MachineInstr &Instr = *I;
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker if (Instr.modifiesRegister(Lanai::SR, TRI) ||
326*9880d681SAndroid Build Coastguard Worker Instr.readsRegister(Lanai::SR, TRI))
327*9880d681SAndroid Build Coastguard Worker // This instruction modifies or uses SR after the one we want to change.
328*9880d681SAndroid Build Coastguard Worker // We can't do this transformation.
329*9880d681SAndroid Build Coastguard Worker return false;
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Worker // Check whether CmpInstr can be made redundant by the current instruction.
332*9880d681SAndroid Build Coastguard Worker if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
333*9880d681SAndroid Build Coastguard Worker Sub = &*I;
334*9880d681SAndroid Build Coastguard Worker break;
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker // Don't search outside the containing basic block.
338*9880d681SAndroid Build Coastguard Worker if (I == B)
339*9880d681SAndroid Build Coastguard Worker return false;
340*9880d681SAndroid Build Coastguard Worker }
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker // Return false if no candidates exist.
343*9880d681SAndroid Build Coastguard Worker if (!MI && !Sub)
344*9880d681SAndroid Build Coastguard Worker return false;
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Worker // The single candidate is called MI.
347*9880d681SAndroid Build Coastguard Worker if (!MI)
348*9880d681SAndroid Build Coastguard Worker MI = Sub;
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker if (flagSettingOpcodeVariant(MI->getOpcode()) != Lanai::NOP) {
351*9880d681SAndroid Build Coastguard Worker bool isSafe = false;
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker SmallVector<std::pair<MachineOperand *, LPCC::CondCode>, 4>
354*9880d681SAndroid Build Coastguard Worker OperandsToUpdate;
355*9880d681SAndroid Build Coastguard Worker I = CmpInstr;
356*9880d681SAndroid Build Coastguard Worker E = CmpInstr.getParent()->end();
357*9880d681SAndroid Build Coastguard Worker while (!isSafe && ++I != E) {
358*9880d681SAndroid Build Coastguard Worker const MachineInstr &Instr = *I;
359*9880d681SAndroid Build Coastguard Worker for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
360*9880d681SAndroid Build Coastguard Worker ++IO) {
361*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = Instr.getOperand(IO);
362*9880d681SAndroid Build Coastguard Worker if (MO.isRegMask() && MO.clobbersPhysReg(Lanai::SR)) {
363*9880d681SAndroid Build Coastguard Worker isSafe = true;
364*9880d681SAndroid Build Coastguard Worker break;
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || MO.getReg() != Lanai::SR)
367*9880d681SAndroid Build Coastguard Worker continue;
368*9880d681SAndroid Build Coastguard Worker if (MO.isDef()) {
369*9880d681SAndroid Build Coastguard Worker isSafe = true;
370*9880d681SAndroid Build Coastguard Worker break;
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker // Condition code is after the operand before SR.
373*9880d681SAndroid Build Coastguard Worker LPCC::CondCode CC;
374*9880d681SAndroid Build Coastguard Worker CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();
375*9880d681SAndroid Build Coastguard Worker
376*9880d681SAndroid Build Coastguard Worker if (Sub) {
377*9880d681SAndroid Build Coastguard Worker LPCC::CondCode NewCC = getOppositeCondition(CC);
378*9880d681SAndroid Build Coastguard Worker if (NewCC == LPCC::ICC_T)
379*9880d681SAndroid Build Coastguard Worker return false;
380*9880d681SAndroid Build Coastguard Worker // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on
381*9880d681SAndroid Build Coastguard Worker // CMP needs to be updated to be based on SUB. Push the condition
382*9880d681SAndroid Build Coastguard Worker // code operands to OperandsToUpdate. If it is safe to remove
383*9880d681SAndroid Build Coastguard Worker // CmpInstr, the condition code of these operands will be modified.
384*9880d681SAndroid Build Coastguard Worker if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
385*9880d681SAndroid Build Coastguard Worker Sub->getOperand(2).getReg() == SrcReg) {
386*9880d681SAndroid Build Coastguard Worker OperandsToUpdate.push_back(
387*9880d681SAndroid Build Coastguard Worker std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker } else {
390*9880d681SAndroid Build Coastguard Worker // No Sub, so this is x = <op> y, z; cmp x, 0.
391*9880d681SAndroid Build Coastguard Worker switch (CC) {
392*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_EQ: // Z
393*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_NE: // Z
394*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_MI: // N
395*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_PL: // N
396*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_F: // none
397*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_T: // none
398*9880d681SAndroid Build Coastguard Worker // SR can be used multiple times, we should continue.
399*9880d681SAndroid Build Coastguard Worker break;
400*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_CS: // C
401*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_CC: // C
402*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_VS: // V
403*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_VC: // V
404*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_HI: // C Z
405*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LS: // C Z
406*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_GE: // N V
407*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LT: // N V
408*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_GT: // Z N V
409*9880d681SAndroid Build Coastguard Worker case LPCC::ICC_LE: // Z N V
410*9880d681SAndroid Build Coastguard Worker // The instruction uses the V bit or C bit which is not safe.
411*9880d681SAndroid Build Coastguard Worker return false;
412*9880d681SAndroid Build Coastguard Worker case LPCC::UNKNOWN:
413*9880d681SAndroid Build Coastguard Worker return false;
414*9880d681SAndroid Build Coastguard Worker }
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker // If SR is not killed nor re-defined, we should check whether it is
420*9880d681SAndroid Build Coastguard Worker // live-out. If it is live-out, do not optimize.
421*9880d681SAndroid Build Coastguard Worker if (!isSafe) {
422*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = CmpInstr.getParent();
423*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
424*9880d681SAndroid Build Coastguard Worker SE = MBB->succ_end();
425*9880d681SAndroid Build Coastguard Worker SI != SE; ++SI)
426*9880d681SAndroid Build Coastguard Worker if ((*SI)->isLiveIn(Lanai::SR))
427*9880d681SAndroid Build Coastguard Worker return false;
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker // Toggle the optional operand to SR.
431*9880d681SAndroid Build Coastguard Worker MI->setDesc(get(flagSettingOpcodeVariant(MI->getOpcode())));
432*9880d681SAndroid Build Coastguard Worker MI->addRegisterDefined(Lanai::SR);
433*9880d681SAndroid Build Coastguard Worker CmpInstr.eraseFromParent();
434*9880d681SAndroid Build Coastguard Worker return true;
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker return false;
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker
analyzeSelect(const MachineInstr & MI,SmallVectorImpl<MachineOperand> & Cond,unsigned & TrueOp,unsigned & FalseOp,bool & Optimizable) const440*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeSelect(const MachineInstr &MI,
441*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond,
442*9880d681SAndroid Build Coastguard Worker unsigned &TrueOp, unsigned &FalseOp,
443*9880d681SAndroid Build Coastguard Worker bool &Optimizable) const {
444*9880d681SAndroid Build Coastguard Worker assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
445*9880d681SAndroid Build Coastguard Worker // Select operands:
446*9880d681SAndroid Build Coastguard Worker // 0: Def.
447*9880d681SAndroid Build Coastguard Worker // 1: True use.
448*9880d681SAndroid Build Coastguard Worker // 2: False use.
449*9880d681SAndroid Build Coastguard Worker // 3: Condition code.
450*9880d681SAndroid Build Coastguard Worker TrueOp = 1;
451*9880d681SAndroid Build Coastguard Worker FalseOp = 2;
452*9880d681SAndroid Build Coastguard Worker Cond.push_back(MI.getOperand(3));
453*9880d681SAndroid Build Coastguard Worker Optimizable = true;
454*9880d681SAndroid Build Coastguard Worker return false;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Worker // Identify instructions that can be folded into a SELECT instruction, and
458*9880d681SAndroid Build Coastguard Worker // return the defining instruction.
canFoldIntoSelect(unsigned Reg,const MachineRegisterInfo & MRI,const TargetInstrInfo * TII)459*9880d681SAndroid Build Coastguard Worker static MachineInstr *canFoldIntoSelect(unsigned Reg,
460*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo &MRI,
461*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII) {
462*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(Reg))
463*9880d681SAndroid Build Coastguard Worker return nullptr;
464*9880d681SAndroid Build Coastguard Worker if (!MRI.hasOneNonDBGUse(Reg))
465*9880d681SAndroid Build Coastguard Worker return nullptr;
466*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = MRI.getVRegDef(Reg);
467*9880d681SAndroid Build Coastguard Worker if (!MI)
468*9880d681SAndroid Build Coastguard Worker return nullptr;
469*9880d681SAndroid Build Coastguard Worker // MI is folded into the SELECT by predicating it.
470*9880d681SAndroid Build Coastguard Worker if (!MI->isPredicable())
471*9880d681SAndroid Build Coastguard Worker return nullptr;
472*9880d681SAndroid Build Coastguard Worker // Check if MI has any non-dead defs or physreg uses. This also detects
473*9880d681SAndroid Build Coastguard Worker // predicated instructions which will be reading SR.
474*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) {
475*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = MI->getOperand(i);
476*9880d681SAndroid Build Coastguard Worker // Reject frame index operands.
477*9880d681SAndroid Build Coastguard Worker if (MO.isFI() || MO.isCPI() || MO.isJTI())
478*9880d681SAndroid Build Coastguard Worker return nullptr;
479*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
480*9880d681SAndroid Build Coastguard Worker continue;
481*9880d681SAndroid Build Coastguard Worker // MI can't have any tied operands, that would conflict with predication.
482*9880d681SAndroid Build Coastguard Worker if (MO.isTied())
483*9880d681SAndroid Build Coastguard Worker return nullptr;
484*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
485*9880d681SAndroid Build Coastguard Worker return nullptr;
486*9880d681SAndroid Build Coastguard Worker if (MO.isDef() && !MO.isDead())
487*9880d681SAndroid Build Coastguard Worker return nullptr;
488*9880d681SAndroid Build Coastguard Worker }
489*9880d681SAndroid Build Coastguard Worker bool DontMoveAcrossStores = true;
490*9880d681SAndroid Build Coastguard Worker if (!MI->isSafeToMove(/*AliasAnalysis=*/nullptr, DontMoveAcrossStores))
491*9880d681SAndroid Build Coastguard Worker return nullptr;
492*9880d681SAndroid Build Coastguard Worker return MI;
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker MachineInstr *
optimizeSelect(MachineInstr & MI,SmallPtrSetImpl<MachineInstr * > & SeenMIs,bool PreferFalse) const496*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::optimizeSelect(MachineInstr &MI,
497*9880d681SAndroid Build Coastguard Worker SmallPtrSetImpl<MachineInstr *> &SeenMIs,
498*9880d681SAndroid Build Coastguard Worker bool PreferFalse) const {
499*9880d681SAndroid Build Coastguard Worker assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
500*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
501*9880d681SAndroid Build Coastguard Worker MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI, this);
502*9880d681SAndroid Build Coastguard Worker bool Invert = !DefMI;
503*9880d681SAndroid Build Coastguard Worker if (!DefMI)
504*9880d681SAndroid Build Coastguard Worker DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI, this);
505*9880d681SAndroid Build Coastguard Worker if (!DefMI)
506*9880d681SAndroid Build Coastguard Worker return nullptr;
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Worker // Find new register class to use.
509*9880d681SAndroid Build Coastguard Worker MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);
510*9880d681SAndroid Build Coastguard Worker unsigned DestReg = MI.getOperand(0).getReg();
511*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
512*9880d681SAndroid Build Coastguard Worker if (!MRI.constrainRegClass(DestReg, PreviousClass))
513*9880d681SAndroid Build Coastguard Worker return nullptr;
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker // Create a new predicated version of DefMI.
516*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder NewMI =
517*9880d681SAndroid Build Coastguard Worker BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
518*9880d681SAndroid Build Coastguard Worker
519*9880d681SAndroid Build Coastguard Worker // Copy all the DefMI operands, excluding its (null) predicate.
520*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &DefDesc = DefMI->getDesc();
521*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, e = DefDesc.getNumOperands();
522*9880d681SAndroid Build Coastguard Worker i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
523*9880d681SAndroid Build Coastguard Worker NewMI.addOperand(DefMI->getOperand(i));
524*9880d681SAndroid Build Coastguard Worker
525*9880d681SAndroid Build Coastguard Worker unsigned CondCode = MI.getOperand(3).getImm();
526*9880d681SAndroid Build Coastguard Worker if (Invert)
527*9880d681SAndroid Build Coastguard Worker NewMI.addImm(getOppositeCondition(LPCC::CondCode(CondCode)));
528*9880d681SAndroid Build Coastguard Worker else
529*9880d681SAndroid Build Coastguard Worker NewMI.addImm(CondCode);
530*9880d681SAndroid Build Coastguard Worker NewMI.copyImplicitOps(MI);
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker // The output register value when the predicate is false is an implicit
533*9880d681SAndroid Build Coastguard Worker // register operand tied to the first def. The tie makes the register
534*9880d681SAndroid Build Coastguard Worker // allocator ensure the FalseReg is allocated the same register as operand 0.
535*9880d681SAndroid Build Coastguard Worker FalseReg.setImplicit();
536*9880d681SAndroid Build Coastguard Worker NewMI.addOperand(FalseReg);
537*9880d681SAndroid Build Coastguard Worker NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker // Update SeenMIs set: register newly created MI and erase removed DefMI.
540*9880d681SAndroid Build Coastguard Worker SeenMIs.insert(NewMI);
541*9880d681SAndroid Build Coastguard Worker SeenMIs.erase(DefMI);
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Worker // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
544*9880d681SAndroid Build Coastguard Worker // DefMI would be invalid when transferred inside the loop. Checking for a
545*9880d681SAndroid Build Coastguard Worker // loop is expensive, but at least remove kill flags if they are in different
546*9880d681SAndroid Build Coastguard Worker // BBs.
547*9880d681SAndroid Build Coastguard Worker if (DefMI->getParent() != MI.getParent())
548*9880d681SAndroid Build Coastguard Worker NewMI->clearKillInfo();
549*9880d681SAndroid Build Coastguard Worker
550*9880d681SAndroid Build Coastguard Worker // The caller will erase MI, but not DefMI.
551*9880d681SAndroid Build Coastguard Worker DefMI->eraseFromParent();
552*9880d681SAndroid Build Coastguard Worker return NewMI;
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker // The AnalyzeBranch function is used to examine conditional instructions and
556*9880d681SAndroid Build Coastguard Worker // remove unnecessary instructions. This method is used by BranchFolder and
557*9880d681SAndroid Build Coastguard Worker // IfConverter machine function passes to improve the CFG.
558*9880d681SAndroid Build Coastguard Worker // - TrueBlock is set to the destination if condition evaluates true (it is the
559*9880d681SAndroid Build Coastguard Worker // nullptr if the destination is the fall-through branch);
560*9880d681SAndroid Build Coastguard Worker // - FalseBlock is set to the destination if condition evaluates to false (it
561*9880d681SAndroid Build Coastguard Worker // is the nullptr if the branch is unconditional);
562*9880d681SAndroid Build Coastguard Worker // - condition is populated with machine operands needed to generate the branch
563*9880d681SAndroid Build Coastguard Worker // to insert in InsertBranch;
564*9880d681SAndroid Build Coastguard Worker // Returns: false if branch could successfully be analyzed.
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TrueBlock,MachineBasicBlock * & FalseBlock,SmallVectorImpl<MachineOperand> & Condition,bool AllowModify) const565*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
566*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&TrueBlock,
567*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&FalseBlock,
568*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Condition,
569*9880d681SAndroid Build Coastguard Worker bool AllowModify) const {
570*9880d681SAndroid Build Coastguard Worker // Iterator to current instruction being considered.
571*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Instruction = MBB.end();
572*9880d681SAndroid Build Coastguard Worker
573*9880d681SAndroid Build Coastguard Worker // Start from the bottom of the block and work up, examining the
574*9880d681SAndroid Build Coastguard Worker // terminator instructions.
575*9880d681SAndroid Build Coastguard Worker while (Instruction != MBB.begin()) {
576*9880d681SAndroid Build Coastguard Worker --Instruction;
577*9880d681SAndroid Build Coastguard Worker
578*9880d681SAndroid Build Coastguard Worker // Skip over debug values.
579*9880d681SAndroid Build Coastguard Worker if (Instruction->isDebugValue())
580*9880d681SAndroid Build Coastguard Worker continue;
581*9880d681SAndroid Build Coastguard Worker
582*9880d681SAndroid Build Coastguard Worker // Working from the bottom, when we see a non-terminator
583*9880d681SAndroid Build Coastguard Worker // instruction, we're done.
584*9880d681SAndroid Build Coastguard Worker if (!isUnpredicatedTerminator(*Instruction))
585*9880d681SAndroid Build Coastguard Worker break;
586*9880d681SAndroid Build Coastguard Worker
587*9880d681SAndroid Build Coastguard Worker // A terminator that isn't a branch can't easily be handled
588*9880d681SAndroid Build Coastguard Worker // by this analysis.
589*9880d681SAndroid Build Coastguard Worker if (!Instruction->isBranch())
590*9880d681SAndroid Build Coastguard Worker return true;
591*9880d681SAndroid Build Coastguard Worker
592*9880d681SAndroid Build Coastguard Worker // Handle unconditional branches.
593*9880d681SAndroid Build Coastguard Worker if (Instruction->getOpcode() == Lanai::BT) {
594*9880d681SAndroid Build Coastguard Worker if (!AllowModify) {
595*9880d681SAndroid Build Coastguard Worker TrueBlock = Instruction->getOperand(0).getMBB();
596*9880d681SAndroid Build Coastguard Worker continue;
597*9880d681SAndroid Build Coastguard Worker }
598*9880d681SAndroid Build Coastguard Worker
599*9880d681SAndroid Build Coastguard Worker // If the block has any instructions after a branch, delete them.
600*9880d681SAndroid Build Coastguard Worker while (std::next(Instruction) != MBB.end()) {
601*9880d681SAndroid Build Coastguard Worker std::next(Instruction)->eraseFromParent();
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker Condition.clear();
605*9880d681SAndroid Build Coastguard Worker FalseBlock = nullptr;
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker // Delete the jump if it's equivalent to a fall-through.
608*9880d681SAndroid Build Coastguard Worker if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
609*9880d681SAndroid Build Coastguard Worker TrueBlock = nullptr;
610*9880d681SAndroid Build Coastguard Worker Instruction->eraseFromParent();
611*9880d681SAndroid Build Coastguard Worker Instruction = MBB.end();
612*9880d681SAndroid Build Coastguard Worker continue;
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker // TrueBlock is used to indicate the unconditional destination.
616*9880d681SAndroid Build Coastguard Worker TrueBlock = Instruction->getOperand(0).getMBB();
617*9880d681SAndroid Build Coastguard Worker continue;
618*9880d681SAndroid Build Coastguard Worker }
619*9880d681SAndroid Build Coastguard Worker
620*9880d681SAndroid Build Coastguard Worker // Handle conditional branches
621*9880d681SAndroid Build Coastguard Worker unsigned Opcode = Instruction->getOpcode();
622*9880d681SAndroid Build Coastguard Worker if (Opcode != Lanai::BRCC)
623*9880d681SAndroid Build Coastguard Worker return true; // Unknown opcode.
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Worker // Multiple conditional branches are not handled here so only proceed if
626*9880d681SAndroid Build Coastguard Worker // there are no conditions enqueued.
627*9880d681SAndroid Build Coastguard Worker if (Condition.empty()) {
628*9880d681SAndroid Build Coastguard Worker LPCC::CondCode BranchCond =
629*9880d681SAndroid Build Coastguard Worker static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker // TrueBlock is the target of the previously seen unconditional branch.
632*9880d681SAndroid Build Coastguard Worker FalseBlock = TrueBlock;
633*9880d681SAndroid Build Coastguard Worker TrueBlock = Instruction->getOperand(0).getMBB();
634*9880d681SAndroid Build Coastguard Worker Condition.push_back(MachineOperand::CreateImm(BranchCond));
635*9880d681SAndroid Build Coastguard Worker continue;
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker // Multiple conditional branches are not handled.
639*9880d681SAndroid Build Coastguard Worker return true;
640*9880d681SAndroid Build Coastguard Worker }
641*9880d681SAndroid Build Coastguard Worker
642*9880d681SAndroid Build Coastguard Worker // Return false indicating branch successfully analyzed.
643*9880d681SAndroid Build Coastguard Worker return false;
644*9880d681SAndroid Build Coastguard Worker }
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker // ReverseBranchCondition - Reverses the branch condition of the specified
647*9880d681SAndroid Build Coastguard Worker // condition list, returning false on success and true if it cannot be
648*9880d681SAndroid Build Coastguard Worker // reversed.
ReverseBranchCondition(SmallVectorImpl<llvm::MachineOperand> & Condition) const649*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::ReverseBranchCondition(
650*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<llvm::MachineOperand> &Condition) const {
651*9880d681SAndroid Build Coastguard Worker assert((Condition.size() == 1) &&
652*9880d681SAndroid Build Coastguard Worker "Lanai branch conditions should have one component.");
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker LPCC::CondCode BranchCond =
655*9880d681SAndroid Build Coastguard Worker static_cast<LPCC::CondCode>(Condition[0].getImm());
656*9880d681SAndroid Build Coastguard Worker Condition[0].setImm(getOppositeCondition(BranchCond));
657*9880d681SAndroid Build Coastguard Worker return false;
658*9880d681SAndroid Build Coastguard Worker }
659*9880d681SAndroid Build Coastguard Worker
660*9880d681SAndroid Build Coastguard Worker // Insert the branch with condition specified in condition and given targets
661*9880d681SAndroid Build Coastguard Worker // (TrueBlock and FalseBlock). This function returns the number of machine
662*9880d681SAndroid Build Coastguard Worker // instructions inserted.
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TrueBlock,MachineBasicBlock * FalseBlock,ArrayRef<MachineOperand> Condition,const DebugLoc & DL) const663*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::InsertBranch(MachineBasicBlock &MBB,
664*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TrueBlock,
665*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FalseBlock,
666*9880d681SAndroid Build Coastguard Worker ArrayRef<MachineOperand> Condition,
667*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL) const {
668*9880d681SAndroid Build Coastguard Worker // Shouldn't be a fall through.
669*9880d681SAndroid Build Coastguard Worker assert(TrueBlock && "InsertBranch must not be told to insert a fallthrough");
670*9880d681SAndroid Build Coastguard Worker
671*9880d681SAndroid Build Coastguard Worker // If condition is empty then an unconditional branch is being inserted.
672*9880d681SAndroid Build Coastguard Worker if (Condition.empty()) {
673*9880d681SAndroid Build Coastguard Worker assert(!FalseBlock && "Unconditional branch with multiple successors!");
674*9880d681SAndroid Build Coastguard Worker BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
675*9880d681SAndroid Build Coastguard Worker return 1;
676*9880d681SAndroid Build Coastguard Worker }
677*9880d681SAndroid Build Coastguard Worker
678*9880d681SAndroid Build Coastguard Worker // Else a conditional branch is inserted.
679*9880d681SAndroid Build Coastguard Worker assert((Condition.size() == 1) &&
680*9880d681SAndroid Build Coastguard Worker "Lanai branch conditions should have one component.");
681*9880d681SAndroid Build Coastguard Worker unsigned ConditionalCode = Condition[0].getImm();
682*9880d681SAndroid Build Coastguard Worker BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker // If no false block, then false behavior is fall through and no branch needs
685*9880d681SAndroid Build Coastguard Worker // to be inserted.
686*9880d681SAndroid Build Coastguard Worker if (!FalseBlock)
687*9880d681SAndroid Build Coastguard Worker return 1;
688*9880d681SAndroid Build Coastguard Worker
689*9880d681SAndroid Build Coastguard Worker BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
690*9880d681SAndroid Build Coastguard Worker return 2;
691*9880d681SAndroid Build Coastguard Worker }
692*9880d681SAndroid Build Coastguard Worker
RemoveBranch(MachineBasicBlock & MBB) const693*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
694*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator Instruction = MBB.end();
695*9880d681SAndroid Build Coastguard Worker unsigned Count = 0;
696*9880d681SAndroid Build Coastguard Worker
697*9880d681SAndroid Build Coastguard Worker while (Instruction != MBB.begin()) {
698*9880d681SAndroid Build Coastguard Worker --Instruction;
699*9880d681SAndroid Build Coastguard Worker if (Instruction->isDebugValue())
700*9880d681SAndroid Build Coastguard Worker continue;
701*9880d681SAndroid Build Coastguard Worker if (Instruction->getOpcode() != Lanai::BT &&
702*9880d681SAndroid Build Coastguard Worker Instruction->getOpcode() != Lanai::BRCC) {
703*9880d681SAndroid Build Coastguard Worker break;
704*9880d681SAndroid Build Coastguard Worker }
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker // Remove the branch.
707*9880d681SAndroid Build Coastguard Worker Instruction->eraseFromParent();
708*9880d681SAndroid Build Coastguard Worker Instruction = MBB.end();
709*9880d681SAndroid Build Coastguard Worker ++Count;
710*9880d681SAndroid Build Coastguard Worker }
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker return Count;
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const715*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
716*9880d681SAndroid Build Coastguard Worker int &FrameIndex) const {
717*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == Lanai::LDW_RI)
718*9880d681SAndroid Build Coastguard Worker if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
719*9880d681SAndroid Build Coastguard Worker MI.getOperand(2).getImm() == 0) {
720*9880d681SAndroid Build Coastguard Worker FrameIndex = MI.getOperand(1).getIndex();
721*9880d681SAndroid Build Coastguard Worker return MI.getOperand(0).getReg();
722*9880d681SAndroid Build Coastguard Worker }
723*9880d681SAndroid Build Coastguard Worker return 0;
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker
isLoadFromStackSlotPostFE(const MachineInstr & MI,int & FrameIndex) const726*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
727*9880d681SAndroid Build Coastguard Worker int &FrameIndex) const {
728*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == Lanai::LDW_RI) {
729*9880d681SAndroid Build Coastguard Worker unsigned Reg;
730*9880d681SAndroid Build Coastguard Worker if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
731*9880d681SAndroid Build Coastguard Worker return Reg;
732*9880d681SAndroid Build Coastguard Worker // Check for post-frame index elimination operations
733*9880d681SAndroid Build Coastguard Worker const MachineMemOperand *Dummy;
734*9880d681SAndroid Build Coastguard Worker return hasLoadFromStackSlot(MI, Dummy, FrameIndex);
735*9880d681SAndroid Build Coastguard Worker }
736*9880d681SAndroid Build Coastguard Worker return 0;
737*9880d681SAndroid Build Coastguard Worker }
738*9880d681SAndroid Build Coastguard Worker
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const739*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
740*9880d681SAndroid Build Coastguard Worker int &FrameIndex) const {
741*9880d681SAndroid Build Coastguard Worker if (MI.getOpcode() == Lanai::SW_RI)
742*9880d681SAndroid Build Coastguard Worker if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
743*9880d681SAndroid Build Coastguard Worker MI.getOperand(1).getImm() == 0) {
744*9880d681SAndroid Build Coastguard Worker FrameIndex = MI.getOperand(0).getIndex();
745*9880d681SAndroid Build Coastguard Worker return MI.getOperand(2).getReg();
746*9880d681SAndroid Build Coastguard Worker }
747*9880d681SAndroid Build Coastguard Worker return 0;
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker
getMemOpBaseRegImmOfsWidth(MachineInstr & LdSt,unsigned & BaseReg,int64_t & Offset,unsigned & Width,const TargetRegisterInfo * TRI) const750*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::getMemOpBaseRegImmOfsWidth(
751*9880d681SAndroid Build Coastguard Worker MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset, unsigned &Width,
752*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
753*9880d681SAndroid Build Coastguard Worker // Handle only loads/stores with base register followed by immediate offset
754*9880d681SAndroid Build Coastguard Worker // and with add as ALU op.
755*9880d681SAndroid Build Coastguard Worker if (LdSt.getNumOperands() != 4)
756*9880d681SAndroid Build Coastguard Worker return false;
757*9880d681SAndroid Build Coastguard Worker if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm() ||
758*9880d681SAndroid Build Coastguard Worker !(LdSt.getOperand(3).isImm() && LdSt.getOperand(3).getImm() == LPAC::ADD))
759*9880d681SAndroid Build Coastguard Worker return false;
760*9880d681SAndroid Build Coastguard Worker
761*9880d681SAndroid Build Coastguard Worker switch (LdSt.getOpcode()) {
762*9880d681SAndroid Build Coastguard Worker default:
763*9880d681SAndroid Build Coastguard Worker return false;
764*9880d681SAndroid Build Coastguard Worker case Lanai::LDW_RI:
765*9880d681SAndroid Build Coastguard Worker case Lanai::LDW_RR:
766*9880d681SAndroid Build Coastguard Worker case Lanai::SW_RR:
767*9880d681SAndroid Build Coastguard Worker case Lanai::SW_RI:
768*9880d681SAndroid Build Coastguard Worker Width = 4;
769*9880d681SAndroid Build Coastguard Worker break;
770*9880d681SAndroid Build Coastguard Worker case Lanai::LDHs_RI:
771*9880d681SAndroid Build Coastguard Worker case Lanai::LDHz_RI:
772*9880d681SAndroid Build Coastguard Worker case Lanai::STH_RI:
773*9880d681SAndroid Build Coastguard Worker Width = 2;
774*9880d681SAndroid Build Coastguard Worker break;
775*9880d681SAndroid Build Coastguard Worker case Lanai::LDBs_RI:
776*9880d681SAndroid Build Coastguard Worker case Lanai::LDBz_RI:
777*9880d681SAndroid Build Coastguard Worker case Lanai::STB_RI:
778*9880d681SAndroid Build Coastguard Worker Width = 1;
779*9880d681SAndroid Build Coastguard Worker break;
780*9880d681SAndroid Build Coastguard Worker }
781*9880d681SAndroid Build Coastguard Worker
782*9880d681SAndroid Build Coastguard Worker BaseReg = LdSt.getOperand(1).getReg();
783*9880d681SAndroid Build Coastguard Worker Offset = LdSt.getOperand(2).getImm();
784*9880d681SAndroid Build Coastguard Worker return true;
785*9880d681SAndroid Build Coastguard Worker }
786*9880d681SAndroid Build Coastguard Worker
getMemOpBaseRegImmOfs(MachineInstr & LdSt,unsigned & BaseReg,int64_t & Offset,const TargetRegisterInfo * TRI) const787*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::getMemOpBaseRegImmOfs(
788*9880d681SAndroid Build Coastguard Worker MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset,
789*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
790*9880d681SAndroid Build Coastguard Worker switch (LdSt.getOpcode()) {
791*9880d681SAndroid Build Coastguard Worker default:
792*9880d681SAndroid Build Coastguard Worker return false;
793*9880d681SAndroid Build Coastguard Worker case Lanai::LDW_RI:
794*9880d681SAndroid Build Coastguard Worker case Lanai::LDW_RR:
795*9880d681SAndroid Build Coastguard Worker case Lanai::SW_RR:
796*9880d681SAndroid Build Coastguard Worker case Lanai::SW_RI:
797*9880d681SAndroid Build Coastguard Worker case Lanai::LDHs_RI:
798*9880d681SAndroid Build Coastguard Worker case Lanai::LDHz_RI:
799*9880d681SAndroid Build Coastguard Worker case Lanai::STH_RI:
800*9880d681SAndroid Build Coastguard Worker case Lanai::LDBs_RI:
801*9880d681SAndroid Build Coastguard Worker case Lanai::LDBz_RI:
802*9880d681SAndroid Build Coastguard Worker unsigned Width;
803*9880d681SAndroid Build Coastguard Worker return getMemOpBaseRegImmOfsWidth(LdSt, BaseReg, Offset, Width, TRI);
804*9880d681SAndroid Build Coastguard Worker }
805*9880d681SAndroid Build Coastguard Worker }
806