+std::vector<LiveInterval*> LiveIntervals::
+addIntervalsForSpillsFast(const LiveInterval &li,
+ const MachineLoopInfo *loopInfo,
+ VirtRegMap &vrm) {
+ unsigned slot = vrm.assignVirt2StackSlot(li.reg);
+
+ std::vector<LiveInterval*> added;
+
+ assert(li.weight != HUGE_VALF &&
+ "attempt to spill already spilled interval!");
+
+ DOUT << "\t\t\t\tadding intervals for spills for interval: ";
+ DEBUG(li.dump());
+ DOUT << '\n';
+
+ const TargetRegisterClass* rc = mri_->getRegClass(li.reg);
+
+ MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg);
+ while (RI != mri_->reg_end()) {
+ MachineInstr* MI = &*RI;
+
+ SmallVector<unsigned, 2> Indices;
+ bool HasUse = false;
+ bool HasDef = false;
+
+ for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+ MachineOperand& mop = MI->getOperand(i);
+ if (!mop.isReg() || mop.getReg() != li.reg) continue;
+
+ HasUse |= MI->getOperand(i).isUse();
+ HasDef |= MI->getOperand(i).isDef();
+
+ Indices.push_back(i);
+ }
+
+ if (!tryFoldMemoryOperand(MI, vrm, NULL, getInstructionIndex(MI),
+ Indices, true, slot, li.reg)) {
+ unsigned NewVReg = mri_->createVirtualRegister(rc);
+ vrm.grow();
+ vrm.assignVirt2StackSlot(NewVReg, slot);
+
+ // create a new register for this spill
+ LiveInterval &nI = getOrCreateInterval(NewVReg);
+
+ // the spill weight is now infinity as it
+ // cannot be spilled again
+ nI.weight = HUGE_VALF;
+
+ // Rewrite register operands to use the new vreg.
+ for (SmallVectorImpl<unsigned>::iterator I = Indices.begin(),
+ E = Indices.end(); I != E; ++I) {
+ MI->getOperand(*I).setReg(NewVReg);
+
+ if (MI->getOperand(*I).isUse())
+ MI->getOperand(*I).setIsKill(true);
+ }
+
+ // Fill in the new live interval.
+ unsigned index = getInstructionIndex(MI);
+ if (HasUse) {
+ LiveRange LR(getLoadIndex(index), getUseIndex(index),
+ nI.getNextValue(0, 0, false, getVNInfoAllocator()));
+ DOUT << " +" << LR;
+ nI.addRange(LR);
+ vrm.addRestorePoint(NewVReg, MI);
+ }
+ if (HasDef) {
+ LiveRange LR(getDefIndex(index), getStoreIndex(index),
+ nI.getNextValue(0, 0, false, getVNInfoAllocator()));
+ DOUT << " +" << LR;
+ nI.addRange(LR);
+ vrm.addSpillPoint(NewVReg, true, MI);
+ }
+
+ added.push_back(&nI);
+
+ DOUT << "\t\t\t\tadded new interval: ";
+ DEBUG(nI.dump());
+ DOUT << '\n';
+ }
+
+
+ RI = mri_->reg_begin(li.reg);
+ }
+
+ return added;
+}