Jacques Pienaar | fcef3e4 | 2016-03-28 13:09:54 +0000 | [diff] [blame^] | 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 |