// Finds compare instruction that corresponds to supported types of branching.
// Returns the instruction or nullptr on failures or detecting unsupported
// instructions.
MachineInstr *AArch64ConditionOptimizer::findSuitableCompare(
    MachineBasicBlock *MBB) {
  MachineBasicBlock::iterator I = MBB->getFirstTerminator();
  if (I == MBB->end())
    return nullptr;

  if (I->getOpcode() != AArch64::Bcc)
    return nullptr;

  // Now find the instruction controlling the terminator.
  for (MachineBasicBlock::iterator B = MBB->begin(); I != B;) {
    --I;
    assert(!I->isTerminator() && "Spurious terminator");
    switch (I->getOpcode()) {
    // cmp is an alias for subs with a dead destination register.
    case AArch64::SUBSWri:
    case AArch64::SUBSXri:
    // cmn is an alias for adds with a dead destination register.
    case AArch64::ADDSWri:
    case AArch64::ADDSXri:
      if (MRI->use_empty(I->getOperand(0).getReg()))
        return I;

      DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n');
      return nullptr;

    // Prevent false positive case like:
    // cmp      w19, #0
    // cinc     w0, w19, gt
    // ...
    // fcmp     d8, #0.0
    // b.gt     .LBB0_5
    case AArch64::FCMPDri:
    case AArch64::FCMPSri:
    case AArch64::FCMPESri:
    case AArch64::FCMPEDri:

    case AArch64::SUBSWrr:
    case AArch64::SUBSXrr:
    case AArch64::ADDSWrr:
    case AArch64::ADDSXrr:
    case AArch64::FCMPSrr:
    case AArch64::FCMPDrr:
    case AArch64::FCMPESrr:
    case AArch64::FCMPEDrr:
      // Skip comparison instructions without immediate operands.
      return nullptr;
    }
  }
  DEBUG(dbgs() << "Flags not defined in BB#" << MBB->getNumber() << '\n');
  return nullptr;
}
Example #2
0
void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
  for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE;
       ++BBI)
    for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end();
         MI != ME; ++MI)
      if (MI->isCall()) {
        // Do not treat tail or sibling call sites as safe points.  This is
        // legal since any arguments passed to the callee which live in the
        // remnants of the callers frame will be owned and updated by the
        // callee if required.
        if (MI->isTerminator())
          continue;
        VisitCallPoint(MI);
      }
}
MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) {
  MachineBasicBlock::iterator I = MBB->getFirstTerminator();
  if (I == MBB->end())
    return nullptr;
  // The terminator must be controlled by the flags.
  if (!I->readsRegister(AArch64::NZCV)) {
    switch (I->getOpcode()) {
    case AArch64::CBZW:
    case AArch64::CBZX:
    case AArch64::CBNZW:
    case AArch64::CBNZX:
      // These can be converted into a ccmp against #0.
      return I;
    }
    ++NumCmpTermRejs;
    DEBUG(dbgs() << "Flags not used by terminator: " << *I);
    return nullptr;
  }

  // Now find the instruction controlling the terminator.
  for (MachineBasicBlock::iterator B = MBB->begin(); I != B;) {
    --I;
    assert(!I->isTerminator() && "Spurious terminator");
    switch (I->getOpcode()) {
    // cmp is an alias for subs with a dead destination register.
    case AArch64::SUBSWri:
    case AArch64::SUBSXri:
    // cmn is an alias for adds with a dead destination register.
    case AArch64::ADDSWri:
    case AArch64::ADDSXri:
      // Check that the immediate operand is within range, ccmp wants a uimm5.
      // Rd = SUBSri Rn, imm, shift
      if (I->getOperand(3).getImm() || !isUInt<5>(I->getOperand(2).getImm())) {
        DEBUG(dbgs() << "Immediate out of range for ccmp: " << *I);
        ++NumImmRangeRejs;
        return nullptr;
      }
    // Fall through.
    case AArch64::SUBSWrr:
    case AArch64::SUBSXrr:
    case AArch64::ADDSWrr:
    case AArch64::ADDSXrr:
      if (isDeadDef(I->getOperand(0).getReg()))
        return I;
      DEBUG(dbgs() << "Can't convert compare with live destination: " << *I);
      ++NumLiveDstRejs;
      return nullptr;
    case AArch64::FCMPSrr:
    case AArch64::FCMPDrr:
    case AArch64::FCMPESrr:
    case AArch64::FCMPEDrr:
      return I;
    }

    // Check for flag reads and clobbers.
    MIOperands::PhysRegInfo PRI =
        MIOperands(I).analyzePhysReg(AArch64::NZCV, TRI);

    if (PRI.Reads) {
      // The ccmp doesn't produce exactly the same flags as the original
      // compare, so reject the transform if there are uses of the flags
      // besides the terminators.
      DEBUG(dbgs() << "Can't create ccmp with multiple uses: " << *I);
      ++NumMultNZCVUses;
      return nullptr;
    }

    if (PRI.Clobbers) {
      DEBUG(dbgs() << "Not convertible compare: " << *I);
      ++NumUnknNZCVDefs;
      return nullptr;
    }
  }
  DEBUG(dbgs() << "Flags not defined in BB#" << MBB->getNumber() << '\n');
  return nullptr;
}
Example #4
0
void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
                                    MachineBasicBlock &MBB) const {
  CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
  bool isHandler = (CallConv == CallingConv::AVR_INTR ||
                    CallConv == CallingConv::AVR_SIGNAL);

  // Early exit if the frame pointer is not needed in this function except for
  // signal/interrupt handlers where special code generation is required.
  if (!hasFP(MF) && !isHandler) {
    return;
  }

  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
  assert(MBBI->getDesc().isReturn() &&
         "Can only insert epilog into returning blocks");

  DebugLoc DL = MBBI->getDebugLoc();
  const MachineFrameInfo &MFI = MF.getFrameInfo();
  const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
  unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
  const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
  const AVRInstrInfo &TII = *STI.getInstrInfo();

  // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
  // handlers at the very end of the function, just before reti.
  if (isHandler) {
    BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0);
    BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
        .addImm(0x3f)
        .addReg(AVR::R0, RegState::Kill);
    BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0);
  }

  if (hasFP(MF))
    BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28);

  // Early exit if there is no need to restore the frame pointer.
  if (!FrameSize) {
    return;
  }

  // Skip the callee-saved pop instructions.
  while (MBBI != MBB.begin()) {
    MachineBasicBlock::iterator PI = std::prev(MBBI);
    int Opc = PI->getOpcode();

    if (Opc != AVR::POPRd && Opc != AVR::POPWRd && !PI->isTerminator()) {
      break;
    }

    --MBBI;
  }

  unsigned Opcode;

  // Select the optimal opcode depending on how big it is.
  if (isUInt<6>(FrameSize)) {
    Opcode = AVR::ADIWRdK;
  } else {
    Opcode = AVR::SUBIWRdK;
    FrameSize = -FrameSize;
  }

  // Restore the frame pointer by doing FP += <size>.
  MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28)
                         .addReg(AVR::R29R28, RegState::Kill)
                         .addImm(FrameSize);
  // The SREG implicit def is dead.
  MI->getOperand(3).setIsDead();

  // Write back R29R28 to SP and temporarily disable interrupts.
  BuildMI(MBB, MBBI, DL, TII.get(AVR::SPWRITE), AVR::SP)
      .addReg(AVR::R29R28, RegState::Kill);
}
Example #5
0
/// insertCSRSpillsAndRestores - Insert spill and restore code for
/// callee saved registers used in the function, handling shrink wrapping.
///
void PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
    // Get callee saved register information.
    MachineFrameInfo *MFI = Fn.getFrameInfo();
    const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();

    MFI->setCalleeSavedInfoValid(true);

    // Early exit if no callee saved registers are modified!
    if (CSI.empty())
        return;

    const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
    const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
    const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
    MachineBasicBlock::iterator I;

    if (!ShrinkWrapThisFunction) {
        // Spill using target interface.
        I = EntryBlock->begin();
        if (!TFI->spillCalleeSavedRegisters(*EntryBlock, I, CSI, TRI)) {
            for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
                // Add the callee-saved register as live-in.
                // It's killed at the spill.
                EntryBlock->addLiveIn(CSI[i].getReg());

                // Insert the spill to the stack frame.
                unsigned Reg = CSI[i].getReg();
                const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
                TII.storeRegToStackSlot(*EntryBlock, I, Reg, true,
                                        CSI[i].getFrameIdx(), RC, TRI);
            }
        }

        // Restore using target interface.
        for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) {
            MachineBasicBlock* MBB = ReturnBlocks[ri];
            I = MBB->end();
            --I;

            // Skip over all terminator instructions, which are part of the return
            // sequence.
            MachineBasicBlock::iterator I2 = I;
            while (I2 != MBB->begin() && (--I2)->isTerminator())
                I = I2;

            bool AtStart = I == MBB->begin();
            MachineBasicBlock::iterator BeforeI = I;
            if (!AtStart)
                --BeforeI;

            // Restore all registers immediately before the return and any
            // terminators that precede it.
            if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) {
                for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
                    unsigned Reg = CSI[i].getReg();
                    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
                    TII.loadRegFromStackSlot(*MBB, I, Reg,
                                             CSI[i].getFrameIdx(),
                                             RC, TRI);
                    assert(I != MBB->begin() &&
                           "loadRegFromStackSlot didn't insert any code!");
                    // Insert in reverse order.  loadRegFromStackSlot can insert
                    // multiple instructions.
                    if (AtStart)
                        I = MBB->begin();
                    else {
                        I = BeforeI;
                        ++I;
                    }
                }
            }
        }
        return;
    }

    // Insert spills.
    std::vector<CalleeSavedInfo> blockCSI;
    for (CSRegBlockMap::iterator BI = CSRSave.begin(),
            BE = CSRSave.end(); BI != BE; ++BI) {
        MachineBasicBlock* MBB = BI->first;
        CSRegSet save = BI->second;

        if (save.empty())
            continue;

        blockCSI.clear();
        for (CSRegSet::iterator RI = save.begin(),
                RE = save.end(); RI != RE; ++RI) {
            blockCSI.push_back(CSI[*RI]);
        }
        assert(blockCSI.size() > 0 &&
               "Could not collect callee saved register info");

        I = MBB->begin();

        // When shrink wrapping, use stack slot stores/loads.
        for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
            // Add the callee-saved register as live-in.
            // It's killed at the spill.
            MBB->addLiveIn(blockCSI[i].getReg());

            // Insert the spill to the stack frame.
            unsigned Reg = blockCSI[i].getReg();
            const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
            TII.storeRegToStackSlot(*MBB, I, Reg,
                                    true,
                                    blockCSI[i].getFrameIdx(),
                                    RC, TRI);
        }
    }

    for (CSRegBlockMap::iterator BI = CSRRestore.begin(),
            BE = CSRRestore.end(); BI != BE; ++BI) {
        MachineBasicBlock* MBB = BI->first;
        CSRegSet restore = BI->second;

        if (restore.empty())
            continue;

        blockCSI.clear();
        for (CSRegSet::iterator RI = restore.begin(),
                RE = restore.end(); RI != RE; ++RI) {
            blockCSI.push_back(CSI[*RI]);
        }
        assert(blockCSI.size() > 0 &&
               "Could not find callee saved register info");

        // If MBB is empty and needs restores, insert at the _beginning_.
        if (MBB->empty()) {
            I = MBB->begin();
        } else {
            I = MBB->end();
            --I;

            // Skip over all terminator instructions, which are part of the
            // return sequence.
            if (! I->isTerminator()) {
                ++I;
            } else {
                MachineBasicBlock::iterator I2 = I;
                while (I2 != MBB->begin() && (--I2)->isTerminator())
                    I = I2;
            }
        }

        bool AtStart = I == MBB->begin();
        MachineBasicBlock::iterator BeforeI = I;
        if (!AtStart)
            --BeforeI;

        // Restore all registers immediately before the return and any
        // terminators that precede it.
        for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) {
            unsigned Reg = blockCSI[i].getReg();
            const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
            TII.loadRegFromStackSlot(*MBB, I, Reg,
                                     blockCSI[i].getFrameIdx(),
                                     RC, TRI);
            assert(I != MBB->begin() &&
                   "loadRegFromStackSlot didn't insert any code!");
            // Insert in reverse order.  loadRegFromStackSlot can insert
            // multiple instructions.
            if (AtStart)
                I = MBB->begin();
            else {
                I = BeforeI;
                ++I;
            }
        }
    }
}
void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
    const MachineFrameInfo *MFI = MF.getFrameInfo();
    MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
    const MSP430InstrInfo &TII =
        *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());

    MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    unsigned RetOpcode = MBBI->getOpcode();
    DebugLoc DL = MBBI->getDebugLoc();

    switch (RetOpcode) {
    case MSP430::RET:
    case MSP430::RETI:
        break;  // These are ok
    default:
        llvm_unreachable("Can only insert epilog into returning blocks");
    }

    // Get the number of bytes to allocate from the FrameInfo
    uint64_t StackSize = MFI->getStackSize();
    unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
    uint64_t NumBytes = 0;

    if (hasFP(MF)) {
        // Calculate required stack adjustment
        uint64_t FrameSize = StackSize - 2;
        NumBytes = FrameSize - CSSize;

        // pop FPW.
        BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
    } else
        NumBytes = StackSize - CSSize;

    // Skip the callee-saved pop instructions.
    while (MBBI != MBB.begin()) {
        MachineBasicBlock::iterator PI = prior(MBBI);
        unsigned Opc = PI->getOpcode();
        if (Opc != MSP430::POP16r && !PI->isTerminator())
            break;
        --MBBI;
    }

    DL = MBBI->getDebugLoc();

    // If there is an ADD16ri or SUB16ri of SPW immediately before this
    // instruction, merge the two instructions.
    //if (NumBytes || MFI->hasVarSizedObjects())
    //  mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);

    if (MFI->hasVarSizedObjects()) {
        BuildMI(MBB, MBBI, DL,
                TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW);
        if (CSSize) {
            MachineInstr *MI =
                BuildMI(MBB, MBBI, DL,
                        TII.get(MSP430::SUB16ri), MSP430::SPW)
                .addReg(MSP430::SPW).addImm(CSSize);
            // The SRW implicit def is dead.
            MI->getOperand(3).setIsDead();
        }
    } else {
        // adjust stack pointer back: SPW += numbytes
        if (NumBytes) {
            MachineInstr *MI =
                BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
                .addReg(MSP430::SPW).addImm(NumBytes);
            // The SRW implicit def is dead.
            MI->getOperand(3).setIsDead();
        }
    }
}