[llvm] r261032 - [WebAssembly] Implement __builtin_frame_address.

Dan Gohman via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 15:48:04 PST 2016


Author: djg
Date: Tue Feb 16 17:48:04 2016
New Revision: 261032

URL: http://llvm.org/viewvc/llvm-project?rev=261032&view=rev
Log:
[WebAssembly] Implement __builtin_frame_address.

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

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp
    llvm/trunk/test/CodeGen/WebAssembly/userstack.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp?rev=261032&r1=261031&r2=261032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp Tue Feb 16 17:48:04 2016
@@ -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

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=261032&r1=261031&r2=261032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Tue Feb 16 17:48:04 2016
@@ -542,9 +542,8 @@ SDValue WebAssemblyTargetLowering::Lower
     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::Lower
   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);

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=261032&r1=261031&r2=261032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Tue Feb 16 17:48:04 2016
@@ -78,6 +78,7 @@ class WebAssemblyTargetLowering final :
   // 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;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp?rev=261032&r1=261031&r2=261032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegNumbering.cpp Tue Feb 16 17:48:04 2016
@@ -108,11 +108,11 @@ bool WebAssemblyRegNumbering::runOnMachi
     }
   }
   // 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++);

Modified: llvm/trunk/test/CodeGen/WebAssembly/userstack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/userstack.ll?rev=261032&r1=261031&r2=261032&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/userstack.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/userstack.ll Tue Feb 16 17:48:04 2016
@@ -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 at 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




More information about the llvm-commits mailing list