+
+ // Sort the frame references by local offset
+ array_pod_sort(FrameReferenceInsns.begin(), FrameReferenceInsns.end());
+
+ MachineBasicBlock *Entry = Fn.begin();
+
+ unsigned BaseReg = 0;
+ int64_t BaseOffset = 0;
+
+ // Loop through the frame references and allocate for them as necessary.
+ for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) {
+ FrameRef &FR = FrameReferenceInsns[ref];
+ MachineBasicBlock::iterator I = FR.getMachineInstr();
+ MachineInstr *MI = I;
+ int64_t LocalOffset = FR.getLocalOffset();
+ int FrameIdx = FR.getFrameIndex();
+ assert(MFI->isObjectPreAllocated(FrameIdx) &&
+ "Only pre-allocated locals expected!");
+
+ DEBUG(dbgs() << "Considering: " << *MI);
+
+ unsigned idx = 0;
+ for (unsigned f = MI->getNumOperands(); idx != f; ++idx) {
+ if (!MI->getOperand(idx).isFI())
+ continue;
+
+ if (FrameIdx == I->getOperand(idx).getIndex())
+ break;
+ }
+
+ assert(idx < MI->getNumOperands() && "Cannot find FI operand");
+
+ int64_t Offset = 0;
+ int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize() : 0;
+
+ DEBUG(dbgs() << " Replacing FI in: " << *MI);
+
+ // If we have a suitable base register available, use it; otherwise
+ // create a new one. Note that any offset encoded in the
+ // instruction itself will be taken into account by the target,
+ // so we don't have to adjust for it here when reusing a base
+ // register.
+ if (UsedBaseReg && lookupCandidateBaseReg(BaseOffset, FrameSizeAdjust,
+ LocalOffset, MI, TRI)) {
+ DEBUG(dbgs() << " Reusing base register " << BaseReg << "\n");
+ // We found a register to reuse.
+ Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
+ } else {
+ // No previously defined register was in range, so create a // new one.
+
+ int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, idx);
+
+ int64_t PrevBaseOffset = BaseOffset;
+ BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
+
+ // We'd like to avoid creating single-use virtual base registers.
+ // Because the FrameRefs are in sorted order, and we've already
+ // processed all FrameRefs before this one, just check whether or not
+ // the next FrameRef will be able to reuse this new register. If not,
+ // then don't bother creating it.
+ bool CanReuse = false;
+ for (int refn = ref + 1; refn < e; ++refn) {
+ FrameRef &FRN = FrameReferenceInsns[refn];
+ MachineBasicBlock::iterator J = FRN.getMachineInstr();
+ MachineInstr *MIN = J;
+
+ CanReuse = lookupCandidateBaseReg(BaseOffset, FrameSizeAdjust,
+ FRN.getLocalOffset(), MIN, TRI);
+ break;
+ }
+
+ if (!CanReuse) {
+ BaseOffset = PrevBaseOffset;
+ continue;
+ }
+
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const TargetRegisterClass *RC = TRI->getPointerRegClass(*MF);
+ BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
+
+ DEBUG(dbgs() << " Materializing base register " << BaseReg <<
+ " at frame local offset " << LocalOffset + InstrOffset << "\n");
+
+ // Tell the target to insert the instruction to initialize
+ // the base register.
+ // MachineBasicBlock::iterator InsertionPt = Entry->begin();
+ TRI->materializeFrameBaseRegister(Entry, BaseReg, FrameIdx,
+ InstrOffset);
+
+ // The base register already includes any offset specified
+ // by the instruction, so account for that so it doesn't get
+ // applied twice.
+ Offset = -InstrOffset;
+
+ ++NumBaseRegisters;
+ UsedBaseReg = true;
+ }
+ assert(BaseReg != 0 && "Unable to allocate virtual base register!");
+
+ // Modify the instruction to use the new base register rather
+ // than the frame index operand.
+ TRI->resolveFrameIndex(I, BaseReg, Offset);
+ DEBUG(dbgs() << "Resolved: " << *MI);
+
+ ++NumReplacements;
+ }
+
+ return UsedBaseReg;