blob: 16a4b6faf7eaefdff98ae87da02be2daa2781a41 [file] [log] [blame]
Jacques Pienaarfcef3e42016-03-28 13:09:54 +00001//===-- LanaiInstrInfo.cpp - Lanai Instruction Information ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Lanai implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Lanai.h"
15#include "LanaiInstrInfo.h"
16#include "LanaiMachineFunctionInfo.h"
17#include "LanaiTargetMachine.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/TargetRegistry.h"
25
Jacques Pienaaradd4a272016-04-14 16:47:42 +000026using namespace llvm;
27
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000028#define GET_INSTRINFO_CTOR_DTOR
29#include "LanaiGenInstrInfo.inc"
30
Jacques Pienaarfcef3e42016-03-28 13:09:54 +000031LanaiInstrInfo::LanaiInstrInfo()
32 : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
33 RegisterInfo() {}
34
35void LanaiInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
36 MachineBasicBlock::iterator Position,
37 DebugLoc DL, unsigned DestinationRegister,
38 unsigned SourceRegister,
39 bool KillSource) const {
40 if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {
41 llvm_unreachable("Impossible reg-to-reg copy");
42 }
43
44 BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)
45 .addReg(SourceRegister, getKillRegState(KillSource))
46 .addImm(0);
47}
48
49void LanaiInstrInfo::storeRegToStackSlot(
50 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
51 unsigned SourceRegister, bool IsKill, int FrameIndex,
52 const TargetRegisterClass *RegisterClass,
53 const TargetRegisterInfo *RegisterInfo) const {
54 DebugLoc DL;
55 if (Position != MBB.end()) {
56 DL = Position->getDebugLoc();
57 }
58
59 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
60 llvm_unreachable("Can't store this register to stack slot");
61 }
62 BuildMI(MBB, Position, DL, get(Lanai::SW_RI))
63 .addReg(SourceRegister, getKillRegState(IsKill))
64 .addFrameIndex(FrameIndex)
65 .addImm(0)
66 .addImm(LPAC::ADD);
67}
68
69void LanaiInstrInfo::loadRegFromStackSlot(
70 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
71 unsigned DestinationRegister, int FrameIndex,
72 const TargetRegisterClass *RegisterClass,
73 const TargetRegisterInfo *RegisterInfo) const {
74 DebugLoc DL;
75 if (Position != MBB.end()) {
76 DL = Position->getDebugLoc();
77 }
78
79 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
80 llvm_unreachable("Can't load this register from stack slot");
81 }
82 BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)
83 .addFrameIndex(FrameIndex)
84 .addImm(0)
85 .addImm(LPAC::ADD);
86}
87
Jacques Pienaaradd4a272016-04-14 16:47:42 +000088bool LanaiInstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr *MIa,
89 MachineInstr *MIb,
90 AliasAnalysis *AA) const {
91 assert(MIa && MIa->mayLoadOrStore() && "MIa must be a load or store.");
92 assert(MIb && MIb->mayLoadOrStore() && "MIb must be a load or store.");
93
94 if (MIa->hasUnmodeledSideEffects() || MIb->hasUnmodeledSideEffects() ||
95 MIa->hasOrderedMemoryRef() || MIb->hasOrderedMemoryRef())
96 return false;
97
98 // Retrieve the base register, offset from the base register and width. Width
99 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If
100 // base registers are identical, and the offset of a lower memory access +
101 // the width doesn't overlap the offset of a higher memory access,
102 // then the memory accesses are different.
103 const TargetRegisterInfo *TRI = &getRegisterInfo();
104 unsigned BaseRegA = 0, BaseRegB = 0;
105 int64_t OffsetA = 0, OffsetB = 0;
106 unsigned int WidthA = 0, WidthB = 0;
107 if (getMemOpBaseRegImmOfsWidth(MIa, BaseRegA, OffsetA, WidthA, TRI) &&
108 getMemOpBaseRegImmOfsWidth(MIb, BaseRegB, OffsetB, WidthB, TRI)) {
109 if (BaseRegA == BaseRegB) {
110 int LowOffset = std::min(OffsetA, OffsetB);
111 int HighOffset = std::max(OffsetA, OffsetB);
112 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
113 if (LowOffset + LowWidth <= HighOffset)
114 return true;
115 }
116 }
117 return false;
118}
119
Jacques Pienaarfcef3e42016-03-28 13:09:54 +0000120bool LanaiInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
121 return false;
122}
123
124static LPCC::CondCode GetOppositeBranchCondition(LPCC::CondCode CC) {
125 switch (CC) {
126 case LPCC::ICC_T: // true
127 return LPCC::ICC_F;
128 case LPCC::ICC_F: // false
129 return LPCC::ICC_T;
130 case LPCC::ICC_HI: // high
131 return LPCC::ICC_LS;
132 case LPCC::ICC_LS: // low or same
133 return LPCC::ICC_HI;
134 case LPCC::ICC_CC: // carry cleared
135 return LPCC::ICC_CS;
136 case LPCC::ICC_CS: // carry set
137 return LPCC::ICC_CC;
138 case LPCC::ICC_NE: // not equal
139 return LPCC::ICC_EQ;
140 case LPCC::ICC_EQ: // equal
141 return LPCC::ICC_NE;
142 case LPCC::ICC_VC: // oVerflow cleared
143 return LPCC::ICC_VS;
144 case LPCC::ICC_VS: // oVerflow set
145 return LPCC::ICC_VC;
146 case LPCC::ICC_PL: // plus (note: 0 is "minus" too here)
147 return LPCC::ICC_MI;
148 case LPCC::ICC_MI: // minus
149 return LPCC::ICC_PL;
150 case LPCC::ICC_GE: // greater than or equal
151 return LPCC::ICC_LT;
152 case LPCC::ICC_LT: // less than
153 return LPCC::ICC_GE;
154 case LPCC::ICC_GT: // greater than
155 return LPCC::ICC_LE;
156 case LPCC::ICC_LE: // less than or equal
157 return LPCC::ICC_GT;
158 default:
159 llvm_unreachable("Invalid condtional code");
160 }
161}
162
163// The AnalyzeBranch function is used to examine conditional instructions and
164// remove unnecessary instructions. This method is used by BranchFolder and
165// IfConverter machine function passes to improve the CFG.
166// - TrueBlock is set to the destination if condition evaluates true (it is the
167// nullptr if the destination is the fall-through branch);
168// - FalseBlock is set to the destination if condition evaluates to false (it
169// is the nullptr if the branch is unconditional);
170// - condition is populated with machine operands needed to generate the branch
171// to insert in InsertBranch;
172// Returns: false if branch could successfully be analyzed.
173bool LanaiInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
174 MachineBasicBlock *&TrueBlock,
175 MachineBasicBlock *&FalseBlock,
176 SmallVectorImpl<MachineOperand> &Condition,
177 bool AllowModify) const {
178 // Iterator to current instruction being considered.
179 MachineBasicBlock::iterator Instruction = MBB.end();
180
181 // Start from the bottom of the block and work up, examining the
182 // terminator instructions.
183 while (Instruction != MBB.begin()) {
184 --Instruction;
185
186 // Skip over debug values.
187 if (Instruction->isDebugValue())
188 continue;
189
190 // Working from the bottom, when we see a non-terminator
191 // instruction, we're done.
192 if (!isUnpredicatedTerminator(*Instruction))
193 break;
194
195 // A terminator that isn't a branch can't easily be handled
196 // by this analysis.
197 if (!Instruction->isBranch())
198 return true;
199
200 // Handle unconditional branches.
201 if (Instruction->getOpcode() == Lanai::BT) {
202 if (!AllowModify) {
203 TrueBlock = Instruction->getOperand(0).getMBB();
204 continue;
205 }
206
207 // If the block has any instructions after a branch, delete them.
208 while (std::next(Instruction) != MBB.end()) {
209 std::next(Instruction)->eraseFromParent();
210 }
211
212 Condition.clear();
213 FalseBlock = nullptr;
214
215 // Delete the jump if it's equivalent to a fall-through.
216 if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
217 TrueBlock = nullptr;
218 Instruction->eraseFromParent();
219 Instruction = MBB.end();
220 continue;
221 }
222
223 // TrueBlock is used to indicate the unconditional destination.
224 TrueBlock = Instruction->getOperand(0).getMBB();
225 continue;
226 }
227
228 // Handle conditional branches
229 unsigned Opcode = Instruction->getOpcode();
230 if (Opcode != Lanai::BRCC)
231 return true; // Unknown opcode.
232
233 // Multiple conditional branches are not handled here so only proceed if
234 // there are no conditions enqueued.
235 if (Condition.empty()) {
236 LPCC::CondCode BranchCond =
237 static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
238
239 // TrueBlock is the target of the previously seen unconditional branch.
240 FalseBlock = TrueBlock;
241 TrueBlock = Instruction->getOperand(0).getMBB();
242 Condition.push_back(MachineOperand::CreateImm(BranchCond));
243 continue;
244 }
245
246 // Multiple conditional branches are not handled.
247 return true;
248 }
249
250 // Return false indicating branch successfully analyzed.
251 return false;
252}
253
254// ReverseBranchCondition - Reverses the branch condition of the specified
255// condition list, returning false on success and true if it cannot be
256// reversed.
257bool LanaiInstrInfo::ReverseBranchCondition(
258 SmallVectorImpl<llvm::MachineOperand> &Condition) const {
259 assert((Condition.size() == 1) &&
260 "Lanai branch conditions should have one component.");
261
262 LPCC::CondCode BranchCond =
263 static_cast<LPCC::CondCode>(Condition[0].getImm());
264 Condition[0].setImm(GetOppositeBranchCondition(BranchCond));
265 return false;
266}
267
268// Insert the branch with condition specified in condition and given targets
269// (TrueBlock and FalseBlock). This function returns the number of machine
270// instructions inserted.
271unsigned LanaiInstrInfo::InsertBranch(MachineBasicBlock &MBB,
272 MachineBasicBlock *TrueBlock,
273 MachineBasicBlock *FalseBlock,
274 ArrayRef<MachineOperand> Condition,
275 DebugLoc DL) const {
276 // Shouldn't be a fall through.
277 assert(TrueBlock && "InsertBranch must not be told to insert a fallthrough");
278
279 // If condition is empty then an unconditional branch is being inserted.
280 if (Condition.empty()) {
281 assert(!FalseBlock && "Unconditional branch with multiple successors!");
282 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
283 return 1;
284 }
285
286 // Else a conditional branch is inserted.
287 assert((Condition.size() == 1) &&
288 "Lanai branch conditions should have one component.");
289 unsigned ConditionalCode = Condition[0].getImm();
290 BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
291
292 // If no false block, then false behavior is fall through and no branch needs
293 // to be inserted.
294 if (!FalseBlock)
295 return 1;
296
297 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
298 return 2;
299}
300
301unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
302 MachineBasicBlock::iterator Instruction = MBB.end();
303 unsigned Count = 0;
304
305 while (Instruction != MBB.begin()) {
306 --Instruction;
307 if (Instruction->isDebugValue())
308 continue;
309 if (Instruction->getOpcode() != Lanai::BT &&
310 Instruction->getOpcode() != Lanai::BRCC) {
311 break;
312 }
313
314 // Remove the branch.
315 Instruction->eraseFromParent();
316 Instruction = MBB.end();
317 ++Count;
318 }
319
320 return Count;
321}
322
323unsigned LanaiInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
324 int &FrameIndex) const {
325 if (MI->getOpcode() == Lanai::LDW_RI)
326 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
327 MI->getOperand(2).getImm() == 0) {
328 FrameIndex = MI->getOperand(1).getIndex();
329 return MI->getOperand(0).getReg();
330 }
331 return 0;
332}
333
334unsigned LanaiInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr *MI,
335 int &FrameIndex) const {
336 if (MI->getOpcode() == Lanai::LDW_RI) {
337 unsigned Reg;
338 if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
339 return Reg;
340 // Check for post-frame index elimination operations
341 const MachineMemOperand *Dummy;
342 return hasLoadFromStackSlot(MI, Dummy, FrameIndex);
343 }
344 return 0;
345}
346
347unsigned LanaiInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
348 int &FrameIndex) const {
349 if (MI->getOpcode() == Lanai::SW_RI)
350 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
351 MI->getOperand(1).getImm() == 0) {
352 FrameIndex = MI->getOperand(0).getIndex();
353 return MI->getOperand(2).getReg();
354 }
355 return 0;
356}
Jacques Pienaaradd4a272016-04-14 16:47:42 +0000357
358bool LanaiInstrInfo::getMemOpBaseRegImmOfsWidth(
359 MachineInstr *LdSt, unsigned &BaseReg, int64_t &Offset, unsigned &Width,
360 const TargetRegisterInfo *TRI) const {
361 // Handle only loads/stores with base register followed by immediate offset
362 // and with add as ALU op.
363 if (LdSt->getNumOperands() != 4)
364 return false;
365 if (!LdSt->getOperand(1).isReg() || !LdSt->getOperand(2).isImm() ||
366 !(LdSt->getOperand(3).isImm() &&
367 LdSt->getOperand(3).getImm() == LPAC::ADD))
368 return false;
369
370 switch (LdSt->getOpcode()) {
371 default:
372 return false;
373 case Lanai::LDW_RI:
374 case Lanai::LDW_RR:
375 case Lanai::SW_RR:
376 case Lanai::SW_RI:
377 Width = 4;
378 break;
379 case Lanai::LDHs_RI:
380 case Lanai::LDHz_RI:
381 case Lanai::STH_RI:
382 Width = 2;
383 break;
384 case Lanai::LDBs_RI:
385 case Lanai::LDBz_RI:
386 case Lanai::STB_RI:
387 Width = 1;
388 break;
389 }
390
391 BaseReg = LdSt->getOperand(1).getReg();
392 Offset = LdSt->getOperand(2).getImm();
393 return true;
394}
395
396bool LanaiInstrInfo::getMemOpBaseRegImmOfs(
397 MachineInstr *LdSt, unsigned &BaseReg, int64_t &Offset,
398 const TargetRegisterInfo *TRI) const {
399 switch (LdSt->getOpcode()) {
400 default:
401 return false;
402 case Lanai::LDW_RI:
403 case Lanai::LDW_RR:
404 case Lanai::SW_RR:
405 case Lanai::SW_RI:
406 case Lanai::LDHs_RI:
407 case Lanai::LDHz_RI:
408 case Lanai::STH_RI:
409 case Lanai::LDBs_RI:
410 case Lanai::LDBz_RI:
411 unsigned Width;
412 return getMemOpBaseRegImmOfsWidth(LdSt, BaseReg, Offset, Width, TRI);
413 }
414}