void MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB) { if (this == FromMBB) return; while (!FromMBB->succ_empty()) { MachineBasicBlock *Succ = *FromMBB->succ_begin(); if (!FromMBB->Probs.empty()) { auto Prob = *FromMBB->Probs.begin(); addSuccessor(Succ, Prob); } else addSuccessorWithoutProb(Succ); FromMBB->removeSuccessor(Succ); // Fix up any PHI nodes in the successor. for (MachineBasicBlock::instr_iterator MI = Succ->instr_begin(), ME = Succ->instr_end(); MI != ME && MI->isPHI(); ++MI) for (unsigned i = 2, e = MI->getNumOperands()+1; i != e; i += 2) { MachineOperand &MO = MI->getOperand(i); if (MO.getMBB() == FromMBB) MO.setMBB(this); } } normalizeSuccProbs(); }
/// processImplicitDefs - Process IMPLICIT_DEF instructions and turn them into /// <undef> operands. bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** PROCESS IMPLICIT DEFS **********\n" << "********** Function: " << MF.getName() << '\n'); bool Changed = false; TII = MF.getSubtarget().getInstrInfo(); TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); assert(MRI->isSSA() && "ProcessImplicitDefs only works on SSA form."); assert(WorkList.empty() && "Inconsistent worklist state"); for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE; ++MFI) { // Scan the basic block for implicit defs. for (MachineBasicBlock::instr_iterator MBBI = MFI->instr_begin(), MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) if (MBBI->isImplicitDef()) WorkList.insert(MBBI); if (WorkList.empty()) continue; DEBUG(dbgs() << "BB#" << MFI->getNumber() << " has " << WorkList.size() << " implicit defs.\n"); Changed = true; // Drain the WorkList to recursively process any new implicit defs. do processImplicitDef(WorkList.pop_back_val()); while (!WorkList.empty()); } return Changed; }
bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = &*I; for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(), MIE = MBB->instr_end(); MII != MIE; ) { MachineInstr *MI = &*MII; // Remove BUNDLE instruction and the InsideBundle flags from bundled // instructions. if (MI->isBundle()) { while (++MII != MIE && MII->isBundledWithPred()) { MII->unbundleFromPred(); for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { MachineOperand &MO = MII->getOperand(i); if (MO.isReg() && MO.isInternalRead()) MO.setIsInternalRead(false); } } MI->eraseFromParent(); Changed = true; continue; } ++MII; } } return Changed; }
/// addNodeToList (MBB) - When an MBB is added to an MF, we need to update the /// parent pointer of the MBB, the MBB numbering, and any instructions in the /// MBB to be on the right operand list for registers. /// /// MBBs start out as #-1. When a MBB is added to a MachineFunction, it /// gets the next available unique MBB number. If it is removed from a /// MachineFunction, it goes back to being #-1. void ilist_traits<MachineBasicBlock>::addNodeToList(MachineBasicBlock *N) { MachineFunction &MF = *N->getParent(); N->Number = MF.addToMBBNumbering(N); // Make sure the instructions have their operands in the reginfo lists. MachineRegisterInfo &RegInfo = MF.getRegInfo(); for (MachineBasicBlock::instr_iterator I = N->instr_begin(), E = N->instr_end(); I != E; ++I) I->AddRegOperandsToUseLists(RegInfo); }
/// finalizeBundle - Same functionality as the previous finalizeBundle except /// the last instruction in the bundle is not provided as an input. This is /// used in cases where bundles are pre-determined by marking instructions /// with 'InsideBundle' marker. It returns the MBB instruction iterator that /// points to the end of the bundle. MachineBasicBlock::instr_iterator llvm::finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI) { MachineBasicBlock::instr_iterator E = MBB.instr_end(); MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI); while (LastMI != E && LastMI->isInsideBundle()) ++LastMI; finalizeBundle(MBB, FirstMI, LastMI); return LastMI; }
void ProcessImplicitDefs::processImplicitDef(MachineInstr *MI) { DEBUG(dbgs() << "Processing " << *MI); unsigned Reg = MI->getOperand(0).getReg(); if (TargetRegisterInfo::isVirtualRegister(Reg)) { // For virtual registers, mark all uses as <undef>, and convert users to // implicit-def when possible. for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) { MO.setIsUndef(); MachineInstr *UserMI = MO.getParent(); if (!canTurnIntoImplicitDef(UserMI)) continue; DEBUG(dbgs() << "Converting to IMPLICIT_DEF: " << *UserMI); UserMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); WorkList.insert(UserMI); } MI->eraseFromParent(); return; } // This is a physreg implicit-def. // Look for the first instruction to use or define an alias. MachineBasicBlock::instr_iterator UserMI = MI; MachineBasicBlock::instr_iterator UserE = MI->getParent()->instr_end(); bool Found = false; for (++UserMI; UserMI != UserE; ++UserMI) { for (MachineOperand &MO : UserMI->operands()) { if (!MO.isReg()) continue; unsigned UserReg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(UserReg) || !TRI->regsOverlap(Reg, UserReg)) continue; // UserMI uses or redefines Reg. Set <undef> flags on all uses. Found = true; if (MO.isUse()) MO.setIsUndef(); } if (Found) break; } // If we found the using MI, we can erase the IMPLICIT_DEF. if (Found) { DEBUG(dbgs() << "Physreg user: "******"Keeping physreg: " << *MI); }
MachineInstr *MachineBasicBlock::remove(MachineInstr *I) { if (I->isBundle()) { MachineBasicBlock::instr_iterator MII = I; ++MII; while (MII != end() && MII->isInsideBundle()) { MachineInstr *MI = &*MII++; Insts.remove(MI); } } return Insts.remove(I); }
// runOnMachineBasicBlock - Fill in delay slots for the given basic block. // There is one or two delay slot per delayed instruction. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; LastFiller = MBB.instr_end(); for (MachineBasicBlock::instr_iterator I = MBB.instr_begin(); I != MBB.instr_end(); ++I) { if (I->getDesc().hasDelaySlot()) { MachineBasicBlock::instr_iterator InstrWithSlot = I; MachineBasicBlock::instr_iterator J = I; // Treat RET specially as it is only instruction with 2 delay slots // generated while all others generated have 1 delay slot. if (I->getOpcode() == Lanai::RET) { // RET is generated as part of epilogue generation and hence we know // what the two instructions preceding it are and that it is safe to // insert RET above them. MachineBasicBlock::reverse_instr_iterator RI(I); assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() && RI->getOperand(0).getReg() == Lanai::FP && RI->getOperand(1).isReg() && RI->getOperand(1).getReg() == Lanai::FP && RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8); ++RI; assert(RI->getOpcode() == Lanai::ADD_I_LO && RI->getOperand(0).isReg() && RI->getOperand(0).getReg() == Lanai::SP && RI->getOperand(1).isReg() && RI->getOperand(1).getReg() == Lanai::FP); ++RI; MachineBasicBlock::instr_iterator FI(RI.base()); MBB.splice(std::next(I), &MBB, FI, I); FilledSlots += 2; } else { if (!NopDelaySlotFiller && findDelayInstr(MBB, I, J)) { MBB.splice(std::next(I), &MBB, J); } else { BuildMI(MBB, std::next(I), DebugLoc(), TII->get(Lanai::NOP)); } ++FilledSlots; } Changed = true; // Record the filler instruction that filled the delay slot. // The instruction after it will be visited in the next iteration. LastFiller = ++I; // Bundle the delay slot filler to InstrWithSlot so that the machine // verifier doesn't expect this instruction to be a terminator. MIBundleBuilder(MBB, InstrWithSlot, std::next(LastFiller)); } } return Changed; }
void MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, MachineBasicBlock &MBB) { DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); // Expand pseudo instruction. Skip if MI was not expanded. if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) && !expandPseudos(MI, MBB)) return; MCE.processDebugLoc(MI->getDebugLoc(), true); emitWord(getBinaryCodeForInstr(*MI)); ++NumEmitted; // Keep track of the # of mi's emitted MCE.processDebugLoc(MI->getDebugLoc(), false); }
bool Filler::findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator Slot, MachineBasicBlock::instr_iterator &Filler) { SmallSet<unsigned, 32> RegDefs; SmallSet<unsigned, 32> RegUses; insertDefsUses(Slot, RegDefs, RegUses); bool SawLoad = false; bool SawStore = false; for (MachineBasicBlock::reverse_instr_iterator I = ++Slot.getReverse(); I != MBB.instr_rend(); ++I) { // skip debug value if (I->isDebugValue()) continue; // Convert to forward iterator. MachineBasicBlock::instr_iterator FI = I.getReverse(); if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isLabel() || FI == LastFiller || I->isPseudo()) break; if (delayHasHazard(FI, SawLoad, SawStore, RegDefs, RegUses)) { insertDefsUses(FI, RegDefs, RegUses); continue; } Filler = FI; return true; } return false; }
ClauseFile MakeALUClause(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I) const { MachineBasicBlock::iterator ClauseHead = I; std::vector<MachineInstr *> ClauseContent; I++; for (MachineBasicBlock::instr_iterator E = MBB.instr_end(); I != E;) { if (IsTrivialInst(I)) { ++I; continue; } if (!I->isBundle() && !TII->isALUInstr(I->getOpcode())) break; std::vector<int64_t> Literals; if (I->isBundle()) { MachineInstr *DeleteMI = I; MachineBasicBlock::instr_iterator BI = I.getInstrIterator(); while (++BI != E && BI->isBundledWithPred()) { BI->unbundleFromPred(); for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i) { MachineOperand &MO = BI->getOperand(i); if (MO.isReg() && MO.isInternalRead()) MO.setIsInternalRead(false); } getLiteral(BI, Literals); ClauseContent.push_back(BI); } I = BI; DeleteMI->eraseFromParent(); } else { getLiteral(I, Literals); ClauseContent.push_back(I); I++; } for (unsigned i = 0, e = Literals.size(); i < e; i+=2) { unsigned literal0 = Literals[i]; unsigned literal2 = (i + 1 < e)?Literals[i + 1]:0; MachineInstr *MILit = BuildMI(MBB, I, I->getDebugLoc(), TII->get(AMDGPU::LITERALS)) .addImm(literal0) .addImm(literal2); ClauseContent.push_back(MILit); } } ClauseHead->getOperand(7).setImm(ClauseContent.size() - 1); return ClauseFile(ClauseHead, ClauseContent); }
// Insert Defs and Uses of MI into the sets RegDefs and RegUses. void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { // If MI is a call or return, just examine the explicit non-variadic operands. MCInstrDesc MCID = MI->getDesc(); unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() : MI->getNumOperands(); for (unsigned I = 0; I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; if (MO.isDef()) RegDefs.insert(Reg); else if (MO.isUse()) RegUses.insert(Reg); } // Call & return instructions defines SP implicitly. Implicit defines are not // included in the RegDefs set of calls but instructions modifying SP cannot // be inserted in the delay slot of a call/return as these instructions are // expanded to multiple instructions with SP modified before the branch that // has the delay slot. if (MI->isCall() || MI->isReturn()) RegDefs.insert(Lanai::SP); }
unsigned WebAssemblyInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::instr_iterator I = MBB.instr_end(); unsigned Count = 0; while (I != MBB.instr_begin()) { --I; if (I->isDebugValue()) continue; if (!I->isTerminator()) break; // Remove the branch. I->eraseFromParent(); I = MBB.instr_end(); ++Count; } return Count; }
void MachineBasicBlock::transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB) { if (this == fromMBB) return; while (!fromMBB->succ_empty()) { MachineBasicBlock *Succ = *fromMBB->succ_begin(); addSuccessor(Succ); fromMBB->removeSuccessor(Succ); // Fix up any PHI nodes in the successor. for (MachineBasicBlock::instr_iterator MI = Succ->instr_begin(), ME = Succ->instr_end(); MI != ME && MI->isPHI(); ++MI) for (unsigned i = 2, e = MI->getNumOperands()+1; i != e; i += 2) { MachineOperand &MO = MI->getOperand(i); if (MO.getMBB() == fromMBB) MO.setMBB(this); } } }
// Insert Defs and Uses of MI into the sets RegDefs and RegUses. void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { // If MI is a call or return, just examine the explicit non-variadic operands. MCInstrDesc MCID = MI->getDesc(); unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() : MI->getNumOperands(); for (unsigned I = 0; I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; if (MO.isDef()) RegDefs.insert(Reg); else if (MO.isUse()) RegUses.insert(Reg); } }
unsigned WebAssemblyInstrInfo::removeBranch(MachineBasicBlock &MBB, int *BytesRemoved) const { assert(!BytesRemoved && "code size not handled"); MachineBasicBlock::instr_iterator I = MBB.instr_end(); unsigned Count = 0; while (I != MBB.instr_begin()) { --I; if (I->isDebugInstr()) continue; if (!I->isTerminator()) break; // Remove the branch. I->eraseFromParent(); I = MBB.instr_end(); ++Count; } return Count; }
void SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, MachineBasicBlock &MBB) { DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); MCE.processDebugLoc(MI->getDebugLoc(), true); ++NumEmitted; switch (MI->getOpcode()) { default: { emitWord(getBinaryCodeForInstr(*MI)); break; } case TargetOpcode::INLINEASM: { // We allow inline assembler nodes with empty bodies - they can // implicitly define registers, which is ok for JIT. if (MI->getOperand(0).getSymbolName()[0]) { report_fatal_error("JIT does not support inline asm!"); } break; } case TargetOpcode::CFI_INSTRUCTION: break; case TargetOpcode::EH_LABEL: { MCE.emitLabel(MI->getOperand(0).getMCSymbol()); break; } case TargetOpcode::IMPLICIT_DEF: case TargetOpcode::KILL: { // Do nothing. break; } case SP::GETPCX: { report_fatal_error("JIT does not support pseudo instruction GETPCX yet!"); break; } } MCE.processDebugLoc(MI->getDebugLoc(), false); }
bool PatmosInstrInfo::NegatePredicate(MachineInstr *MI) const { if (!MI->isPredicable(MachineInstr::AnyInBundle)) return false; if (MI->isBundle()) { MachineBasicBlock::instr_iterator II = MI; while (II->isBundledWithSucc()) { ++II; NegatePredicate(&*II); } return true; } int i = MI->findFirstPredOperandIdx(); assert(i != -1); MachineOperand &PO2 = MI->getOperand(i+1); assert(PO2.isImm() && "Unexpected Patmos predicate operand"); bool flag = (PO2.getImm() != 0) ^ 1; PO2.setImm(flag); return true; }
/// finalizeBundles - Finalize instruction bundles in the specified /// MachineFunction. Return true if any bundles are finalized. bool llvm::finalizeBundles(MachineFunction &MF) { bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock &MBB = *I; MachineBasicBlock::instr_iterator MII = MBB.instr_begin(); MachineBasicBlock::instr_iterator MIE = MBB.instr_end(); if (MII == MIE) continue; assert(!MII->isInsideBundle() && "First instr cannot be inside bundle before finalization!"); for (++MII; MII != MIE; ) { if (!MII->isInsideBundle()) ++MII; else { MII = finalizeBundle(MBB, std::prev(MII)); Changed = true; } } } return Changed; }
bool Filler::delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad, bool &SawStore, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { if (MI->isImplicitDef() || MI->isKill()) return true; // Loads or stores cannot be moved past a store to the delay slot // and stores cannot be moved past a load. if (MI->mayLoad()) { if (SawStore) return true; SawLoad = true; } if (MI->mayStore()) { if (SawStore) return true; SawStore = true; if (SawLoad) return true; } assert((!MI->isCall() && !MI->isReturn()) && "Cannot put calls or returns in delay slot."); for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; // skip if (MO.isDef()) { // check whether Reg is defined or used before delay slot. if (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg)) return true; } if (MO.isUse()) { // check whether Reg is defined before delay slot. if (isRegInSet(RegDefs, Reg)) return true; } } return false; }
/// ReplaceUsesOfBlockWith - Given a machine basic block that branched to /// 'Old', change the code and CFG so that it branches to 'New' instead. void MachineBasicBlock::ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New) { assert(Old != New && "Cannot replace self with self!"); MachineBasicBlock::instr_iterator I = instr_end(); while (I != instr_begin()) { --I; if (!I->isTerminator()) break; // Scan the operands of this machine instruction, replacing any uses of Old // with New. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (I->getOperand(i).isMBB() && I->getOperand(i).getMBB() == Old) I->getOperand(i).setMBB(New); } // Update the successor information. replaceSuccessor(Old, New); }
MachineBasicBlock * MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) { // Splitting the critical edge to a landing pad block is non-trivial. Don't do // it in this generic function. if (Succ->isLandingPad()) return nullptr; MachineFunction *MF = getParent(); DebugLoc dl; // FIXME: this is nowhere // Performance might be harmed on HW that implements branching using exec mask // where both sides of the branches are always executed. if (MF->getTarget().requiresStructuredCFG()) return nullptr; // We may need to update this's terminator, but we can't do that if // AnalyzeBranch fails. If this uses a jump table, we won't touch it. const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); MachineBasicBlock *TBB = nullptr, *FBB = nullptr; SmallVector<MachineOperand, 4> Cond; if (TII->AnalyzeBranch(*this, TBB, FBB, Cond)) return nullptr; // Avoid bugpoint weirdness: A block may end with a conditional branch but // jumps to the same MBB is either case. We have duplicate CFG edges in that // case that we can't handle. Since this never happens in properly optimized // code, just skip those edges. if (TBB && TBB == FBB) { DEBUG(dbgs() << "Won't split critical edge after degenerate BB#" << getNumber() << '\n'); return nullptr; } MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); MF->insert(std::next(MachineFunction::iterator(this)), NMBB); DEBUG(dbgs() << "Splitting critical edge:" " BB#" << getNumber() << " -- BB#" << NMBB->getNumber() << " -- BB#" << Succ->getNumber() << '\n'); LiveIntervals *LIS = P->getAnalysisIfAvailable<LiveIntervals>(); SlotIndexes *Indexes = P->getAnalysisIfAvailable<SlotIndexes>(); if (LIS) LIS->insertMBBInMaps(NMBB); else if (Indexes) Indexes->insertMBBInMaps(NMBB); // On some targets like Mips, branches may kill virtual registers. Make sure // that LiveVariables is properly updated after updateTerminator replaces the // terminators. LiveVariables *LV = P->getAnalysisIfAvailable<LiveVariables>(); // Collect a list of virtual registers killed by the terminators. SmallVector<unsigned, 4> KilledRegs; if (LV) for (instr_iterator I = getFirstInstrTerminator(), E = instr_end(); I != E; ++I) { MachineInstr *MI = I; for (MachineInstr::mop_iterator OI = MI->operands_begin(), OE = MI->operands_end(); OI != OE; ++OI) { if (!OI->isReg() || OI->getReg() == 0 || !OI->isUse() || !OI->isKill() || OI->isUndef()) continue; unsigned Reg = OI->getReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg) || LV->getVarInfo(Reg).removeKill(MI)) { KilledRegs.push_back(Reg); DEBUG(dbgs() << "Removing terminator kill: " << *MI); OI->setIsKill(false); } } } SmallVector<unsigned, 4> UsedRegs; if (LIS) { for (instr_iterator I = getFirstInstrTerminator(), E = instr_end(); I != E; ++I) { MachineInstr *MI = I; for (MachineInstr::mop_iterator OI = MI->operands_begin(), OE = MI->operands_end(); OI != OE; ++OI) { if (!OI->isReg() || OI->getReg() == 0) continue; unsigned Reg = OI->getReg(); if (std::find(UsedRegs.begin(), UsedRegs.end(), Reg) == UsedRegs.end()) UsedRegs.push_back(Reg); } } } ReplaceUsesOfBlockWith(Succ, NMBB); // If updateTerminator() removes instructions, we need to remove them from // SlotIndexes. SmallVector<MachineInstr*, 4> Terminators; if (Indexes) { for (instr_iterator I = getFirstInstrTerminator(), E = instr_end(); I != E; ++I) Terminators.push_back(I); } updateTerminator(); if (Indexes) { SmallVector<MachineInstr*, 4> NewTerminators; for (instr_iterator I = getFirstInstrTerminator(), E = instr_end(); I != E; ++I) NewTerminators.push_back(I); for (SmallVectorImpl<MachineInstr*>::iterator I = Terminators.begin(), E = Terminators.end(); I != E; ++I) { if (std::find(NewTerminators.begin(), NewTerminators.end(), *I) == NewTerminators.end()) Indexes->removeMachineInstrFromMaps(*I); } } // Insert unconditional "jump Succ" instruction in NMBB if necessary. NMBB->addSuccessor(Succ); if (!NMBB->isLayoutSuccessor(Succ)) { Cond.clear(); MF->getSubtarget().getInstrInfo()->InsertBranch(*NMBB, Succ, nullptr, Cond, dl); if (Indexes) { for (instr_iterator I = NMBB->instr_begin(), E = NMBB->instr_end(); I != E; ++I) { // Some instructions may have been moved to NMBB by updateTerminator(), // so we first remove any instruction that already has an index. if (Indexes->hasIndex(I)) Indexes->removeMachineInstrFromMaps(I); Indexes->insertMachineInstrInMaps(I); } } } // Fix PHI nodes in Succ so they refer to NMBB instead of this for (MachineBasicBlock::instr_iterator i = Succ->instr_begin(),e = Succ->instr_end(); i != e && i->isPHI(); ++i) for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) if (i->getOperand(ni+1).getMBB() == this) i->getOperand(ni+1).setMBB(NMBB); // Inherit live-ins from the successor for (MachineBasicBlock::livein_iterator I = Succ->livein_begin(), E = Succ->livein_end(); I != E; ++I) NMBB->addLiveIn(*I); // Update LiveVariables. const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); if (LV) { // Restore kills of virtual registers that were killed by the terminators. while (!KilledRegs.empty()) { unsigned Reg = KilledRegs.pop_back_val(); for (instr_iterator I = instr_end(), E = instr_begin(); I != E;) { if (!(--I)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */ false)) continue; if (TargetRegisterInfo::isVirtualRegister(Reg)) LV->getVarInfo(Reg).Kills.push_back(I); DEBUG(dbgs() << "Restored terminator kill: " << *I); break; } } // Update relevant live-through information. LV->addNewBlock(NMBB, this, Succ); } if (LIS) { // After splitting the edge and updating SlotIndexes, live intervals may be // in one of two situations, depending on whether this block was the last in // the function. If the original block was the last in the function, all live // intervals will end prior to the beginning of the new split block. If the // original block was not at the end of the function, all live intervals will // extend to the end of the new split block. bool isLastMBB = std::next(MachineFunction::iterator(NMBB)) == getParent()->end(); SlotIndex StartIndex = Indexes->getMBBEndIdx(this); SlotIndex PrevIndex = StartIndex.getPrevSlot(); SlotIndex EndIndex = Indexes->getMBBEndIdx(NMBB); // Find the registers used from NMBB in PHIs in Succ. SmallSet<unsigned, 8> PHISrcRegs; for (MachineBasicBlock::instr_iterator I = Succ->instr_begin(), E = Succ->instr_end(); I != E && I->isPHI(); ++I) { for (unsigned ni = 1, ne = I->getNumOperands(); ni != ne; ni += 2) { if (I->getOperand(ni+1).getMBB() == NMBB) { MachineOperand &MO = I->getOperand(ni); unsigned Reg = MO.getReg(); PHISrcRegs.insert(Reg); if (MO.isUndef()) continue; LiveInterval &LI = LIS->getInterval(Reg); VNInfo *VNI = LI.getVNInfoAt(PrevIndex); assert(VNI && "PHI sources should be live out of their predecessors."); LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI)); } } } MachineRegisterInfo *MRI = &getParent()->getRegInfo(); for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned Reg = TargetRegisterInfo::index2VirtReg(i); if (PHISrcRegs.count(Reg) || !LIS->hasInterval(Reg)) continue; LiveInterval &LI = LIS->getInterval(Reg); if (!LI.liveAt(PrevIndex)) continue; bool isLiveOut = LI.liveAt(LIS->getMBBStartIdx(Succ)); if (isLiveOut && isLastMBB) { VNInfo *VNI = LI.getVNInfoAt(PrevIndex); assert(VNI && "LiveInterval should have VNInfo where it is live."); LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI)); } else if (!isLiveOut && !isLastMBB) { LI.removeSegment(StartIndex, EndIndex); } } // Update all intervals for registers whose uses may have been modified by // updateTerminator(). LIS->repairIntervalsInRange(this, getFirstTerminator(), end(), UsedRegs); } if (MachineDominatorTree *MDT = P->getAnalysisIfAvailable<MachineDominatorTree>()) MDT->recordSplitCriticalEdge(this, Succ, NMBB); if (MachineLoopInfo *MLI = P->getAnalysisIfAvailable<MachineLoopInfo>()) if (MachineLoop *TIL = MLI->getLoopFor(this)) { // If one or the other blocks were not in a loop, the new block is not // either, and thus LI doesn't need to be updated. if (MachineLoop *DestLoop = MLI->getLoopFor(Succ)) { if (TIL == DestLoop) { // Both in the same loop, the NMBB joins loop. DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); } else if (TIL->contains(DestLoop)) { // Edge from an outer loop to an inner loop. Add to the outer loop. TIL->addBasicBlockToLoop(NMBB, MLI->getBase()); } else if (DestLoop->contains(TIL)) { // Edge from an inner loop to an outer loop. Add to the outer loop. DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); } else { // Edge from two loops with no containment relation. Because these // are natural loops, we know that the destination block must be the // header of its loop (adding a branch into a loop elsewhere would // create an irreducible loop). assert(DestLoop->getHeader() == Succ && "Should not create irreducible loops!"); if (MachineLoop *P = DestLoop->getParentLoop()) P->addBasicBlockToLoop(NMBB, MLI->getBase()); } } } return NMBB; }
bool PatmosDelaySlotKiller::killDelaySlots(MachineBasicBlock &MBB) { bool Changed = false; DEBUG( dbgs() << "Killing slots in BB#" << MBB.getNumber() << " (" << MBB.getFullName() << ")\n" ); // consider the basic block from top to bottom for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { // Control-flow instructions ("proper" delay slots) if (I->hasDelaySlot()) { assert( ( I->isCall() || I->isReturn() || I->isBranch() ) && "Unexpected instruction with delay slot."); MachineBasicBlock::instr_iterator MI = *I; if (I->isBundle()) { ++MI; } unsigned Opcode = MI->getOpcode(); if (Opcode == Patmos::BR || Opcode == Patmos::BRu || Opcode == Patmos::BRR || Opcode == Patmos::BRRu || Opcode == Patmos::BRT || Opcode == Patmos::BRTu || Opcode == Patmos::BRCF || Opcode == Patmos::BRCFu || Opcode == Patmos::BRCFR || Opcode == Patmos::BRCFRu || Opcode == Patmos::BRCFT || Opcode == Patmos::BRCFTu || Opcode == Patmos::CALL || Opcode == Patmos::CALLR || Opcode == Patmos::RET || Opcode == Patmos::XRET) { bool onlyNops = true; unsigned maxCount = TM.getSubtargetImpl()->getDelaySlotCycles(&*I); unsigned count = 0; for (MachineBasicBlock::iterator K = llvm::next(I), E = MBB.end(); K != E && count < maxCount; ++K, ++count) { TII->skipPseudos(MBB, K); if (K->getOpcode() != Patmos::NOP) { onlyNops = false; } } if (onlyNops) { unsigned NewOpcode = 0; switch(Opcode) { case Patmos::BR: NewOpcode = Patmos::BRND; break; case Patmos::BRu: NewOpcode = Patmos::BRNDu; break; case Patmos::BRR: NewOpcode = Patmos::BRRND; break; case Patmos::BRRu: NewOpcode = Patmos::BRRNDu; break; case Patmos::BRT: NewOpcode = Patmos::BRTND; break; case Patmos::BRTu: NewOpcode = Patmos::BRTNDu; break; case Patmos::BRCF: NewOpcode = Patmos::BRCFND; break; case Patmos::BRCFu: NewOpcode = Patmos::BRCFNDu; break; case Patmos::BRCFR: NewOpcode = Patmos::BRCFRND; break; case Patmos::BRCFRu: NewOpcode = Patmos::BRCFRNDu; break; case Patmos::BRCFT: NewOpcode = Patmos::BRCFTND; break; case Patmos::BRCFTu: NewOpcode = Patmos::BRCFTNDu; break; case Patmos::CALL: NewOpcode = Patmos::CALLND; break; case Patmos::CALLR: NewOpcode = Patmos::CALLRND; break; case Patmos::RET: NewOpcode = Patmos::RETND; break; case Patmos::XRET: NewOpcode = Patmos::XRETND; break; } const MCInstrDesc &nonDelayed = TII->get(NewOpcode); MI->setDesc(nonDelayed); unsigned killCount = 0; MachineBasicBlock::iterator K = llvm::next(I); for (MachineBasicBlock::iterator E = MBB.end(); K != E && killCount < count; ++K, ++killCount) { TII->skipPseudos(MBB, K); KilledSlots++; } MBB.erase(llvm::next(I), K); } } Changed = true; // pass result } } return Changed; }
bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB) { bool Modified = false; // Yes, CPSR could be livein. bool LiveCPSR = MBB.isLiveIn(ARM::CPSR); MachineInstr *CPSRDef = 0; MachineInstr *BundleMI = 0; // If this BB loops back to itself, conservatively avoid narrowing the // first instruction that does partial flag update. bool IsSelfLoop = MBB.isSuccessor(&MBB); MachineBasicBlock::instr_iterator MII = MBB.instr_begin(), E = MBB.instr_end(); MachineBasicBlock::instr_iterator NextMII; for (; MII != E; MII = NextMII) { NextMII = llvm::next(MII); MachineInstr *MI = &*MII; if (MI->isBundle()) { BundleMI = MI; continue; } LiveCPSR = UpdateCPSRUse(*MI, LiveCPSR); unsigned Opcode = MI->getOpcode(); DenseMap<unsigned, unsigned>::iterator OPI = ReduceOpcodeMap.find(Opcode); if (OPI != ReduceOpcodeMap.end()) { const ReduceEntry &Entry = ReduceTable[OPI->second]; // Ignore "special" cases for now. if (Entry.Special) { if (ReduceSpecial(MBB, MI, Entry, LiveCPSR, CPSRDef, IsSelfLoop)) { Modified = true; MachineBasicBlock::instr_iterator I = prior(NextMII); MI = &*I; } goto ProcessNext; } // Try to transform to a 16-bit two-address instruction. if (Entry.NarrowOpc2 && ReduceTo2Addr(MBB, MI, Entry, LiveCPSR, CPSRDef, IsSelfLoop)) { Modified = true; MachineBasicBlock::instr_iterator I = prior(NextMII); MI = &*I; goto ProcessNext; } // Try to transform to a 16-bit non-two-address instruction. if (Entry.NarrowOpc1 && ReduceToNarrow(MBB, MI, Entry, LiveCPSR, CPSRDef, IsSelfLoop)) { Modified = true; MachineBasicBlock::instr_iterator I = prior(NextMII); MI = &*I; } } ProcessNext: if (NextMII != E && MI->isInsideBundle() && !NextMII->isInsideBundle()) { // FIXME: Since post-ra scheduler operates on bundles, the CPSR kill // marker is only on the BUNDLE instruction. Process the BUNDLE // instruction as we finish with the bundled instruction to work around // the inconsistency. if (BundleMI->killsRegister(ARM::CPSR)) LiveCPSR = false; MachineOperand *MO = BundleMI->findRegisterDefOperand(ARM::CPSR); if (MO && !MO->isDead()) LiveCPSR = true; } bool DefCPSR = false; LiveCPSR = UpdateCPSRDef(*MI, LiveCPSR, DefCPSR); if (MI->isCall()) { // Calls don't really set CPSR. CPSRDef = 0; IsSelfLoop = false; } else if (DefCPSR) { // This is the last CPSR defining instruction. CPSRDef = MI; IsSelfLoop = false; } } return Modified; }
bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB) { bool Modified = false; // Yes, CPSR could be livein. bool LiveCPSR = MBB.isLiveIn(ARM::CPSR); MachineInstr *BundleMI = 0; CPSRDef = 0; HighLatencyCPSR = false; // Check predecessors for the latest CPSRDef. for (MachineBasicBlock::pred_iterator I = MBB.pred_begin(), E = MBB.pred_end(); I != E; ++I) { const MBBInfo &PInfo = BlockInfo[(*I)->getNumber()]; if (!PInfo.Visited) { // Since blocks are visited in RPO, this must be a back-edge. continue; } if (PInfo.HighLatencyCPSR) { HighLatencyCPSR = true; break; } } // If this BB loops back to itself, conservatively avoid narrowing the // first instruction that does partial flag update. bool IsSelfLoop = MBB.isSuccessor(&MBB); MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),E = MBB.instr_end(); MachineBasicBlock::instr_iterator NextMII; for (; MII != E; MII = NextMII) { NextMII = llvm::next(MII); MachineInstr *MI = &*MII; if (MI->isBundle()) { BundleMI = MI; continue; } if (MI->isDebugValue()) continue; LiveCPSR = UpdateCPSRUse(*MI, LiveCPSR); // Does NextMII belong to the same bundle as MI? bool NextInSameBundle = NextMII != E && NextMII->isBundledWithPred(); if (ReduceMI(MBB, MI, LiveCPSR, IsSelfLoop)) { Modified = true; MachineBasicBlock::instr_iterator I = prior(NextMII); MI = &*I; // Removing and reinserting the first instruction in a bundle will break // up the bundle. Fix the bundling if it was broken. if (NextInSameBundle && !NextMII->isBundledWithPred()) NextMII->bundleWithPred(); } if (!NextInSameBundle && MI->isInsideBundle()) { // FIXME: Since post-ra scheduler operates on bundles, the CPSR kill // marker is only on the BUNDLE instruction. Process the BUNDLE // instruction as we finish with the bundled instruction to work around // the inconsistency. if (BundleMI->killsRegister(ARM::CPSR)) LiveCPSR = false; MachineOperand *MO = BundleMI->findRegisterDefOperand(ARM::CPSR); if (MO && !MO->isDead()) LiveCPSR = true; } bool DefCPSR = false; LiveCPSR = UpdateCPSRDef(*MI, LiveCPSR, DefCPSR); if (MI->isCall()) { // Calls don't really set CPSR. CPSRDef = 0; HighLatencyCPSR = false; IsSelfLoop = false; } else if (DefCPSR) { // This is the last CPSR defining instruction. CPSRDef = MI; HighLatencyCPSR = isHighLatencyCPSR(CPSRDef); IsSelfLoop = false; } } MBBInfo &Info = BlockInfo[MBB.getNumber()]; Info.HighLatencyCPSR = HighLatencyCPSR; Info.Visited = true; return Modified; }
MachineBasicBlock * MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) { // Splitting the critical edge to a landing pad block is non-trivial. Don't do // it in this generic function. if (Succ->isLandingPad()) return NULL; MachineFunction *MF = getParent(); DebugLoc dl; // FIXME: this is nowhere // We may need to update this's terminator, but we can't do that if // AnalyzeBranch fails. If this uses a jump table, we won't touch it. const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); MachineBasicBlock *TBB = 0, *FBB = 0; SmallVector<MachineOperand, 4> Cond; if (TII->AnalyzeBranch(*this, TBB, FBB, Cond)) return NULL; // Avoid bugpoint weirdness: A block may end with a conditional branch but // jumps to the same MBB is either case. We have duplicate CFG edges in that // case that we can't handle. Since this never happens in properly optimized // code, just skip those edges. if (TBB && TBB == FBB) { DEBUG(dbgs() << "Won't split critical edge after degenerate BB#" << getNumber() << '\n'); return NULL; } MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); MF->insert(llvm::next(MachineFunction::iterator(this)), NMBB); DEBUG(dbgs() << "Splitting critical edge:" " BB#" << getNumber() << " -- BB#" << NMBB->getNumber() << " -- BB#" << Succ->getNumber() << '\n'); // On some targets like Mips, branches may kill virtual registers. Make sure // that LiveVariables is properly updated after updateTerminator replaces the // terminators. LiveVariables *LV = P->getAnalysisIfAvailable<LiveVariables>(); // Collect a list of virtual registers killed by the terminators. SmallVector<unsigned, 4> KilledRegs; if (LV) for (instr_iterator I = getFirstInstrTerminator(), E = instr_end(); I != E; ++I) { MachineInstr *MI = I; for (MachineInstr::mop_iterator OI = MI->operands_begin(), OE = MI->operands_end(); OI != OE; ++OI) { if (!OI->isReg() || OI->getReg() == 0 || !OI->isUse() || !OI->isKill() || OI->isUndef()) continue; unsigned Reg = OI->getReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg) || LV->getVarInfo(Reg).removeKill(MI)) { KilledRegs.push_back(Reg); DEBUG(dbgs() << "Removing terminator kill: " << *MI); OI->setIsKill(false); } } } ReplaceUsesOfBlockWith(Succ, NMBB); updateTerminator(); // Insert unconditional "jump Succ" instruction in NMBB if necessary. NMBB->addSuccessor(Succ); if (!NMBB->isLayoutSuccessor(Succ)) { Cond.clear(); MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, Succ, NULL, Cond, dl); } // Fix PHI nodes in Succ so they refer to NMBB instead of this for (MachineBasicBlock::instr_iterator i = Succ->instr_begin(),e = Succ->instr_end(); i != e && i->isPHI(); ++i) for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) if (i->getOperand(ni+1).getMBB() == this) i->getOperand(ni+1).setMBB(NMBB); // Inherit live-ins from the successor for (MachineBasicBlock::livein_iterator I = Succ->livein_begin(), E = Succ->livein_end(); I != E; ++I) NMBB->addLiveIn(*I); // Update LiveVariables. const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); if (LV) { // Restore kills of virtual registers that were killed by the terminators. while (!KilledRegs.empty()) { unsigned Reg = KilledRegs.pop_back_val(); for (instr_iterator I = instr_end(), E = instr_begin(); I != E;) { if (!(--I)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */ false)) continue; if (TargetRegisterInfo::isVirtualRegister(Reg)) LV->getVarInfo(Reg).Kills.push_back(I); DEBUG(dbgs() << "Restored terminator kill: " << *I); break; } } // Update relevant live-through information. LV->addNewBlock(NMBB, this, Succ); } if (MachineDominatorTree *MDT = P->getAnalysisIfAvailable<MachineDominatorTree>()) { // Update dominator information. MachineDomTreeNode *SucccDTNode = MDT->getNode(Succ); bool IsNewIDom = true; for (const_pred_iterator PI = Succ->pred_begin(), E = Succ->pred_end(); PI != E; ++PI) { MachineBasicBlock *PredBB = *PI; if (PredBB == NMBB) continue; if (!MDT->dominates(SucccDTNode, MDT->getNode(PredBB))) { IsNewIDom = false; break; } } // We know "this" dominates the newly created basic block. MachineDomTreeNode *NewDTNode = MDT->addNewBlock(NMBB, this); // If all the other predecessors of "Succ" are dominated by "Succ" itself // then the new block is the new immediate dominator of "Succ". Otherwise, // the new block doesn't dominate anything. if (IsNewIDom) MDT->changeImmediateDominator(SucccDTNode, NewDTNode); } if (MachineLoopInfo *MLI = P->getAnalysisIfAvailable<MachineLoopInfo>()) if (MachineLoop *TIL = MLI->getLoopFor(this)) { // If one or the other blocks were not in a loop, the new block is not // either, and thus LI doesn't need to be updated. if (MachineLoop *DestLoop = MLI->getLoopFor(Succ)) { if (TIL == DestLoop) { // Both in the same loop, the NMBB joins loop. DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); } else if (TIL->contains(DestLoop)) { // Edge from an outer loop to an inner loop. Add to the outer loop. TIL->addBasicBlockToLoop(NMBB, MLI->getBase()); } else if (DestLoop->contains(TIL)) { // Edge from an inner loop to an outer loop. Add to the outer loop. DestLoop->addBasicBlockToLoop(NMBB, MLI->getBase()); } else { // Edge from two loops with no containment relation. Because these // are natural loops, we know that the destination block must be the // header of its loop (adding a branch into a loop elsewhere would // create an irreducible loop). assert(DestLoop->getHeader() == Succ && "Should not create irreducible loops!"); if (MachineLoop *P = DestLoop->getParentLoop()) P->addBasicBlockToLoop(NMBB, MLI->getBase()); } } } return NMBB; }
/// finalizeBundle - Finalize a machine instruction bundle which includes /// a sequence of instructions starting from FirstMI to LastMI (exclusive). /// This routine adds a BUNDLE instruction to represent the bundle, it adds /// IsInternalRead markers to MachineOperands which are defined inside the /// bundle, and it copies externally visible defs and uses to the BUNDLE /// instruction. void llvm::finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI) { assert(FirstMI != LastMI && "Empty bundle?"); MIBundleBuilder Bundle(MBB, FirstMI, LastMI); const TargetMachine &TM = MBB.getParent()->getTarget(); const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo(); const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo(); MachineInstrBuilder MIB = BuildMI(*MBB.getParent(), FirstMI->getDebugLoc(), TII->get(TargetOpcode::BUNDLE)); Bundle.prepend(MIB); SmallVector<unsigned, 32> LocalDefs; SmallSet<unsigned, 32> LocalDefSet; SmallSet<unsigned, 8> DeadDefSet; SmallSet<unsigned, 16> KilledDefSet; SmallVector<unsigned, 8> ExternUses; SmallSet<unsigned, 8> ExternUseSet; SmallSet<unsigned, 8> KilledUseSet; SmallSet<unsigned, 8> UndefUseSet; SmallVector<MachineOperand*, 4> Defs; for (; FirstMI != LastMI; ++FirstMI) { for (unsigned i = 0, e = FirstMI->getNumOperands(); i != e; ++i) { MachineOperand &MO = FirstMI->getOperand(i); if (!MO.isReg()) continue; if (MO.isDef()) { Defs.push_back(&MO); continue; } unsigned Reg = MO.getReg(); if (!Reg) continue; assert(TargetRegisterInfo::isPhysicalRegister(Reg)); if (LocalDefSet.count(Reg)) { MO.setIsInternalRead(); if (MO.isKill()) // Internal def is now killed. KilledDefSet.insert(Reg); } else { if (ExternUseSet.insert(Reg)) { ExternUses.push_back(Reg); if (MO.isUndef()) UndefUseSet.insert(Reg); } if (MO.isKill()) // External def is now killed. KilledUseSet.insert(Reg); } } for (unsigned i = 0, e = Defs.size(); i != e; ++i) { MachineOperand &MO = *Defs[i]; unsigned Reg = MO.getReg(); if (!Reg) continue; if (LocalDefSet.insert(Reg)) { LocalDefs.push_back(Reg); if (MO.isDead()) { DeadDefSet.insert(Reg); } } else { // Re-defined inside the bundle, it's no longer killed. KilledDefSet.erase(Reg); if (!MO.isDead()) // Previously defined but dead. DeadDefSet.erase(Reg); } if (!MO.isDead()) { for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { unsigned SubReg = *SubRegs; if (LocalDefSet.insert(SubReg)) LocalDefs.push_back(SubReg); } } } Defs.clear(); } SmallSet<unsigned, 32> Added; for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { unsigned Reg = LocalDefs[i]; if (Added.insert(Reg)) { // If it's not live beyond end of the bundle, mark it dead. bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | getImplRegState(true)); } } for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) { unsigned Reg = ExternUses[i]; bool isKill = KilledUseSet.count(Reg); bool isUndef = UndefUseSet.count(Reg); MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | getImplRegState(true)); } }