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; }
// 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(); } }
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; }
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; }
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; }
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; }
// 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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)); Opcode = AMDGPU::V_MOV_B32_e32; SubIndices = Sub0_2; } else if (AMDGPU::VReg_128RegClass.contains(DestReg)) { assert(AMDGPU::VReg_128RegClass.contains(SrcReg) || AMDGPU::SReg_128RegClass.contains(SrcReg)); Opcode = AMDGPU::V_MOV_B32_e32; SubIndices = Sub0_3; } else if (AMDGPU::VReg_256RegClass.contains(DestReg)) { assert(AMDGPU::VReg_256RegClass.contains(SrcReg) || AMDGPU::SReg_256RegClass.contains(SrcReg)); Opcode = AMDGPU::V_MOV_B32_e32; SubIndices = Sub0_7; } else if (AMDGPU::VReg_512RegClass.contains(DestReg)) { assert(AMDGPU::VReg_512RegClass.contains(SrcReg) || AMDGPU::SReg_512RegClass.contains(SrcReg)); Opcode = AMDGPU::V_MOV_B32_e32; SubIndices = Sub0_15; } else { llvm_unreachable("Can't copy register!"); } while (unsigned SubIdx = *SubIndices++) { MachineInstrBuilder Builder = BuildMI(MBB, MI, DL, get(Opcode), RI.getSubReg(DestReg, SubIdx)); Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc)); if (*SubIndices) Builder.addReg(DestReg, RegState::Define | RegState::Implicit); } }
/// 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; FirstUse = PredI; KnownRegs.push_back(RegImm(DstReg, 0)); return true; } // Look for NZCV setting instructions that define something other than // WZR/XZR. case AArch64::ADCSWr: case AArch64::ADCSXr: case AArch64::ADDSWrr: case AArch64::ADDSWrs: case AArch64::ADDSWrx: case AArch64::ADDSXrr: case AArch64::ADDSXrs: case AArch64::ADDSXrx: case AArch64::ADDSXrx64: case AArch64::ANDSWri: case AArch64::ANDSWrr: case AArch64::ANDSWrs: case AArch64::ANDSXri: case AArch64::ANDSXrr: case AArch64::ANDSXrs: case AArch64::BICSWrr: case AArch64::BICSWrs: case AArch64::BICSXrs: case AArch64::BICSXrr: case AArch64::SBCSWr: case AArch64::SBCSXr: case AArch64::SUBSWrr: case AArch64::SUBSWrs: case AArch64::SUBSWrx: case AArch64::SUBSXrr: case AArch64::SUBSXrs: case AArch64::SUBSXrx: case AArch64::SUBSXrx64: { MCPhysReg DstReg = PredI.getOperand(0).getReg(); if (DstReg == AArch64::WZR || DstReg == AArch64::XZR) return false; // The destination register of the NZCV setting instruction must not be // modified before the conditional branch. if (DomBBClobberedRegs[DstReg]) return false; // We've found the instruction that sets NZCV whose DstReg == 0. FirstUse = PredI; KnownRegs.push_back(RegImm(DstReg, 0)); return true; } } // Bail if we see an instruction that defines NZCV that we don't handle. if (PredI.definesRegister(AArch64::NZCV)) return false; // Track clobbered registers. trackRegDefs(PredI, DomBBClobberedRegs, TRI); } return false; }
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; }
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; }
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); } } return MadeChange; }
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); } } } // We didn't delete the current instruction, so increment MII to // the next one. ++MII; } } LivePhysRegs.clear(); return AnyChanges; }
bool CoffeeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) 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)) { // If this block ends with no branches (it just falls through to its succ) // just return false, leaving TBB/FBB null. TBB = FBB = NULL; return false; } MachineInstr *LastInst = &*I; unsigned LastOpc = LastInst->getOpcode(); // Not an analyzable branch (must be an indirect jump). if (!GetAnalyzableBrOpc(LastOpc)) return true; // Get the second to last instruction in the block. unsigned SecondLastOpc = 0; MachineInstr *SecondLastInst = NULL; if (++I != REnd) { SecondLastInst = &*I; SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode()); // Not an analyzable branch (must be an indirect jump). if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) return true; } // If there is only one terminator instruction, process it. if (!SecondLastOpc) { // Unconditional branch if (LastOpc == UncondBrOpc) { TBB = LastInst->getOperand(0).getMBB(); return false; } // Conditional branch AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); return false; } // 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 true; // If second to last instruction is an unconditional branch, // analyze it and remove the last instruction. if (SecondLastOpc == UncondBrOpc) { // Return if the last instruction cannot be removed. if (!AllowModify) return true; TBB = SecondLastInst->getOperand(0).getMBB(); LastInst->eraseFromParent(); return false; } // Conditional branch followed by an unconditional branch. // The last one must be unconditional. if (LastOpc != UncondBrOpc) return true; AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); FBB = LastInst->getOperand(0).getMBB(); return false; }
bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { if (skipOptnoneFunction(*MF.getFunction())) return false; bool AnyChanges = false; MRI = &MF.getRegInfo(); TRI = MF.getSubtarget().getRegisterInfo(); TII = MF.getSubtarget().getInstrInfo(); // 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 = MRI->getReservedRegs(); // 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. for (MachineBasicBlock::succ_iterator S = MBB->succ_begin(), E = MBB->succ_end(); S != E; S++) for (MachineBasicBlock::livein_iterator LI = (*S)->livein_begin(); LI != (*S)->livein_end(); LI++) LivePhysRegs.set(*LI); // 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. They get marked as undef and will be deleted // in the live debug variable analysis. MI->eraseFromParentAndMarkDBGValuesForRemoval(); AnyChanges = true; ++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 (TargetRegisterInfo::isPhysicalRegister(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 (MCSubRegIterator SR(Reg, TRI,/*IncludeSelf=*/true); SR.isValid(); ++SR) LivePhysRegs.reset(*SR); } } else if (MO.isRegMask()) { // Register mask of preserved registers. All clobbers are dead. LivePhysRegs.clearBitsNotInMask(MO.getRegMask()); } } // 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 (TargetRegisterInfo::isPhysicalRegister(Reg)) { for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) LivePhysRegs.set(*AI); } } } // We didn't delete the current instruction, so increment MII to // the next one. ++MII; } } LivePhysRegs.clear(); return AnyChanges; }