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; }
// Return true if \p MI dominates of uses of virtual register \p VReg static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg, MachineDominatorTree *MDT, MachineRegisterInfo *MRI) { assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Expected virtual register!"); for (auto it = MRI->use_nodbg_begin(VReg), end = MRI->use_nodbg_end(); it != end; ++it) { MachineInstr *User = it->getParent(); if (User->isPHI()) { unsigned BBOperandIdx = User->getOperandNo(&*it) + 1; MachineBasicBlock *MBB = User->getOperand(BBOperandIdx).getMBB(); if (MBB->empty()) { const MachineBasicBlock *InstBB = MI->getParent(); assert(InstBB != MBB && "Instruction found in empty MBB"); if (!MDT->dominates(InstBB, MBB)) return false; continue; } User = &*MBB->rbegin(); } if (!MDT->dominates(MI, User)) return false; } return true; }
void SIWholeQuadMode::propagateBlock(MachineBasicBlock &MBB, std::vector<WorkItem>& Worklist) { BlockInfo BI = Blocks[&MBB]; // Make a copy to prevent dangling references. // Propagate through instructions if (!MBB.empty()) { MachineInstr *LastMI = &*MBB.rbegin(); InstrInfo &LastII = Instructions[LastMI]; if ((LastII.OutNeeds | BI.OutNeeds) != LastII.OutNeeds) { LastII.OutNeeds |= BI.OutNeeds; Worklist.push_back(LastMI); } } // Predecessor blocks must provide for our WQM/Exact needs. for (MachineBasicBlock *Pred : MBB.predecessors()) { BlockInfo &PredBI = Blocks[Pred]; if ((PredBI.OutNeeds | BI.InNeeds) == PredBI.OutNeeds) continue; PredBI.OutNeeds |= BI.InNeeds; PredBI.InNeeds |= BI.InNeeds; Worklist.push_back(Pred); } // All successors must be prepared to accept the same set of WQM/Exact data. for (MachineBasicBlock *Succ : MBB.successors()) { BlockInfo &SuccBI = Blocks[Succ]; if ((SuccBI.InNeeds | BI.OutNeeds) == SuccBI.InNeeds) continue; SuccBI.InNeeds |= BI.OutNeeds; Worklist.push_back(Succ); } }
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(); } }
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; }
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; }
// All currently live registers must remain so in the remainder block. void SILowerControlFlow::splitBlockLiveIns(const MachineBasicBlock &MBB, const MachineInstr &MI, MachineBasicBlock &LoopBB, MachineBasicBlock &RemainderBB, unsigned SaveReg, const MachineOperand &IdxReg) { LivePhysRegs RemainderLiveRegs(TRI); RemainderLiveRegs.addLiveOuts(MBB); for (MachineBasicBlock::const_reverse_iterator I = MBB.rbegin(), E(&MI); I != E; ++I) { RemainderLiveRegs.stepBackward(*I); } // Add reg defined in loop body. RemainderLiveRegs.addReg(SaveReg); if (const MachineOperand *Val = TII->getNamedOperand(MI, AMDGPU::OpName::val)) { if (!Val->isUndef()) { RemainderLiveRegs.addReg(Val->getReg()); LoopBB.addLiveIn(Val->getReg()); } } const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); for (unsigned Reg : RemainderLiveRegs) { if (MRI.isAllocatable(Reg)) RemainderBB.addLiveIn(Reg); } const MachineOperand *Src = TII->getNamedOperand(MI, AMDGPU::OpName::src); if (!Src->isUndef()) LoopBB.addLiveIn(Src->getReg()); if (!IdxReg.isUndef()) LoopBB.addLiveIn(IdxReg.getReg()); LoopBB.sortUniqueLiveIns(); }
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; }
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; }
// Expand branch instructions to long branches. // TODO: This function has to be fixed for beqz16 and bnez16, because it // currently assumes that all branches have 16-bit offsets, and will produce // wrong code if branches whose allowed offsets are [-128, -126, ..., 126] // are present. void MipsLongBranch::expandToLongBranch(MBBInfo &I) { MachineBasicBlock::iterator Pos; MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); DebugLoc DL = I.Br->getDebugLoc(); const BasicBlock *BB = MBB->getBasicBlock(); MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); const MipsSubtarget &Subtarget = static_cast<const MipsSubtarget &>(MF->getSubtarget()); const MipsInstrInfo *TII = static_cast<const MipsInstrInfo *>(Subtarget.getInstrInfo()); MF->insert(FallThroughMBB, LongBrMBB); MBB->replaceSuccessor(TgtMBB, LongBrMBB); if (IsPIC) { MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); MF->insert(FallThroughMBB, BalTgtMBB); LongBrMBB->addSuccessor(BalTgtMBB); BalTgtMBB->addSuccessor(TgtMBB); // We must select between the MIPS32r6/MIPS64r6 BALC (which is a normal // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an // pseudo-instruction wrapping BGEZAL). const unsigned BalOp = Subtarget.hasMips32r6() ? Subtarget.inMicroMipsMode() ? Mips::BALC_MMR6 : Mips::BALC : Mips::BAL_BR; if (!ABI.IsN64()) { // Pre R6: // $longbr: // addiu $sp, $sp, -8 // sw $ra, 0($sp) // lui $at, %hi($tgt - $baltgt) // bal $baltgt // addiu $at, $at, %lo($tgt - $baltgt) // $baltgt: // addu $at, $ra, $at // lw $ra, 0($sp) // jr $at // addiu $sp, $sp, 8 // $fallthrough: // // R6: // $longbr: // addiu $sp, $sp, -8 // sw $ra, 0($sp) // lui $at, %hi($tgt - $baltgt) // addiu $at, $at, %lo($tgt - $baltgt) // balc $baltgt // $baltgt: // addu $at, $ra, $at // lw $ra, 0($sp) // addiu $sp, $sp, 8 // jic $at, 0 // $fallthrough: Pos = LongBrMBB->begin(); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(-8); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) .addReg(Mips::SP).addImm(0); // LUi and ADDiu instructions create 32-bit offset of the target basic // block from the target of BAL(C) instruction. We cannot use immediate // value for this offset because it cannot be determined accurately when // the program has inline assembly statements. We therefore use the // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which // are resolved during the fixup, so the values will always be correct. // // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt) // expressions at this point (it is possible only at the MC layer), // we replace LUi and ADDiu with pseudo instructions // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic // blocks as operands to these instructions. When lowering these pseudo // instructions to LUi and ADDiu in the MC layer, we will create // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as // operands to lowered instructions. BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) .addMBB(TgtMBB).addMBB(BalTgtMBB); MachineInstrBuilder BalInstr = BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); MachineInstrBuilder ADDiuInstr = BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) .addReg(Mips::AT) .addMBB(TgtMBB) .addMBB(BalTgtMBB); if (Subtarget.hasMips32r6()) { LongBrMBB->insert(Pos, ADDiuInstr); LongBrMBB->insert(Pos, BalInstr); } else { LongBrMBB->insert(Pos, BalInstr); LongBrMBB->insert(Pos, ADDiuInstr); LongBrMBB->rbegin()->bundleWithPred(); } Pos = BalTgtMBB->begin(); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) .addReg(Mips::RA).addReg(Mips::AT); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) .addReg(Mips::SP).addImm(0); if (Subtarget.isTargetNaCl()) // Bundle-align the target of indirect branch JR. TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); // In NaCl, modifying the sp is not allowed in branch delay slot. // For MIPS32R6, we can skip using a delay slot branch. if (Subtarget.isTargetNaCl() || (Subtarget.hasMips32r6() && !Subtarget.useIndirectJumpsHazard())) BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP).addImm(8); if (Subtarget.hasMips32r6() && !Subtarget.useIndirectJumpsHazard()) { const unsigned JICOp = Subtarget.inMicroMipsMode() ? Mips::JIC_MMR6 : Mips::JIC; BuildMI(*BalTgtMBB, Pos, DL, TII->get(JICOp)) .addReg(Mips::AT) .addImm(0); } else { unsigned JROp = Subtarget.useIndirectJumpsHazard() ? (Subtarget.hasMips32r6() ? Mips::JR_HB_R6 : Mips::JR_HB) : Mips::JR; BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT); if (Subtarget.isTargetNaCl()) { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::NOP)); } else BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) .addReg(Mips::SP) .addImm(8); BalTgtMBB->rbegin()->bundleWithPred(); } } else { // Pre R6: // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) // daddiu $at, $zero, %hi($tgt - $baltgt) // dsll $at, $at, 16 // bal $baltgt // daddiu $at, $at, %lo($tgt - $baltgt) // $baltgt: // daddu $at, $ra, $at // ld $ra, 0($sp) // jr64 $at // daddiu $sp, $sp, 16 // $fallthrough: // R6: // $longbr: // daddiu $sp, $sp, -16 // sd $ra, 0($sp) // daddiu $at, $zero, %hi($tgt - $baltgt) // dsll $at, $at, 16 // daddiu $at, $at, %lo($tgt - $baltgt) // balc $baltgt // $baltgt: // daddu $at, $ra, $at // ld $ra, 0($sp) // daddiu $sp, $sp, 16 // jic $at, 0 // $fallthrough: // We assume the branch is within-function, and that offset is within // +/- 2GB. High 32 bits will therefore always be zero. // Note that this will work even if the offset is negative, because // of the +1 modification that's added in that case. For example, if the // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is // // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 // // and the bits [47:32] are zero. For %highest // // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 // // and the bits [63:48] are zero. Pos = LongBrMBB->begin(); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) .addReg(Mips::SP_64).addImm(-16); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) .addReg(Mips::SP_64).addImm(0); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64).addReg(Mips::ZERO_64) .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB); BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) .addReg(Mips::AT_64).addImm(16); MachineInstrBuilder BalInstr = BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB); MachineInstrBuilder DADDiuInstr = BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) .addReg(Mips::AT_64) .addMBB(TgtMBB, MipsII::MO_ABS_LO) .addMBB(BalTgtMBB); if (Subtarget.hasMips32r6()) { LongBrMBB->insert(Pos, DADDiuInstr); LongBrMBB->insert(Pos, BalInstr); } else { LongBrMBB->insert(Pos, BalInstr); LongBrMBB->insert(Pos, DADDiuInstr); LongBrMBB->rbegin()->bundleWithPred(); } Pos = BalTgtMBB->begin(); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64) .addReg(Mips::RA_64).addReg(Mips::AT_64); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) .addReg(Mips::SP_64).addImm(0); if (Subtarget.hasMips64r6() && !Subtarget.useIndirectJumpsHazard()) { BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) .addReg(Mips::SP_64) .addImm(16); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::JIC64)) .addReg(Mips::AT_64) .addImm(0); } else { unsigned JROp = Subtarget.useIndirectJumpsHazard() ? (Subtarget.hasMips32r6() ? Mips::JR_HB64_R6 : Mips::JR_HB64) : Mips::JR64; BuildMI(*BalTgtMBB, Pos, DL, TII->get(JROp)).addReg(Mips::AT_64); BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) .addReg(Mips::SP_64) .addImm(16); BalTgtMBB->rbegin()->bundleWithPred(); } } assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize); } else { // Pre R6: R6: // $longbr: $longbr: // j $tgt bc $tgt // nop $fallthrough // $fallthrough: // Pos = LongBrMBB->begin(); LongBrMBB->addSuccessor(TgtMBB); if (Subtarget.hasMips32r6()) BuildMI(*LongBrMBB, Pos, DL, TII->get(Subtarget.inMicroMipsMode() ? Mips::BC_MMR6 : Mips::BC)) .addMBB(TgtMBB); else MIBundleBuilder(*LongBrMBB, Pos) .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); assert(LongBrMBB->size() == LongBranchSeqSize); } if (I.Br->isUnconditionalBranch()) { // Change branch destination. assert(I.Br->getDesc().getNumOperands() == 1); I.Br->RemoveOperand(0); I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB)); } else // Change branch destination and reverse condition. replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB); }
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 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 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; }