diff options
author | Dan Gohman <dan433584@gmail.com> | 2016-02-16 23:48:04 +0000 |
---|---|---|
committer | Dan Gohman <dan433584@gmail.com> | 2016-02-16 23:48:04 +0000 |
commit | 94c6566055b856c9580a2b27bf4dd3aa8ac61482 (patch) | |
tree | ea3a0b8565018a7b4d96ada0c27b1b2806f86b21 /llvm/lib/Target/WebAssembly | |
parent | 0520929231d9517a13ec66da6675485aa649b312 (diff) | |
download | bcm5719-llvm-94c6566055b856c9580a2b27bf4dd3aa8ac61482.tar.gz bcm5719-llvm-94c6566055b856c9580a2b27bf4dd3aa8ac61482.zip |
[WebAssembly] Implement __builtin_frame_address.
Differential Revision: http://reviews.llvm.org/D17307
llvm-svn: 261032
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
4 files changed, 23 insertions, 8 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp index 27274c066b2..1c358b340bd 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp @@ -44,11 +44,11 @@ using namespace llvm; /// register. bool WebAssemblyFrameLowering::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - assert(!MFI->isFrameAddressTaken()); const auto *RegInfo = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); - return MFI->hasVarSizedObjects() || MFI->hasStackMap() || - MFI->hasPatchPoint() || RegInfo->needsStackRealignment(MF); + return MFI->isFrameAddressTaken() || MFI->hasVarSizedObjects() || + MFI->hasStackMap() || MFI->hasPatchPoint() || + RegInfo->needsStackRealignment(MF); } /// Under normal circumstances, when a frame pointer is not required, we reserve diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 2027e8ba678..c5ec506804c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -542,9 +542,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, case ISD::RETURNADDR: // Probably nothing meaningful can be returned here. fail(DL, DAG, "WebAssembly hasn't implemented __builtin_return_address"); return SDValue(); - case ISD::FRAMEADDR: // TODO: Make this return the userspace frame address - fail(DL, DAG, "WebAssembly hasn't implemented __builtin_frame_address"); - return SDValue(); + case ISD::FRAMEADDR: + return LowerFRAMEADDR(Op, DAG); case ISD::CopyToReg: return LowerCopyToReg(Op, DAG); } @@ -579,6 +578,21 @@ SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op, return DAG.getTargetFrameIndex(FI, Op.getValueType()); } +SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op, + SelectionDAG &DAG) const { + // Non-zero depths are not supported by WebAssembly currently. Use the + // legalizer's default expansion, which is to return 0 (what this function is + // documented to do). + if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) + return SDValue(); + + DAG.getMachineFunction().getFrameInfo()->setFrameAddressIsTaken(true); + EVT VT = Op.getValueType(); + unsigned FP = + Subtarget->getRegisterInfo()->getFrameRegister(DAG.getMachineFunction()); + return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT); +} + SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h index 4aed2b1ec82..5b538fda479 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -78,6 +78,7 @@ class WebAssemblyTargetLowering final : public TargetLowering { // Custom lowering hooks. SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; SDValue LowerFrameIndex(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp index f38f635d822..76ea0d72f6d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp @@ -108,11 +108,11 @@ bool WebAssemblyRegNumbering::runOnMachineFunction(MachineFunction &MF) { } } // Allocate locals for used physical registers - if (FrameInfo.getStackSize() > 0 || FrameInfo.adjustsStack()) { + bool HasFP = MF.getSubtarget().getFrameLowering()->hasFP(MF); + if (FrameInfo.getStackSize() > 0 || FrameInfo.adjustsStack() || HasFP) { DEBUG(dbgs() << "PReg SP " << CurReg << "\n"); MFI.addPReg(WebAssembly::SP32, CurReg++); } - bool HasFP = MF.getSubtarget().getFrameLowering()->hasFP(MF); if (HasFP) { DEBUG(dbgs() << "PReg FP " << CurReg << "\n"); MFI.addPReg(WebAssembly::FP32, CurReg++); |