VNInfo *SplitEditor::defValue(unsigned RegIdx, const VNInfo *ParentVNI, SlotIndex Idx) { assert(ParentVNI && "Mapping NULL value"); assert(Idx.isValid() && "Invalid SlotIndex"); assert(Edit->getParent().getVNInfoAt(Idx) == ParentVNI && "Bad Parent VNI"); LiveInterval *LI = Edit->get(RegIdx); // Create a new value. VNInfo *VNI = LI->getNextValue(Idx, 0, LIS.getVNInfoAllocator()); // Use insert for lookup, so we can add missing values with a second lookup. std::pair<ValueMap::iterator, bool> InsP = Values.insert(std::make_pair(std::make_pair(RegIdx, ParentVNI->id), ValueForcePair(VNI, false))); // This was the first time (RegIdx, ParentVNI) was mapped. // Keep it as a simple def without any liveness. if (InsP.second) return VNI; // If the previous value was a simple mapping, add liveness for it now. if (VNInfo *OldVNI = InsP.first->second.getPointer()) { SlotIndex Def = OldVNI->def; LI->addRange(LiveRange(Def, Def.getNextSlot(), OldVNI)); // No longer a simple mapping. Switch to a complex, non-forced mapping. InsP.first->second = ValueForcePair(); } // This is a complex mapping, add liveness for VNI SlotIndex Def = VNI->def; LI->addRange(LiveRange(Def, Def.getNextSlot(), VNI)); return VNI; }
/// When adding a new instruction to liveness, the newly added definition /// will start a new live segment. This may happen at a position that falls /// within an existing live segment. In such case that live segment needs to /// be truncated to make room for the new segment. Ultimately, the truncation /// will occur at the last use, but for now the segment can be terminated /// right at the place where the new segment will start. The segments will be /// shrunk-to-uses later. void HexagonExpandCondsets::terminateSegment(LiveInterval::iterator LT, SlotIndex S, LiveInterval &LI) { // Terminate the live segment pointed to by LT within a live interval LI. if (LT == LI.end()) return; VNInfo *OldVN = LT->valno; SlotIndex EX = LT->end; LT->end = S; // If LT does not end at a block boundary, the termination is done. if (!EX.isBlock()) return; // If LT ended at a block boundary, it's possible that its value number // is picked up at the beginning other blocks. Create a new value number // and change such blocks to use it instead. VNInfo *NewVN = 0; for (LiveInterval::iterator I = LI.begin(), E = LI.end(); I != E; ++I) { if (!I->start.isBlock() || I->valno != OldVN) continue; // Generate on-demand a new value number that is defined by the // block beginning (i.e. -phi). if (!NewVN) NewVN = LI.getNextValue(I->start, LIS->getVNInfoAllocator()); I->valno = NewVN; } }
/// insertSpill - Insert a spill of NewLI.reg after MI. void InlineSpiller::insertSpill(LiveInterval &NewLI, const LiveInterval &OldLI, SlotIndex Idx, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); TII.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, StackSlot, MRI.getRegClass(NewLI.reg), &TRI); --MI; // Point to store instruction. SlotIndex StoreIdx = LIS.InsertMachineInstrInMaps(MI).getRegSlot(); DEBUG(dbgs() << "\tspilled: " << StoreIdx << '\t' << *MI); VNInfo *StoreVNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator()); NewLI.addRange(LiveRange(Idx, StoreIdx, StoreVNI)); ++NumSpills; }
/// insertSpill - Insert a spill of NewLI.reg after MI. void InlineSpiller::insertSpill(LiveInterval &NewLI, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex(); tii_.storeRegToStackSlot(MBB, ++MI, NewLI.reg, true, stackSlot_, rc_, &tri_); --MI; // Point to store instruction. SlotIndex StoreIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex(); vrm_.addSpillSlotUse(stackSlot_, MI); DEBUG(dbgs() << "\tspilled: " << StoreIdx << '\t' << *MI); VNInfo *StoreVNI = NewLI.getNextValue(Idx, 0, true, lis_.getVNInfoAllocator()); NewLI.addRange(LiveRange(Idx, StoreIdx, StoreVNI)); }
/// insertReload - Insert a reload of NewLI.reg before MI. void InlineSpiller::insertReload(LiveInterval &NewLI, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); SlotIndex Idx = lis_.getInstructionIndex(MI).getDefIndex(); tii_.loadRegFromStackSlot(MBB, MI, NewLI.reg, stackSlot_, rc_, &tri_); --MI; // Point to load instruction. SlotIndex LoadIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex(); vrm_.addSpillSlotUse(stackSlot_, MI); DEBUG(dbgs() << "\treload: " << LoadIdx << '\t' << *MI); VNInfo *LoadVNI = NewLI.getNextValue(LoadIdx, 0, true, lis_.getVNInfoAllocator()); NewLI.addRange(LiveRange(LoadIdx, Idx, LoadVNI)); }
/// insertReload - Insert a reload of NewLI.reg before MI. void InlineSpiller::insertReload(LiveInterval &NewLI, SlotIndex Idx, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); TII.loadRegFromStackSlot(MBB, MI, NewLI.reg, StackSlot, MRI.getRegClass(NewLI.reg), &TRI); --MI; // Point to load instruction. SlotIndex LoadIdx = LIS.InsertMachineInstrInMaps(MI).getRegSlot(); // Some (out-of-tree) targets have EC reload instructions. if (MachineOperand *MO = MI->findRegisterDefOperand(NewLI.reg)) if (MO->isEarlyClobber()) LoadIdx = LoadIdx.getRegSlot(true); DEBUG(dbgs() << "\treload: " << LoadIdx << '\t' << *MI); VNInfo *LoadVNI = NewLI.getNextValue(LoadIdx, LIS.getVNInfoAllocator()); NewLI.addRange(LiveRange(LoadIdx, Idx, LoadVNI)); ++NumReloads; }
bool StackColoring::runOnMachineFunction(MachineFunction &Func) { DEBUG(dbgs() << "********** Stack Coloring **********\n" << "********** Function: " << ((const Value*)Func.getFunction())->getName() << '\n'); MF = &Func; MFI = MF->getFrameInfo(); Indexes = &getAnalysis<SlotIndexes>(); BlockLiveness.clear(); BasicBlocks.clear(); BasicBlockNumbering.clear(); Markers.clear(); Intervals.clear(); VNInfoAllocator.Reset(); unsigned NumSlots = MFI->getObjectIndexEnd(); // If there are no stack slots then there are no markers to remove. if (!NumSlots) return false; SmallVector<int, 8> SortedSlots; SortedSlots.reserve(NumSlots); Intervals.reserve(NumSlots); unsigned NumMarkers = collectMarkers(NumSlots); unsigned TotalSize = 0; DEBUG(dbgs()<<"Found "<<NumMarkers<<" markers and "<<NumSlots<<" slots\n"); DEBUG(dbgs()<<"Slot structure:\n"); for (int i=0; i < MFI->getObjectIndexEnd(); ++i) { DEBUG(dbgs()<<"Slot #"<<i<<" - "<<MFI->getObjectSize(i)<<" bytes.\n"); TotalSize += MFI->getObjectSize(i); } DEBUG(dbgs()<<"Total Stack size: "<<TotalSize<<" bytes\n\n"); // Don't continue because there are not enough lifetime markers, or the // stack is too small, or we are told not to optimize the slots. if (NumMarkers < 2 || TotalSize < 16 || DisableColoring) { DEBUG(dbgs()<<"Will not try to merge slots.\n"); return removeAllMarkers(); } for (unsigned i=0; i < NumSlots; ++i) { LiveInterval *LI = new LiveInterval(i, 0); Intervals.push_back(LI); LI->getNextValue(Indexes->getZeroIndex(), VNInfoAllocator); SortedSlots.push_back(i); } // Calculate the liveness of each block. calculateLocalLiveness(); // Propagate the liveness information. calculateLiveIntervals(NumSlots); // Search for allocas which are used outside of the declared lifetime // markers. if (ProtectFromEscapedAllocas) removeInvalidSlotRanges(); // Maps old slots to new slots. DenseMap<int, int> SlotRemap; unsigned RemovedSlots = 0; unsigned ReducedSize = 0; // Do not bother looking at empty intervals. for (unsigned I = 0; I < NumSlots; ++I) { if (Intervals[SortedSlots[I]]->empty()) SortedSlots[I] = -1; } // This is a simple greedy algorithm for merging allocas. First, sort the // slots, placing the largest slots first. Next, perform an n^2 scan and look // for disjoint slots. When you find disjoint slots, merge the samller one // into the bigger one and update the live interval. Remove the small alloca // and continue. // Sort the slots according to their size. Place unused slots at the end. // Use stable sort to guarantee deterministic code generation. std::stable_sort(SortedSlots.begin(), SortedSlots.end(), SlotSizeSorter(MFI)); bool Changed = true; while (Changed) { Changed = false; for (unsigned I = 0; I < NumSlots; ++I) { if (SortedSlots[I] == -1) continue; for (unsigned J=I+1; J < NumSlots; ++J) { if (SortedSlots[J] == -1) continue; int FirstSlot = SortedSlots[I]; int SecondSlot = SortedSlots[J]; LiveInterval *First = Intervals[FirstSlot]; LiveInterval *Second = Intervals[SecondSlot]; assert (!First->empty() && !Second->empty() && "Found an empty range"); // Merge disjoint slots. if (!First->overlaps(*Second)) { Changed = true; First->MergeSegmentsInAsValue(*Second, First->getValNumInfo(0)); SlotRemap[SecondSlot] = FirstSlot; SortedSlots[J] = -1; DEBUG(dbgs()<<"Merging #"<<FirstSlot<<" and slots #"<< SecondSlot<<" together.\n"); unsigned MaxAlignment = std::max(MFI->getObjectAlignment(FirstSlot), MFI->getObjectAlignment(SecondSlot)); assert(MFI->getObjectSize(FirstSlot) >= MFI->getObjectSize(SecondSlot) && "Merging a small object into a larger one"); RemovedSlots+=1; ReducedSize += MFI->getObjectSize(SecondSlot); MFI->setObjectAlignment(FirstSlot, MaxAlignment); MFI->RemoveStackObject(SecondSlot); } } } }// While changed. // Record statistics. StackSpaceSaved += ReducedSize; StackSlotMerged += RemovedSlots; DEBUG(dbgs()<<"Merge "<<RemovedSlots<<" slots. Saved "<< ReducedSize<<" bytes\n"); // Scan the entire function and update all machine operands that use frame // indices to use the remapped frame index. expungeSlotMap(SlotRemap, NumSlots); remapInstructions(SlotRemap); // Release the intervals. for (unsigned I = 0; I < NumSlots; ++I) { delete Intervals[I]; } return removeAllMarkers(); }
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, MachineBasicBlock::iterator mi, SlotIndex MIIdx, MachineOperand& MO, unsigned MOIdx, LiveInterval &interval) { DEBUG(dbgs() << "\t\tregister: " << PrintReg(interval.reg, tri_)); // Virtual registers may be defined multiple times (due to phi // elimination and 2-addr elimination). Much of what we do only has to be // done once for the vreg. We use an empty interval to detect the first // time we see a vreg. LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); if (interval.empty()) { // Get the Idx of the defining instructions. SlotIndex defIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); // Make sure the first definition is not a partial redefinition. Add an // <imp-def> of the full register. // FIXME: LiveIntervals shouldn't modify the code like this. Whoever // created the machine instruction should annotate it with <undef> flags // as needed. Then we can simply assert here. The REG_SEQUENCE lowering // is the main suspect. if (MO.getSubReg()) { mi->addRegisterDefined(interval.reg); // Mark all defs of interval.reg on this instruction as reading <undef>. for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) { MachineOperand &MO2 = mi->getOperand(i); if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg()) MO2.setIsUndef(); } } MachineInstr *CopyMI = NULL; if (mi->isCopyLike()) { CopyMI = mi; } VNInfo *ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator); assert(ValNo->id == 0 && "First value in interval is not 0?"); // Loop over all of the blocks that the vreg is defined in. There are // two cases we have to handle here. The most common case is a vreg // whose lifetime is contained within a basic block. In this case there // will be a single kill, in MBB, which comes after the definition. if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) { // FIXME: what about dead vars? SlotIndex killIdx; if (vi.Kills[0] != mi) killIdx = getInstructionIndex(vi.Kills[0]).getRegSlot(); else killIdx = defIndex.getDeadSlot(); // If the kill happens after the definition, we have an intra-block // live range. if (killIdx > defIndex) { assert(vi.AliveBlocks.empty() && "Shouldn't be alive across any blocks!"); LiveRange LR(defIndex, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR << "\n"); return; } } // The other case we handle is when a virtual register lives to the end // of the defining block, potentially live across some blocks, then is // live into some number of blocks, but gets killed. Start by adding a // range that goes from this definition to the end of the defining block. LiveRange NewLR(defIndex, getMBBEndIdx(mbb), ValNo); DEBUG(dbgs() << " +" << NewLR); interval.addRange(NewLR); bool PHIJoin = lv_->isPHIJoin(interval.reg); if (PHIJoin) { // A phi join register is killed at the end of the MBB and revived as a new // valno in the killing blocks. assert(vi.AliveBlocks.empty() && "Phi join can't pass through blocks"); DEBUG(dbgs() << " phi-join"); ValNo->setHasPHIKill(true); } else { // Iterate over all of the blocks that the variable is completely // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the // live interval. for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(), E = vi.AliveBlocks.end(); I != E; ++I) { MachineBasicBlock *aliveBlock = mf_->getBlockNumbered(*I); LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock), ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } // Finally, this virtual register is live from the start of any killing // block to the 'use' slot of the killing instruction. for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { MachineInstr *Kill = vi.Kills[i]; SlotIndex Start = getMBBStartIdx(Kill->getParent()); SlotIndex killIdx = getInstructionIndex(Kill).getRegSlot(); // Create interval with one of a NEW value number. Note that this value // number isn't actually defined by an instruction, weird huh? :) if (PHIJoin) { assert(getInstructionFromIndex(Start) == 0 && "PHI def index points at actual instruction."); ValNo = interval.getNextValue(Start, 0, VNInfoAllocator); ValNo->setIsPHIDef(true); } LiveRange LR(Start, killIdx, ValNo); interval.addRange(LR); DEBUG(dbgs() << " +" << LR); } } else { if (MultipleDefsBySameMI(*mi, MOIdx)) // Multiple defs of the same virtual register by the same instruction. // e.g. %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ... // This is likely due to elimination of REG_SEQUENCE instructions. Return // here since there is nothing to do. return; // If this is the second time we see a virtual register definition, it // must be due to phi elimination or two addr elimination. If this is // the result of two address elimination, then the vreg is one of the // def-and-use register operand. // It may also be partial redef like this: // 80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0 // 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0 bool PartReDef = isPartialRedef(MIIdx, MO, interval); if (PartReDef || mi->isRegTiedToUseOperand(MOIdx)) { // If this is a two-address definition, then we have already processed // the live range. The only problem is that we didn't realize there // are actually two values in the live interval. Because of this we // need to take the LiveRegion that defines this register and split it // into two values. SlotIndex RedefIndex = MIIdx.getRegSlot(MO.isEarlyClobber()); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex.getRegSlot(true)); VNInfo *OldValNo = OldLR->valno; SlotIndex DefIndex = OldValNo->def.getRegSlot(); // Delete the previous value, which should be short and continuous, // because the 2-addr copy must be in the same MBB as the redef. interval.removeRange(DefIndex, RedefIndex); // The new value number (#1) is defined by the instruction we claimed // defined value #0. VNInfo *ValNo = interval.createValueCopy(OldValNo, VNInfoAllocator); // Value#0 is now defined by the 2-addr instruction. OldValNo->def = RedefIndex; OldValNo->setCopy(0); // A re-def may be a copy. e.g. %reg1030:6<def> = VMOVD %reg1026, ... if (PartReDef && mi->isCopyLike()) OldValNo->setCopy(&*mi); // Add the new live interval which replaces the range for the input copy. LiveRange LR(DefIndex, RedefIndex, ValNo); DEBUG(dbgs() << " replace range with " << LR); interval.addRange(LR); // If this redefinition is dead, we need to add a dummy unit live // range covering the def slot. if (MO.isDead()) interval.addRange(LiveRange(RedefIndex, RedefIndex.getDeadSlot(), OldValNo)); DEBUG({ dbgs() << " RESULT: "; interval.print(dbgs(), tri_); }); } else if (lv_->isPHIJoin(interval.reg)) {