/// ConvertInstTo3Addr - Convert the specified two-address instruction into a /// three address one. Return true if this transformation was successful. bool TwoAddressInstructionPass::ConvertInstTo3Addr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, MachineFunction::iterator &mbbi, unsigned RegB, unsigned Dist) { MachineInstr *NewMI = TII->convertToThreeAddress(mbbi, mi, LV); if (NewMI) { DEBUG(errs() << "2addr: CONVERTING 2-ADDR: " << *mi); DEBUG(errs() << "2addr: TO 3-ADDR: " << *NewMI); bool Sunk = false; if (NewMI->findRegisterUseOperand(RegB, false, TRI)) // FIXME: Temporary workaround. If the new instruction doesn't // uses RegB, convertToThreeAddress must have created more // then one instruction. Sunk = Sink3AddrInstruction(mbbi, NewMI, RegB, mi); mbbi->erase(mi); // Nuke the old inst. if (!Sunk) { DistanceMap.insert(std::make_pair(NewMI, Dist)); mi = NewMI; nmi = next(mi); } return true; } return false; }
/// CommuteInstruction - Commute a two-address instruction and update the basic /// block, distance map, and live variables if needed. Return true if it is /// successful. bool TwoAddressInstructionPass::CommuteInstruction(MachineBasicBlock::iterator &mi, MachineFunction::iterator &mbbi, unsigned RegB, unsigned RegC, unsigned Dist) { MachineInstr *MI = mi; DEBUG(errs() << "2addr: COMMUTING : " << *MI); MachineInstr *NewMI = TII->commuteInstruction(MI); if (NewMI == 0) { DEBUG(errs() << "2addr: COMMUTING FAILED!\n"); return false; } DEBUG(errs() << "2addr: COMMUTED TO: " << *NewMI); // If the instruction changed to commute it, update livevar. if (NewMI != MI) { if (LV) // Update live variables LV->replaceKillInstruction(RegC, MI, NewMI); mbbi->insert(mi, NewMI); // Insert the new inst mbbi->erase(mi); // Nuke the old inst. mi = NewMI; DistanceMap.insert(std::make_pair(NewMI, Dist)); } // Update source register map. unsigned FromRegC = getMappedReg(RegC, SrcRegMap); if (FromRegC) { unsigned RegA = MI->getOperand(0).getReg(); SrcRegMap[RegA] = FromRegC; } return true; }
/// fixupLoopInsts - For Hexagon, if the loop label is to far from the /// loop instruction then we need to set the LC0 and SA0 registers /// explicitly instead of using LOOP(start,count). This function /// checks the distance, and generates register assignments if needed. /// /// This function makes two passes over the basic blocks. The first /// pass computes the offset of the basic block from the start. /// The second pass checks all the loop instructions. bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) { // Offset of the current instruction from the start. unsigned InstOffset = 0; // Map for each basic block to it's first instruction. DenseMap<MachineBasicBlock*, unsigned> BlockToInstOffset; // First pass - compute the offset of each basic block. for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); MBB != MBBe; ++MBB) { BlockToInstOffset[MBB] = InstOffset; InstOffset += (MBB->size() * 4); } // Second pass - check each loop instruction to see if it needs to // be converted. InstOffset = 0; bool Changed = false; RegScavenger RS; // Loop over all the basic blocks. for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); MBB != MBBe; ++MBB) { InstOffset = BlockToInstOffset[MBB]; RS.enterBasicBlock(MBB); // Loop over all the instructions. MachineBasicBlock::iterator MIE = MBB->end(); MachineBasicBlock::iterator MII = MBB->begin(); while (MII != MIE) { if (isHardwareLoop(MII)) { RS.forward(MII); assert(MII->getOperand(0).isMBB() && "Expect a basic block as loop operand"); int diff = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()]; diff = (diff > 0 ? diff : -diff); if ((unsigned)diff > MAX_LOOP_DISTANCE) { // Convert to explicity setting LC0 and SA0. convertLoopInstr(MF, MII, RS); MII = MBB->erase(MII); Changed = true; } else { ++MII; } } else { ++MII; } InstOffset += 4; } } return Changed; }
/// DeleteUnusedInstr - If an instruction with a tied register operand can /// be safely deleted, just delete it. bool TwoAddressInstructionPass::DeleteUnusedInstr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, MachineFunction::iterator &mbbi, unsigned Dist) { // Check if the instruction has no side effects and if all its defs are dead. SmallVector<unsigned, 4> Kills; if (!isSafeToDelete(mi, TII, Kills)) return false; // If this instruction kills some virtual registers, we need to // update the kill information. If it's not possible to do so, // then bail out. SmallVector<NewKill, 4> NewKills; if (!canUpdateDeletedKills(Kills, NewKills, &*mbbi, Dist)) return false; if (LV) { while (!NewKills.empty()) { MachineInstr *NewKill = NewKills.back().second; unsigned Kill = NewKills.back().first.first; bool isDead = NewKills.back().first.second; NewKills.pop_back(); if (LV->removeVirtualRegisterKilled(Kill, mi)) { if (isDead) LV->addVirtualRegisterDead(Kill, NewKill); else LV->addVirtualRegisterKilled(Kill, NewKill); } } } mbbi->erase(mi); // Nuke the old inst. mi = nmi; return true; }
/// scavengeFrameVirtualRegs - Replace all frame index virtual registers /// with physical registers. Use the register scavenger to find an /// appropriate register to use. void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { // Run through the instructions and find any virtual registers. for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { RS->enterBasicBlock(BB); // FIXME: The logic flow in this function is still too convoluted. // It needs a cleanup refactoring. Do that in preparation for tracking // more than one scratch register value and using ranges to find // available scratch registers. unsigned CurrentVirtReg = 0; unsigned CurrentScratchReg = 0; bool havePrevValue = false; TargetRegisterInfo::FrameIndexValue PrevValue(0,0); TargetRegisterInfo::FrameIndexValue Value(0,0); MachineInstr *PrevLastUseMI = NULL; unsigned PrevLastUseOp = 0; bool trackingCurrentValue = false; int SPAdj = 0; // The instruction stream may change in the loop, so check BB->end() // directly. for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { MachineInstr *MI = I; bool isDefInsn = false; bool isKillInsn = false; bool clobbersScratchReg = false; bool DoIncr = true; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { if (MI->getOperand(i).isReg()) { MachineOperand &MO = MI->getOperand(i); unsigned Reg = MO.getReg(); if (Reg == 0) continue; if (!TargetRegisterInfo::isVirtualRegister(Reg)) { // If we have a previous scratch reg, check and see if anything // here kills whatever value is in there. if (Reg == CurrentScratchReg) { if (MO.isUse()) { // Two-address operands implicitly kill if (MO.isKill() || MI->isRegTiedToDefOperand(i)) clobbersScratchReg = true; } else { assert (MO.isDef()); clobbersScratchReg = true; } } continue; } // If this is a def, remember that this insn defines the value. // This lets us properly consider insns which re-use the scratch // register, such as r2 = sub r2, #imm, in the middle of the // scratch range. if (MO.isDef()) isDefInsn = true; // Have we already allocated a scratch register for this virtual? if (Reg != CurrentVirtReg) { // When we first encounter a new virtual register, it // must be a definition. assert(MI->getOperand(i).isDef() && "frame index virtual missing def!"); // We can't have nested virtual register live ranges because // there's only a guarantee of one scavenged register at a time. assert (CurrentVirtReg == 0 && "overlapping frame index virtual registers!"); // If the target gave us information about what's in the register, // we can use that to re-use scratch regs. DenseMap<unsigned, FrameConstantEntry>::iterator Entry = FrameConstantRegMap.find(Reg); trackingCurrentValue = Entry != FrameConstantRegMap.end(); if (trackingCurrentValue) { SPAdj = (*Entry).second.second; Value = (*Entry).second.first; } else { SPAdj = 0; Value.first = 0; Value.second = 0; } // If the scratch register from the last allocation is still // available, see if the value matches. If it does, just re-use it. if (trackingCurrentValue && havePrevValue && PrevValue == Value) { // FIXME: This assumes that the instructions in the live range // for the virtual register are exclusively for the purpose // of populating the value in the register. That's reasonable // for these frame index registers, but it's still a very, very // strong assumption. rdar://7322732. Better would be to // explicitly check each instruction in the range for references // to the virtual register. Only delete those insns that // touch the virtual register. // Find the last use of the new virtual register. Remove all // instruction between here and there, and update the current // instruction to reference the last use insn instead. MachineBasicBlock::iterator LastUseMI = findLastUseReg(I, BB->end(), Reg); // Remove all instructions up 'til the last use, since they're // just calculating the value we already have. BB->erase(I, LastUseMI); I = LastUseMI; // Extend the live range of the scratch register PrevLastUseMI->getOperand(PrevLastUseOp).setIsKill(false); RS->setUsed(CurrentScratchReg); CurrentVirtReg = Reg; // We deleted the instruction we were scanning the operands of. // Jump back to the instruction iterator loop. Don't increment // past this instruction since we updated the iterator already. DoIncr = false; break; } // Scavenge a new scratch register CurrentVirtReg = Reg; const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); CurrentScratchReg = RS->scavengeRegister(RC, I, SPAdj); PrevValue = Value; } // replace this reference to the virtual register with the // scratch register. assert (CurrentScratchReg && "Missing scratch register!"); MI->getOperand(i).setReg(CurrentScratchReg); if (MI->getOperand(i).isKill()) { isKillInsn = true; PrevLastUseOp = i; PrevLastUseMI = MI; } } } // If this is the last use of the scratch, stop tracking it. The // last use will be a kill operand in an instruction that does // not also define the scratch register. if (isKillInsn && !isDefInsn) { CurrentVirtReg = 0; havePrevValue = trackingCurrentValue; } // Similarly, notice if instruction clobbered the value in the // register we're tracking for possible later reuse. This is noted // above, but enforced here since the value is still live while we // process the rest of the operands of the instruction. if (clobbersScratchReg) { havePrevValue = false; CurrentScratchReg = 0; } if (DoIncr) { RS->forward(I); ++I; } } } }
bool MSPUPacketizer::runOnMachineFunction(MachineFunction &Fn) { const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); // Instantiate the packetizer. MSPUPacketizerList Packetizer(Fn, MLI, MDT); // DFA state table should not be empty. assert(Packetizer.getResourceTracker() && "Empty DFA table!"); // // Loop over all basic blocks and remove KILL pseudo-instructions // These instructions confuse the dependence analysis. Consider: // D0 = ... (Insn 0) // R0 = KILL R0, D0 (Insn 1) // R0 = ... (Insn 2) // Here, Insn 1 will result in the dependence graph not emitting an output // dependence between Insn 0 and Insn 2. This can lead to incorrect // packetization // for(MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) { MachineBasicBlock::iterator End = MBB->end(); MachineBasicBlock::iterator MI = MBB->begin(); while(MI != End) { if(MI->isKill()) { MachineBasicBlock::iterator DeleteMI = MI; ++MI; MBB->erase(DeleteMI); End = MBB->end(); continue; } ++MI; } } // Loop over all of the basic blocks. for(MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); MBB != MBBe; ++MBB) { // Find scheduling regions and schedule / packetize each region. unsigned RemainingCount = MBB->size(); for(MachineBasicBlock::iterator RegionEnd = MBB->end(); RegionEnd != MBB->begin();) { // The next region starts above the previous region. Look backward in the // instruction stream until we find the nearest boundary. MachineBasicBlock::iterator I = RegionEnd; for(; I != MBB->begin(); --I, --RemainingCount) { if(TII->isSchedulingBoundary(llvm::prior(I), MBB, Fn)) break; } I = MBB->begin(); // Skip empty scheduling regions. if(I == RegionEnd) { RegionEnd = llvm::prior(RegionEnd); --RemainingCount; continue; } // Skip regions with one instruction. if(I == llvm::prior(RegionEnd)) { RegionEnd = llvm::prior(RegionEnd); continue; } // PacketizeMIs() does a VLIW scheduling on MachineInstr list and packetizing. Packetizer.PacketizeMIs(MBB, I, RegionEnd); RegionEnd = I; } } return true; }