[llvm-commits] [llvm] r111585 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h lib/CodeGen/LocalStackSlotAllocation.cpp lib/Target/ARM/ARMBaseRegisterInfo.cpp lib/Target/ARM/ARMBaseRegisterInfo.h
Jim Grosbach
grosbach at apple.com
Thu Aug 19 16:52:25 PDT 2010
Author: grosbach
Date: Thu Aug 19 18:52:25 2010
New Revision: 111585
URL: http://llvm.org/viewvc/llvm-project?rev=111585&view=rev
Log:
Better handling of offsets on frame index references. rdar://8277890
Modified:
llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h
Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=111585&r1=111584&r2=111585&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Thu Aug 19 18:52:25 2010
@@ -636,6 +636,12 @@
return false;
}
+ /// getFrameIndexInstrOffset - Get the offset from the referenced frame
+ /// index in the instruction, if the is one.
+ virtual int64_t getFrameIndexInstrOffset(MachineInstr *MI, int Idx) const {
+ return 0;
+ }
+
/// needsFrameBaseReg - Returns true if the instruction's frame index
/// reference would be better served by a base register other than FP
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
@@ -647,8 +653,8 @@
/// materializeFrameBaseRegister - Insert defining instruction(s) for
/// BaseReg to be a pointer to FrameIdx before insertion point I.
virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
- unsigned BaseReg,
- int FrameIdx) const {
+ unsigned BaseReg, int FrameIdx,
+ int64_t Offset) const {
assert(0 && "materializeFrameBaseRegister does not exist on this target");
}
@@ -659,11 +665,11 @@
assert(0 && "resolveFrameIndex does not exist on this target");
}
- /// isBaseRegInRange - Determine whether a given base register definition
- /// is in range to resolve a frame index.
- virtual bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
- int64_t Offset) const {
- assert(0 && "isBaseRegInRange does not exist on this target");
+ /// isFrameOffsetLegal - Determine whether a given offset immediate is
+ /// encodable to resolve a frame index.
+ virtual bool isFrameOffsetLegal(const MachineInstr *MI,
+ int64_t Offset) const {
+ assert(0 && "isFrameOffsetLegal does not exist on this target");
return false; // Must return a value in order to compile with VS 2005
}
Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp?rev=111585&r1=111584&r2=111585&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp (original)
+++ llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Thu Aug 19 18:52:25 2010
@@ -182,7 +182,7 @@
// Check if the relative offset from the where the base register references
// to the target address is in range for the instruction.
int64_t Offset = LocalFrameOffset - RegOffset.second;
- if (TRI->isBaseRegInRange(MI, RegOffset.first, Offset))
+ if (TRI->isFrameOffsetLegal(MI, Offset))
return true;
}
return false;
@@ -225,6 +225,7 @@
// an object allocated in the local block.
if (MI->getOperand(i).isFI()) {
int FrameIdx = MI->getOperand(i).getIndex();
+
// Don't try this with values not in the local block.
if (!MFI->isObjectPreAllocated(FrameIdx))
continue;
@@ -232,13 +233,15 @@
DEBUG(dbgs() << "Considering: " << *MI);
if (TRI->needsFrameBaseReg(MI, i)) {
unsigned BaseReg = 0;
- unsigned Offset = 0;
+ int64_t Offset = 0;
DEBUG(dbgs() << " Replacing FI in: " << *MI);
// If we have a suitable base register available, use it; otherwise
- // create a new one.
-
+ // 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.
std::pair<unsigned, int64_t> RegOffset;
if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
LocalOffsets[FrameIdx], MI, TRI)) {
@@ -250,15 +253,26 @@
} else {
// No previously defined register was in range, so create a
// new one.
+ int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, i);
const TargetRegisterClass *RC = TRI->getPointerRegClass();
BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
+ DEBUG(dbgs() << " Materializing base register " << BaseReg <<
+ " at frame local offset " <<
+ LocalOffsets[FrameIdx] + InstrOffset << "\n");
// Tell the target to insert the instruction to initialize
// the base register.
- TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+ TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx,
+ InstrOffset);
- BaseRegisters.push_back(std::pair<unsigned, int64_t>(BaseReg,
- Offset));
+ // The base register already includes any offset specified
+ // by the instruction, so account for that so it doesn't get
+ // applied twice.
+ Offset = -InstrOffset;
+
+ BaseRegisters.push_back(
+ std::pair<unsigned, int64_t>(BaseReg,
+ LocalOffsets[FrameIdx] + InstrOffset));
++NumBaseRegisters;
}
assert(BaseReg != 0 && "Unable to allocate virtual base register!");
Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=111585&r1=111584&r2=111585&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Thu Aug 19 18:52:25 2010
@@ -1367,6 +1367,59 @@
MBB.erase(I);
}
+
+int64_t ARMBaseRegisterInfo::
+getFrameIndexInstrOffset(MachineInstr *MI, int Idx) const {
+ const TargetInstrDesc &Desc = MI->getDesc();
+ unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+ int64_t InstrOffs = 0;;
+ int Scale = 1;
+ unsigned ImmIdx = 0;
+ switch(AddrMode) {
+ case ARMII::AddrModeT2_i8:
+ case ARMII::AddrModeT2_i12:
+ // i8 supports only negative, and i12 supports only positive, so
+ // based on Offset sign, consider the appropriate instruction
+ InstrOffs = MI->getOperand(Idx+1).getImm();
+ Scale = 1;
+ break;
+ case ARMII::AddrMode5: {
+ // VFP address mode.
+ const MachineOperand &OffOp = MI->getOperand(Idx+1);
+ int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
+ if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
+ InstrOffs = -InstrOffs;
+ Scale = 4;
+ break;
+ }
+ case ARMII::AddrMode2: {
+ ImmIdx = Idx+2;
+ InstrOffs = ARM_AM::getAM2Offset(MI->getOperand(ImmIdx).getImm());
+ if (ARM_AM::getAM2Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
+ InstrOffs = -InstrOffs;
+ break;
+ }
+ case ARMII::AddrMode3: {
+ ImmIdx = Idx+2;
+ InstrOffs = ARM_AM::getAM3Offset(MI->getOperand(ImmIdx).getImm());
+ if (ARM_AM::getAM3Op(MI->getOperand(ImmIdx).getImm()) == ARM_AM::sub)
+ InstrOffs = -InstrOffs;
+ break;
+ }
+ case ARMII::AddrModeT1_s: {
+ ImmIdx = Idx+1;
+ InstrOffs = MI->getOperand(ImmIdx).getImm();
+ Scale = 4;
+ break;
+ }
+ default:
+ llvm_unreachable("Unsupported addressing mode!");
+ break;
+ }
+
+ return InstrOffs * Scale;
+}
+
/// needsFrameBaseReg - Returns true if the instruction's frame index
/// reference would be better served by a base register other than FP
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
@@ -1404,8 +1457,8 @@
/// materializeFrameBaseRegister - Insert defining instruction(s) for
/// BaseReg to be a pointer to FrameIdx before insertion point I.
void ARMBaseRegisterInfo::
-materializeFrameBaseRegister(MachineBasicBlock::iterator I,
- unsigned BaseReg, int FrameIdx) const {
+materializeFrameBaseRegister(MachineBasicBlock::iterator I, unsigned BaseReg,
+ int FrameIdx, int64_t Offset) const {
ARMFunctionInfo *AFI =
I->getParent()->getParent()->getInfo<ARMFunctionInfo>();
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri :
@@ -1413,7 +1466,7 @@
MachineInstrBuilder MIB =
BuildMI(*I->getParent(), I, I->getDebugLoc(), TII.get(ADDriOpc), BaseReg)
- .addFrameIndex(FrameIdx).addImm(0);
+ .addFrameIndex(FrameIdx).addImm(Offset);
if (!AFI->isThumb1OnlyFunction())
AddDefaultCC(AddDefaultPred(MIB));
}
@@ -1445,8 +1498,8 @@
assert (Done && "Unable to resolve frame index!");
}
-bool ARMBaseRegisterInfo::isBaseRegInRange(const MachineInstr *MI,
- unsigned Reg, int64_t Offset) const {
+bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
+ int64_t Offset) const {
const TargetInstrDesc &Desc = MI->getDesc();
unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
unsigned i = 0;
@@ -1464,6 +1517,7 @@
unsigned Scale = 1;
unsigned ImmIdx = 0;
int InstrOffs = 0;;
+ bool isSigned = true;
switch(AddrMode) {
case ARMII::AddrModeT2_i8:
case ARMII::AddrModeT2_i12:
@@ -1509,6 +1563,7 @@
InstrOffs = MI->getOperand(ImmIdx).getImm();
NumBits = 5;
Scale = 4;
+ isSigned = false;
break;
}
default:
@@ -1518,7 +1573,7 @@
Offset += InstrOffs * Scale;
assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
- if (Offset < 0)
+ if (isSigned && Offset < 0)
Offset = -Offset;
unsigned Mask = (1 << NumBits) - 1;
Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h?rev=111585&r1=111584&r2=111585&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h Thu Aug 19 18:52:25 2010
@@ -105,13 +105,14 @@
bool canRealignStack(const MachineFunction &MF) const;
bool needsStackRealignment(const MachineFunction &MF) const;
+ int64_t getFrameIndexInstrOffset(MachineInstr *MI, int Idx) const;
bool needsFrameBaseReg(MachineInstr *MI, unsigned operand) const;
void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
- unsigned BaseReg, int FrameIdx) const;
+ unsigned BaseReg, int FrameIdx,
+ int64_t Offset) const;
void resolveFrameIndex(MachineBasicBlock::iterator I,
unsigned BaseReg, int64_t Offset) const;
- bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
- int64_t Offset) const;
+ bool isFrameOffsetLegal(const MachineInstr *MI, int64_t Offset) const;
bool cannotEliminateFrame(const MachineFunction &MF) const;
More information about the llvm-commits
mailing list