unsigned ARCInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { assert(!BytesRemoved && "Code size not handled"); MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); if (I == MBB.end()) return 0; if (!isUncondBranchOpcode(I->getOpcode()) && !isCondBranchOpcode(I->getOpcode())) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (!isCondBranchOpcode(I->getOpcode())) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
unsigned SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); removeHBR(MBB); if (I == MBB.begin()) return 0; --I; while (I->isDebugValue()) { if (I == MBB.begin()) return 0; --I; } if (!isCondBranch(I) && !isUncondBranch(I)) return 0; // Remove the first branch. DEBUG(errs() << "Removing branch: "); DEBUG(I->dump()); I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (!(isCondBranch(I) || isUncondBranch(I))) return 1; // Remove the second branch. DEBUG(errs() << "Removing second branch: "); DEBUG(I->dump()); I->eraseFromParent(); return 2; }
unsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; while (I->isDebugValue()) { if (I == MBB.begin()) return 0; --I; } if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC && I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ && I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != PPC::BCC && I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ && I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
unsigned MipsInstrInfo:: RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; while (I->isDebugValue()) { if (I == MBB.begin()) return 0; --I; } if (I->getOpcode() != Mips::J && GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
MachineBasicBlock::iterator AArch64LoadStoreOpt::mergeUpdateInsn(MachineBasicBlock::iterator I, MachineBasicBlock::iterator Update, bool IsPreIdx) { assert((Update->getOpcode() == AArch64::ADDXri || Update->getOpcode() == AArch64::SUBXri) && "Unexpected base register update instruction to merge!"); MachineBasicBlock::iterator NextI = I; // Return the instruction following the merged instruction, which is // the instruction following our unmerged load. Unless that's the add/sub // instruction we're merging, in which case it's the one after that. if (++NextI == Update) ++NextI; int Value = Update->getOperand(2).getImm(); assert(AArch64_AM::getShiftValue(Update->getOperand(3).getImm()) == 0 && "Can't merge 1 << 12 offset into pre-/post-indexed load / store"); if (Update->getOpcode() == AArch64::SUBXri) Value = -Value; unsigned NewOpc = IsPreIdx ? getPreIndexedOpcode(I->getOpcode()) : getPostIndexedOpcode(I->getOpcode()); MachineInstrBuilder MIB; if (!isPairedLdSt(I)) { // Non-paired instruction. MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc)) .addOperand(getLdStRegOp(Update)) .addOperand(getLdStRegOp(I)) .addOperand(getLdStBaseOp(I)) .addImm(Value); } else { // Paired instruction. int Scale = getMemScale(I); MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(NewOpc)) .addOperand(getLdStRegOp(Update)) .addOperand(getLdStRegOp(I, 0)) .addOperand(getLdStRegOp(I, 1)) .addOperand(getLdStBaseOp(I)) .addImm(Value / Scale); } (void)MIB; if (IsPreIdx) DEBUG(dbgs() << "Creating pre-indexed load/store."); else DEBUG(dbgs() << "Creating post-indexed load/store."); DEBUG(dbgs() << " Replacing instructions:\n "); DEBUG(I->print(dbgs())); DEBUG(dbgs() << " "); DEBUG(Update->print(dbgs())); DEBUG(dbgs() << " with instruction:\n "); DEBUG(((MachineInstr *)MIB)->print(dbgs())); DEBUG(dbgs() << "\n"); // Erase the old instructions for the block. I->eraseFromParent(); Update->eraseFromParent(); return NextI; }
unsigned XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; while (I->isDebugValue()) { if (I == MBB.begin()) return 0; --I; } if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (!IsCondBranch(I->getOpcode())) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { assert(!BytesRemoved && "code size not handled"); MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != NVPTX::CBranch) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) { if (!MF.getFunction()->hasFnAttribute("patchable-function")) return false; #ifndef NDEBUG Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function"); StringRef PatchType = PatchAttr.getValueAsString(); assert(PatchType == "prologue-short-redirect" && "Only possibility today!"); #endif auto &FirstMBB = *MF.begin(); MachineBasicBlock::iterator FirstActualI = FirstMBB.begin(); for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI) assert(FirstActualI != FirstMBB.end()); auto *TII = MF.getSubtarget().getInstrInfo(); auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(), TII->get(TargetOpcode::PATCHABLE_OP)) .addImm(2) .addImm(FirstActualI->getOpcode()); for (auto &MO : FirstActualI->operands()) MIB.addOperand(MO); FirstActualI->eraseFromParent(); MF.ensureAlignment(4); return true; }
bool PIC16InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return true; // Get the terminator instruction. --I; while (I->isDebugValue()) { if (I == MBB.begin()) return true; --I; } // Handle unconditional branches. If the unconditional branch's target is // successor basic block then remove the unconditional branch. if (I->getOpcode() == PIC16::br_uncond && AllowModify) { if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { TBB = 0; I->eraseFromParent(); } } return true; }
/// foldMemoryOperand - Try folding stack slot references in Ops into MI. /// Return true on success, and MI will be erased. bool InlineSpiller::foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl<unsigned> &Ops) { // TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied // operands. SmallVector<unsigned, 8> FoldOps; for (unsigned i = 0, e = Ops.size(); i != e; ++i) { unsigned Idx = Ops[i]; MachineOperand &MO = MI->getOperand(Idx); if (MO.isImplicit()) continue; // FIXME: Teach targets to deal with subregs. if (MO.getSubReg()) return false; // Tied use operands should not be passed to foldMemoryOperand. if (!MI->isRegTiedToDefOperand(Idx)) FoldOps.push_back(Idx); } MachineInstr *FoldMI = tii_.foldMemoryOperand(MI, FoldOps, stackSlot_); if (!FoldMI) return false; lis_.ReplaceMachineInstrInMaps(MI, FoldMI); vrm_.addSpillSlotUse(stackSlot_, FoldMI); MI->eraseFromParent(); DEBUG(dbgs() << "\tfolded: " << *FoldMI); return true; }
unsigned SVMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { unsigned removedInstructions = 0; MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; do { if (I->isDebugValue()) { --I; } else if (isNearBranchOpcode(I->getOpcode())) { I->eraseFromParent(); removedInstructions++; I = MBB.end(); if (I == MBB.begin()) break; --I; } else { break; } } while (I != MBB.begin()); return removedInstructions; }
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator AddMI, const TargetInstrInfo *TII) { // Before: add <op0>, <op1>, %i[0-7] // restore %g0, %g0, %i[0-7] // // After : restore <op0>, <op1>, %o[0-7] unsigned reg = AddMI->getOperand(0).getReg(); if (reg < SP::I0 || reg > SP::I7) return false; // Erase RESTORE. RestoreMI->eraseFromParent(); // Change ADD to RESTORE. AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr) ? SP::RESTORErr : SP::RESTOREri)); // Map the destination register. AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); return true; }
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// true if it cannot be understood (e.g. it's a switch dispatch or isn't /// implemented for a target). Upon success, this returns false and returns /// with the following information in various cases: /// /// 1. If this block ends with no branches (it just falls through to its succ) /// just return false, leaving TBB/FBB null. /// 2. If this block ends with only an unconditional branch, it sets TBB to be /// the destination block. /// 3. If this block ends with an conditional branch and it falls through to /// an successor block, it sets TBB to be the branch destination block and a /// list of operands that evaluate the condition. These /// operands can be passed to other TargetInstrInfo methods to create new /// branches. /// 4. If this block ends with an conditional branch and an unconditional /// block, it returns the 'true' destination in TBB, the 'false' destination /// in FBB, and a list of operands that evaluate the condition. These /// operands can be passed to other TargetInstrInfo methods to create new /// branches. /// /// Note that RemoveBranch and InsertBranch must be implemented to support /// cases where this method returns success. /// bool NVPTXInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { // If the block has no terminators, it just falls into the block after it. MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) return false; // Get the last instruction in the block. MachineInstr *LastInst = I; // If there is only one terminator instruction, process it. if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { if (LastInst->getOpcode() == NVPTX::GOTO) { TBB = LastInst->getOperand(0).getMBB(); return false; } else if (LastInst->getOpcode() == NVPTX::CBranch) { // Block ends with fall-through condbranch. TBB = LastInst->getOperand(1).getMBB(); Cond.push_back(LastInst->getOperand(0)); return false; } // Otherwise, don't know what this is. return true; } // Get the instruction before it if it's a terminator. MachineInstr *SecondLastInst = I; // If there are three terminators, we don't know what sort of block this is. if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) return true; // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it. if (SecondLastInst->getOpcode() == NVPTX::CBranch && LastInst->getOpcode() == NVPTX::GOTO) { TBB = SecondLastInst->getOperand(1).getMBB(); Cond.push_back(SecondLastInst->getOperand(0)); FBB = LastInst->getOperand(0).getMBB(); return false; } // If the block ends with two NVPTX:GOTOs, handle it. The second one is not // executed, so remove it. if (SecondLastInst->getOpcode() == NVPTX::GOTO && LastInst->getOpcode() == NVPTX::GOTO) { TBB = SecondLastInst->getOperand(0).getMBB(); I = LastInst; if (AllowModify) I->eraseFromParent(); return false; } // Otherwise, can't handle this. return true; }
bool OR1KInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { // Start from the bottom of the block and work up, examining the // terminator instructions. MachineBasicBlock::iterator I = MBB.end(); while (I != MBB.begin()) { --I; if (I->isDebugValue()) continue; // Working from the bottom, when we see a non-terminator // instruction, we're done. if (!isUnpredicatedTerminator(*I)) break; // A terminator that isn't a branch can't easily be handled // by this analysis. if (!I->isBranch()) return true; // Cannot handle indirect branches. if (I->getOpcode() == OR1K::JR) return true; // Handle unconditional branches. if (I->getOpcode() == OR1K::J) { if (!AllowModify) { TBB = I->getOperand(0).getMBB(); continue; } // If the block has any instructions after a J, delete them. while (std::next(I) != MBB.end()) std::next(I)->eraseFromParent(); Cond.clear(); FBB = 0; // Delete the J if it's equivalent to a fall-through. if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { TBB = 0; I->eraseFromParent(); I = MBB.end(); continue; } // TBB is used to indicate the unconditinal destination. TBB = I->getOperand(0).getMBB(); continue; } // Cannot handle conditional branches return true; } return false; }
unsigned R600InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { // Note : we leave PRED* instructions there. // They may be needed when predicating instructions. MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) { return 0; } --I; switch (I->getOpcode()) { default: return 0; case AMDGPU::JUMP: if (isPredicated(I)) { MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); clearFlag(predSet, 0, MO_FLAG_PUSH); } I->eraseFromParent(); break; } I = MBB.end(); if (I == MBB.begin()) { return 1; } --I; switch (I->getOpcode()) { // FIXME: only one case?? default: return 1; case AMDGPU::JUMP: if (isPredicated(I)) { MachineInstr *predSet = findFirstPredicateSetterFrom(MBB, I); clearFlag(predSet, 0, MO_FLAG_PUSH); } I->eraseFromParent(); break; } return 2; }
/// Replace pseudo store instructions that pass arguments through the stack with /// real instructions. If insertPushes is true then all instructions are /// replaced with push instructions, otherwise regular std instructions are /// inserted. static void fixStackStores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const TargetInstrInfo &TII, bool insertPushes) { const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); // Iterate through the BB until we hit a call instruction or we reach the end. for (auto I = MI, E = MBB.end(); I != E && !I->isCall();) { MachineBasicBlock::iterator NextMI = std::next(I); MachineInstr &MI = *I; unsigned Opcode = I->getOpcode(); // Only care of pseudo store instructions where SP is the base pointer. if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr) { I = NextMI; continue; } assert(MI.getOperand(0).getReg() == AVR::SP && "Invalid register, should be SP!"); if (insertPushes) { // Replace this instruction with a push. unsigned SrcReg = MI.getOperand(2).getReg(); bool SrcIsKill = MI.getOperand(2).isKill(); // We can't use PUSHWRr here because when expanded the order of the new // instructions are reversed from what we need. Perform the expansion now. if (Opcode == AVR::STDWSPQRr) { BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) .addReg(TRI.getSubReg(SrcReg, AVR::sub_hi), getKillRegState(SrcIsKill)); BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) .addReg(TRI.getSubReg(SrcReg, AVR::sub_lo), getKillRegState(SrcIsKill)); } else { BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr)) .addReg(SrcReg, getKillRegState(SrcIsKill)); } MI.eraseFromParent(); I = NextMI; continue; } // Replace this instruction with a regular store. Use Y as the base // pointer since it is guaranteed to contain a copy of SP. unsigned STOpc = (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr; MI.setDesc(TII.get(STOpc)); MI.getOperand(0).setReg(AVR::R29R28); I = NextMI; } }
void PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return; --I; if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC) return; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return; --I; if (I->getOpcode() != PPC::BCC) return; // Remove the branch. I->eraseFromParent(); }
unsigned NVPTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != NVPTX::CBranch) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
unsigned LembergInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; if (I->getOpcode() != Lemberg::JUMP && I->getOpcode() != Lemberg::JUMPtrue && I->getOpcode() != Lemberg::JUMPfalse && I->getOpcode() != Lemberg::JUMPpred && I->getOpcode() != Lemberg::JUMPeqz && I->getOpcode() != Lemberg::JUMPnez && I->getOpcode() != Lemberg::JUMPltz && I->getOpcode() != Lemberg::JUMPgez && I->getOpcode() != Lemberg::JUMPgtz && I->getOpcode() != Lemberg::JUMPlez) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != Lemberg::JUMPtrue && I->getOpcode() != Lemberg::JUMPfalse && I->getOpcode() != Lemberg::JUMPpred && I->getOpcode() != Lemberg::JUMPeqz && I->getOpcode() != Lemberg::JUMPnez && I->getOpcode() != Lemberg::JUMPltz && I->getOpcode() != Lemberg::JUMPgez && I->getOpcode() != Lemberg::JUMPgtz && I->getOpcode() != Lemberg::JUMPlez) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
void Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const { MachineBasicBlock *MBB = Tail->getParent(); ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>(); if (!AFI->hasITBlocks()) { TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest); return; } // If the first instruction of Tail is predicated, we may have to update // the IT instruction. unsigned PredReg = 0; ARMCC::CondCodes CC = getInstrPredicate(Tail, PredReg); MachineBasicBlock::iterator MBBI = Tail; if (CC != ARMCC::AL) // Expecting at least the t2IT instruction before it. --MBBI; // Actually replace the tail. TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest); // Fix up IT. if (CC != ARMCC::AL) { MachineBasicBlock::iterator E = MBB->begin(); unsigned Count = 4; // At most 4 instructions in an IT block. while (Count && MBBI != E) { if (MBBI->isDebugValue()) { --MBBI; continue; } if (MBBI->getOpcode() == ARM::t2IT) { unsigned Mask = MBBI->getOperand(1).getImm(); if (Count == 4) MBBI->eraseFromParent(); else { unsigned MaskOn = 1 << Count; unsigned MaskOff = ~(MaskOn - 1); MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn); } return; } --MBBI; --Count; } // Ctrl flow can reach here if branch folding is run before IT block // formation pass. } }
unsigned PatmosInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->isDebugValue()) continue; if (!I->isBranch()) break; // Not a branch // Remove the branch. I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return 0; --I; if (I->getOpcode() != Alpha::BR && I->getOpcode() != Alpha::COND_BRANCH_I && I->getOpcode() != Alpha::COND_BRANCH_F) return 0; // Remove the branch. I->eraseFromParent(); I = MBB.end(); if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != Alpha::COND_BRANCH_I && I->getOpcode() != Alpha::COND_BRANCH_F) return 1; // Remove the branch. I->eraseFromParent(); return 2; }
unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->getOpcode() != SystemZ::JMP && getCondFromBranchOpc(I->getOpcode()) == SystemZCC::INVALID) break; // Remove the branch. I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
unsigned MSP430InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->getOpcode() != MSP430::JMP && I->getOpcode() != MSP430::JCC) break; // Remove the branch. I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->isDebugValue()) continue; if (I->getOpcode() != BPF::JMP) break; // Remove the branch. I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
bool MOVToLEAPass::runOnMachineFunction(MachineFunction &Fn) { const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); bool Changed = false; for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { ++PreMOVtoLEAInstructionCount; if (I->getNumOperands() != 2 || !I->getOperand(0).isReg() || !I->getOperand(1).isReg()) { ++I; continue; } unsigned leaOpc; if (I->getOpcode() == X86::MOV32rr) { leaOpc = X86::LEA32r; } else if (I->getOpcode() == X86::MOV64rr) { leaOpc = X86::LEA64r; } else { ++I; continue; } unsigned int Roll = RandomNumberGenerator::Generator().Random(100); ++MOVCandidates; if (Roll >= multicompiler::getFunctionOption( multicompiler::MOVToLEAPercentage, *Fn.getFunction())) { ++I; continue; } ++ReplacedMOV; MachineBasicBlock::iterator J = I; ++I; addRegOffset(BuildMI(*BB, J, J->getDebugLoc(), TII->get(leaOpc), J->getOperand(0).getReg()), J->getOperand(1).getReg(), false, 0); J->eraseFromParent(); Changed = true; } return Changed; }
unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator Instruction = MBB.end(); unsigned Count = 0; while (Instruction != MBB.begin()) { --Instruction; if (Instruction->isDebugValue()) continue; if (Instruction->getOpcode() != Lanai::BT && Instruction->getOpcode() != Lanai::BRCC) { break; } // Remove the branch. Instruction->eraseFromParent(); Instruction = MBB.end(); ++Count; } return Count; }
unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { assert(!BytesRemoved && "code size not handled"); MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->isDebugValue()) continue; if (I->getOpcode() != BPF::JMP) break; // Remove the branch. I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
unsigned Mos6502InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator I = MBB.end(); unsigned Count = 0; while (I != MBB.begin()) { --I; if (I->isDebugValue()) continue; if (I->getOpcode() != M6502::BA && I->getOpcode() != M6502::BCOND && I->getOpcode() != M6502::FBCOND) break; // Not a branch I->eraseFromParent(); I = MBB.end(); ++Count; } return Count; }
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator SetHiMI, const TargetInstrInfo *TII) { // Before: sethi imm3, %i[0-7] // restore %g0, %g0, %g0 // // After : restore %g0, (imm3<<10), %o[0-7] unsigned reg = SetHiMI->getOperand(0).getReg(); if (reg < SP::I0 || reg > SP::I7) return false; if (!SetHiMI->getOperand(1).isImm()) return false; int64_t imm = SetHiMI->getOperand(1).getImm(); // Is it a 3 bit immediate? if (!isInt<3>(imm)) return false; // Make it a 13 bit immediate. imm = (imm << 10) & 0x1FFF; assert(RestoreMI->getOpcode() == SP::RESTORErr); RestoreMI->setDesc(TII->get(SP::RESTOREri)); RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); RestoreMI->getOperand(1).setReg(SP::G0); RestoreMI->getOperand(2).ChangeToImmediate(imm); // Erase the original SETHI. SetHiMI->eraseFromParent(); return true; }