Пример #1
0
unsigned MipsInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                     int *BytesRemoved) const {
  assert(!BytesRemoved && "code size not handled");

  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
  unsigned removed = 0;

  // Up to 2 branches are removed.
  // Note that indirect branches are not removed.
  while (I != REnd && removed < 2) {
    // Skip past debug instructions.
    if (I->isDebugValue()) {
      ++I;
      continue;
    }
    if (!getAnalyzableBrOpc(I->getOpcode()))
      break;
    // Remove the branch.
    I->eraseFromParent();
    I = MBB.rbegin();
    ++removed;
  }

  return removed;
}
Пример #2
0
// Return true if \p MI dominates of uses of virtual register \p VReg
static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg,
                               MachineDominatorTree *MDT,
                               MachineRegisterInfo *MRI) {

  assert(TargetRegisterInfo::isVirtualRegister(VReg) &&
         "Expected virtual register!");

  for (auto it = MRI->use_nodbg_begin(VReg), end = MRI->use_nodbg_end();
       it != end; ++it) {
    MachineInstr *User = it->getParent();
    if (User->isPHI()) {
      unsigned BBOperandIdx = User->getOperandNo(&*it) + 1;
      MachineBasicBlock *MBB = User->getOperand(BBOperandIdx).getMBB();
      if (MBB->empty()) {
        const MachineBasicBlock *InstBB = MI->getParent();
        assert(InstBB != MBB && "Instruction found in empty MBB");
        if (!MDT->dominates(InstBB, MBB))
          return false;
        continue;
      }
      User = &*MBB->rbegin();
    }

    if (!MDT->dominates(MI, User))
      return false;
  }
  return true;
}
Пример #3
0
void SIWholeQuadMode::propagateBlock(MachineBasicBlock &MBB,
                                     std::vector<WorkItem>& Worklist) {
  BlockInfo BI = Blocks[&MBB]; // Make a copy to prevent dangling references.

  // Propagate through instructions
  if (!MBB.empty()) {
    MachineInstr *LastMI = &*MBB.rbegin();
    InstrInfo &LastII = Instructions[LastMI];
    if ((LastII.OutNeeds | BI.OutNeeds) != LastII.OutNeeds) {
      LastII.OutNeeds |= BI.OutNeeds;
      Worklist.push_back(LastMI);
    }
  }

  // Predecessor blocks must provide for our WQM/Exact needs.
  for (MachineBasicBlock *Pred : MBB.predecessors()) {
    BlockInfo &PredBI = Blocks[Pred];
    if ((PredBI.OutNeeds | BI.InNeeds) == PredBI.OutNeeds)
      continue;

    PredBI.OutNeeds |= BI.InNeeds;
    PredBI.InNeeds |= BI.InNeeds;
    Worklist.push_back(Pred);
  }

  // All successors must be prepared to accept the same set of WQM/Exact data.
  for (MachineBasicBlock *Succ : MBB.successors()) {
    BlockInfo &SuccBI = Blocks[Succ];
    if ((SuccBI.InNeeds | BI.OutNeeds) == SuccBI.InNeeds)
      continue;

    SuccBI.InNeeds |= BI.OutNeeds;
    Worklist.push_back(Succ);
  }
}
Пример #4
0
unsigned MipsInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                     int *BytesRemoved) const {
  assert(!BytesRemoved && "code size not handled");

  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
  unsigned removed;

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  if (I == REnd)
    return 0;

  MachineBasicBlock::iterator FirstBr = ++I.getReverse();

  // Up to 2 branches are removed.
  // Note that indirect branches are not removed.
  for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
    if (!getAnalyzableBrOpc(I->getOpcode()))
      break;

  MBB.erase((--I).getReverse(), FirstBr);

  return removed;
}
Пример #5
0
// Fill MBBInfos.
void MipsLongBranch::initMBBInfo() {
  // Split the MBBs if they have two branches. Each basic block should have at
  // most one branch after this loop is executed.
  for (auto &MBB : *MF)
    splitMBB(&MBB);

  MF->RenumberBlocks();
  MBBInfos.clear();
  MBBInfos.resize(MF->size());

  const MipsInstrInfo *TII =
      static_cast<const MipsInstrInfo *>(MF->getSubtarget().getInstrInfo());
  for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) {
    MachineBasicBlock *MBB = MF->getBlockNumbered(I);

    // Compute size of MBB.
    for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin();
         MI != MBB->instr_end(); ++MI)
      MBBInfos[I].Size += TII->GetInstSizeInBytes(&*MI);

    // Search for MBB's branch instruction.
    ReverseIter End = MBB->rend();
    ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End);

    if ((Br != End) && !Br->isIndirectBranch() &&
        (Br->isConditionalBranch() ||
         (Br->isUnconditionalBranch() &&
          TM.getRelocationModel() == Reloc::PIC_)))
      MBBInfos[I].Br = (++Br).base();
  }
}
Пример #6
0
static MachineBasicBlock::reverse_iterator fixTerminators(
  const SIInstrInfo &TII,
  MachineBasicBlock &MBB) {
  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend();
  for (; I != E; ++I) {
    if (!I->isTerminator())
      return I;

    if (removeTerminatorBit(TII, *I))
      return I;
  }

  return E;
}
Пример #7
0
// Iterate through fallen through blocks trying to find a previous non-pseudo if
// there is one, otherwise return nullptr. Only look for instructions in
// previous blocks, not the current block, since we only use this to look at
// previous blocks.
static MachineInstr *getLastNonPseudo(MachineBasicBlock &MBB,
                                      const TargetInstrInfo *TII) {
  MachineBasicBlock *FMBB = &MBB;

  // If there is no non-pseudo in the current block, loop back around and try
  // the previous block (if there is one).
  while ((FMBB = getBBFallenThrough(FMBB, TII))) {
    for (MachineInstr &I : make_range(FMBB->rbegin(), FMBB->rend()))
      if (!I.isPseudo())
        return &I;
  }

  // There was no previous non-pseudo in the fallen through blocks
  return nullptr;
}
Пример #8
0
unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
  MachineBasicBlock::reverse_iterator FirstBr;
  unsigned removed;

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  FirstBr = I;

  // Up to 2 branches are removed.
  // Note that indirect branches are not removed.
  for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
    if (!getAnalyzableBrOpc(I->getOpcode()))
      break;

  MBB.erase(I.base(), FirstBr.base());

  return removed;
}
Пример #9
0
// All currently live registers must remain so in the remainder block.
void SILowerControlFlow::splitBlockLiveIns(const MachineBasicBlock &MBB,
                                           const MachineInstr &MI,
                                           MachineBasicBlock &LoopBB,
                                           MachineBasicBlock &RemainderBB,
                                           unsigned SaveReg,
                                           const MachineOperand &IdxReg) {
  LivePhysRegs RemainderLiveRegs(TRI);

  RemainderLiveRegs.addLiveOuts(MBB);
  for (MachineBasicBlock::const_reverse_iterator I = MBB.rbegin(), E(&MI);
       I != E; ++I) {
    RemainderLiveRegs.stepBackward(*I);
  }

  // Add reg defined in loop body.
  RemainderLiveRegs.addReg(SaveReg);

  if (const MachineOperand *Val = TII->getNamedOperand(MI, AMDGPU::OpName::val)) {
    if (!Val->isUndef()) {
      RemainderLiveRegs.addReg(Val->getReg());
      LoopBB.addLiveIn(Val->getReg());
    }
  }

  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
  for (unsigned Reg : RemainderLiveRegs) {
    if (MRI.isAllocatable(Reg))
      RemainderBB.addLiveIn(Reg);
  }


  const MachineOperand *Src = TII->getNamedOperand(MI, AMDGPU::OpName::src);
  if (!Src->isUndef())
    LoopBB.addLiveIn(Src->getReg());

  if (!IdxReg.isUndef())
    LoopBB.addLiveIn(IdxReg.getReg());
  LoopBB.sortUniqueLiveIns();
}
Пример #10
0
bool PatmosInstrInfo::mayFallthrough(MachineBasicBlock &MBB) const {

  // Look back 1 slot further than the call to catch the case where a SENS
  // is scheduled after an noreturn call delay slot.
  int maxLookback = PST.getCFLDelaySlotCycles(false) + 1;

  // find last terminator
  for(MachineBasicBlock::reverse_iterator t(MBB.rbegin()),
      te(MBB.rend()); t != te && maxLookback >= 0; t++)
  {
    MachineInstr *mi = &*t;

    if (!mi->isPseudo(MachineInstr::AllInBundle)) {
      maxLookback--;
    }

    if (mi->isCall()) {
      const Function *F = getCallee(mi);
      if (F && F->hasFnAttribute(Attribute::NoReturn)) {
        return false;
      }
    }

    // skip non-terminator instructions
    if (!mi->isTerminator()) {
      continue;
    }

    // fix opcode for branch instructions to set barrier flag correctly
    fixOpcodeForGuard(mi);

    return !mi->isBarrier();
  }

  return true;
}
Пример #11
0
MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch(
    MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
    SmallVectorImpl<MachineOperand> &Cond, bool AllowModify,
    SmallVectorImpl<MachineInstr *> &BranchInstrs) const {

  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();

  // Skip all the debug instructions.
  while (I != REnd && I->isDebugValue())
    ++I;

  if (I == REnd || !isUnpredicatedTerminator(*I)) {
    // This block ends with no branches (it just falls through to its succ).
    // Leave TBB/FBB null.
    TBB = FBB = nullptr;
    return BT_NoBranch;
  }

  MachineInstr *LastInst = &*I;
  unsigned LastOpc = LastInst->getOpcode();
  BranchInstrs.push_back(LastInst);

  // Not an analyzable branch (e.g., indirect jump).
  if (!getAnalyzableBrOpc(LastOpc))
    return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;

  // Get the second to last instruction in the block.
  unsigned SecondLastOpc = 0;
  MachineInstr *SecondLastInst = nullptr;

  if (++I != REnd) {
    SecondLastInst = &*I;
    SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());

    // Not an analyzable branch (must be an indirect jump).
    if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
      return BT_None;
  }

  // If there is only one terminator instruction, process it.
  if (!SecondLastOpc) {
    // Unconditional branch.
    if (LastInst->isUnconditionalBranch()) {
      TBB = LastInst->getOperand(0).getMBB();
      return BT_Uncond;
    }

    // Conditional branch
    AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
    return BT_Cond;
  }

  // If we reached here, there are two branches.
  // If there are three terminators, we don't know what sort of block this is.
  if (++I != REnd && isUnpredicatedTerminator(*I))
    return BT_None;

  BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);

  // If second to last instruction is an unconditional branch,
  // analyze it and remove the last instruction.
  if (SecondLastInst->isUnconditionalBranch()) {
    // Return if the last instruction cannot be removed.
    if (!AllowModify)
      return BT_None;

    TBB = SecondLastInst->getOperand(0).getMBB();
    LastInst->eraseFromParent();
    BranchInstrs.pop_back();
    return BT_Uncond;
  }

  // Conditional branch followed by an unconditional branch.
  // The last one must be unconditional.
  if (!LastInst->isUnconditionalBranch())
    return BT_None;

  AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
  FBB = LastInst->getOperand(0).getMBB();

  return BT_CondUncond;
}
Пример #12
0
// Expand branch instructions to long branches.
// TODO: This function has to be fixed for beqz16 and bnez16, because it
// currently assumes that all branches have 16-bit offsets, and will produce
// wrong code if branches whose allowed offsets are [-128, -126, ..., 126]
// are present.
void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
  MachineBasicBlock::iterator Pos;
  MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br);
  DebugLoc DL = I.Br->getDebugLoc();
  const BasicBlock *BB = MBB->getBasicBlock();
  MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB);
  MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB);
  const MipsSubtarget &Subtarget =
      static_cast<const MipsSubtarget &>(MF->getSubtarget());
  const MipsInstrInfo *TII =
      static_cast<const MipsInstrInfo *>(Subtarget.getInstrInfo());

  MF->insert(FallThroughMBB, LongBrMBB);
  MBB->replaceSuccessor(TgtMBB, LongBrMBB);

  if (IsPIC) {
    MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB);
    MF->insert(FallThroughMBB, BalTgtMBB);
    LongBrMBB->addSuccessor(BalTgtMBB);
    BalTgtMBB->addSuccessor(TgtMBB);

    // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal
    // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an
    // pseudo-instruction wrapping BGEZAL).
    const unsigned BalOp =
        Subtarget.hasMips32r6()
            ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC
            : Mips::BAL_BR;

    if (!ABI.IsN64()) {
      // Pre R6:
      // $longbr:
      //  addiu $sp, $sp, -8
      //  sw $ra, 0($sp)
      //  lui $at, %hi($tgt - $baltgt)
      //  bal $baltgt
      //  addiu $at, $at, %lo($tgt - $baltgt)
      // $baltgt:
      //  addu $at, $ra, $at
      //  lw $ra, 0($sp)
      //  jr $at
      //  addiu $sp, $sp, 8
      // $fallthrough:
      //

      // R6:
      // $longbr:
      //  addiu $sp, $sp, -8
      //  sw $ra, 0($sp)
      //  lui $at, %hi($tgt - $baltgt)
      //  addiu $at, $at, %lo($tgt - $baltgt)
      //  balc $baltgt
      // $baltgt:
      //  addu $at, $ra, $at
      //  lw $ra, 0($sp)
      //  addiu $sp, $sp, 8
      //  jic $at, 0
      // $fallthrough:

      Pos = LongBrMBB->begin();

      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
        .addReg(Mips::SP).addImm(-8);
      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA)
        .addReg(Mips::SP).addImm(0);

      // LUi and ADDiu instructions create 32-bit offset of the target basic
      // block from the target of BAL(C) instruction.  We cannot use immediate
      // value for this offset because it cannot be determined accurately when
      // the program has inline assembly statements.  We therefore use the
      // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which
      // are resolved during the fixup, so the values will always be correct.
      //
      // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt)
      // expressions at this point (it is possible only at the MC layer),
      // we replace LUi and ADDiu with pseudo instructions
      // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic
      // blocks as operands to these instructions.  When lowering these pseudo
      // instructions to LUi and ADDiu in the MC layer, we will create
      // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as
      // operands to lowered instructions.

      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)
        .addMBB(TgtMBB).addMBB(BalTgtMBB);

      MachineInstrBuilder BalInstr =
          BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
      MachineInstrBuilder ADDiuInstr =
          BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)
              .addReg(Mips::AT)
              .addMBB(TgtMBB)
              .addMBB(BalTgtMBB);
      if (Subtarget.hasMips32r6()) {
        LongBrMBB->insert(Pos, ADDiuInstr);
        LongBrMBB->insert(Pos, BalInstr);
      } else {
        LongBrMBB->insert(Pos, BalInstr);
        LongBrMBB->insert(Pos, ADDiuInstr);
        LongBrMBB->rbegin()->bundleWithPred();
      }

      Pos = BalTgtMBB->begin();

      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
        .addReg(Mips::RA).addReg(Mips::AT);
      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
        .addReg(Mips::SP).addImm(0);
      if (Subtarget.isTargetNaCl())
        // Bundle-align the target of indirect branch JR.
        TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN);

      // In NaCl, modifying the sp is not allowed in branch delay slot.
      // For MIPS32R6, we can skip using a delay slot branch.
      if (Subtarget.isTargetNaCl() ||
          (Subtarget.hasMips32r6() && !Subtarget.useIndirectJumpsHazard()))
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
          .addReg(Mips::SP).addImm(8);

      if (Subtarget.hasMips32r6() && !Subtarget.useIndirectJumpsHazard()) {
        const unsigned JICOp =
            Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC;
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp))
            .addReg(Mips::AT)
            .addImm(0);

      } else {
        unsigned JROp =
            Subtarget.useIndirectJumpsHazard()
                ? (Subtarget.hasMips32r6() ? Mips::JR_HB_R6 : Mips::JR_HB)
                : Mips::JR;
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT);

        if (Subtarget.isTargetNaCl()) {
          BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP));
        } else
          BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
              .addReg(Mips::SP)
              .addImm(8);

        BalTgtMBB->rbegin()->bundleWithPred();
      }
    } else {
      // Pre R6:
      // $longbr:
      //  daddiu $sp, $sp, -16
      //  sd $ra, 0($sp)
      //  daddiu $at, $zero, %hi($tgt - $baltgt)
      //  dsll $at, $at, 16
      //  bal $baltgt
      //  daddiu $at, $at, %lo($tgt - $baltgt)
      // $baltgt:
      //  daddu $at, $ra, $at
      //  ld $ra, 0($sp)
      //  jr64 $at
      //  daddiu $sp, $sp, 16
      // $fallthrough:

      // R6:
      // $longbr:
      //  daddiu $sp, $sp, -16
      //  sd $ra, 0($sp)
      //  daddiu $at, $zero, %hi($tgt - $baltgt)
      //  dsll $at, $at, 16
      //  daddiu $at, $at, %lo($tgt - $baltgt)
      //  balc $baltgt
      // $baltgt:
      //  daddu $at, $ra, $at
      //  ld $ra, 0($sp)
      //  daddiu $sp, $sp, 16
      //  jic $at, 0
      // $fallthrough:

      // We assume the branch is within-function, and that offset is within
      // +/- 2GB.  High 32 bits will therefore always be zero.

      // Note that this will work even if the offset is negative, because
      // of the +1 modification that's added in that case.  For example, if the
      // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is
      //
      // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000
      //
      // and the bits [47:32] are zero.  For %highest
      //
      // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000
      //
      // and the bits [63:48] are zero.

      Pos = LongBrMBB->begin();

      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
        .addReg(Mips::SP_64).addImm(-16);
      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
        .addReg(Mips::SP_64).addImm(0);
      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),
              Mips::AT_64).addReg(Mips::ZERO_64)
                          .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB);
      BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
        .addReg(Mips::AT_64).addImm(16);

      MachineInstrBuilder BalInstr =
          BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB);
      MachineInstrBuilder DADDiuInstr =
          BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)
              .addReg(Mips::AT_64)
              .addMBB(TgtMBB, MipsII::MO_ABS_LO)
              .addMBB(BalTgtMBB);
      if (Subtarget.hasMips32r6()) {
        LongBrMBB->insert(Pos, DADDiuInstr);
        LongBrMBB->insert(Pos, BalInstr);
      } else {
        LongBrMBB->insert(Pos, BalInstr);
        LongBrMBB->insert(Pos, DADDiuInstr);
        LongBrMBB->rbegin()->bundleWithPred();
      }

      Pos = BalTgtMBB->begin();

      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
        .addReg(Mips::RA_64).addReg(Mips::AT_64);
      BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
        .addReg(Mips::SP_64).addImm(0);

      if (Subtarget.hasMips64r6() && !Subtarget.useIndirectJumpsHazard()) {
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
            .addReg(Mips::SP_64)
            .addImm(16);
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64))
            .addReg(Mips::AT_64)
            .addImm(0);
      } else {
        unsigned JROp =
            Subtarget.useIndirectJumpsHazard()
                ? (Subtarget.hasMips32r6() ? Mips::JR_HB64_R6 : Mips::JR_HB64)
                : Mips::JR64;
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT_64);
        BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
            .addReg(Mips::SP_64)
            .addImm(16);
        BalTgtMBB->rbegin()->bundleWithPred();
      }
    }

    assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize);
  } else {
    // Pre R6:                  R6:
    // $longbr:                 $longbr:
    //  j $tgt                   bc $tgt
    //  nop                     $fallthrough
    // $fallthrough:
    //
    Pos = LongBrMBB->begin();
    LongBrMBB->addSuccessor(TgtMBB);
    if (Subtarget.hasMips32r6())
      BuildMI(*LongBrMBB, Pos, DL,
              TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC))
          .addMBB(TgtMBB);
    else
      MIBundleBuilder(*LongBrMBB, Pos)
        .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
        .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));

    assert(LongBrMBB->size() == LongBranchSeqSize);
  }

  if (I.Br->isUnconditionalBranch()) {
    // Change branch destination.
    assert(I.Br->getDesc().getNumOperands() == 1);
    I.Br->RemoveOperand(0);
    I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
  } else
    // Change branch destination and reverse condition.
    replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB);
}
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
  bool AnyChanges = false;
  MRI = &MF.getRegInfo();
  TRI = MF.getTarget().getRegisterInfo();
  TII = MF.getTarget().getInstrInfo();

  // Treat reserved registers as always live.
  BitVector ReservedRegs = TRI->getReservedRegs(MF);

  // Loop over all instructions in all blocks, from bottom to top, so that it's
  // more likely that chains of dependent but ultimately dead instructions will
  // be cleaned up.
  for (MachineFunction::reverse_iterator I = MF.rbegin(), E = MF.rend();
       I != E; ++I) {
    MachineBasicBlock *MBB = &*I;

    // Start out assuming that reserved registers are live out of this block.
    LivePhysRegs = ReservedRegs;

    // Also add any explicit live-out physregs for this block.
    if (!MBB->empty() && MBB->back().getDesc().isReturn())
      for (MachineRegisterInfo::liveout_iterator LOI = MRI->liveout_begin(),
           LOE = MRI->liveout_end(); LOI != LOE; ++LOI) {
        unsigned Reg = *LOI;
        if (TargetRegisterInfo::isPhysicalRegister(Reg))
          LivePhysRegs.set(Reg);
      }

    // FIXME: Add live-ins from sucessors to LivePhysRegs. Normally, physregs
    // are not live across blocks, but some targets (x86) can have flags live
    // out of a block.

    // Now scan the instructions and delete dead ones, tracking physreg
    // liveness as we go.
    for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(),
         MIE = MBB->rend(); MII != MIE; ) {
      MachineInstr *MI = &*MII;

      // If the instruction is dead, delete it!
      if (isDead(MI)) {
        DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
        // It is possible that some DBG_VALUE instructions refer to this
        // instruction.  Examine each def operand for such references;
        // if found, mark the DBG_VALUE as undef (but don't delete it).
        for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
          const MachineOperand &MO = MI->getOperand(i);
          if (!MO.isReg() || !MO.isDef())
            continue;
          unsigned Reg = MO.getReg();
          if (!TargetRegisterInfo::isVirtualRegister(Reg))
            continue;
          MachineRegisterInfo::use_iterator nextI;
          for (MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg),
               E = MRI->use_end(); I!=E; I=nextI) {
            nextI = llvm::next(I);  // I is invalidated by the setReg
            MachineOperand& Use = I.getOperand();
            MachineInstr *UseMI = Use.getParent();
            if (UseMI==MI)
              continue;
            assert(Use.isDebug());
            UseMI->getOperand(0).setReg(0U);
          }
        }
        AnyChanges = true;
        MI->eraseFromParent();
        ++NumDeletes;
        MIE = MBB->rend();
        // MII is now pointing to the next instruction to process,
        // so don't increment it.
        continue;
      }

      // Record the physreg defs.
      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
        const MachineOperand &MO = MI->getOperand(i);
        if (MO.isReg() && MO.isDef()) {
          unsigned Reg = MO.getReg();
          if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) {
            LivePhysRegs.reset(Reg);
            // Check the subreg set, not the alias set, because a def
            // of a super-register may still be partially live after
            // this def.
            for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
                 *SubRegs; ++SubRegs)
              LivePhysRegs.reset(*SubRegs);
          }
        }
      }
      // Record the physreg uses, after the defs, in case a physreg is
      // both defined and used in the same instruction.
      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
        const MachineOperand &MO = MI->getOperand(i);
        if (MO.isReg() && MO.isUse()) {
          unsigned Reg = MO.getReg();
          if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) {
            LivePhysRegs.set(Reg);
            for (const unsigned *AliasSet = TRI->getAliasSet(Reg);
                 *AliasSet; ++AliasSet)
              LivePhysRegs.set(*AliasSet);
          }
        }
      }

      // We didn't delete the current instruction, so increment MII to
      // the next one.
      ++MII;
    }
  }

  LivePhysRegs.clear();
  return AnyChanges;
}
Пример #14
0
bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
                                         MachineFunction &MF,
                                         const TargetRegisterInfo *TRI,
                                         const TargetInstrInfo *TII) {
  SmallPtrSet<MachineBasicBlock *, 2> SinkableBBs;
  // FIXME: For now, we sink only to a successor which has a single predecessor
  // so that we can directly sink COPY instructions to the successor without
  // adding any new block or branch instruction.
  for (MachineBasicBlock *SI : CurBB.successors())
    if (!SI->livein_empty() && SI->pred_size() == 1)
      SinkableBBs.insert(SI);

  if (SinkableBBs.empty())
    return false;

  bool Changed = false;

  // Track which registers have been modified and used between the end of the
  // block and the current instruction.
  ModifiedRegUnits.clear();
  UsedRegUnits.clear();

  for (auto I = CurBB.rbegin(), E = CurBB.rend(); I != E;) {
    MachineInstr *MI = &*I;
    ++I;

    if (MI->isDebugInstr())
      continue;

    // Do not move any instruction across function call.
    if (MI->isCall())
      return false;

    if (!MI->isCopy() || !MI->getOperand(0).isRenamable()) {
      LiveRegUnits::accumulateUsedDefed(*MI, ModifiedRegUnits, UsedRegUnits,
                                        TRI);
      continue;
    }

    // Track the operand index for use in Copy.
    SmallVector<unsigned, 2> UsedOpsInCopy;
    // Track the register number defed in Copy.
    SmallVector<unsigned, 2> DefedRegsInCopy;

    // Don't sink the COPY if it would violate a register dependency.
    if (hasRegisterDependency(MI, UsedOpsInCopy, DefedRegsInCopy,
                              ModifiedRegUnits, UsedRegUnits)) {
      LiveRegUnits::accumulateUsedDefed(*MI, ModifiedRegUnits, UsedRegUnits,
                                        TRI);
      continue;
    }
    assert((!UsedOpsInCopy.empty() && !DefedRegsInCopy.empty()) &&
           "Unexpect SrcReg or DefReg");
    MachineBasicBlock *SuccBB =
        getSingleLiveInSuccBB(CurBB, SinkableBBs, DefedRegsInCopy, TRI);
    // Don't sink if we cannot find a single sinkable successor in which Reg
    // is live-in.
    if (!SuccBB) {
      LiveRegUnits::accumulateUsedDefed(*MI, ModifiedRegUnits, UsedRegUnits,
                                        TRI);
      continue;
    }
    assert((SuccBB->pred_size() == 1 && *SuccBB->pred_begin() == &CurBB) &&
           "Unexpected predecessor");

    // Clear the kill flag if SrcReg is killed between MI and the end of the
    // block.
    clearKillFlags(MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI);
    MachineBasicBlock::iterator InsertPos = SuccBB->getFirstNonPHI();
    performSink(*MI, *SuccBB, InsertPos);
    updateLiveIn(MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);

    Changed = true;
    ++NumPostRACopySink;
  }
  return Changed;
}
Пример #15
0
bool PPCQPXLoadSplat::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(*MF.getFunction()))
    return false;

  bool MadeChange = false;
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();

  for (auto MFI = MF.begin(), MFIE = MF.end(); MFI != MFIE; ++MFI) {
    MachineBasicBlock *MBB = &*MFI;
    SmallVector<MachineInstr *, 4> Splats;

    for (auto MBBI = MBB->rbegin(); MBBI != MBB->rend(); ++MBBI) {
      MachineInstr *MI = &*MBBI;

      if (MI->hasUnmodeledSideEffects() || MI->isCall()) {
        Splats.clear();
        continue;
      }

      // We're looking for a sequence like this:
      // %F0<def> = LFD 0, %X3<kill>, %QF0<imp-def>; mem:LD8[%a](tbaa=!2)
      // %QF1<def> = QVESPLATI %QF0<kill>, 0, %RM<imp-use>

      for (auto SI = Splats.begin(); SI != Splats.end();) {
        MachineInstr *SMI = *SI;
        unsigned SplatReg = SMI->getOperand(0).getReg();
        unsigned SrcReg = SMI->getOperand(1).getReg();

        if (MI->modifiesRegister(SrcReg, TRI)) {
          switch (MI->getOpcode()) {
          default:
            SI = Splats.erase(SI);
            continue;
          case PPC::LFS:
          case PPC::LFD:
          case PPC::LFSU:
          case PPC::LFDU:
          case PPC::LFSUX:
          case PPC::LFDUX:
          case PPC::LFSX:
          case PPC::LFDX:
          case PPC::LFIWAX:
          case PPC::LFIWZX:
            if (SplatReg != SrcReg) {
              // We need to change the load to define the scalar subregister of
              // the QPX splat source register.
              unsigned SubRegIndex =
                TRI->getSubRegIndex(SrcReg, MI->getOperand(0).getReg());
              unsigned SplatSubReg = TRI->getSubReg(SplatReg, SubRegIndex);

              // Substitute both the explicit defined register, and also the
              // implicit def of the containing QPX register.
              MI->getOperand(0).setReg(SplatSubReg);
              MI->substituteRegister(SrcReg, SplatReg, 0, *TRI);
            }

            SI = Splats.erase(SI);

            // If SMI is directly after MI, then MBBI's base iterator is
            // pointing at SMI.  Adjust MBBI around the call to erase SMI to
            // avoid invalidating MBBI.
            ++MBBI;
            SMI->eraseFromParent();
            --MBBI;

            ++NumSimplified;
            MadeChange = true;
            continue;
          }
        }

        // If this instruction defines the splat register, then we cannot move
        // the previous definition above it. If it reads from the splat
        // register, then it must already be alive from some previous
        // definition, and if the splat register is different from the source
        // register, then this definition must not be the load for which we're
        // searching.
        if (MI->modifiesRegister(SplatReg, TRI) ||
            (SrcReg != SplatReg &&
             MI->readsRegister(SplatReg, TRI))) {
          SI = Splats.erase(SI);
          continue;
        }

        ++SI;
      }

      if (MI->getOpcode() != PPC::QVESPLATI &&
          MI->getOpcode() != PPC::QVESPLATIs &&
          MI->getOpcode() != PPC::QVESPLATIb)
        continue;
      if (MI->getOperand(2).getImm() != 0)
        continue;

      // If there are other uses of the scalar value after this, replacing
      // those uses might be non-trivial.
      if (!MI->getOperand(1).isKill())
        continue;

      Splats.push_back(MI);
    }
  }

  return MadeChange;
}
Пример #16
0
bool CoffeeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
                                 MachineBasicBlock *&FBB,
                                 SmallVectorImpl<MachineOperand> &Cond,
                                 bool AllowModify) const {

    MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();

    // Skip all the debug instructions.
    while (I != REnd && I->isDebugValue())
      ++I;

    if (I == REnd || !isUnpredicatedTerminator(&*I)) {
      // If this block ends with no branches (it just falls through to its succ)
      // just return false, leaving TBB/FBB null.
      TBB = FBB = NULL;
      return false;
    }

    MachineInstr *LastInst = &*I;
    unsigned LastOpc = LastInst->getOpcode();

    // Not an analyzable branch (must be an indirect jump).
    if (!GetAnalyzableBrOpc(LastOpc))
      return true;

    // Get the second to last instruction in the block.
    unsigned SecondLastOpc = 0;
    MachineInstr *SecondLastInst = NULL;

    if (++I != REnd) {
      SecondLastInst = &*I;
      SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode());

      // Not an analyzable branch (must be an indirect jump).
      if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
        return true;
    }

    // If there is only one terminator instruction, process it.
    if (!SecondLastOpc) {
      // Unconditional branch
      if (LastOpc == UncondBrOpc) {
        TBB = LastInst->getOperand(0).getMBB();
        return false;
      }

      // Conditional branch
      AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
      return false;
    }

    // If we reached here, there are two branches.
    // If there are three terminators, we don't know what sort of block this is.
    if (++I != REnd && isUnpredicatedTerminator(&*I))
      return true;

    // If second to last instruction is an unconditional branch,
    // analyze it and remove the last instruction.
    if (SecondLastOpc == UncondBrOpc) {
      // Return if the last instruction cannot be removed.
      if (!AllowModify)
        return true;

      TBB = SecondLastInst->getOperand(0).getMBB();
      LastInst->eraseFromParent();
      return false;
    }

    // Conditional branch followed by an unconditional branch.
    // The last one must be unconditional.
    if (LastOpc != UncondBrOpc)
      return true;

    AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
    FBB = LastInst->getOperand(0).getMBB();

    return false;
  }
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
    if (skipOptnoneFunction(*MF.getFunction()))
        return false;

    bool AnyChanges = false;
    MRI = &MF.getRegInfo();
    TRI = MF.getSubtarget().getRegisterInfo();
    TII = MF.getSubtarget().getInstrInfo();

    // Loop over all instructions in all blocks, from bottom to top, so that it's
    // more likely that chains of dependent but ultimately dead instructions will
    // be cleaned up.
    for (MachineFunction::reverse_iterator I = MF.rbegin(), E = MF.rend();
            I != E; ++I) {
        MachineBasicBlock *MBB = &*I;

        // Start out assuming that reserved registers are live out of this block.
        LivePhysRegs = MRI->getReservedRegs();

        // Add live-ins from sucessors to LivePhysRegs. Normally, physregs are not
        // live across blocks, but some targets (x86) can have flags live out of a
        // block.
        for (MachineBasicBlock::succ_iterator S = MBB->succ_begin(),
                E = MBB->succ_end(); S != E; S++)
            for (MachineBasicBlock::livein_iterator LI = (*S)->livein_begin();
                    LI != (*S)->livein_end(); LI++)
                LivePhysRegs.set(*LI);

        // Now scan the instructions and delete dead ones, tracking physreg
        // liveness as we go.
        for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(),
                MIE = MBB->rend(); MII != MIE; ) {
            MachineInstr *MI = &*MII;

            // If the instruction is dead, delete it!
            if (isDead(MI)) {
                DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
                // It is possible that some DBG_VALUE instructions refer to this
                // instruction.  They get marked as undef and will be deleted
                // in the live debug variable analysis.
                MI->eraseFromParentAndMarkDBGValuesForRemoval();
                AnyChanges = true;
                ++NumDeletes;
                MIE = MBB->rend();
                // MII is now pointing to the next instruction to process,
                // so don't increment it.
                continue;
            }

            // Record the physreg defs.
            for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
                const MachineOperand &MO = MI->getOperand(i);
                if (MO.isReg() && MO.isDef()) {
                    unsigned Reg = MO.getReg();
                    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
                        // Check the subreg set, not the alias set, because a def
                        // of a super-register may still be partially live after
                        // this def.
                        for (MCSubRegIterator SR(Reg, TRI,/*IncludeSelf=*/true);
                                SR.isValid(); ++SR)
                            LivePhysRegs.reset(*SR);
                    }
                } else if (MO.isRegMask()) {
                    // Register mask of preserved registers. All clobbers are dead.
                    LivePhysRegs.clearBitsNotInMask(MO.getRegMask());
                }
            }
            // Record the physreg uses, after the defs, in case a physreg is
            // both defined and used in the same instruction.
            for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
                const MachineOperand &MO = MI->getOperand(i);
                if (MO.isReg() && MO.isUse()) {
                    unsigned Reg = MO.getReg();
                    if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
                        for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
                            LivePhysRegs.set(*AI);
                    }
                }
            }

            // We didn't delete the current instruction, so increment MII to
            // the next one.
            ++MII;
        }
    }

    LivePhysRegs.clear();
    return AnyChanges;
}