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