本文整理汇总了C++中MachineBasicBlock::rend方法的典型用法代码示例。如果您正苦于以下问题:C++ MachineBasicBlock::rend方法的具体用法?C++ MachineBasicBlock::rend怎么用?C++ MachineBasicBlock::rend使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MachineBasicBlock
的用法示例。
在下文中一共展示了MachineBasicBlock::rend方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: removeBranch
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;
}
示例2: initMBBInfo
// 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();
}
}
示例3: findDelayInstr
bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
Iter &Filler) const {
RegDefsUses RegDU(TM);
RegDU.init(*Slot);
bool SawLoad = false;
bool SawStore = false;
for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
// skip debug value
if (I->isDebugValue())
continue;
if (terminateSearch(*I))
break;
if (delayHasHazard(*I, SawLoad, SawStore, RegDU))
continue;
Filler = llvm::next(I).base();
return true;
}
return false;
}
示例4: removeBranch
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;
}
示例5: runOnWWMInstruction
bool SIFixWWMLiveness::runOnWWMInstruction(MachineInstr &WWM) {
MachineBasicBlock *MBB = WWM.getParent();
// Compute the registers that are live out of MI by figuring out which defs
// are reachable from MI.
SparseBitVector<> LiveOut;
for (auto II = MachineBasicBlock::iterator(WWM), IE =
MBB->end(); II != IE; ++II) {
addDefs(*II, LiveOut);
}
for (df_iterator<MachineBasicBlock *> I = ++df_begin(MBB),
E = df_end(MBB);
I != E; ++I) {
for (const MachineInstr &MI : **I) {
addDefs(MI, LiveOut);
}
}
// Compute the registers that reach MI.
SparseBitVector<> Reachable;
for (auto II = ++MachineBasicBlock::reverse_iterator(WWM), IE =
MBB->rend(); II != IE; ++II) {
addDefs(*II, Reachable);
}
for (idf_iterator<MachineBasicBlock *> I = ++idf_begin(MBB),
E = idf_end(MBB);
I != E; ++I) {
for (const MachineInstr &MI : **I) {
addDefs(MI, Reachable);
}
}
// find the intersection, and add implicit uses.
LiveOut &= Reachable;
bool Modified = false;
for (unsigned Reg : LiveOut) {
WWM.addOperand(MachineOperand::CreateReg(Reg, false, /*isImp=*/true));
if (LIS) {
// FIXME: is there a better way to update the live interval?
LIS->removeInterval(Reg);
LIS->createAndComputeVirtRegInterval(Reg);
}
Modified = true;
}
return Modified;
}
示例6: fixTerminators
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: while
// 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: findExecCopy
static MachineBasicBlock::reverse_iterator findExecCopy(
const SIInstrInfo &TII,
MachineBasicBlock &MBB,
MachineBasicBlock::reverse_iterator I,
unsigned CopyToExec) {
const unsigned InstLimit = 25;
auto E = MBB.rend();
for (unsigned N = 0; N <= InstLimit && I != E; ++I, ++N) {
unsigned CopyFromExec = isCopyFromExec(*I);
if (CopyFromExec != AMDGPU::NoRegister)
return I;
}
return E;
}
示例9: searchBackward
bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot) const {
if (DisableBackwardSearch)
return false;
RegDefsUses RegDU(TM);
MemDefsUses MemDU(MBB.getParent()->getFrameInfo());
ReverseIter Filler;
RegDU.init(*Slot);
if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Filler))
return false;
MBB.splice(std::next(Slot), &MBB, std::next(Filler).base());
MIBundleBuilder(MBB, Slot, std::next(Slot, 2));
++UsefulSlots;
return true;
}
示例10: findDelayInstr
bool Filler::findDelayInstr(MachineBasicBlock &MBB,
MachineBasicBlock::iterator slot,
MachineBasicBlock::iterator &Filler) {
SmallSet<unsigned, 32> RegDefs;
SmallSet<unsigned, 32> RegUses;
insertDefsUses(slot, RegDefs, RegUses);
bool sawLoad = false;
bool sawStore = false;
for (MachineBasicBlock::reverse_iterator I(slot); I != MBB.rend(); ++I) {
// skip debug value
if (I->isDebugValue())
continue;
// Convert to forward iterator.
MachineBasicBlock::iterator FI(llvm::next(I).base());
if (I->hasUnmodeledSideEffects()
|| I->isInlineAsm()
|| I->isLabel()
|| FI == LastFiller
|| I->isPseudo()
//
// Should not allow:
// ERET, DERET or WAIT, PAUSE. Need to add these to instruction
// list. TBD.
)
break;
if (delayHasHazard(FI, sawLoad, sawStore, RegDefs, RegUses)) {
insertDefsUses(FI, RegDefs, RegUses);
continue;
}
Filler = FI;
return true;
}
return false;
}
示例11: findDelayInstr
bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
Iter &Filler) const {
RegDefsUses RegDU(TM);
RegDU.init(*Slot);
bool SawLoad = false;
bool SawStore = false;
for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
// skip debug value
if (I->isDebugValue())
continue;
// @LOCALMOD-START - Don't put in delay slot instructions that could be masked.
//
// Should not allow:
// ERET, DERET or WAIT, PAUSE. Need to add these to instruction
// list. TBD.
if (Triple(TM.getTargetTriple()).isOSNaCl()) {
int Dummy;
Iter FI(llvm::next(I).base());
if (terminateSearch(*I) || (IsDangerousLoad(*FI, &Dummy)
|| IsDangerousStore(*FI, &Dummy)
|| FI->modifiesRegister(Mips::SP, TM.getRegisterInfo())))
break;
} else {
if (terminateSearch(*I))
break;
}
// @LOCALMOD-END
if (delayHasHazard(*I, SawLoad, SawStore, RegDU))
continue;
Filler = llvm::next(I).base();
return true;
}
return false;
}
示例12: RemoveBranch
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;
}
示例13: mayFallthrough
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;
}
示例14: assert
void
SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
// If we are trying to copy to or from SCC, there is a bug somewhere else in
// the backend. While it may be theoretically possible to do this, it should
// never be necessary.
assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC);
static const int16_t Sub0_15[] = {
AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0
};
static const int16_t Sub0_7[] = {
AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0
};
static const int16_t Sub0_3[] = {
AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
};
static const int16_t Sub0_2[] = {
AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
};
static const int16_t Sub0_1[] = {
AMDGPU::sub0, AMDGPU::sub1, 0
};
unsigned Opcode;
const int16_t *SubIndices;
if (AMDGPU::M0 == DestReg) {
// Check if M0 isn't already set to this value
for (MachineBasicBlock::reverse_iterator E = MBB.rend(),
I = MachineBasicBlock::reverse_iterator(MI); I != E; ++I) {
if (!I->definesRegister(AMDGPU::M0))
continue;
unsigned Opc = I->getOpcode();
if (Opc != TargetOpcode::COPY && Opc != AMDGPU::S_MOV_B32)
break;
if (!I->readsRegister(SrcReg))
break;
// The copy isn't necessary
return;
}
}
if (AMDGPU::SReg_32RegClass.contains(DestReg)) {
assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
return;
} else if (AMDGPU::SReg_64RegClass.contains(DestReg)) {
assert(AMDGPU::SReg_64RegClass.contains(SrcReg));
BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
return;
} else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
Opcode = AMDGPU::S_MOV_B32;
SubIndices = Sub0_3;
} else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
Opcode = AMDGPU::S_MOV_B32;
SubIndices = Sub0_7;
} else if (AMDGPU::SReg_512RegClass.contains(DestReg)) {
assert(AMDGPU::SReg_512RegClass.contains(SrcReg));
Opcode = AMDGPU::S_MOV_B32;
SubIndices = Sub0_15;
} else if (AMDGPU::VReg_32RegClass.contains(DestReg)) {
assert(AMDGPU::VReg_32RegClass.contains(SrcReg) ||
AMDGPU::SReg_32RegClass.contains(SrcReg));
BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
return;
} else if (AMDGPU::VReg_64RegClass.contains(DestReg)) {
assert(AMDGPU::VReg_64RegClass.contains(SrcReg) ||
AMDGPU::SReg_64RegClass.contains(SrcReg));
Opcode = AMDGPU::V_MOV_B32_e32;
SubIndices = Sub0_1;
} else if (AMDGPU::VReg_96RegClass.contains(DestReg)) {
assert(AMDGPU::VReg_96RegClass.contains(SrcReg));
//.........这里部分代码省略.........
示例15: assert
/// It's possible to determine the value of a register based on a dominating
/// condition. To do so, this function checks to see if the basic block \p MBB
/// is the target of a conditional branch \p CondBr with an equality comparison.
/// If the branch is a CBZ/CBNZ, we know the value of its source operand is zero
/// in \p MBB for some cases. Otherwise, we find and inspect the NZCV setting
/// instruction (e.g., SUBS, ADDS). If this instruction defines a register
/// other than WZR/XZR, we know the value of the destination register is zero in
/// \p MMB for some cases. In addition, if the NZCV setting instruction is
/// comparing against a constant we know the other source register is equal to
/// the constant in \p MBB for some cases. If we find any constant values, push
/// a physical register and constant value pair onto the KnownRegs vector and
/// return true. Otherwise, return false if no known values were found.
bool AArch64RedundantCopyElimination::knownRegValInBlock(
MachineInstr &CondBr, MachineBasicBlock *MBB,
SmallVectorImpl<RegImm> &KnownRegs, MachineBasicBlock::iterator &FirstUse) {
unsigned Opc = CondBr.getOpcode();
// Check if the current basic block is the target block to which the
// CBZ/CBNZ instruction jumps when its Wt/Xt is zero.
if (((Opc == AArch64::CBZW || Opc == AArch64::CBZX) &&
MBB == CondBr.getOperand(1).getMBB()) ||
((Opc == AArch64::CBNZW || Opc == AArch64::CBNZX) &&
MBB != CondBr.getOperand(1).getMBB())) {
FirstUse = CondBr;
KnownRegs.push_back(RegImm(CondBr.getOperand(0).getReg(), 0));
return true;
}
// Otherwise, must be a conditional branch.
if (Opc != AArch64::Bcc)
return false;
// Must be an equality check (i.e., == or !=).
AArch64CC::CondCode CC = (AArch64CC::CondCode)CondBr.getOperand(0).getImm();
if (CC != AArch64CC::EQ && CC != AArch64CC::NE)
return false;
MachineBasicBlock *BrTarget = CondBr.getOperand(1).getMBB();
if ((CC == AArch64CC::EQ && BrTarget != MBB) ||
(CC == AArch64CC::NE && BrTarget == MBB))
return false;
// Stop if we get to the beginning of PredMBB.
MachineBasicBlock *PredMBB = *MBB->pred_begin();
assert(PredMBB == CondBr.getParent() &&
"Conditional branch not in predecessor block!");
if (CondBr == PredMBB->begin())
return false;
// Registers clobbered in PredMBB between CondBr instruction and current
// instruction being checked in loop.
DomBBClobberedRegs.reset();
// Find compare instruction that sets NZCV used by CondBr.
MachineBasicBlock::reverse_iterator RIt = CondBr.getReverseIterator();
for (MachineInstr &PredI : make_range(std::next(RIt), PredMBB->rend())) {
bool IsCMN = false;
switch (PredI.getOpcode()) {
default:
break;
// CMN is an alias for ADDS with a dead destination register.
case AArch64::ADDSWri:
case AArch64::ADDSXri:
IsCMN = true;
LLVM_FALLTHROUGH;
// CMP is an alias for SUBS with a dead destination register.
case AArch64::SUBSWri:
case AArch64::SUBSXri: {
MCPhysReg DstReg = PredI.getOperand(0).getReg();
MCPhysReg SrcReg = PredI.getOperand(1).getReg();
bool Res = false;
// If we're comparing against a non-symbolic immediate and the source
// register of the compare is not modified (including a self-clobbering
// compare) between the compare and conditional branch we known the value
// of the 1st source operand.
if (PredI.getOperand(2).isImm() && !DomBBClobberedRegs[SrcReg] &&
SrcReg != DstReg) {
// We've found the instruction that sets NZCV.
int32_t KnownImm = PredI.getOperand(2).getImm();
int32_t Shift = PredI.getOperand(3).getImm();
KnownImm <<= Shift;
if (IsCMN)
KnownImm = -KnownImm;
FirstUse = PredI;
KnownRegs.push_back(RegImm(SrcReg, KnownImm));
Res = true;
}
// If this instructions defines something other than WZR/XZR, we know it's
// result is zero in some cases.
if (DstReg == AArch64::WZR || DstReg == AArch64::XZR)
return Res;
// The destination register must not be modified between the NZCV setting
// instruction and the conditional branch.
if (DomBBClobberedRegs[DstReg])
return Res;
//.........这里部分代码省略.........