brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.4 KiB · 14b7557 Raw
820 lines · cpp
1//===-- LanaiInstrInfo.cpp - Lanai Instruction Information ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the Lanai implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "LanaiInstrInfo.h"14#include "LanaiAluCode.h"15#include "LanaiCondCode.h"16#include "LanaiSubtarget.h"17#include "MCTargetDesc/LanaiBaseInfo.h"18#include "llvm/ADT/STLExtras.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/MachineRegisterInfo.h"22#include "llvm/Support/ErrorHandling.h"23 24using namespace llvm;25 26#define GET_INSTRINFO_CTOR_DTOR27#include "LanaiGenInstrInfo.inc"28 29LanaiInstrInfo::LanaiInstrInfo(const LanaiSubtarget &STI)30    : LanaiGenInstrInfo(STI, RegisterInfo, Lanai::ADJCALLSTACKDOWN,31                        Lanai::ADJCALLSTACKUP),32      RegisterInfo() {}33 34void LanaiInstrInfo::copyPhysReg(MachineBasicBlock &MBB,35                                 MachineBasicBlock::iterator Position,36                                 const DebugLoc &DL,37                                 Register DestinationRegister,38                                 Register SourceRegister, bool KillSource,39                                 bool RenamableDest, bool RenamableSrc) 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    Register SourceRegister, bool IsKill, int FrameIndex,52    const TargetRegisterClass *RegisterClass, Register /*VReg*/,53    MachineInstr::MIFlag /*Flags*/) 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    Register DestinationRegister, int FrameIndex,72    const TargetRegisterClass *RegisterClass, Register /*VReg*/,73    MachineInstr::MIFlag /*Flags*/) 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 88bool LanaiInstrInfo::areMemAccessesTriviallyDisjoint(89    const MachineInstr &MIa, const MachineInstr &MIb) const {90  assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");91  assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");92 93  if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||94      MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())95    return false;96 97  // Retrieve the base register, offset from the base register and width. Width98  // is the size of memory that is being loaded/stored (e.g. 1, 2, 4).  If99  // base registers are identical, and the offset of a lower memory access +100  // the width doesn't overlap the offset of a higher memory access,101  // then the memory accesses are different.102  const TargetRegisterInfo *TRI = &getRegisterInfo();103  const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;104  int64_t OffsetA = 0, OffsetB = 0;105  LocationSize WidthA = LocationSize::precise(0),106               WidthB = LocationSize::precise(0);107  if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&108      getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {109    if (BaseOpA->isIdenticalTo(*BaseOpB)) {110      int LowOffset = std::min(OffsetA, OffsetB);111      int HighOffset = std::max(OffsetA, OffsetB);112      LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;113      if (LowWidth.hasValue() &&114          LowOffset + (int)LowWidth.getValue() <= HighOffset)115        return true;116    }117  }118  return false;119}120 121bool LanaiInstrInfo::expandPostRAPseudo(MachineInstr & /*MI*/) const {122  return false;123}124 125static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC) {126  switch (CC) {127  case LPCC::ICC_T: //  true128    return LPCC::ICC_F;129  case LPCC::ICC_F: //  false130    return LPCC::ICC_T;131  case LPCC::ICC_HI: //  high132    return LPCC::ICC_LS;133  case LPCC::ICC_LS: //  low or same134    return LPCC::ICC_HI;135  case LPCC::ICC_CC: //  carry cleared136    return LPCC::ICC_CS;137  case LPCC::ICC_CS: //  carry set138    return LPCC::ICC_CC;139  case LPCC::ICC_NE: //  not equal140    return LPCC::ICC_EQ;141  case LPCC::ICC_EQ: //  equal142    return LPCC::ICC_NE;143  case LPCC::ICC_VC: //  oVerflow cleared144    return LPCC::ICC_VS;145  case LPCC::ICC_VS: //  oVerflow set146    return LPCC::ICC_VC;147  case LPCC::ICC_PL: //  plus (note: 0 is "minus" too here)148    return LPCC::ICC_MI;149  case LPCC::ICC_MI: //  minus150    return LPCC::ICC_PL;151  case LPCC::ICC_GE: //  greater than or equal152    return LPCC::ICC_LT;153  case LPCC::ICC_LT: //  less than154    return LPCC::ICC_GE;155  case LPCC::ICC_GT: //  greater than156    return LPCC::ICC_LE;157  case LPCC::ICC_LE: //  less than or equal158    return LPCC::ICC_GT;159  default:160    llvm_unreachable("Invalid condtional code");161  }162}163 164std::pair<unsigned, unsigned>165LanaiInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {166  return std::make_pair(TF, 0u);167}168 169ArrayRef<std::pair<unsigned, const char *>>170LanaiInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {171  using namespace LanaiII;172  static const std::pair<unsigned, const char *> TargetFlags[] = {173      {MO_ABS_HI, "lanai-hi"},174      {MO_ABS_LO, "lanai-lo"},175      {MO_NO_FLAG, "lanai-nf"}};176  return ArrayRef(TargetFlags);177}178 179bool LanaiInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,180                                    Register &SrcReg2, int64_t &CmpMask,181                                    int64_t &CmpValue) const {182  switch (MI.getOpcode()) {183  default:184    break;185  case Lanai::SFSUB_F_RI_LO:186  case Lanai::SFSUB_F_RI_HI:187    SrcReg = MI.getOperand(0).getReg();188    SrcReg2 = Register();189    CmpMask = ~0;190    CmpValue = MI.getOperand(1).getImm();191    return true;192  case Lanai::SFSUB_F_RR:193    SrcReg = MI.getOperand(0).getReg();194    SrcReg2 = MI.getOperand(1).getReg();195    CmpMask = ~0;196    CmpValue = 0;197    return true;198  }199 200  return false;201}202 203// isRedundantFlagInstr - check whether the first instruction, whose only204// purpose is to update flags, can be made redundant.205// * SFSUB_F_RR can be made redundant by SUB_RI if the operands are the same.206// * SFSUB_F_RI can be made redundant by SUB_I if the operands are the same.207inline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,208                                        unsigned SrcReg2, int64_t ImmValue,209                                        MachineInstr *OI) {210  if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&211      OI->getOpcode() == Lanai::SUB_R &&212      ((OI->getOperand(1).getReg() == SrcReg &&213        OI->getOperand(2).getReg() == SrcReg2) ||214       (OI->getOperand(1).getReg() == SrcReg2 &&215        OI->getOperand(2).getReg() == SrcReg)))216    return true;217 218  if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&219        OI->getOpcode() == Lanai::SUB_I_LO) ||220       (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&221        OI->getOpcode() == Lanai::SUB_I_HI)) &&222      OI->getOperand(1).getReg() == SrcReg &&223      OI->getOperand(2).getImm() == ImmValue)224    return true;225  return false;226}227 228inline static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {229  switch (OldOpcode) {230  case Lanai::ADD_I_HI:231    return Lanai::ADD_F_I_HI;232  case Lanai::ADD_I_LO:233    return Lanai::ADD_F_I_LO;234  case Lanai::ADD_R:235    return Lanai::ADD_F_R;236  case Lanai::ADDC_I_HI:237    return Lanai::ADDC_F_I_HI;238  case Lanai::ADDC_I_LO:239    return Lanai::ADDC_F_I_LO;240  case Lanai::ADDC_R:241    return Lanai::ADDC_F_R;242  case Lanai::AND_I_HI:243    return Lanai::AND_F_I_HI;244  case Lanai::AND_I_LO:245    return Lanai::AND_F_I_LO;246  case Lanai::AND_R:247    return Lanai::AND_F_R;248  case Lanai::OR_I_HI:249    return Lanai::OR_F_I_HI;250  case Lanai::OR_I_LO:251    return Lanai::OR_F_I_LO;252  case Lanai::OR_R:253    return Lanai::OR_F_R;254  case Lanai::SL_I:255    return Lanai::SL_F_I;256  case Lanai::SRL_R:257    return Lanai::SRL_F_R;258  case Lanai::SA_I:259    return Lanai::SA_F_I;260  case Lanai::SRA_R:261    return Lanai::SRA_F_R;262  case Lanai::SUB_I_HI:263    return Lanai::SUB_F_I_HI;264  case Lanai::SUB_I_LO:265    return Lanai::SUB_F_I_LO;266  case Lanai::SUB_R:267    return Lanai::SUB_F_R;268  case Lanai::SUBB_I_HI:269    return Lanai::SUBB_F_I_HI;270  case Lanai::SUBB_I_LO:271    return Lanai::SUBB_F_I_LO;272  case Lanai::SUBB_R:273    return Lanai::SUBB_F_R;274  case Lanai::XOR_I_HI:275    return Lanai::XOR_F_I_HI;276  case Lanai::XOR_I_LO:277    return Lanai::XOR_F_I_LO;278  case Lanai::XOR_R:279    return Lanai::XOR_F_R;280  default:281    return Lanai::NOP;282  }283}284 285bool LanaiInstrInfo::optimizeCompareInstr(286    MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2,287    int64_t /*CmpMask*/, int64_t CmpValue,288    const MachineRegisterInfo *MRI) const {289  // Get the unique definition of SrcReg.290  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);291  if (!MI)292    return false;293 294  // Get ready to iterate backward from CmpInstr.295  MachineBasicBlock::iterator I = CmpInstr, E = MI,296                              B = CmpInstr.getParent()->begin();297 298  // Early exit if CmpInstr is at the beginning of the BB.299  if (I == B)300    return false;301 302  // There are two possible candidates which can be changed to set SR:303  // One is MI, the other is a SUB instruction.304  // * For SFSUB_F_RR(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).305  // * For SFSUB_F_RI(r1, CmpValue), we are looking for SUB(r1, CmpValue).306  MachineInstr *Sub = nullptr;307  if (SrcReg2 != 0)308    // MI is not a candidate to transform into a flag setting instruction.309    MI = nullptr;310  else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {311    // Conservatively refuse to convert an instruction which isn't in the same312    // BB as the comparison. Don't return if SFSUB_F_RI and CmpValue != 0 as Sub313    // may still be a candidate.314    if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)315      MI = nullptr;316    else317      return false;318  }319 320  // Check that SR isn't set between the comparison instruction and the321  // instruction we want to change while searching for Sub.322  const TargetRegisterInfo *TRI = &getRegisterInfo();323  for (--I; I != E; --I) {324    const MachineInstr &Instr = *I;325 326    if (Instr.modifiesRegister(Lanai::SR, TRI) ||327        Instr.readsRegister(Lanai::SR, TRI))328      // This instruction modifies or uses SR after the one we want to change.329      // We can't do this transformation.330      return false;331 332    // Check whether CmpInstr can be made redundant by the current instruction.333    if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {334      Sub = &*I;335      break;336    }337 338    // Don't search outside the containing basic block.339    if (I == B)340      return false;341  }342 343  // Return false if no candidates exist.344  if (!MI && !Sub)345    return false;346 347  // The single candidate is called MI.348  if (!MI)349    MI = Sub;350 351  if (flagSettingOpcodeVariant(MI->getOpcode()) != Lanai::NOP) {352    bool isSafe = false;353 354    SmallVector<std::pair<MachineOperand *, LPCC::CondCode>, 4>355        OperandsToUpdate;356    I = CmpInstr;357    E = CmpInstr.getParent()->end();358    while (!isSafe && ++I != E) {359      const MachineInstr &Instr = *I;360      for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;361           ++IO) {362        const MachineOperand &MO = Instr.getOperand(IO);363        if (MO.isRegMask() && MO.clobbersPhysReg(Lanai::SR)) {364          isSafe = true;365          break;366        }367        if (!MO.isReg() || MO.getReg() != Lanai::SR)368          continue;369        if (MO.isDef()) {370          isSafe = true;371          break;372        }373        // Condition code is after the operand before SR.374        LPCC::CondCode CC;375        CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();376 377        if (Sub) {378          LPCC::CondCode NewCC = getOppositeCondition(CC);379          if (NewCC == LPCC::ICC_T)380            return false;381          // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on382          // CMP needs to be updated to be based on SUB.  Push the condition383          // code operands to OperandsToUpdate.  If it is safe to remove384          // CmpInstr, the condition code of these operands will be modified.385          if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&386              Sub->getOperand(2).getReg() == SrcReg) {387            OperandsToUpdate.push_back(388                std::make_pair(&((*I).getOperand(IO - 1)), NewCC));389          }390        } else {391          // No Sub, so this is x = <op> y, z; cmp x, 0.392          switch (CC) {393          case LPCC::ICC_EQ: // Z394          case LPCC::ICC_NE: // Z395          case LPCC::ICC_MI: // N396          case LPCC::ICC_PL: // N397          case LPCC::ICC_F:  // none398          case LPCC::ICC_T:  // none399            // SR can be used multiple times, we should continue.400            break;401          case LPCC::ICC_CS: // C402          case LPCC::ICC_CC: // C403          case LPCC::ICC_VS: // V404          case LPCC::ICC_VC: // V405          case LPCC::ICC_HI: // C Z406          case LPCC::ICC_LS: // C Z407          case LPCC::ICC_GE: // N V408          case LPCC::ICC_LT: // N V409          case LPCC::ICC_GT: // Z N V410          case LPCC::ICC_LE: // Z N V411            // The instruction uses the V bit or C bit which is not safe.412            return false;413          case LPCC::UNKNOWN:414            return false;415          }416        }417      }418    }419 420    // If SR is not killed nor re-defined, we should check whether it is421    // live-out. If it is live-out, do not optimize.422    if (!isSafe) {423      MachineBasicBlock *MBB = CmpInstr.getParent();424      for (const MachineBasicBlock *Succ : MBB->successors())425        if (Succ->isLiveIn(Lanai::SR))426          return false;427    }428 429    // Toggle the optional operand to SR.430    MI->setDesc(get(flagSettingOpcodeVariant(MI->getOpcode())));431    MI->addRegisterDefined(Lanai::SR);432    CmpInstr.eraseFromParent();433    return true;434  }435 436  return false;437}438 439bool LanaiInstrInfo::analyzeSelect(const MachineInstr &MI,440                                   SmallVectorImpl<MachineOperand> &Cond,441                                   unsigned &TrueOp, unsigned &FalseOp,442                                   bool &Optimizable) const {443  assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");444  // Select operands:445  // 0: Def.446  // 1: True use.447  // 2: False use.448  // 3: Condition code.449  TrueOp = 1;450  FalseOp = 2;451  Cond.push_back(MI.getOperand(3));452  Optimizable = true;453  return false;454}455 456// Identify instructions that can be folded into a SELECT instruction, and457// return the defining instruction.458static MachineInstr *canFoldIntoSelect(Register Reg,459                                       const MachineRegisterInfo &MRI) {460  if (!Reg.isVirtual())461    return nullptr;462  if (!MRI.hasOneNonDBGUse(Reg))463    return nullptr;464  MachineInstr *MI = MRI.getVRegDef(Reg);465  if (!MI)466    return nullptr;467  // MI is folded into the SELECT by predicating it.468  if (!MI->isPredicable())469    return nullptr;470  // Check if MI has any non-dead defs or physreg uses. This also detects471  // predicated instructions which will be reading SR.472  for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 1)) {473    // Reject frame index operands.474    if (MO.isFI() || MO.isCPI() || MO.isJTI())475      return nullptr;476    if (!MO.isReg())477      continue;478    // MI can't have any tied operands, that would conflict with predication.479    if (MO.isTied())480      return nullptr;481    if (MO.getReg().isPhysical())482      return nullptr;483    if (MO.isDef() && !MO.isDead())484      return nullptr;485  }486  bool DontMoveAcrossStores = true;487  if (!MI->isSafeToMove(DontMoveAcrossStores))488    return nullptr;489  return MI;490}491 492MachineInstr *493LanaiInstrInfo::optimizeSelect(MachineInstr &MI,494                               SmallPtrSetImpl<MachineInstr *> &SeenMIs,495                               bool /*PreferFalse*/) const {496  assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");497  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();498  MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI);499  bool Invert = !DefMI;500  if (!DefMI)501    DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI);502  if (!DefMI)503    return nullptr;504 505  // Find new register class to use.506  MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);507  Register DestReg = MI.getOperand(0).getReg();508  const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());509  if (!MRI.constrainRegClass(DestReg, PreviousClass))510    return nullptr;511 512  // Create a new predicated version of DefMI.513  MachineInstrBuilder NewMI =514      BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);515 516  // Copy all the DefMI operands, excluding its (null) predicate.517  const MCInstrDesc &DefDesc = DefMI->getDesc();518  for (unsigned i = 1, e = DefDesc.getNumOperands();519       i != e && !DefDesc.operands()[i].isPredicate(); ++i)520    NewMI.add(DefMI->getOperand(i));521 522  unsigned CondCode = MI.getOperand(3).getImm();523  if (Invert)524    NewMI.addImm(getOppositeCondition(LPCC::CondCode(CondCode)));525  else526    NewMI.addImm(CondCode);527  NewMI.copyImplicitOps(MI);528 529  // The output register value when the predicate is false is an implicit530  // register operand tied to the first def.  The tie makes the register531  // allocator ensure the FalseReg is allocated the same register as operand 0.532  FalseReg.setImplicit();533  NewMI.add(FalseReg);534  NewMI->tieOperands(0, NewMI->getNumOperands() - 1);535 536  // Update SeenMIs set: register newly created MI and erase removed DefMI.537  SeenMIs.insert(NewMI);538  SeenMIs.erase(DefMI);539 540  // If MI is inside a loop, and DefMI is outside the loop, then kill flags on541  // DefMI would be invalid when transferred inside the loop.  Checking for a542  // loop is expensive, but at least remove kill flags if they are in different543  // BBs.544  if (DefMI->getParent() != MI.getParent())545    NewMI->clearKillInfo();546 547  // The caller will erase MI, but not DefMI.548  DefMI->eraseFromParent();549  return NewMI;550}551 552// The analyzeBranch function is used to examine conditional instructions and553// remove unnecessary instructions. This method is used by BranchFolder and554// IfConverter machine function passes to improve the CFG.555// - TrueBlock is set to the destination if condition evaluates true (it is the556//   nullptr if the destination is the fall-through branch);557// - FalseBlock is set to the destination if condition evaluates to false (it558//   is the nullptr if the branch is unconditional);559// - condition is populated with machine operands needed to generate the branch560//   to insert in insertBranch;561// Returns: false if branch could successfully be analyzed.562bool LanaiInstrInfo::analyzeBranch(MachineBasicBlock &MBB,563                                   MachineBasicBlock *&TrueBlock,564                                   MachineBasicBlock *&FalseBlock,565                                   SmallVectorImpl<MachineOperand> &Condition,566                                   bool AllowModify) const {567  // Iterator to current instruction being considered.568  MachineBasicBlock::iterator Instruction = MBB.end();569 570  // Start from the bottom of the block and work up, examining the571  // terminator instructions.572  while (Instruction != MBB.begin()) {573    --Instruction;574 575    // Skip over debug instructions.576    if (Instruction->isDebugInstr())577      continue;578 579    // Working from the bottom, when we see a non-terminator580    // instruction, we're done.581    if (!isUnpredicatedTerminator(*Instruction))582      break;583 584    // A terminator that isn't a branch can't easily be handled585    // by this analysis.586    if (!Instruction->isBranch())587      return true;588 589    // Handle unconditional branches.590    if (Instruction->getOpcode() == Lanai::BT) {591      if (!AllowModify) {592        TrueBlock = Instruction->getOperand(0).getMBB();593        continue;594      }595 596      // If the block has any instructions after a branch, delete them.597      MBB.erase(std::next(Instruction), MBB.end());598 599      Condition.clear();600      FalseBlock = nullptr;601 602      // Delete the jump if it's equivalent to a fall-through.603      if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {604        TrueBlock = nullptr;605        Instruction->eraseFromParent();606        Instruction = MBB.end();607        continue;608      }609 610      // TrueBlock is used to indicate the unconditional destination.611      TrueBlock = Instruction->getOperand(0).getMBB();612      continue;613    }614 615    // Handle conditional branches616    unsigned Opcode = Instruction->getOpcode();617    if (Opcode != Lanai::BRCC)618      return true; // Unknown opcode.619 620    // Multiple conditional branches are not handled here so only proceed if621    // there are no conditions enqueued.622    if (Condition.empty()) {623      LPCC::CondCode BranchCond =624          static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());625 626      // TrueBlock is the target of the previously seen unconditional branch.627      FalseBlock = TrueBlock;628      TrueBlock = Instruction->getOperand(0).getMBB();629      Condition.push_back(MachineOperand::CreateImm(BranchCond));630      continue;631    }632 633    // Multiple conditional branches are not handled.634    return true;635  }636 637  // Return false indicating branch successfully analyzed.638  return false;639}640 641// reverseBranchCondition - Reverses the branch condition of the specified642// condition list, returning false on success and true if it cannot be643// reversed.644bool LanaiInstrInfo::reverseBranchCondition(645    SmallVectorImpl<llvm::MachineOperand> &Condition) const {646  assert((Condition.size() == 1) &&647         "Lanai branch conditions should have one component.");648 649  LPCC::CondCode BranchCond =650      static_cast<LPCC::CondCode>(Condition[0].getImm());651  Condition[0].setImm(getOppositeCondition(BranchCond));652  return false;653}654 655// Insert the branch with condition specified in condition and given targets656// (TrueBlock and FalseBlock). This function returns the number of machine657// instructions inserted.658unsigned LanaiInstrInfo::insertBranch(MachineBasicBlock &MBB,659                                      MachineBasicBlock *TrueBlock,660                                      MachineBasicBlock *FalseBlock,661                                      ArrayRef<MachineOperand> Condition,662                                      const DebugLoc &DL,663                                      int *BytesAdded) const {664  // Shouldn't be a fall through.665  assert(TrueBlock && "insertBranch must not be told to insert a fallthrough");666  assert(!BytesAdded && "code size not handled");667 668  // If condition is empty then an unconditional branch is being inserted.669  if (Condition.empty()) {670    assert(!FalseBlock && "Unconditional branch with multiple successors!");671    BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);672    return 1;673  }674 675  // Else a conditional branch is inserted.676  assert((Condition.size() == 1) &&677         "Lanai branch conditions should have one component.");678  unsigned ConditionalCode = Condition[0].getImm();679  BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);680 681  // If no false block, then false behavior is fall through and no branch needs682  // to be inserted.683  if (!FalseBlock)684    return 1;685 686  BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);687  return 2;688}689 690unsigned LanaiInstrInfo::removeBranch(MachineBasicBlock &MBB,691                                      int *BytesRemoved) const {692  assert(!BytesRemoved && "code size not handled");693 694  MachineBasicBlock::iterator Instruction = MBB.end();695  unsigned Count = 0;696 697  while (Instruction != MBB.begin()) {698    --Instruction;699    if (Instruction->isDebugInstr())700      continue;701    if (Instruction->getOpcode() != Lanai::BT &&702        Instruction->getOpcode() != Lanai::BRCC) {703      break;704    }705 706    // Remove the branch.707    Instruction->eraseFromParent();708    Instruction = MBB.end();709    ++Count;710  }711 712  return Count;713}714 715Register LanaiInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,716                                             int &FrameIndex) const {717  if (MI.getOpcode() == Lanai::LDW_RI)718    if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&719        MI.getOperand(2).getImm() == 0) {720      FrameIndex = MI.getOperand(1).getIndex();721      return MI.getOperand(0).getReg();722    }723  return 0;724}725 726Register LanaiInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,727                                                   int &FrameIndex) const {728  if (MI.getOpcode() == Lanai::LDW_RI) {729    unsigned Reg;730    if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))731      return Reg;732    // Check for post-frame index elimination operations733    SmallVector<const MachineMemOperand *, 1> Accesses;734    if (hasLoadFromStackSlot(MI, Accesses)){735      FrameIndex =736          cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())737              ->getFrameIndex();738      return 1;739    }740  }741  return 0;742}743 744Register LanaiInstrInfo::isStoreToStackSlot(const MachineInstr &MI,745                                            int &FrameIndex) const {746  if (MI.getOpcode() == Lanai::SW_RI)747    if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&748        MI.getOperand(1).getImm() == 0) {749      FrameIndex = MI.getOperand(0).getIndex();750      return MI.getOperand(2).getReg();751    }752  return 0;753}754 755bool LanaiInstrInfo::getMemOperandWithOffsetWidth(756    const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset,757    LocationSize &Width, const TargetRegisterInfo * /*TRI*/) const {758  // Handle only loads/stores with base register followed by immediate offset759  // and with add as ALU op.760  if (LdSt.getNumOperands() != 4)761    return false;762  if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm() ||763      !(LdSt.getOperand(3).isImm() && LdSt.getOperand(3).getImm() == LPAC::ADD))764    return false;765 766  switch (LdSt.getOpcode()) {767  default:768    return false;769  case Lanai::LDW_RI:770  case Lanai::LDW_RR:771  case Lanai::SW_RR:772  case Lanai::SW_RI:773    Width = LocationSize::precise(4);774    break;775  case Lanai::LDHs_RI:776  case Lanai::LDHz_RI:777  case Lanai::STH_RI:778    Width = LocationSize::precise(2);779    break;780  case Lanai::LDBs_RI:781  case Lanai::LDBz_RI:782  case Lanai::STB_RI:783    Width = LocationSize::precise(1);784    break;785  }786 787  BaseOp = &LdSt.getOperand(1);788  Offset = LdSt.getOperand(2).getImm();789 790  if (!BaseOp->isReg())791    return false;792 793  return true;794}795 796bool LanaiInstrInfo::getMemOperandsWithOffsetWidth(797    const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,798    int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,799    const TargetRegisterInfo *TRI) const {800  switch (LdSt.getOpcode()) {801  default:802    return false;803  case Lanai::LDW_RI:804  case Lanai::LDW_RR:805  case Lanai::SW_RR:806  case Lanai::SW_RI:807  case Lanai::LDHs_RI:808  case Lanai::LDHz_RI:809  case Lanai::STH_RI:810  case Lanai::LDBs_RI:811  case Lanai::LDBz_RI:812    const MachineOperand *BaseOp;813    OffsetIsScalable = false;814    if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))815      return false;816    BaseOps.push_back(BaseOp);817    return true;818  }819}820