blob: 90dce19da48808f7d8ae0de8bf9585dcc03ae7b4 [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
26#define GET_INSTRINFO_CTOR_DTOR
27#include "LanaiGenInstrInfo.inc"
28
29namespace llvm {
30LanaiInstrInfo::LanaiInstrInfo()
31 : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
32 RegisterInfo() {}
33
34void LanaiInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
35 MachineBasicBlock::iterator Position,
36 DebugLoc DL, unsigned DestinationRegister,
37 unsigned SourceRegister,
38 bool KillSource) const {
39 if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {
40 llvm_unreachable("Impossible reg-to-reg copy");
41 }
42
43 BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)
44 .addReg(SourceRegister, getKillRegState(KillSource))
45 .addImm(0);
46}
47
48void LanaiInstrInfo::storeRegToStackSlot(
49 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
50 unsigned SourceRegister, bool IsKill, int FrameIndex,
51 const TargetRegisterClass *RegisterClass,
52 const TargetRegisterInfo *RegisterInfo) const {
53 DebugLoc DL;
54 if (Position != MBB.end()) {
55 DL = Position->getDebugLoc();
56 }
57
58 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
59 llvm_unreachable("Can't store this register to stack slot");
60 }
61 BuildMI(MBB, Position, DL, get(Lanai::SW_RI))
62 .addReg(SourceRegister, getKillRegState(IsKill))
63 .addFrameIndex(FrameIndex)
64 .addImm(0)
65 .addImm(LPAC::ADD);
66}
67
68void LanaiInstrInfo::loadRegFromStackSlot(
69 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
70 unsigned DestinationRegister, int FrameIndex,
71 const TargetRegisterClass *RegisterClass,
72 const TargetRegisterInfo *RegisterInfo) const {
73 DebugLoc DL;
74 if (Position != MBB.end()) {
75 DL = Position->getDebugLoc();
76 }
77
78 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
79 llvm_unreachable("Can't load this register from stack slot");
80 }
81 BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)
82 .addFrameIndex(FrameIndex)
83 .addImm(0)
84 .addImm(LPAC::ADD);
85}
86
87bool LanaiInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
88 return false;
89}
90
91static LPCC::CondCode GetOppositeBranchCondition(LPCC::CondCode CC) {
92 switch (CC) {
93 case LPCC::ICC_T: // true
94 return LPCC::ICC_F;
95 case LPCC::ICC_F: // false
96 return LPCC::ICC_T;
97 case LPCC::ICC_HI: // high
98 return LPCC::ICC_LS;
99 case LPCC::ICC_LS: // low or same
100 return LPCC::ICC_HI;
101 case LPCC::ICC_CC: // carry cleared
102 return LPCC::ICC_CS;
103 case LPCC::ICC_CS: // carry set
104 return LPCC::ICC_CC;
105 case LPCC::ICC_NE: // not equal
106 return LPCC::ICC_EQ;
107 case LPCC::ICC_EQ: // equal
108 return LPCC::ICC_NE;
109 case LPCC::ICC_VC: // oVerflow cleared
110 return LPCC::ICC_VS;
111 case LPCC::ICC_VS: // oVerflow set
112 return LPCC::ICC_VC;
113 case LPCC::ICC_PL: // plus (note: 0 is "minus" too here)
114 return LPCC::ICC_MI;
115 case LPCC::ICC_MI: // minus
116 return LPCC::ICC_PL;
117 case LPCC::ICC_GE: // greater than or equal
118 return LPCC::ICC_LT;
119 case LPCC::ICC_LT: // less than
120 return LPCC::ICC_GE;
121 case LPCC::ICC_GT: // greater than
122 return LPCC::ICC_LE;
123 case LPCC::ICC_LE: // less than or equal
124 return LPCC::ICC_GT;
125 default:
126 llvm_unreachable("Invalid condtional code");
127 }
128}
129
130// The AnalyzeBranch function is used to examine conditional instructions and
131// remove unnecessary instructions. This method is used by BranchFolder and
132// IfConverter machine function passes to improve the CFG.
133// - TrueBlock is set to the destination if condition evaluates true (it is the
134// nullptr if the destination is the fall-through branch);
135// - FalseBlock is set to the destination if condition evaluates to false (it
136// is the nullptr if the branch is unconditional);
137// - condition is populated with machine operands needed to generate the branch
138// to insert in InsertBranch;
139// Returns: false if branch could successfully be analyzed.
140bool LanaiInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
141 MachineBasicBlock *&TrueBlock,
142 MachineBasicBlock *&FalseBlock,
143 SmallVectorImpl<MachineOperand> &Condition,
144 bool AllowModify) const {
145 // Iterator to current instruction being considered.
146 MachineBasicBlock::iterator Instruction = MBB.end();
147
148 // Start from the bottom of the block and work up, examining the
149 // terminator instructions.
150 while (Instruction != MBB.begin()) {
151 --Instruction;
152
153 // Skip over debug values.
154 if (Instruction->isDebugValue())
155 continue;
156
157 // Working from the bottom, when we see a non-terminator
158 // instruction, we're done.
159 if (!isUnpredicatedTerminator(*Instruction))
160 break;
161
162 // A terminator that isn't a branch can't easily be handled
163 // by this analysis.
164 if (!Instruction->isBranch())
165 return true;
166
167 // Handle unconditional branches.
168 if (Instruction->getOpcode() == Lanai::BT) {
169 if (!AllowModify) {
170 TrueBlock = Instruction->getOperand(0).getMBB();
171 continue;
172 }
173
174 // If the block has any instructions after a branch, delete them.
175 while (std::next(Instruction) != MBB.end()) {
176 std::next(Instruction)->eraseFromParent();
177 }
178
179 Condition.clear();
180 FalseBlock = nullptr;
181
182 // Delete the jump if it's equivalent to a fall-through.
183 if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
184 TrueBlock = nullptr;
185 Instruction->eraseFromParent();
186 Instruction = MBB.end();
187 continue;
188 }
189
190 // TrueBlock is used to indicate the unconditional destination.
191 TrueBlock = Instruction->getOperand(0).getMBB();
192 continue;
193 }
194
195 // Handle conditional branches
196 unsigned Opcode = Instruction->getOpcode();
197 if (Opcode != Lanai::BRCC)
198 return true; // Unknown opcode.
199
200 // Multiple conditional branches are not handled here so only proceed if
201 // there are no conditions enqueued.
202 if (Condition.empty()) {
203 LPCC::CondCode BranchCond =
204 static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
205
206 // TrueBlock is the target of the previously seen unconditional branch.
207 FalseBlock = TrueBlock;
208 TrueBlock = Instruction->getOperand(0).getMBB();
209 Condition.push_back(MachineOperand::CreateImm(BranchCond));
210 continue;
211 }
212
213 // Multiple conditional branches are not handled.
214 return true;
215 }
216
217 // Return false indicating branch successfully analyzed.
218 return false;
219}
220
221// ReverseBranchCondition - Reverses the branch condition of the specified
222// condition list, returning false on success and true if it cannot be
223// reversed.
224bool LanaiInstrInfo::ReverseBranchCondition(
225 SmallVectorImpl<llvm::MachineOperand> &Condition) const {
226 assert((Condition.size() == 1) &&
227 "Lanai branch conditions should have one component.");
228
229 LPCC::CondCode BranchCond =
230 static_cast<LPCC::CondCode>(Condition[0].getImm());
231 Condition[0].setImm(GetOppositeBranchCondition(BranchCond));
232 return false;
233}
234
235// Insert the branch with condition specified in condition and given targets
236// (TrueBlock and FalseBlock). This function returns the number of machine
237// instructions inserted.
238unsigned LanaiInstrInfo::InsertBranch(MachineBasicBlock &MBB,
239 MachineBasicBlock *TrueBlock,
240 MachineBasicBlock *FalseBlock,
241 ArrayRef<MachineOperand> Condition,
242 DebugLoc DL) const {
243 // Shouldn't be a fall through.
244 assert(TrueBlock && "InsertBranch must not be told to insert a fallthrough");
245
246 // If condition is empty then an unconditional branch is being inserted.
247 if (Condition.empty()) {
248 assert(!FalseBlock && "Unconditional branch with multiple successors!");
249 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
250 return 1;
251 }
252
253 // Else a conditional branch is inserted.
254 assert((Condition.size() == 1) &&
255 "Lanai branch conditions should have one component.");
256 unsigned ConditionalCode = Condition[0].getImm();
257 BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
258
259 // If no false block, then false behavior is fall through and no branch needs
260 // to be inserted.
261 if (!FalseBlock)
262 return 1;
263
264 BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
265 return 2;
266}
267
268unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
269 MachineBasicBlock::iterator Instruction = MBB.end();
270 unsigned Count = 0;
271
272 while (Instruction != MBB.begin()) {
273 --Instruction;
274 if (Instruction->isDebugValue())
275 continue;
276 if (Instruction->getOpcode() != Lanai::BT &&
277 Instruction->getOpcode() != Lanai::BRCC) {
278 break;
279 }
280
281 // Remove the branch.
282 Instruction->eraseFromParent();
283 Instruction = MBB.end();
284 ++Count;
285 }
286
287 return Count;
288}
289
290unsigned LanaiInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
291 int &FrameIndex) const {
292 if (MI->getOpcode() == Lanai::LDW_RI)
293 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
294 MI->getOperand(2).getImm() == 0) {
295 FrameIndex = MI->getOperand(1).getIndex();
296 return MI->getOperand(0).getReg();
297 }
298 return 0;
299}
300
301unsigned LanaiInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr *MI,
302 int &FrameIndex) const {
303 if (MI->getOpcode() == Lanai::LDW_RI) {
304 unsigned Reg;
305 if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
306 return Reg;
307 // Check for post-frame index elimination operations
308 const MachineMemOperand *Dummy;
309 return hasLoadFromStackSlot(MI, Dummy, FrameIndex);
310 }
311 return 0;
312}
313
314unsigned LanaiInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
315 int &FrameIndex) const {
316 if (MI->getOpcode() == Lanai::SW_RI)
317 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
318 MI->getOperand(1).getImm() == 0) {
319 FrameIndex = MI->getOperand(0).getIndex();
320 return MI->getOperand(2).getReg();
321 }
322 return 0;
323}
324} // namespace llvm