1 //===-- 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 
29 namespace llvm {
30 LanaiInstrInfo::LanaiInstrInfo()
31     : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
32       RegisterInfo() {}
33 
34 void 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 
48 void 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 
68 void 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 
87 bool LanaiInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
88   return false;
89 }
90 
91 static 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.
140 bool 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.
224 bool 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.
238 unsigned 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 
268 unsigned 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 
290 unsigned 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 
301 unsigned 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 
314 unsigned 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
325