本文整理汇总了C++中MachineBasicBlock::rbegin方法的典型用法代码示例。如果您正苦于以下问题:C++ MachineBasicBlock::rbegin方法的具体用法?C++ MachineBasicBlock::rbegin怎么用?C++ MachineBasicBlock::rbegin使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MachineBasicBlock
的用法示例。
在下文中一共展示了MachineBasicBlock::rbegin方法的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 = 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: dominatesAllUsesOf
// 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: propagateBlock
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: 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;
}
示例5: 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();
}
}
示例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: 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;
}
示例9: splitBlockLiveIns
// 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: 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;
}
示例11: AnalyzeBranch
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: expandToLongBranch
//.........这里部分代码省略.........
// 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);
示例13: runOnMachineFunction
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);
}
//.........这里部分代码省略.........
示例14: tryToSinkCopy
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: runOnMachineFunction
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);
//.........这里部分代码省略.........