Skip to content

Commit

Permalink
[WinEH] Update exception pointer registers
Browse files Browse the repository at this point in the history
Summary:
The CLR's personality routine passes these in rdx/edx, not rax/eax.

Make getExceptionPointerRegister a virtual method parameterized by
personality function to allow making this distinction.

Similarly make getExceptionSelectorRegister a virtual method parameterized
by personality function, for symmetry.


Reviewers: pgavlin, majnemer, rnk

Subscribers: jyknight, dsanders, llvm-commits

Differential Revision: http://reviews.llvm.org/D14344

llvm-svn: 252383
  • Loading branch information
JosephTremoulet committed Nov 7, 2015
1 parent c22811b commit f748c89
Show file tree
Hide file tree
Showing 25 changed files with 210 additions and 90 deletions.
34 changes: 9 additions & 25 deletions llvm/include/llvm/Target/TargetLowering.h
Expand Up @@ -939,15 +939,19 @@ class TargetLoweringBase {
}

/// If a physical register, this returns the register that receives the
/// exception address on entry to a landing pad.
unsigned getExceptionPointerRegister() const {
return ExceptionPointerRegister;
/// exception address on entry to an EH pad.
virtual unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const {
// 0 is guaranteed to be the NoRegister value on all targets
return 0;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned getExceptionSelectorRegister() const {
return ExceptionSelectorRegister;
virtual unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const {
// 0 is guaranteed to be the NoRegister value on all targets
return 0;
}

/// Returns the target's jmp_buf size in bytes (if never set, the default is
Expand Down Expand Up @@ -1228,18 +1232,6 @@ class TargetLoweringBase {
StackPointerRegisterToSaveRestore = R;
}

/// If set to a physical register, this sets the register that receives the
/// exception address on entry to a landing pad.
void setExceptionPointerRegister(unsigned R) {
ExceptionPointerRegister = R;
}

/// If set to a physical register, this sets the register that receives the
/// exception typeid on entry to a landing pad.
void setExceptionSelectorRegister(unsigned R) {
ExceptionSelectorRegister = R;
}

/// Tells the code generator not to expand operations into sequences that use
/// the select operations if possible.
void setSelectIsExpensive(bool isExpensive = true) {
Expand Down Expand Up @@ -1856,14 +1848,6 @@ class TargetLoweringBase {
/// llvm.savestack/llvm.restorestack should save and restore.
unsigned StackPointerRegisterToSaveRestore;

/// If set to a physical register, this specifies the register that receives
/// the exception address on entry to a landing pad.
unsigned ExceptionPointerRegister;

/// If set to a physical register, this specifies the register that receives
/// the exception typeid on entry to a landing pad.
unsigned ExceptionSelectorRegister;

/// This indicates the default register class to use for each ValueType the
/// target supports natively.
const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Expand Up @@ -2184,8 +2184,9 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
// If there aren't registers to copy the values into (e.g., during SjLj
// exceptions), then don't bother to create these DAG nodes.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (TLI.getExceptionPointerRegister() == 0 &&
TLI.getExceptionSelectorRegister() == 0)
const Constant *PersonalityFn = FuncInfo.Fn->getPersonalityFn();
if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 &&
TLI.getExceptionSelectorRegister(PersonalityFn) == 0)
return;

SmallVector<EVT, 2> ValueVTs;
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Expand Up @@ -938,6 +938,7 @@ static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
/// do other setup for EH landing-pad blocks.
bool SelectionDAGISel::PrepareEHLandingPad() {
MachineBasicBlock *MBB = FuncInfo->MBB;
const Constant *PersonalityFn = FuncInfo->Fn->getPersonalityFn();
const BasicBlock *LLVMBB = MBB->getBasicBlock();
const TargetRegisterClass *PtrRC =
TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));
Expand All @@ -948,7 +949,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
if (hasExceptionPointerOrCodeUser(CPI)) {
// Get or create the virtual register to hold the pointer or code. Mark
// the live in physreg and copy into the vreg.
MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister();
MCPhysReg EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn);
assert(EHPhysReg && "target lacks exception pointer register");
MBB->addLiveIn(EHPhysReg);
unsigned VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
Expand All @@ -974,11 +975,11 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
.addSym(Label);

// Mark exception register as live in.
if (unsigned Reg = TLI->getExceptionPointerRegister())
if (unsigned Reg = TLI->getExceptionPointerRegister(PersonalityFn))
FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);

// Mark exception selector register as live in.
if (unsigned Reg = TLI->getExceptionSelectorRegister())
if (unsigned Reg = TLI->getExceptionSelectorRegister(PersonalityFn))
FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);

return true;
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Expand Up @@ -765,8 +765,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
EnableExtLdPromotion = false;
HasFloatingPointExceptions = true;
StackPointerRegisterToSaveRestore = 0;
ExceptionPointerRegister = 0;
ExceptionSelectorRegister = 0;
BooleanContents = UndefinedBooleanContent;
BooleanFloatContents = UndefinedBooleanContent;
BooleanVectorContents = UndefinedBooleanContent;
Expand Down
5 changes: 0 additions & 5 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Expand Up @@ -196,11 +196,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);

// Exception handling.
// FIXME: These are guesses. Has this been defined yet?
setExceptionPointerRegister(AArch64::X0);
setExceptionSelectorRegister(AArch64::X1);

// Constant pool entries
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);

Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H
#define LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H

#include "AArch64.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/IR/CallingConv.h"
Expand Down Expand Up @@ -366,6 +367,22 @@ class AArch64TargetLowering : public TargetLowering {
/// returns the address of that location. Otherwise, returns nullptr.
Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override;

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override {
// FIXME: This is a guess. Has this been defined yet?
return AArch64::X0;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
// FIXME: This is a guess. Has this been defined yet?
return AArch64::X1;
}

private:
bool isExtFreeImpl(const Instruction *Ext) const override;

Expand Down
21 changes: 14 additions & 7 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Expand Up @@ -813,13 +813,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);

if (!Subtarget->useSjLjEH()) {
// Platforms which do not use SjLj EH may return values in these registers
// via the personality function.
setExceptionPointerRegister(ARM::R0);
setExceptionSelectorRegister(ARM::R1);
}

if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment())
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
else
Expand Down Expand Up @@ -12147,3 +12140,17 @@ bool ARMTargetLowering::functionArgumentNeedsConsecutiveRegisters(
bool IsIntArray = Ty->isArrayTy() && Ty->getArrayElementType()->isIntegerTy();
return IsHA || IsIntArray;
}

unsigned ARMTargetLowering::getExceptionPointerRegister(
const Constant *PersonalityFn) const {
// Platforms which do not use SjLj EH may return values in these registers
// via the personality function.
return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R0;
}

unsigned ARMTargetLowering::getExceptionSelectorRegister(
const Constant *PersonalityFn) const {
// Platforms which do not use SjLj EH may return values in these registers
// via the personality function.
return Subtarget->useSjLjEH() ? ARM::NoRegister : ARM::R1;
}
10 changes: 10 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.h
Expand Up @@ -423,6 +423,16 @@ namespace llvm {
bool functionArgumentNeedsConsecutiveRegisters(
Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override;

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override;

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override;

Instruction *makeDMB(IRBuilder<> &Builder, ARM_MB::MemBOpt Domain) const;
Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
AtomicOrdering Ord) const override;
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Expand Up @@ -1286,8 +1286,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setPrefFunctionAlignment(4);
setMinFunctionAlignment(2);
setInsertFencesForAtomic(false);
setExceptionPointerRegister(Hexagon::R0);
setExceptionSelectorRegister(Hexagon::R1);
setStackPointerRegisterToSaveRestore(HRI.getStackRegister());

if (EnableHexSDNodeSched)
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.h
Expand Up @@ -163,6 +163,20 @@ bool isPositiveHalfWord(SDNode *N);
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB) const override;

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override {
return Hexagon::R0;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
return Hexagon::R1;
}

SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Expand Up @@ -438,9 +438,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,

setStackPointerRegisterToSaveRestore(ABI.IsN64() ? Mips::SP_64 : Mips::SP);

setExceptionPointerRegister(ABI.IsN64() ? Mips::A0_64 : Mips::A0);
setExceptionSelectorRegister(ABI.IsN64() ? Mips::A1_64 : Mips::A1);

MaxStoresPerMemcpy = 16;

isMicroMips = Subtarget.inMicroMipsMode();
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Expand Up @@ -267,6 +267,20 @@ namespace llvm {
unsigned getRegisterByName(const char* RegName, EVT VT,
SelectionDAG &DAG) const override;

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override {
return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
}

/// Returns true if a cast between SrcAS and DestAS is a noop.
bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
// Mips doesn't have any special address spaces so we just reserve
Expand Down
20 changes: 11 additions & 9 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Expand Up @@ -827,15 +827,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setLibcallName(RTLIB::SRA_I128, nullptr);
}

if (isPPC64) {
setStackPointerRegisterToSaveRestore(PPC::X1);
setExceptionPointerRegister(PPC::X3);
setExceptionSelectorRegister(PPC::X4);
} else {
setStackPointerRegisterToSaveRestore(PPC::R1);
setExceptionPointerRegister(PPC::R3);
setExceptionSelectorRegister(PPC::R4);
}
setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1);

// We have target-specific dag combine patterns for the following nodes:
setTargetDAGCombine(ISD::SINT_TO_FP);
Expand Down Expand Up @@ -11532,6 +11524,16 @@ PPCTargetLowering::getScratchRegisters(CallingConv::ID) const {
return ScratchRegs;
}

unsigned PPCTargetLowering::getExceptionPointerRegister(
const Constant *PersonalityFn) const {
return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
}

unsigned PPCTargetLowering::getExceptionSelectorRegister(
const Constant *PersonalityFn) const {
return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
}

bool
PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
EVT VT , unsigned DefinedValues) const {
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Target/PowerPC/PPCISelLowering.h
Expand Up @@ -655,8 +655,17 @@ namespace llvm {
return Ty->isArrayTy();
}

private:
/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override;

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override;

private:
struct ReuseLoadInfo {
SDValue Ptr;
SDValue Chain;
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/Sparc/SparcISelLowering.cpp
Expand Up @@ -1674,9 +1674,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM,
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Custom);

setExceptionPointerRegister(SP::I0);
setExceptionSelectorRegister(SP::I1);

setStackPointerRegisterToSaveRestore(SP::O6);

setOperationAction(ISD::CTPOP, MVT::i32,
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Sparc/SparcISelLowering.h
Expand Up @@ -89,6 +89,20 @@ namespace llvm {
return MVT::i32;
}

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override {
return SP::I0;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
return SP::I1;
}

/// getSetCCResultType - Return the ISD::SETCC ValueType
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
EVT VT) const override;
Expand Down
2 changes: 0 additions & 2 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Expand Up @@ -114,8 +114,6 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
computeRegisterProperties(Subtarget.getRegisterInfo());

// Set up special registers.
setExceptionPointerRegister(SystemZ::R6D);
setExceptionSelectorRegister(SystemZ::R7D);
setStackPointerRegisterToSaveRestore(SystemZ::R15D);

// TODO: It may be better to default to latency-oriented scheduling, however
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.h
Expand Up @@ -409,6 +409,20 @@ class SystemZTargetLowering : public TargetLowering {
return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
}

/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
unsigned
getExceptionPointerRegister(const Constant *PersonalityFn) const override {
return SystemZ::R6D;
}

/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
unsigned
getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
return SystemZ::R7D;
}

MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB) const
override;
Expand Down

0 comments on commit f748c89

Please sign in to comment.