SPScope::SPScope(SPScope *parent, MachineLoop &loop)
    : Parent(parent), FCFG(loop.getHeader()),
      RootTopLevel(false), LoopBound(-1) {

    assert(parent);
    MachineBasicBlock *header = loop.getHeader();

    // add to parent's child list
    Parent->HeaderMap[header] = this;
    Parent->Subscopes.push_back(this);
    // add to parent's block list as well
    Parent->addMBB(header);
    Depth = Parent->Depth + 1;

    // add header also to this SPScope's block list
    Blocks.push_back(header);

    // info about loop latches and exit edges
    loop.getLoopLatches(Latches);
    loop.getExitEdges(ExitEdges);

    // scan the header for loopbound info
    for (MachineBasicBlock::iterator MI = header->begin(), ME = header->end();
            MI != ME; ++MI) {
        if (MI->getOpcode() == Patmos::PSEUDO_LOOPBOUND) {
            // max is the second operand (idx 1)
            LoopBound = MI->getOperand(1).getImm() + 1;
            break;
        }
    }

}
Example #2
0
void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator I) const {
  // This pseudo instruction is generated as part of the lowering of
  // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and
  // indirect jump to TargetReg
  MipsABIInfo ABI = Subtarget.getABI();
  unsigned ADDU = ABI.GetPtrAdduOp();
  unsigned SP = Subtarget.isGP64bit() ? Mips::SP_64 : Mips::SP;
  unsigned RA = Subtarget.isGP64bit() ? Mips::RA_64 : Mips::RA;
  unsigned T9 = Subtarget.isGP64bit() ? Mips::T9_64 : Mips::T9;
  unsigned ZERO = Subtarget.isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
  unsigned OffsetReg = I->getOperand(0).getReg();
  unsigned TargetReg = I->getOperand(1).getReg();

  // addu $ra, $v0, $zero
  // addu $sp, $sp, $v1
  // jr   $ra (via RetRA)
  const TargetMachine &TM = MBB.getParent()->getTarget();
  if (TM.isPositionIndependent())
    BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), T9)
        .addReg(TargetReg)
        .addReg(ZERO);
  BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), RA)
      .addReg(TargetReg)
      .addReg(ZERO);
  BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), SP).addReg(SP).addReg(OffsetReg);
  expandRetRA(MBB, I);
}
int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C,
                                                MachineBasicBlock &MBB) {
  RegScavenger RS;
  RS.enterBasicBlock(&MBB);
  RS.forward(MachineBasicBlock::iterator(G->getStart()));

  // Can we find an appropriate register that is available throughout the life 
  // of the chain?
  unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass;
  BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID));
  for (MachineBasicBlock::iterator I = G->getStart(), E = G->getEnd();
       I != E; ++I) {
    RS.forward(I);
    AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID));

    // Remove any registers clobbered by a regmask.
    for (auto J : I->operands()) {
      if (J.isRegMask())
        AvailableRegs.clearBitsNotInMask(J.getRegMask());
    }
  }

  // Make sure we allocate in-order, to get the cheapest registers first.
  auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID));
  for (auto Reg : Ord) {
    if (!AvailableRegs[Reg])
      continue;
    if ((C == Color::Even && (Reg % 2) == 0) ||
        (C == Color::Odd && (Reg % 2) == 1))
      return Reg;
  }

  return -1;
}
Example #4
0
bool LDVImpl::collectDebugValues(MachineFunction &mf) {
  bool Changed = false;
  for (MachineFunction::iterator MFI = mf.begin(), MFE = mf.end(); MFI != MFE;
       ++MFI) {
    MachineBasicBlock *MBB = MFI;
    for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end();
         MBBI != MBBE;) {
      if (!MBBI->isDebugValue()) {
        ++MBBI;
        continue;
      }
      // DBG_VALUE has no slot index, use the previous instruction instead.
      SlotIndex Idx = MBBI == MBB->begin() ?
        LIS->getMBBStartIdx(MBB) :
        LIS->getInstructionIndex(llvm::prior(MBBI)).getRegSlot();
      // Handle consecutive DBG_VALUE instructions with the same slot index.
      do {
        if (handleDebugValue(MBBI, Idx)) {
          MBBI = MBB->erase(MBBI);
          Changed = true;
        } else
          ++MBBI;
      } while (MBBI != MBBE && MBBI->isDebugValue());
    }
  }
  return Changed;
}
void VectorProcFrameLowering::emitEpilogue(MachineFunction &MF,
                                           MachineBasicBlock &MBB) const {
  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  const VectorProcInstrInfo &TII =
      *static_cast<const VectorProcInstrInfo *>(MF.getTarget().getInstrInfo());
  DebugLoc DL = MBBI->getDebugLoc();
  assert(MBBI->getOpcode() == VectorProc::RET &&
         "Can only put epilog before 'retl' instruction!");

  // if framepointer enabled, restore the stack pointer.
  if (hasFP(MF)) {
    // Find the first instruction that restores a callee-saved register.
    MachineBasicBlock::iterator I = MBBI;
    for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
      --I;

    BuildMI(MBB, I, DL, TII.get(VectorProc::MOVESS))
        .addReg(VectorProc::SP_REG)
        .addReg(VectorProc::FP_REG);
  }

  uint64_t StackSize = RoundUpToAlignment(MFI->getStackSize(), getStackAlignment());
  if (!StackSize)
    return;

  TII.adjustStackPointer(MBB, MBBI, StackSize);
}
unsigned EpiphanyInstrInfo::estimateRSStackLimit(MachineFunction &MF) const {
    unsigned Limit = (1 << 16) - 1;
    for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
        for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
                I != E; ++I) {
            for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
                if (!I->getOperand(i).isFI()) continue;

                // When using ADDwwi_lsl0_s to get the address of a stack object, 0x3FF
                // is the largest offset guaranteed to fit in the immediate offset.
                if (I->getOpcode() == Epiphany::ADDri) {
                    Limit = std::min(Limit, 0x3FFu);
                    break;
                }

                int AccessScale, MinOffset, MaxOffset;
                getAddressConstraints(*I, AccessScale, MinOffset, MaxOffset);
                Limit = std::min(Limit, static_cast<unsigned>(MaxOffset));

                break; // At most one FI per instruction
            }
        }
    }

    return Limit;
}
Example #7
0
void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator I,
                                         unsigned LoOpc,
                                         unsigned HiOpc,
                                         bool HasExplicitDef) const {
  // Expand
  //  lo_hi pseudomtlohi $gpr0, $gpr1
  // to these two instructions:
  //  mtlo $gpr0
  //  mthi $gpr1

  DebugLoc DL = I->getDebugLoc();
  const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2);
  MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc));
  MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc));

  // Add lo/hi registers if the mtlo/hi instructions created have explicit
  // def registers.
  if (HasExplicitDef) {
    unsigned DstReg = I->getOperand(0).getReg();
    unsigned DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
    unsigned DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi);
    LoInst.addReg(DstLo, RegState::Define);
    HiInst.addReg(DstHi, RegState::Define);
  }

  LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill()));
  HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill()));
}
Example #8
0
void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator I) const {
  // This pseudo instruction is generated as part of the lowering of
  // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and
  // indirect jump to TargetReg
  const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
  unsigned ADDU = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
  unsigned OR = STI.isABI_N64() ? Mips::OR64 : Mips::OR;
  unsigned JR = STI.isABI_N64() ? Mips::JR64 : Mips::JR;
  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
  unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA;
  unsigned T9 = STI.isABI_N64() ? Mips::T9_64 : Mips::T9;
  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
  unsigned OffsetReg = I->getOperand(0).getReg();
  unsigned TargetReg = I->getOperand(1).getReg();

  // or   $ra, $v0, $zero
  // addu $sp, $sp, $v1
  // jr   $ra
  if (TM.getRelocationModel() == Reloc::PIC_)
    BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), T9)
        .addReg(TargetReg).addReg(ZERO);
  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(OR), RA)
      .addReg(TargetReg).addReg(ZERO);
  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), SP)
      .addReg(SP).addReg(OffsetReg);
  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(JR)).addReg(RA);
}
/// materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to
/// be a pointer to FrameIdx at the beginning of the basic block.
void ARMBaseRegisterInfo::
materializeFrameBaseRegister(MachineBasicBlock *MBB,
                             unsigned BaseReg, int FrameIdx,
                             int64_t Offset) const {
  ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
  unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
    (AFI->isThumb1OnlyFunction() ? ARM::tADDrSPi : ARM::t2ADDri);

  MachineBasicBlock::iterator Ins = MBB->begin();
  DebugLoc DL;                  // Defaults to "unknown"
  if (Ins != MBB->end())
    DL = Ins->getDebugLoc();

  const MachineFunction &MF = *MBB->getParent();
  MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
  const MCInstrDesc &MCID = TII.get(ADDriOpc);
  MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF));

  MachineInstrBuilder MIB = AddDefaultPred(BuildMI(*MBB, Ins, DL, MCID, BaseReg)
    .addFrameIndex(FrameIdx).addImm(Offset));

  if (!AFI->isThumb1OnlyFunction())
    AddDefaultCC(MIB);
}
Example #10
0
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// We assume there is only one delay slot per delayed instruction.
///
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;

  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
    if (I->getDesc().hasDelaySlot()) {
      MachineBasicBlock::iterator D = MBB.end();
      MachineBasicBlock::iterator J = I;

      if (!DisableDelaySlotFiller)
        D = findDelayInstr(MBB, I);

      ++FilledSlots;
      Changed = true;

      if (D == MBB.end())
        BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(SP::NOP));
      else
        MBB.splice(++J, &MBB, D);
      unsigned structSize = 0;
      if (needsUnimp(I, structSize)) {
        MachineBasicBlock::iterator J = I;
        ++J; //skip the delay filler.
        BuildMI(MBB, ++J, I->getDebugLoc(),
                TII->get(SP::UNIMP)).addImm(structSize);
      }
    }
  return Changed;
}
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// We assume there is only one delay slot per delayed instruction.
bool Filler::
runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;
  LastFiller = MBB.end();

  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
    if (I->hasDelaySlot()) {
      ++FilledSlots;
      Changed = true;

      MachineBasicBlock::iterator D;

      if (EnableDelaySlotFiller && findDelayInstr(MBB, I, D)) {
        MBB.splice(llvm::next(I), &MBB, D);
        ++UsefulSlots;
      } else
        BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));

      // Record the filler instruction that filled the delay slot.
      // The instruction after it will be visited in the next iteration.
      LastFiller = ++I;
     }
  return Changed;

}
Example #12
0
  bool runOnMachineFunction(MachineFunction &MF) {
    // Early exit when there are no variable sized objects in the function.
    if (!MF.getFrameInfo().hasVarSizedObjects()) {
      return false;
    }

    const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
    const TargetInstrInfo &TII = *STI.getInstrInfo();
    MachineBasicBlock &EntryMBB = MF.front();
    MachineBasicBlock::iterator MBBI = EntryMBB.begin();
    DebugLoc DL = EntryMBB.findDebugLoc(MBBI);

    unsigned SPCopy =
        MF.getRegInfo().createVirtualRegister(&AVR::DREGSRegClass);

    // Create a copy of SP in function entry before any dynallocas are
    // inserted.
    BuildMI(EntryMBB, MBBI, DL, TII.get(AVR::COPY), SPCopy).addReg(AVR::SP);

    // Restore SP in all exit basic blocks.
    for (MachineBasicBlock &MBB : MF) {
      // If last instruction is a return instruction, add a restore copy.
      if (!MBB.empty() && MBB.back().isReturn()) {
        MBBI = MBB.getLastNonDebugInstr();
        DL = MBBI->getDebugLoc();
        BuildMI(MBB, MBBI, DL, TII.get(AVR::COPY), AVR::SP)
            .addReg(SPCopy, RegState::Kill);
      }
    }

    return true;
  }
/// \brief Replace loop instructions with the constant extended version.
void HexagonFixupHwLoops::useExtLoopInstr(MachineFunction &MF,
                                          MachineBasicBlock::iterator &MII) {
  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
  MachineBasicBlock *MBB = MII->getParent();
  DebugLoc DL = MII->getDebugLoc();
  MachineInstrBuilder MIB;
  unsigned newOp;
  switch (MII->getOpcode()) {
  case Hexagon::J2_loop0r:
    newOp = Hexagon::J2_loop0rext;
    break;
  case Hexagon::J2_loop0i:
    newOp = Hexagon::J2_loop0iext;
    break;
  case Hexagon::J2_loop1r:
    newOp = Hexagon::J2_loop1rext;
    break;
  case Hexagon::J2_loop1i:
    newOp = Hexagon::J2_loop1iext;
    break;
  default:
    llvm_unreachable("Invalid Hardware Loop Instruction.");
  }
  MIB = BuildMI(*MBB, MII, DL, TII->get(newOp));

  for (unsigned i = 0; i < MII->getNumOperands(); ++i)
    MIB.add(MII->getOperand(i));
}
static void replaceFrameIndexes(MachineFunction &MF, 
                                SmallVector<std::pair<int,int64_t>, 16> &FR) {
  MachineFrameInfo *MFI = MF.getFrameInfo();
  MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
  const SmallVector<std::pair<int,int64_t>, 16>::iterator FRB = FR.begin();
  const SmallVector<std::pair<int,int64_t>, 16>::iterator FRE = FR.end();

  SmallVector<std::pair<int,int64_t>, 16>::iterator FRI = FRB;
  for (; FRI != FRE; ++FRI) {
    MFI->RemoveStackObject(FRI->first);
    int NFI = MFI->CreateFixedObject(4, FRI->second, true);
    MBlazeFI->recordReplacement(FRI->first, NFI);

    for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) {
      MachineBasicBlock::iterator MBB = MB->begin();
      const MachineBasicBlock::iterator MBE = MB->end();

      for (; MBB != MBE; ++MBB) {
        MachineInstr::mop_iterator MIB = MBB->operands_begin();
        const MachineInstr::mop_iterator MIE = MBB->operands_end();

        for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) {
          if (!MII->isFI() || MII->getIndex() != FRI->first) continue;
          DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n");
          MII->setIndex(NFI);
        }
      }
    }
  }
}
void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
  MachineBasicBlock &MBB = MF.front();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  const HexagonRegisterInfo *QRI =
      MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
  determineFrameLayout(MF);

  // Get the number of bytes to allocate from the FrameInfo.
  int NumBytes = (int) MFI->getStackSize();

  // LLVM expects allocframe not to be the first instruction in the
  // basic block.
  MachineBasicBlock::iterator InsertPt = MBB.begin();

  //
  // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
  //
  HexagonMachineFunctionInfo *FuncInfo =
    MF.getInfo<HexagonMachineFunctionInfo>();
  const std::vector<MachineInstr*>& AdjustRegs =
    FuncInfo->getAllocaAdjustInsts();
  for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
         e = AdjustRegs.end();
       i != e; ++i) {
    MachineInstr* MI = *i;
    assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
           "Expected adjust alloca node");

    MachineOperand& MO = MI->getOperand(2);
    assert(MO.isImm() && "Expected immediate");
    MO.setImm(MFI->getMaxCallFrameSize());
  }

  //
  // Only insert ALLOCFRAME if we need to.
  //
  if (hasFP(MF)) {
    // Check for overflow.
    // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
    const int ALLOCFRAME_MAX = 16384;
    const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();

    if (NumBytes >= ALLOCFRAME_MAX) {
      // Emit allocframe(#0).
      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0);

      // Subtract offset from frame pointer.
      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
                                      HEXAGON_RESERVED_REG_1).addImm(NumBytes);
      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub),
                                      QRI->getStackRegister()).
                                      addReg(QRI->getStackRegister()).
                                      addReg(HEXAGON_RESERVED_REG_1);
    } else {
      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes);
    }
  }
}
Example #16
0
bool MipsExpandPseudo::runOnMachineBasicBlock(MachineBasicBlock& MBB) {

  bool Changed = false;
  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end();) {
    const TargetInstrDesc& Tid = I->getDesc();

    switch(Tid.getOpcode()) {
    default: 
      ++I;
      continue;
    case Mips::BuildPairF64:
      ExpandBuildPairF64(MBB, I);
      break;
    case Mips::ExtractElementF64:
      ExpandExtractElementF64(MBB, I);
      break;
    } 

    // delete original instr
    MBB.erase(I++);
    Changed = true;
  }

  return Changed;
}
Example #17
0
void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  const MachineFrameInfo *MFI = MF.getFrameInfo();
  const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
  MachineBasicBlock::iterator MBBI = prior(MBB.end());
  SystemZMachineFunctionInfo *SystemZMFI =
    MF.getInfo<SystemZMachineFunctionInfo>();
  unsigned RetOpcode = MBBI->getOpcode();

  switch (RetOpcode) {
  case SystemZ::RET: break;  // These are ok
  default:
    assert(0 && "Can only insert epilog into returning blocks");
  }

  // Get the number of bytes to allocate from the FrameInfo
  // Note that area for callee-saved stuff is already allocated, thus we need to
  // 'undo' the stack movement.
  uint64_t StackSize =
    MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
  uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();

  // Skip the final terminator instruction.
  while (MBBI != MBB.begin()) {
    MachineBasicBlock::iterator PI = prior(MBBI);
    --MBBI;
    if (!PI->getDesc().isTerminator())
      break;
  }

  // During callee-saved restores emission stack frame was not yet finialized
  // (and thus - the stack size was unknown). Tune the offset having full stack
  // size in hands.
  if (StackSize || MFI->hasCalls()) {
    assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
            MBBI->getOpcode() == SystemZ::MOV64rm) &&
           "Expected to see callee-save register restore code");
    assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
           "Invalid stack frame calculation!");

    unsigned i = 0;
    MachineInstr &MI = *MBBI;
    while (!MI.getOperand(i).isImm()) {
      ++i;
      assert(i < MI.getNumOperands() && "Unexpected restore code!");
    }

    uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
    // If Offset does not fit into 20-bit signed displacement field we need to
    // emit some additional code...
    if (Offset > 524287) {
      // Fold the displacement into load instruction as much as possible.
      NumBytes = Offset - 524287;
      Offset = 524287;
      emitSPUpdate(MBB, MBBI, NumBytes, TII);
    }

    MI.getOperand(i).ChangeToImmediate(Offset);
  }
}
Example #18
0
unsigned Disassembler::printInstructions(formatted_raw_ostream &Out,
  unsigned Address, unsigned Size, bool PrintTypes) {
  MachineFunction *MF = disassemble(Address);

  MachineFunction::iterator BI = MF->begin(), BE = MF->end();
  // Skip to first basic block with instruction in desired address
  // Out << BI->instr_rbegin()->getDebugLoc().getLine() << "\n";
  while (BI != BE
    && getDebugOffset(BI->instr_rbegin()->getDebugLoc()) < Address) {
    ++BI;
  }
  if (BI == BE) {
    printError("Could not disassemble, reached end of function's basic blocks"
      " when looking for first instruction.");
    return 0;
  }


  MachineBasicBlock::iterator II = BI->instr_begin(), IE = BI->instr_end();
  // skip to first instruction
  while (getDebugOffset(II->getDebugLoc()) < Address) {
    if (II == IE) {
      printError("Unreachable: reached end of basic block whe looking for first"
        " instruction.");
      ++BI;
      II = BI->instr_begin();
      IE = BI->instr_end();
    }
    ++II;
  }
  if (Address != getDebugOffset(II->getDebugLoc())) {
    Out << "Warning: starting at " << getDebugOffset(II->getDebugLoc())
        << " instead of " << Address << ".\n";
  }

  // Function Name and Offset
  Out << "<" << MF->getName();
  if (getDebugOffset(MF->begin()->instr_begin()->getDebugLoc()) != Address) {
    Out << "+"
        << (Address
          - getDebugOffset(MF->begin()->instr_begin()->getDebugLoc()));
  }
  Out << ">:\n";

  // Print each instruction
  unsigned InstrCount = 0;
  while (BI != BE && (Size == 0 || InstrCount < Size)) {
    printInstruction(Out, II, PrintTypes);
    ++InstrCount;
    ++II;
    if (II == IE) {
      ++BI;
      II = BI->instr_begin();
      IE = BI->instr_end();
    }
  }

  return InstrCount;
}
/// \brief For Hexagon, if the loop label is to far from the
/// loop instruction then we need to set the LC0 and SA0 registers
/// explicitly instead of using LOOP(start,count).  This function
/// checks the distance, and generates register assignments if needed.
///
/// This function makes two passes over the basic blocks.  The first
/// pass computes the offset of the basic block from the start.
/// The second pass checks all the loop instructions.
bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {

  // Offset of the current instruction from the start.
  unsigned InstOffset = 0;
  // Map for each basic block to it's first instruction.
  DenseMap<const MachineBasicBlock *, unsigned> BlockToInstOffset;

  const HexagonInstrInfo *HII =
      static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());

  // First pass - compute the offset of each basic block.
  for (const MachineBasicBlock &MBB : MF) {
    if (MBB.getAlignment()) {
      // Although we don't know the exact layout of the final code, we need
      // to account for alignment padding somehow. This heuristic pads each
      // aligned basic block according to the alignment value.
      int ByteAlign = (1u << MBB.getAlignment()) - 1;
      InstOffset = (InstOffset + ByteAlign) & ~(ByteAlign);
    }

    BlockToInstOffset[&MBB] = InstOffset;
    for (const MachineInstr &MI : MBB)
      InstOffset += HII->getSize(MI);
  }

  // Second pass - check each loop instruction to see if it needs to be
  // converted.
  bool Changed = false;
  for (MachineBasicBlock &MBB : MF) {
    InstOffset = BlockToInstOffset[&MBB];

    // Loop over all the instructions.
    MachineBasicBlock::iterator MII = MBB.begin();
    MachineBasicBlock::iterator MIE = MBB.end();
    while (MII != MIE) {
      InstOffset += HII->getSize(*MII);
      if (MII->isMetaInstruction()) {
        ++MII;
        continue;
      }
      if (isHardwareLoop(*MII)) {
        assert(MII->getOperand(0).isMBB() &&
               "Expect a basic block as loop operand");
        int diff = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()];
        if ((unsigned)abs(diff) > MaxLoopRange) {
          useExtLoopInstr(MF, MII);
          MII = MBB.erase(MII);
          Changed = true;
        } else {
          ++MII;
        }
      } else {
        ++MII;
      }
    }
  }

  return Changed;
}
Example #20
0
void XCoreFrameInfo::emitEpilogue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  MachineFrameInfo *MFI            = MF.getFrameInfo();
  MachineBasicBlock::iterator MBBI = prior(MBB.end());
  const XCoreInstrInfo &TII =
    *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
  DebugLoc dl = MBBI->getDebugLoc();

  bool FP = hasFP(MF);
  if (FP) {
    // Restore the stack pointer.
    unsigned FramePtr = XCore::R10;
    BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r))
      .addReg(FramePtr);
  }

  // Work out frame sizes.
  int FrameSize = MFI->getStackSize();

  assert(FrameSize%4 == 0 && "Misaligned frame size");

  FrameSize/=4;

  bool isU6 = isImmU6(FrameSize);

  if (!isU6 && !isImmU16(FrameSize)) {
    // FIXME could emit multiple instructions.
    report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize));
  }

  if (FrameSize) {
    XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();

    if (FP) {
      // Restore R10
      int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
      FPSpillOffset += FrameSize*4;
      loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII);
    }
    bool restoreLR = XFI->getUsesLR();
    if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) {
      int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
      LRSpillOffset += FrameSize*4;
      loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII);
      restoreLR = false;
    }
    if (restoreLR) {
      // Fold prologue into return instruction
      assert(MBBI->getOpcode() == XCore::RETSP_u6
        || MBBI->getOpcode() == XCore::RETSP_lu6);
      int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
      BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
      MBB.erase(MBBI);
    } else {
      int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
      BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize);
    }
  }
}
Example #21
0
unsigned StackColoring::collectMarkers(unsigned NumSlot) {
  unsigned MarkersFound = 0;
  // Scan the function to find all lifetime markers.
  // NOTE: We use the a reverse-post-order iteration to ensure that we obtain a
  // deterministic numbering, and because we'll need a post-order iteration
  // later for solving the liveness dataflow problem.
  for (df_iterator<MachineFunction*> FI = df_begin(MF), FE = df_end(MF);
       FI != FE; ++FI) {

    // Assign a serial number to this basic block.
    BasicBlocks[*FI] = BasicBlockNumbering.size();
    BasicBlockNumbering.push_back(*FI);

    // Keep a reference to avoid repeated lookups.
    BlockLifetimeInfo &BlockInfo = BlockLiveness[*FI];

    BlockInfo.Begin.resize(NumSlot);
    BlockInfo.End.resize(NumSlot);

    for (MachineBasicBlock::iterator BI = (*FI)->begin(), BE = (*FI)->end();
         BI != BE; ++BI) {

      if (BI->getOpcode() != TargetOpcode::LIFETIME_START &&
          BI->getOpcode() != TargetOpcode::LIFETIME_END)
        continue;

      Markers.push_back(BI);

      bool IsStart = BI->getOpcode() == TargetOpcode::LIFETIME_START;
      const MachineOperand &MI = BI->getOperand(0);
      unsigned Slot = MI.getIndex();

      MarkersFound++;

      const AllocaInst *Allocation = MFI->getObjectAllocation(Slot);
      if (Allocation) {
        DEBUG(dbgs()<<"Found a lifetime marker for slot #"<<Slot<<
              " with allocation: "<< Allocation->getName()<<"\n");
      }

      if (IsStart) {
        BlockInfo.Begin.set(Slot);
      } else {
        if (BlockInfo.Begin.test(Slot)) {
          // Allocas that start and end within a single block are handled
          // specially when computing the LiveIntervals to avoid pessimizing
          // the liveness propagation.
          BlockInfo.Begin.reset(Slot);
        } else {
          BlockInfo.End.set(Slot);
        }
      }
    }
  }

  // Update statistics.
  NumMarkerSeen += MarkersFound;
  return MarkersFound;
}
Example #22
0
static bool memAccessesCanBeReordered(MachineBasicBlock::iterator A,
                                      MachineBasicBlock::iterator B,
                                      AliasAnalysis *AA) {
  // RAW or WAR - cannot reorder
  // WAW - cannot reorder
  // RAR - safe to reorder
  return !(A->mayStore() || B->mayStore()) || !A->mayAlias(AA, *B, true);
}
/// TransferImplicitOperands - MI is a pseudo-instruction, and the lowered
/// replacement instructions immediately precede it.  Copy any implicit
/// operands from MI to the replacement instruction.
void ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) {
  MachineBasicBlock::iterator CopyMI = MI;
  --CopyMI;

  for (const MachineOperand &MO : MI->implicit_operands())
    if (MO.isReg())
      CopyMI->addOperand(MO);
}
Example #24
0
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't
/// implemented for a target).  Upon success, this returns false and returns
/// with the following information in various cases:
///
/// 1. If this block ends with no branches (it just falls through to its succ)
///    just return false, leaving TBB/FBB null.
/// 2. If this block ends with only an unconditional branch, it sets TBB to be
///    the destination block.
/// 3. If this block ends with an conditional branch and it falls through to
///    an successor block, it sets TBB to be the branch destination block and a
///    list of operands that evaluate the condition. These
///    operands can be passed to other TargetInstrInfo methods to create new
///    branches.
/// 4. If this block ends with an conditional branch and an unconditional
///    block, it returns the 'true' destination in TBB, the 'false' destination
///    in FBB, and a list of operands that evaluate the condition. These
///    operands can be passed to other TargetInstrInfo methods to create new
///    branches.
///
/// Note that removeBranch and insertBranch must be implemented to support
/// cases where this method returns success.
///
bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                   MachineBasicBlock *&TBB,
                                   MachineBasicBlock *&FBB,
                                   SmallVectorImpl<MachineOperand> &Cond,
                                   bool AllowModify) const {
  // If the block has no terminators, it just falls into the block after it.
  MachineBasicBlock::iterator I = MBB.end();
  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
    return false;

  // Get the last instruction in the block.
  MachineInstr &LastInst = *I;

  // If there is only one terminator instruction, process it.
  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
    if (LastInst.getOpcode() == NVPTX::GOTO) {
      TBB = LastInst.getOperand(0).getMBB();
      return false;
    } else if (LastInst.getOpcode() == NVPTX::CBranch) {
      // Block ends with fall-through condbranch.
      TBB = LastInst.getOperand(1).getMBB();
      Cond.push_back(LastInst.getOperand(0));
      return false;
    }
    // Otherwise, don't know what this is.
    return true;
  }

  // Get the instruction before it if it's a terminator.
  MachineInstr &SecondLastInst = *I;

  // If there are three terminators, we don't know what sort of block this is.
  if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
    return true;

  // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
  if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
      LastInst.getOpcode() == NVPTX::GOTO) {
    TBB = SecondLastInst.getOperand(1).getMBB();
    Cond.push_back(SecondLastInst.getOperand(0));
    FBB = LastInst.getOperand(0).getMBB();
    return false;
  }

  // If the block ends with two NVPTX:GOTOs, handle it.  The second one is not
  // executed, so remove it.
  if (SecondLastInst.getOpcode() == NVPTX::GOTO &&
      LastInst.getOpcode() == NVPTX::GOTO) {
    TBB = SecondLastInst.getOperand(0).getMBB();
    I = LastInst;
    if (AllowModify)
      I->eraseFromParent();
    return false;
  }

  // Otherwise, can't handle this.
  return true;
}
bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
  MachineBasicBlock *MBB = MI->getParent();
  assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
         MI->getOperand(1).isImm() &&
         (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&
          MI->getOperand(3).isImm() && "Invalid subreg_to_reg");

  unsigned DstReg  = MI->getOperand(0).getReg();
  unsigned InsReg  = MI->getOperand(2).getReg();
  assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?");
  unsigned SubIdx  = MI->getOperand(3).getImm();

  assert(SubIdx != 0 && "Invalid index for insert_subreg");
  unsigned DstSubReg = TRI->getSubReg(DstReg, SubIdx);

  assert(TargetRegisterInfo::isPhysicalRegister(DstReg) &&
         "Insert destination must be in a physical register");
  assert(TargetRegisterInfo::isPhysicalRegister(InsReg) &&
         "Inserted value must be in a physical register");

  LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);

  if (MI->allDefsAreDead()) {
    MI->setDesc(TII->get(TargetOpcode::KILL));
    MI->RemoveOperand(3); // SubIdx
    MI->RemoveOperand(1); // Imm
    LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI);
    return true;
  }

  if (DstSubReg == InsReg) {
    // No need to insert an identity copy instruction.
    // Watch out for case like this:
    // %rax = SUBREG_TO_REG 0, killed %eax, 3
    // We must leave %rax live.
    if (DstReg != InsReg) {
      MI->setDesc(TII->get(TargetOpcode::KILL));
      MI->RemoveOperand(3);     // SubIdx
      MI->RemoveOperand(1);     // Imm
      LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI);
      return true;
    }
    LLVM_DEBUG(dbgs() << "subreg: eliminated!");
  } else {
    TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,
                     MI->getOperand(2).isKill());

    // Implicitly define DstReg for subsequent uses.
    MachineBasicBlock::iterator CopyMI = MI;
    --CopyMI;
    CopyMI->addRegisterDefined(DstReg);
    LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI);
  }

  LLVM_DEBUG(dbgs() << '\n');
  MBB->erase(MI);
  return true;
}
void VectorProcFrameLowering::emitPrologue(MachineFunction &MF) const {
  MachineBasicBlock &MBB = MF.front();
  MachineFrameInfo *MFI = MF.getFrameInfo();
  const VectorProcInstrInfo &TII =
      *static_cast<const VectorProcInstrInfo *>(MF.getTarget().getInstrInfo());
  MachineModuleInfo &MMI = MF.getMMI();
  const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();

  // Compute stack size. Allocate space, keeping SP 64 byte aligned so we
  // can do block vector load/stores
  int StackSize = RoundUpToAlignment(MFI->getStackSize(), getStackAlignment()); 

  // Bail if there is no stack allocation
  if (StackSize == 0 && !MFI->adjustsStack()) return;

  TII.adjustStackPointer(MBB, MBBI, -StackSize);

  // emit ".cfi_def_cfa_offset StackSize" (debug information)
  unsigned CFIIndex = MMI.addFrameInst(
      MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
  BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
      .addCFIIndex(CFIIndex);

  // Find the instruction past the last instruction that saves a callee-saved
  // register to the stack.  We need to set up FP after its old value has been
  // saved.
  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
  if (CSI.size()) {
    for (unsigned i = 0; i < CSI.size(); ++i)
      ++MBBI;

    // Iterate over list of callee-saved registers and emit .cfi_offset
    // directives (debug information)
    for (const auto &I : CSI) {
      int64_t Offset = MFI->getObjectOffset(I.getFrameIdx());
      unsigned Reg = I.getReg();
      unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
          nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));
      BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
          .addCFIIndex(CFIIndex);
    }
  }

  // fp = sp
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, DL, TII.get(VectorProc::MOVESS))
        .addReg(VectorProc::FP_REG)
        .addReg(VectorProc::SP_REG);

    // emit ".cfi_def_cfa_register $fp" (debug information)
    unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
        nullptr, MRI->getDwarfRegNum(VectorProc::FP_REG, true)));
    BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex);
  }
}
void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
  DebugLoc dl = MBBI->getDebugLoc();
  //
  // Only insert deallocframe if we need to.  Also at -O0.  See comment
  // in emitPrologue above.
  //
  if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) {
    MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
    MachineBasicBlock::iterator MBBI_end = MBB.end();

    const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
    // Handle EH_RETURN.
    if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
      assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::A2_add),
              Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
      return;
    }
    // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
    // versions.
    if (MF.getSubtarget<HexagonSubtarget>().hasV4TOps() &&
        MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) {
      // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC
      // instruction if we encounter it.
      MachineBasicBlock::iterator BeforeJMPR =
        MBB.begin() == MBBI ? MBBI : std::prev(MBBI);
      if (BeforeJMPR != MBBI &&
          BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
        // Remove the JMPR node.
        MBB.erase(MBBI);
        return;
      }

      // Add dealloc_return.
      MachineInstrBuilder MIB =
        BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::L4_return));
      // Transfer the function live-out registers.
      MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
      // Remove the JUMPR node.
      MBB.erase(MBBI);
    } else { // Add deallocframe for V2 and V3, and V4 tail calls.
      // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra
      // DEALLOCFRAME instruction after it.
      MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
      MachineBasicBlock::iterator I =
        Term == MBB.begin() ?  MBB.end() : std::prev(Term);
      if (I != MBB.end() &&
          I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
        return;

      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
    }
  }
}
Example #28
0
MachineBasicBlock::iterator
MachineBasicBlock::erase(MachineBasicBlock::iterator I) {
  if (I->isBundle()) {
    MachineBasicBlock::iterator E = llvm::next(I);
    return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
  }

  return Insts.erase(I.getInstrIterator());
}
Example #29
0
void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator I,
                                         bool FP64) const {
  unsigned DstReg = I->getOperand(0).getReg();
  unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
  const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
  DebugLoc dl = I->getDebugLoc();
  const TargetRegisterInfo &TRI = getRegisterInfo();

  // When mthc1 is available, use:
  //   mtc1 Lo, $fp
  //   mthc1 Hi, $fp
  //
  // Otherwise, for O32 FPXX ABI:
  //   spill + reload via ldc1
  // This case is handled by the frame lowering code.
  //
  // Otherwise, for FP32:
  //   mtc1 Lo, $fp
  //   mtc1 Hi, $fp + 1
  //
  // The case where dmtc1 is available doesn't need to be handled here
  // because it never creates a BuildPairF64 node.

  // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
  // in MipsSEFrameLowering.cpp.
  assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));

  // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
  // in MipsSEFrameLowering.cpp.
  assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));

  BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
    .addReg(LoReg);

  if (Subtarget.hasMTHC1()) {
    // FIXME: The .addReg(DstReg) is a white lie used to temporarily work
    //        around a widespread bug in the -mfp64 support.
    //        The problem is that none of the 32-bit fpu ops mention the fact
    //        that they clobber the upper 32-bits of the 64-bit FPR. Fixing that
    //        requires a major overhaul of the FPU implementation which can't
    //        be done right now due to time constraints.
    //        MTHC1 is one of two instructions that are affected since they are
    //        the only instructions that don't read the lower 32-bits.
    //        We therefore pretend that it reads the bottom 32-bits to
    //        artificially create a dependency and prevent the scheduler
    //        changing the behaviour of the code.
    BuildMI(MBB, I, dl, get(FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32), DstReg)
        .addReg(DstReg)
        .addReg(HiReg);
  } else if (Subtarget.isABI_FPXX())
    llvm_unreachable("BuildPairF64 not expanded in frame lowering code!");
  else
    BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
      .addReg(HiReg);
}
Example #30
0
static bool memAccessesCanBeReordered(MachineBasicBlock::iterator A,
                                      MachineBasicBlock::iterator B,
                                      const SIInstrInfo *TII,
                                      AliasAnalysis * AA) {
  return (TII->areMemAccessesTriviallyDisjoint(*A, *B, AA) ||
    // RAW or WAR - cannot reorder
    // WAW - cannot reorder
    // RAR - safe to reorder
    !(A->mayStore() || B->mayStore()));
}