Skip to content

Commit 70d484d

Browse files
author
Mandeep Singh Grang
committed
[COFF, ARM64] Fix localaddress to handle stack realignment and variable size objects
Summary: This fixes using the correct stack registers for SEH when stack realignment is needed or when variable size objects are present. Reviewers: rnk, efriedma, ssijaric, TomTan Reviewed By: rnk, efriedma Subscribers: javed.absar, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D57183 llvm-svn: 352923
1 parent e95550f commit 70d484d

File tree

11 files changed

+330
-112
lines changed

11 files changed

+330
-112
lines changed

llvm/include/llvm/CodeGen/MachineFunction.h

-4
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,6 @@ class MachineFunction {
328328
bool CallsUnwindInit = false;
329329
bool HasEHScopes = false;
330330
bool HasEHFunclets = false;
331-
bool HasLocalEscape = false;
332331

333332
/// List of C++ TypeInfo used.
334333
std::vector<const GlobalValue *> TypeInfos;
@@ -811,9 +810,6 @@ class MachineFunction {
811810
bool hasEHFunclets() const { return HasEHFunclets; }
812811
void setHasEHFunclets(bool V) { HasEHFunclets = V; }
813812

814-
bool hasLocalEscape() const { return HasLocalEscape; }
815-
void setHasLocalEscape(bool V) { HasLocalEscape = V; }
816-
817813
/// Find or create an LandingPadInfo for the specified MachineBasicBlock.
818814
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
819815

llvm/include/llvm/CodeGen/TargetFrameLowering.h

+11
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,17 @@ class TargetFrameLowering {
261261
return getFrameIndexReference(MF, FI, FrameReg);
262262
}
263263

264+
/// getNonLocalFrameIndexReference - This method returns the offset used to
265+
/// reference a frame index location. The offset can be from either FP/BP/SP
266+
/// based on which base register is returned by llvm.localaddress.
267+
virtual int getNonLocalFrameIndexReference(const MachineFunction &MF,
268+
int FI) const {
269+
// By default, dispatch to getFrameIndexReference. Interested targets can
270+
// override this.
271+
unsigned FrameReg;
272+
return getFrameIndexReference(MF, FI, FrameReg);
273+
}
274+
264275
/// This method determines which of the registers reported by
265276
/// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
266277
/// The default implementation checks populates the \p SavedRegs bitset with

llvm/lib/CodeGen/AsmPrinter/WinException.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -937,11 +937,7 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
937937
int FI = FuncInfo.EHRegNodeFrameIndex;
938938
if (FI != INT_MAX) {
939939
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
940-
unsigned UnusedReg;
941-
// FIXME: getFrameIndexReference needs to match the behavior of
942-
// AArch64RegisterInfo::hasBasePointer in which one of the scenarios where
943-
// SP is used is if frame size >= 256.
944-
Offset = TFI->getFrameIndexReference(*Asm->MF, FI, UnusedReg);
940+
Offset = TFI->getNonLocalFrameIndexReference(*Asm->MF, FI);
945941
}
946942

947943
MCContext &Ctx = Asm->OutContext;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -6220,8 +6220,6 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
62206220
.addFrameIndex(FI);
62216221
}
62226222

6223-
MF.setHasLocalEscape(true);
6224-
62256223
return nullptr;
62266224
}
62276225

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

+34-13
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,6 @@ bool AArch64FrameLowering::hasFP(const MachineFunction &MF) const {
227227
MFI.getMaxCallFrameSize() > DefaultSafeSPDisplacement)
228228
return true;
229229

230-
// Win64 SEH requires frame pointer if funclets are present.
231-
if (MF.hasLocalEscape())
232-
return true;
233-
234230
return false;
235231
}
236232

@@ -1469,19 +1465,44 @@ int AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF,
14691465
return resolveFrameIndexReference(MF, FI, FrameReg);
14701466
}
14711467

1468+
int AArch64FrameLowering::getNonLocalFrameIndexReference(
1469+
const MachineFunction &MF, int FI) const {
1470+
return getSEHFrameIndexOffset(MF, FI);
1471+
}
1472+
1473+
static int getFPOffset(const MachineFunction &MF, int FI) {
1474+
const auto &MFI = MF.getFrameInfo();
1475+
const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1476+
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1477+
bool IsWin64 =
1478+
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
1479+
unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
1480+
return MFI.getObjectOffset(FI) + FixedObject + 16;
1481+
}
1482+
1483+
static int getStackOffset(const MachineFunction &MF, int FI) {
1484+
const auto &MFI = MF.getFrameInfo();
1485+
return MFI.getObjectOffset(FI) + MFI.getStackSize();
1486+
}
1487+
1488+
int AArch64FrameLowering::getSEHFrameIndexOffset(const MachineFunction &MF,
1489+
int FI) const {
1490+
const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
1491+
MF.getSubtarget().getRegisterInfo());
1492+
return RegInfo->getLocalAddressRegister(MF) == AArch64::FP ?
1493+
getFPOffset(MF, FI) : getStackOffset(MF, FI);
1494+
}
1495+
14721496
int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF,
14731497
int FI, unsigned &FrameReg,
14741498
bool PreferFP) const {
1475-
const MachineFrameInfo &MFI = MF.getFrameInfo();
1476-
const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
1499+
const auto &MFI = MF.getFrameInfo();
1500+
const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
14771501
MF.getSubtarget().getRegisterInfo());
1478-
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
1479-
const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1480-
bool IsWin64 =
1481-
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
1482-
unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
1483-
int FPOffset = MFI.getObjectOffset(FI) + FixedObject + 16;
1484-
int Offset = MFI.getObjectOffset(FI) + MFI.getStackSize();
1502+
const auto *AFI = MF.getInfo<AArch64FunctionInfo>();
1503+
const auto &Subtarget = MF.getSubtarget<AArch64Subtarget>();
1504+
int FPOffset = getFPOffset(MF, FI);
1505+
int Offset = getStackOffset(MF, FI);
14851506
bool isFixed = MFI.isFixedObjectIndex(FI);
14861507
bool isCSR = !isFixed && MFI.getObjectOffset(FI) >=
14871508
-((int)AFI->getCalleeSavedStackSize());

llvm/lib/Target/AArch64/AArch64FrameLowering.h

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class AArch64FrameLowering : public TargetFrameLowering {
7878
int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
7979
unsigned &FrameReg,
8080
bool IgnoreSPUpdates) const override;
81+
int getNonLocalFrameIndexReference(const MachineFunction &MF,
82+
int FI) const override;
83+
int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
8184

8285
private:
8386
bool shouldCombineCSRLocalStackBump(MachineFunction &MF,

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

+3-9
Original file line numberDiff line numberDiff line change
@@ -2744,15 +2744,9 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
27442744
Op.getOperand(1), Op.getOperand(2));
27452745

27462746
case Intrinsic::localaddress: {
2747-
// Returns one of the stack, base, or frame pointer registers, depending on
2748-
// which is used to reference local variables.
2749-
MachineFunction &MF = DAG.getMachineFunction();
2750-
const AArch64RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2751-
unsigned Reg;
2752-
if (RegInfo->hasBasePointer(MF))
2753-
Reg = RegInfo->getBaseRegister();
2754-
else // This function handles the SP or FP case.
2755-
Reg = RegInfo->getFrameRegister(MF);
2747+
const auto &MF = DAG.getMachineFunction();
2748+
const auto *RegInfo = Subtarget->getRegisterInfo();
2749+
unsigned Reg = RegInfo->getLocalAddressRegister(MF);
27562750
return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg,
27572751
Op.getSimpleValueType());
27582752
}

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,16 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
463463
return;
464464
}
465465

466-
// Modify MI as necessary to handle as much of 'Offset' as possible
467-
Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg);
468-
469466
if (MI.getOpcode() == TargetOpcode::LOCAL_ESCAPE) {
470467
MachineOperand &FI = MI.getOperand(FIOperandNum);
468+
Offset = TFI->getNonLocalFrameIndexReference(MF, FrameIndex);
471469
FI.ChangeToImmediate(Offset);
472470
return;
473471
}
474472

473+
// Modify MI as necessary to handle as much of 'Offset' as possible
474+
Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
475+
475476
if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
476477
return;
477478

@@ -525,3 +526,13 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
525526
return 16;
526527
}
527528
}
529+
530+
unsigned AArch64RegisterInfo::getLocalAddressRegister(
531+
const MachineFunction &MF) const {
532+
const auto &MFI = MF.getFrameInfo();
533+
if (!MF.hasEHFunclets() && !MFI.hasVarSizedObjects())
534+
return AArch64::SP;
535+
else if (needsStackRealignment(MF))
536+
return getBaseRegister();
537+
return getFrameRegister(MF);
538+
}

llvm/lib/Target/AArch64/AArch64RegisterInfo.h

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
121121
bool trackLivenessAfterRegAlloc(const MachineFunction&) const override {
122122
return true;
123123
}
124+
125+
unsigned getLocalAddressRegister(const MachineFunction &MF) const;
124126
};
125127

126128
} // end namespace llvm

0 commit comments

Comments
 (0)