本文整理汇总了C++中machinebasicblock::iterator::isTerminator方法的典型用法代码示例。如果您正苦于以下问题:C++ iterator::isTerminator方法的具体用法?C++ iterator::isTerminator怎么用?C++ iterator::isTerminator使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类machinebasicblock::iterator
的用法示例。
在下文中一共展示了iterator::isTerminator方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: findInsertionPoint
/// Find an insertion point in Head for the speculated instructions. The
/// insertion point must be:
///
/// 1. Before any terminators.
/// 2. After any instructions in InsertAfter.
/// 3. Not have any clobbered regunits live.
///
/// This function sets InsertionPoint and returns true when successful, it
/// returns false if no valid insertion point could be found.
///
bool SSAIfConv::findInsertionPoint() {
// Keep track of live regunits before the current position.
// Only track RegUnits that are also in ClobberedRegUnits.
LiveRegUnits.clear();
SmallVector<unsigned, 8> Reads;
MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
MachineBasicBlock::iterator I = Head->end();
MachineBasicBlock::iterator B = Head->begin();
while (I != B) {
--I;
// Some of the conditional code depends in I.
if (InsertAfter.count(I)) {
DEBUG(dbgs() << "Can't insert code after " << *I);
return false;
}
// Update live regunits.
for (MIOperands MO(I); MO.isValid(); ++MO) {
// We're ignoring regmask operands. That is conservatively correct.
if (!MO->isReg())
continue;
unsigned Reg = MO->getReg();
if (!TargetRegisterInfo::isPhysicalRegister(Reg))
continue;
// I clobbers Reg, so it isn't live before I.
if (MO->isDef())
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
LiveRegUnits.erase(*Units);
// Unless I reads Reg.
if (MO->readsReg())
Reads.push_back(Reg);
}
// Anything read by I is live before I.
while (!Reads.empty())
for (MCRegUnitIterator Units(Reads.pop_back_val(), TRI); Units.isValid();
++Units)
if (ClobberedRegUnits.test(*Units))
LiveRegUnits.insert(*Units);
// We can't insert before a terminator.
if (I != FirstTerm && I->isTerminator())
continue;
// Some of the clobbered registers are live before I, not a valid insertion
// point.
if (!LiveRegUnits.empty()) {
DEBUG({
dbgs() << "Would clobber";
for (SparseSet<unsigned>::const_iterator
i = LiveRegUnits.begin(), e = LiveRegUnits.end(); i != e; ++i)
dbgs() << ' ' << PrintRegUnit(*i, TRI);
dbgs() << " live before " << *I;
});
continue;
}
示例2: initMBBInfo
// Fill MBBs and Terminators, setting the addresses on the assumption
// that no branches need relaxation. Return the size of the function under
// this assumption.
uint64_t SystemZLongBranch::initMBBInfo() {
MF->RenumberBlocks();
unsigned NumBlocks = MF->size();
MBBs.clear();
MBBs.resize(NumBlocks);
Terminators.clear();
Terminators.reserve(NumBlocks);
BlockPosition Position(MF->getAlignment());
for (unsigned I = 0; I < NumBlocks; ++I) {
MachineBasicBlock *MBB = MF->getBlockNumbered(I);
MBBInfo &Block = MBBs[I];
// Record the alignment, for quick access.
Block.Alignment = MBB->getAlignment();
// Calculate the size of the fixed part of the block.
MachineBasicBlock::iterator MI = MBB->begin();
MachineBasicBlock::iterator End = MBB->end();
while (MI != End && !MI->isTerminator()) {
Block.Size += TII->getInstSizeInBytes(*MI);
++MI;
}
skipNonTerminators(Position, Block);
// Add the terminators.
while (MI != End) {
if (!MI->isDebugValue()) {
assert(MI->isTerminator() && "Terminator followed by non-terminator");
Terminators.push_back(describeTerminator(*MI));
skipTerminator(Position, Terminators.back(), false);
++Block.NumTerminators;
}
++MI;
}
}
return Position.Address;
}
示例3: assert
// 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;
}
示例4: FindSafePoints
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);
}
}
示例5: switch
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;
}
示例6: assert
// 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;
// Since we may modify cmp of this MBB, make sure NZCV does not live out.
for (auto SuccBB : MBB->successors())
if (SuccBB->isLiveIn(AArch64::NZCV))
return nullptr;
// Now find the instruction controlling the terminator.
for (MachineBasicBlock::iterator B = MBB->begin(); I != B;) {
--I;
assert(!I->isTerminator() && "Spurious terminator");
// Check if there is any use of NZCV between CMP and Bcc.
if (I->readsRegister(AArch64::NZCV))
return nullptr;
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: {
unsigned ShiftAmt = AArch64_AM::getShiftValue(I->getOperand(3).getImm());
if (!I->getOperand(2).isImm()) {
DEBUG(dbgs() << "Immediate of cmp is symbolic, " << *I << '\n');
return nullptr;
} else if (I->getOperand(2).getImm() << ShiftAmt >= 0xfff) {
DEBUG(dbgs() << "Immediate of cmp may be out of range, " << *I << '\n');
return nullptr;
} else if (!MRI->use_empty(I->getOperand(0).getReg())) {
DEBUG(dbgs() << "Destination of cmp is not dead, " << *I << '\n');
return nullptr;
}
return I;
}
// 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;
}
示例7: trackRegDefs
bool AArch64RedundantCopyElimination::optimizeBlock(MachineBasicBlock *MBB) {
// Check if the current basic block has a single predecessor.
if (MBB->pred_size() != 1)
return false;
// Check if the predecessor has two successors, implying the block ends in a
// conditional branch.
MachineBasicBlock *PredMBB = *MBB->pred_begin();
if (PredMBB->succ_size() != 2)
return false;
MachineBasicBlock::iterator CondBr = PredMBB->getLastNonDebugInstr();
if (CondBr == PredMBB->end())
return false;
// Keep track of the earliest point in the PredMBB block where kill markers
// need to be removed if a COPY is removed.
MachineBasicBlock::iterator FirstUse;
// After calling knownRegValInBlock, FirstUse will either point to a CBZ/CBNZ
// or a compare (i.e., SUBS). In the latter case, we must take care when
// updating FirstUse when scanning for COPY instructions. In particular, if
// there's a COPY in between the compare and branch the COPY should not
// update FirstUse.
bool SeenFirstUse = false;
// Registers that contain a known value at the start of MBB.
SmallVector<RegImm, 4> KnownRegs;
MachineBasicBlock::iterator Itr = std::next(CondBr);
do {
--Itr;
if (!knownRegValInBlock(*Itr, MBB, KnownRegs, FirstUse))
continue;
// Reset the clobber list.
OptBBClobberedRegs.reset();
// Look backward in PredMBB for COPYs from the known reg to find other
// registers that are known to be a constant value.
for (auto PredI = Itr;; --PredI) {
if (FirstUse == PredI)
SeenFirstUse = true;
if (PredI->isCopy()) {
MCPhysReg CopyDstReg = PredI->getOperand(0).getReg();
MCPhysReg CopySrcReg = PredI->getOperand(1).getReg();
for (auto &KnownReg : KnownRegs) {
if (OptBBClobberedRegs[KnownReg.Reg])
continue;
// If we have X = COPY Y, and Y is known to be zero, then now X is
// known to be zero.
if (CopySrcReg == KnownReg.Reg && !OptBBClobberedRegs[CopyDstReg]) {
KnownRegs.push_back(RegImm(CopyDstReg, KnownReg.Imm));
if (SeenFirstUse)
FirstUse = PredI;
break;
}
// If we have X = COPY Y, and X is known to be zero, then now Y is
// known to be zero.
if (CopyDstReg == KnownReg.Reg && !OptBBClobberedRegs[CopySrcReg]) {
KnownRegs.push_back(RegImm(CopySrcReg, KnownReg.Imm));
if (SeenFirstUse)
FirstUse = PredI;
break;
}
}
}
// Stop if we get to the beginning of PredMBB.
if (PredI == PredMBB->begin())
break;
trackRegDefs(*PredI, OptBBClobberedRegs, TRI);
// Stop if all of the known-zero regs have been clobbered.
if (all_of(KnownRegs, [&](RegImm KnownReg) {
return OptBBClobberedRegs[KnownReg.Reg];
}))
break;
}
break;
} while (Itr != PredMBB->begin() && Itr->isTerminator());
// We've not found a registers with a known value, time to bail out.
if (KnownRegs.empty())
return false;
bool Changed = false;
// UsedKnownRegs is the set of KnownRegs that have had uses added to MBB.
SmallSetVector<unsigned, 4> UsedKnownRegs;
MachineBasicBlock::iterator LastChange = MBB->begin();
// Remove redundant copy/move instructions unless KnownReg is modified.
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) {
MachineInstr *MI = &*I;
++I;
bool RemovedMI = false;
bool IsCopy = MI->isCopy();
bool IsMoveImm = MI->isMoveImmediate();
if (IsCopy || IsMoveImm) {
MCPhysReg DefReg = MI->getOperand(0).getReg();
//.........这里部分代码省略.........
示例8: emitEpilogue
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);
}
示例9: insertCSRSpillsAndRestores
/// 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.
//.........这里部分代码省略.........
示例10: while
bool AArch64RedundantCopyElimination::optimizeCopy(MachineBasicBlock *MBB) {
// Check if the current basic block has a single predecessor.
if (MBB->pred_size() != 1)
return false;
MachineBasicBlock *PredMBB = *MBB->pred_begin();
MachineBasicBlock::iterator CompBr = PredMBB->getLastNonDebugInstr();
if (CompBr == PredMBB->end() || PredMBB->succ_size() != 2)
return false;
++CompBr;
do {
--CompBr;
if (guaranteesZeroRegInBlock(*CompBr, MBB))
break;
} while (CompBr != PredMBB->begin() && CompBr->isTerminator());
// We've not found a CBZ/CBNZ, time to bail out.
if (!guaranteesZeroRegInBlock(*CompBr, MBB))
return false;
unsigned TargetReg = CompBr->getOperand(0).getReg();
if (!TargetReg)
return false;
assert(TargetRegisterInfo::isPhysicalRegister(TargetReg) &&
"Expect physical register");
// Remember all registers aliasing with TargetReg.
SmallSetVector<unsigned, 8> TargetRegs;
for (MCRegAliasIterator AI(TargetReg, TRI, true); AI.isValid(); ++AI)
TargetRegs.insert(*AI);
bool Changed = false;
MachineBasicBlock::iterator LastChange = MBB->begin();
unsigned SmallestDef = TargetReg;
// Remove redundant Copy instructions unless TargetReg is modified.
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;) {
MachineInstr *MI = &*I;
++I;
if (MI->isCopy() && MI->getOperand(0).isReg() &&
MI->getOperand(1).isReg()) {
unsigned DefReg = MI->getOperand(0).getReg();
unsigned SrcReg = MI->getOperand(1).getReg();
if ((SrcReg == AArch64::XZR || SrcReg == AArch64::WZR) &&
!MRI->isReserved(DefReg) &&
(TargetReg == DefReg || TRI->isSuperRegister(DefReg, TargetReg))) {
DEBUG(dbgs() << "Remove redundant Copy : ");
DEBUG((MI)->print(dbgs()));
MI->eraseFromParent();
Changed = true;
LastChange = I;
NumCopiesRemoved++;
SmallestDef =
TRI->isSubRegister(SmallestDef, DefReg) ? DefReg : SmallestDef;
continue;
}
}
if (MI->modifiesRegister(TargetReg, TRI))
break;
}
if (!Changed)
return false;
// Otherwise, we have to fixup the use-def chain, starting with the
// CBZ/CBNZ. Conservatively mark as much as we can live.
CompBr->clearRegisterKills(SmallestDef, TRI);
if (std::none_of(TargetRegs.begin(), TargetRegs.end(),
[&](unsigned Reg) { return MBB->isLiveIn(Reg); }))
MBB->addLiveIn(TargetReg);
// Clear any kills of TargetReg between CompBr and the last removed COPY.
for (MachineInstr &MMI :
make_range(MBB->begin()->getIterator(), LastChange->getIterator()))
MMI.clearRegisterKills(SmallestDef, TRI);
return true;
}
示例11: switch
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.getSubtarget().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 FP.
BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP);
} else
NumBytes = StackSize - CSSize;
// Skip the callee-saved pop instructions.
while (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PI = std::prev(MBBI);
unsigned Opc = PI->getOpcode();
if (Opc != MSP430::POP16r && !PI->isTerminator())
break;
--MBBI;
}
DL = MBBI->getDebugLoc();
// If there is an ADD16ri or SUB16ri of SP 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::SP).addReg(MSP430::FP);
if (CSSize) {
MachineInstr *MI =
BuildMI(MBB, MBBI, DL,
TII.get(MSP430::SUB16ri), MSP430::SP)
.addReg(MSP430::SP).addImm(CSSize);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
} else {
// adjust stack pointer back: SP += numbytes
if (NumBytes) {
MachineInstr *MI =
BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
.addReg(MSP430::SP).addImm(NumBytes);
// The SRW implicit def is dead.
MI->getOperand(3).setIsDead();
}
}
}
示例12: analyzeBranch
bool ARCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
TBB = FBB = nullptr;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin())
return false;
--I;
while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
// Flag to be raised on unanalyzeable instructions. This is useful in cases
// where we want to clean up on the end of the basic block before we bail
// out.
bool CantAnalyze = false;
// Skip over DEBUG values and predicated nonterminators.
while (I->isDebugValue() || !I->isTerminator()) {
if (I == MBB.begin())
return false;
--I;
}
if (isJumpOpcode(I->getOpcode())) {
// Indirect branches and jump tables can't be analyzed, but we still want
// to clean up any instructions at the tail of the basic block.
CantAnalyze = true;
} else if (isUncondBranchOpcode(I->getOpcode())) {
TBB = I->getOperand(0).getMBB();
} else if (isCondBranchOpcode(I->getOpcode())) {
// Bail out if we encounter multiple conditional branches.
if (!Cond.empty())
return true;
assert(!FBB && "FBB should have been null.");
FBB = TBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(I->getOperand(1));
Cond.push_back(I->getOperand(2));
Cond.push_back(I->getOperand(3));
} else if (I->isReturn()) {
// Returns can't be analyzed, but we should run cleanup.
CantAnalyze = !isPredicated(*I);
} else {
// We encountered other unrecognized terminator. Bail out immediately.
return true;
}
// Cleanup code - to be run for unpredicated unconditional branches and
// returns.
if (!isPredicated(*I) && (isUncondBranchOpcode(I->getOpcode()) ||
isJumpOpcode(I->getOpcode()) || I->isReturn())) {
// Forget any previous condition branch information - it no longer
// applies.
Cond.clear();
FBB = nullptr;
// If we can modify the function, delete everything below this
// unconditional branch.
if (AllowModify) {
MachineBasicBlock::iterator DI = std::next(I);
while (DI != MBB.end()) {
MachineInstr &InstToDelete = *DI;
++DI;
InstToDelete.eraseFromParent();
}
}
}
if (CantAnalyze)
return true;
if (I == MBB.begin())
return false;
--I;
}
// We made it past the terminators without bailing out - we must have
// analyzed this branch successfully.
return false;
}