mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-07 12:30:44 +00:00
[WebAssembly] Implement __builtin_frame_address.
Differential Revision: http://reviews.llvm.org/D17307 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261032 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
30d7b4334a
commit
f3e241c3c2
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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++);
|
||||
|
@ -181,4 +181,35 @@ exit:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @use_i8_star(i8*)
|
||||
declare i8* @llvm.frameaddress(i32)
|
||||
|
||||
; Test __builtin_frame_address(0).
|
||||
; TODO: When the prolog/epilog sequences are optimized, refine these checks to
|
||||
; be more specific.
|
||||
|
||||
; CHECK-LABEL: frameaddress_0:
|
||||
; CHECK: __stack_pointer
|
||||
; CHECK: load
|
||||
; CHECK: call use_i8_star
|
||||
; CHECK: __stack_pointer
|
||||
; CHECK: store
|
||||
define void @frameaddress_0() {
|
||||
%t = call i8* @llvm.frameaddress(i32 0)
|
||||
call void @use_i8_star(i8* %t)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Test __builtin_frame_address(1).
|
||||
|
||||
; CHECK-LABEL: frameaddress_1:
|
||||
; CHECK-NEXT: i32.const $push0=, 0{{$}}
|
||||
; CHECK-NEXT: call use_i8_star@FUNCTION, $pop0{{$}}
|
||||
; CHECK-NEXT: return{{$}}
|
||||
define void @frameaddress_1() {
|
||||
%t = call i8* @llvm.frameaddress(i32 1)
|
||||
call void @use_i8_star(i8* %t)
|
||||
ret void
|
||||
}
|
||||
|
||||
; TODO: test over-aligned alloca
|
||||
|
Loading…
Reference in New Issue
Block a user