unsigned PTXInstrInfo:: InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const { DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(if (TBB) dbgs() << "InsertBranch: TBB: " << TBB->getName().str() << "\n"; else dbgs() << "InsertBranch: TBB: (NULL)\n"); DEBUG(if (FBB) dbgs() << "InsertBranch: FBB: " << FBB->getName().str() << "\n"; else dbgs() << "InsertBranch: FBB: (NULL)\n"); DEBUG(dbgs() << "InsertBranch: Cond size: " << Cond.size() << "\n"); assert(TBB && "TBB is NULL"); if (FBB) { BuildMI(&MBB, DL, get(PTX::BRAdp)) .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm()); BuildMI(&MBB, DL, get(PTX::BRAd)) .addMBB(FBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL); return 2; } else if (Cond.size()) { BuildMI(&MBB, DL, get(PTX::BRAdp)) .addMBB(TBB).addReg(Cond[0].getReg()).addImm(Cond[1].getImm()); return 1; } else { BuildMI(&MBB, DL, get(PTX::BRAd)) .addMBB(TBB).addReg(PTX::NoRegister).addImm(PTX::PRED_NORMAL); return 1; } }
bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { SmallSetVector<MachineInstr*, 8> MaybeDeadCopies; // Candidates for deletion DenseMap<unsigned, MachineInstr*> AvailCopyMap; // Def -> available copies map DenseMap<unsigned, MachineInstr*> CopyMap; // Def -> copies map SourceMap SrcMap; // Src -> Def map DEBUG(dbgs() << "MCP: CopyPropagateBlock " << MBB.getName() << "\n"); bool Changed = false; for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) { MachineInstr *MI = &*I; ++I; if (MI->isCopy()) { unsigned Def = MI->getOperand(0).getReg(); unsigned Src = MI->getOperand(1).getReg(); if (TargetRegisterInfo::isVirtualRegister(Def) || TargetRegisterInfo::isVirtualRegister(Src)) report_fatal_error("MachineCopyPropagation should be run after" " register allocation!"); DenseMap<unsigned, MachineInstr*>::iterator CI = AvailCopyMap.find(Src); if (CI != AvailCopyMap.end()) { MachineInstr *CopyMI = CI->second; if (!MRI->isReserved(Def) && (!MRI->isReserved(Src) || NoInterveningSideEffect(CopyMI, MI)) && isNopCopy(CopyMI, Def, Src, TRI)) { // The two copies cancel out and the source of the first copy // hasn't been overridden, eliminate the second one. e.g. // %ECX<def> = COPY %EAX<kill> // ... nothing clobbered EAX. // %EAX<def> = COPY %ECX // => // %ECX<def> = COPY %EAX // // Also avoid eliminating a copy from reserved registers unless the // definition is proven not clobbered. e.g. // %RSP<def> = COPY %RAX // CALL // %RAX<def> = COPY %RSP DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; MI->dump()); // Clear any kills of Def between CopyMI and MI. This extends the // live range. for (MachineBasicBlock::iterator I = CopyMI, E = MI; I != E; ++I) I->clearRegisterKills(Def, TRI); removeCopy(MI); Changed = true; ++NumDeletes; continue; } }
unsigned PTXInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { unsigned count = 0; while (!MBB.empty()) if (IsAnyKindOfBranch(MBB.back())) { MBB.pop_back(); ++count; } else break; DEBUG(dbgs() << "RemoveBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "RemoveBranch: remove " << count << " branch inst\n"); return count; }
/// HoistPostRA - When an instruction is found to only use loop invariant /// operands that is safe to hoist, this instruction is called to do the /// dirty work. void MachineLICM::HoistPostRA(MachineInstr *MI, unsigned Def) { MachineBasicBlock *Preheader = getCurPreheader(); if (!Preheader) return; // Now move the instructions to the predecessor, inserting it before any // terminator instructions. DEBUG({ dbgs() << "Hoisting " << *MI; if (Preheader->getBasicBlock()) dbgs() << " to MachineBasicBlock " << Preheader->getName(); if (MI->getParent()->getBasicBlock()) dbgs() << " from MachineBasicBlock " << MI->getParent()->getName(); dbgs() << "\n"; });
unsigned LM32InstrInfo:: InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl<MachineOperand> &Cond, DebugLoc DL) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "LM32 branch conditions have two components!"); unsigned Opc = LM32::BI; if (!Cond.empty()) Opc = (unsigned)Cond[0].getImm(); DEBUG(dbgs() << "InsertBranch:Opcode: " << Opc << "\n"); DEBUG(dbgs() << "InsertBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "InsertBranch: MBB: " << MBB << "\n"); DEBUG( MBB.dump(););
// AnalyzeBranch returns a Boolean value and takes four parameters: // MachineBasicBlock &MBB — The incoming block to be examined. // MachineBasicBlock *&TBB — A destination block that is returned. For // a conditional branch that evaluates to true, TBB is the destination. // MachineBasicBlock *&FBB — For a conditional branch that evaluates to // false, FBB is returned as the destination. // std::vector<MachineOperand> &Cond — List of operands to evaluate a // condition for a conditional branch. // Return false if the branch is sucessfully analyzed, true otherwise. // // Note that Cond appears to be only used by the target specific code. The // generic code just checks if Cond is empty or not. bool LM32InstrInfo:: AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { // The Cond parameters need to be fixed - disable this for now. return true; DEBUG(dbgs() << "AnalyzeBranch: blocks:\n"); DEBUG(MBB.dump()); DEBUG(dbgs() << "AnalyzeBranch: end blocks:\n"); // If the block has no terminators, it just falls into the block after it. MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin()) return false; --I; while (I->isDebugValue()) { if (I == MBB.begin()) return false; --I; } if (!isUnpredicatedTerminator(I)) { DEBUG(dbgs() << "AnalyzeBranch:predicated Terminator\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); return false; } // Get the last instruction in the block. MachineInstr *LastInst = I; // If there is only one terminator instruction, process it. unsigned LastOpc = LastInst->getOpcode(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { if (LM32::isUncondBranchOpcode(LastOpc)) { DEBUG(dbgs() << "AnalyzeBranch:one terminator instruction\n"); TBB = LastInst->getOperand(0).getMBB(); DEBUG(dbgs() << "AnalyzeBranch: instruction: " << *LastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: opcode: " << LastInst->getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB->getName().str() << "\n"); return false; } if (LM32::isCondBranchOpcode(LastOpc)) { // Block ends with fall-through condbranch. DEBUG(dbgs() << "AnalyzeBranch:Block ends with fall-through condbranch\n"); DEBUG(dbgs() << "AnalyzeBranch: instruction: " << *LastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: opcode: " << LastOpc << "\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); TBB = GetBranchTarget(*LastInst); Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); Cond.push_back(LastInst->getOperand(0)); DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB->getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: Cond[0]:" << Cond[0] << "\n"); DEBUG(dbgs() << "AnalyzeBranch: Cond[1]:" << Cond[1] << "\n"); return false; } // Otherwise, don't know what this is. return true; } // Get the instruction before it if it's a terminator. MachineInstr *SecondLastInst = I; // If there are three terminators, we don't know what sort of block this is. if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) return true; // The block ends with both a conditional branch and an ensuing // unconditional branch. if (LM32::isCondBranchOpcode(SecondLastInst->getOpcode()) && LM32::isUncondBranchOpcode(LastInst->getOpcode())) { DEBUG(dbgs() << "AnalyzeBranch:Conditional branch and ensuing unconditional\n"); TBB = GetBranchTarget(*SecondLastInst); Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode())); Cond.push_back(SecondLastInst->getOperand(0)); FBB = GetBranchTarget(*LastInst); DEBUG(dbgs() << "AnalyzeBranch: 2nd instr: " << *SecondLastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: last instr: " << *LastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: 2nd opcode: " << SecondLastInst->getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: last opcode: " << LastInst->getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB->getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: FBB: " << FBB->getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: Cond[0]:" << Cond[0] << "\n"); DEBUG(dbgs() << "AnalyzeBranch: Cond[1]:" << Cond[1] << "\n"); return false; } // If the block ends with two unconditional branches, handle it. // The second one is not executed, so remove it. if (LM32::isUncondBranchOpcode(SecondLastInst->getOpcode()) && LM32::isUncondBranchOpcode(LastInst->getOpcode())) { TBB = GetBranchTarget(*SecondLastInst); I = LastInst; if (AllowModify) I->eraseFromParent(); DEBUG(dbgs() << "AnalyzeBranch:two unconditional branches\n"); DEBUG(dbgs() << "AnalyzeBranch: instruction: " << *LastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: 2nd instr: " << *SecondLastInst << "\n"); DEBUG(dbgs() << "AnalyzeBranch: opcode: " << LastInst->getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: 2nd opcode: " << SecondLastInst->getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB->getName().str() << "\n"); return false; } // Otherwise, can't handle this. return true; }
/// computeIntervals - computes the live intervals for virtual /// registers. for some ordering of the machine instructions [1,N] a /// live interval is an interval [i, j) where 1 <= i <= j < N for /// which a variable is live void LiveIntervals::computeIntervals() { DEBUG(dbgs() << "********** COMPUTING LIVE INTERVALS **********\n" << "********** Function: " << MF->getName() << '\n'); RegMaskBlocks.resize(MF->getNumBlockIDs()); SmallVector<unsigned, 8> UndefUses; for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end(); MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; RegMaskBlocks[MBB->getNumber()].first = RegMaskSlots.size(); if (MBB->empty()) continue; // Track the index of the current machine instr. SlotIndex MIIndex = getMBBStartIdx(MBB); DEBUG(dbgs() << "BB#" << MBB->getNumber() << ":\t\t# derived from " << MBB->getName() << "\n"); // Skip over empty initial indices. if (getInstructionFromIndex(MIIndex) == 0) MIIndex = Indexes->getNextNonNullIndex(MIIndex); for (MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end(); MI != miEnd; ++MI) { DEBUG(dbgs() << MIIndex << "\t" << *MI); if (MI->isDebugValue()) continue; assert(Indexes->getInstructionFromIndex(MIIndex) == MI && "Lost SlotIndex synchronization"); // Handle defs. for (int i = MI->getNumOperands() - 1; i >= 0; --i) { MachineOperand &MO = MI->getOperand(i); // Collect register masks. if (MO.isRegMask()) { RegMaskSlots.push_back(MIIndex.getRegSlot()); RegMaskBits.push_back(MO.getRegMask()); continue; } if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue; // handle register defs - build intervals if (MO.isDef()) handleRegisterDef(MBB, MI, MIIndex, MO, i); else if (MO.isUndef()) UndefUses.push_back(MO.getReg()); } // Move to the next instr slot. MIIndex = Indexes->getNextNonNullIndex(MIIndex); } // Compute the number of register mask instructions in this block. std::pair<unsigned, unsigned> &RMB = RegMaskBlocks[MBB->getNumber()]; RMB.second = RegMaskSlots.size() - RMB.first; } // Create empty intervals for registers defined by implicit_def's (except // for those implicit_def that define values which are liveout of their // blocks. for (unsigned i = 0, e = UndefUses.size(); i != e; ++i) { unsigned UndefReg = UndefUses[i]; (void)getOrCreateInterval(UndefReg); } }
bool PTXInstrInfo:: AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, bool AllowModify) const { // TODO implement cases when AllowModify is true if (MBB.empty()) return true; MachineBasicBlock::const_iterator iter = MBB.end(); const MachineInstr& instLast1 = *--iter; const MCInstrDesc &desc1 = instLast1.getDesc(); // for special case that MBB has only 1 instruction const bool IsSizeOne = MBB.size() == 1; // if IsSizeOne is true, *--iter and instLast2 are invalid // we put a dummy value in instLast2 and desc2 since they are used const MachineInstr& instLast2 = IsSizeOne ? instLast1 : *--iter; const MCInstrDesc &desc2 = IsSizeOne ? desc1 : instLast2.getDesc(); DEBUG(dbgs() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: opcode: " << instLast1.getOpcode() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: MBB: " << MBB.getName().str() << "\n"); DEBUG(dbgs() << "AnalyzeBranch: TBB: " << TBB << "\n"); DEBUG(dbgs() << "AnalyzeBranch: FBB: " << FBB << "\n"); // this block ends with no branches if (!IsAnyKindOfBranch(instLast1)) { DEBUG(dbgs() << "AnalyzeBranch: ends with no branch\n"); return false; } // this block ends with only an unconditional branch if (desc1.isUnconditionalBranch() && // when IsSizeOne is true, it "absorbs" the evaluation of instLast2 (IsSizeOne || !IsAnyKindOfBranch(instLast2))) { DEBUG(dbgs() << "AnalyzeBranch: ends with only uncond branch\n"); TBB = GetBranchTarget(instLast1); return false; } // this block ends with a conditional branch and // it falls through to a successor block if (desc1.isConditionalBranch() && IsAnySuccessorAlsoLayoutSuccessor(MBB)) { DEBUG(dbgs() << "AnalyzeBranch: ends with cond branch and fall through\n"); TBB = GetBranchTarget(instLast1); int i = instLast1.findFirstPredOperandIdx(); Cond.push_back(instLast1.getOperand(i)); Cond.push_back(instLast1.getOperand(i+1)); return false; } // when IsSizeOne is true, we are done if (IsSizeOne) return true; // this block ends with a conditional branch // followed by an unconditional branch if (desc2.isConditionalBranch() && desc1.isUnconditionalBranch()) { DEBUG(dbgs() << "AnalyzeBranch: ends with cond and uncond branch\n"); TBB = GetBranchTarget(instLast2); FBB = GetBranchTarget(instLast1); int i = instLast2.findFirstPredOperandIdx(); Cond.push_back(instLast2.getOperand(i)); Cond.push_back(instLast2.getOperand(i+1)); return false; } // branch cannot be understood DEBUG(dbgs() << "AnalyzeBranch: cannot be understood\n"); return true; }