[llvm] r241643 - [WinEH] Add localaddress intrinsic instead of using frameaddress

Reid Kleckner reid at kleckner.net
Tue Jul 7 16:23:04 PDT 2015


Author: rnk
Date: Tue Jul  7 18:23:03 2015
New Revision: 241643

URL: http://llvm.org/viewvc/llvm-project?rev=241643&view=rev
Log:
[WinEH] Add localaddress intrinsic instead of using frameaddress

Clang uses this for SEH finally. The new intrinsic will produce the
right value when stack realignment is required.

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/Intrinsics.td
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/WinEH/seh-inlined-finally.ll
    llvm/trunk/test/CodeGen/WinEH/seh-outlined-finally.ll
    llvm/trunk/test/CodeGen/X86/seh-except-finally.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Jul  7 18:23:03 2015
@@ -7811,10 +7811,10 @@ bitcasted pointer to a function defined
 generator cannot determine the frame allocation offset of functions defined in
 other modules.
 
-The ``fp`` argument to '``llvm.localrecover``' must be a frame
-pointer of a call frame that is currently live. The return value of
-'``llvm.frameaddress``' is one way to produce such a value, but most platforms
-also expose the frame pointer through stack unwinding mechanisms.
+The ``fp`` argument to '``llvm.localrecover``' must be a frame pointer of a
+call frame that is currently live. The return value of '``llvm.localaddress``'
+is one way to produce such a value, but various runtimes also expose a suitable
+pointer in platform-specific ways.
 
 The ``idx`` argument to '``llvm.localrecover``' indicates which alloca passed to
 '``llvm.localescape``' to recover. It is zero-indexed.

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Tue Jul  7 18:23:03 2015
@@ -268,15 +268,23 @@ def int_gcwrite : Intrinsic<[],
 //
 def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
 def int_frameaddress  : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
-def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
-def int_localrecover : Intrinsic<[llvm_ptr_ty],
-                                 [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
-                                 [IntrNoMem]>;
 def int_read_register  : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
                                    [IntrReadMem], "llvm.read_register">;
 def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
                                    [], "llvm.write_register">;
 
+// Gets the address of the local variable area. This is typically a copy of the
+// stack, frame, or base pointer depending on the type of prologue.
+def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
+
+// Escapes local variables to allow access from other functions.
+def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
+
+// Given a function and the localaddress of a parent frame, returns a pointer
+// to an escaped allocation indicated by the index.
+def int_localrecover : Intrinsic<[llvm_ptr_ty],
+                                 [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+                                 [IntrNoMem]>;
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave     : Intrinsic<[llvm_ptr_ty]>,

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Tue Jul  7 18:23:03 2015
@@ -155,7 +155,7 @@ private:
   // outlined but before the outlined code is pruned from the parent function.
   DenseMap<const BasicBlock *, BasicBlock *> LPadTargetBlocks;
 
-  // Map from outlined handler to call to llvm.frameaddress(1). Only used for
+  // Map from outlined handler to call to parent local address. Only used for
   // 32-bit EH.
   DenseMap<Function *, Value *> HandlerToParentFP;
 
@@ -1595,9 +1595,8 @@ void LandingPadMap::remapEHValues(ValueT
     VMap[Extract] = SelectorValue;
 }
 
-static bool isFrameAddressCall(const Value *V) {
-  return match(const_cast<Value *>(V),
-               m_Intrinsic<Intrinsic::frameaddress>(m_SpecificInt(0)));
+static bool isLocalAddressCall(const Value *V) {
+  return match(const_cast<Value *>(V), m_Intrinsic<Intrinsic::localaddress>());
 }
 
 CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction(
@@ -1639,9 +1638,9 @@ CloningDirector::CloningAction WinEHClon
   if (match(Inst, m_Intrinsic<Intrinsic::eh_typeid_for>()))
     return handleTypeIdFor(VMap, Inst, NewBB);
 
-  // When outlining llvm.frameaddress(i32 0), remap that to the second argument,
+  // When outlining llvm.localaddress(), remap that to the second argument,
   // which is the FP of the parent.
-  if (isFrameAddressCall(Inst)) {
+  if (isLocalAddressCall(Inst)) {
     VMap[Inst] = ParentFP;
     return CloningDirector::SkipInstruction;
   }
@@ -2233,16 +2232,16 @@ static void createCleanupHandler(Landing
 static CallSite matchOutlinedFinallyCall(BasicBlock *BB,
                                          Instruction *MaybeCall) {
   // Look for finally blocks that Clang has already outlined for us.
-  //   %fp = call i8* @llvm.frameaddress(i32 0)
+  //   %fp = call i8* @llvm.localaddress()
   //   call void @"fin$parent"(iN 1, i8* %fp)
-  if (isFrameAddressCall(MaybeCall) && MaybeCall != BB->getTerminator())
+  if (isLocalAddressCall(MaybeCall) && MaybeCall != BB->getTerminator())
     MaybeCall = MaybeCall->getNextNode();
   CallSite FinallyCall(MaybeCall);
   if (!FinallyCall || FinallyCall.arg_size() != 2)
     return CallSite();
   if (!match(FinallyCall.getArgument(0), m_SpecificInt(1)))
     return CallSite();
-  if (!isFrameAddressCall(FinallyCall.getArgument(1)))
+  if (!isLocalAddressCall(FinallyCall.getArgument(1)))
     return CallSite();
   return FinallyCall;
 }

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Jul  7 18:23:03 2015
@@ -15737,6 +15737,19 @@ static SDValue LowerINTRINSIC_WO_CHAIN(S
           "llvm.x86.seh.recoverfp must take a function as the first argument");
     return recoverFramePointer(DAG, Fn, IncomingFPOp);
   }
+
+  case Intrinsic::localaddress: {
+    // Returns one of the stack, base, or frame pointer registers, depending on
+    // which is used to reference local variables.
+    MachineFunction &MF = DAG.getMachineFunction();
+    const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
+    unsigned Reg;
+    if (RegInfo->hasBasePointer(MF))
+      Reg = RegInfo->getBaseRegister();
+    else // This function handles the SP or FP case.
+      Reg = RegInfo->getPtrSizedFrameRegister(MF);
+    return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
+  }
   }
 }
 

Modified: llvm/trunk/test/CodeGen/WinEH/seh-inlined-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-inlined-finally.ll?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-inlined-finally.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-inlined-finally.ll Tue Jul  7 18:23:03 2015
@@ -14,7 +14,7 @@ declare i32 @puts(i8*)
 declare void @may_crash()
 declare i32 @__C_specific_handler(...)
 declare i8* @llvm.localrecover(i8*, i8*, i32) #1
-declare i8* @llvm.frameaddress(i32)
+declare i8* @llvm.localaddress()
 declare void @llvm.localescape(...)
 declare dllimport void @EnterCriticalSection(%struct._RTL_CRITICAL_SECTION*)
 declare dllimport void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION*)
@@ -53,7 +53,7 @@ entry:
           to label %invoke.cont unwind label %lpad
 
 invoke.cont:                                      ; preds = %entry
-  %tmp2 = call i8* @llvm.frameaddress(i32 0)
+  %tmp2 = call i8* @llvm.localaddress()
   %tmp3 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp2, i32 0) #2
   %tmp6 = bitcast i8* %tmp3 to %struct._RTL_CRITICAL_SECTION*
   call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp6)
@@ -62,7 +62,7 @@ invoke.cont:
 lpad:                                             ; preds = %entry
   %tmp7 = landingpad { i8*, i32 }
             cleanup
-  %tmp8 = call i8* @llvm.frameaddress(i32 0)
+  %tmp8 = call i8* @llvm.localaddress()
   %tmp9 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp8, i32 0)
   %tmp12 = bitcast i8* %tmp9 to %struct._RTL_CRITICAL_SECTION*
   call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp12)

Modified: llvm/trunk/test/CodeGen/WinEH/seh-outlined-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/seh-outlined-finally.ll?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/seh-outlined-finally.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/seh-outlined-finally.ll Tue Jul  7 18:23:03 2015
@@ -49,12 +49,12 @@ entry:
           to label %invoke.cont unwind label %lpad
 
 invoke.cont:                                      ; preds = %entry
-  %0 = call i8* @llvm.frameaddress(i32 0)
+  %0 = call i8* @llvm.localaddress()
   invoke void @"\01?fin$1 at 0@main@@"(i1 zeroext false, i8* %0) #4
           to label %invoke.cont2 unwind label %lpad1
 
 invoke.cont2:                                     ; preds = %invoke.cont
-  %1 = call i8* @llvm.frameaddress(i32 0)
+  %1 = call i8* @llvm.localaddress()
   call void @"\01?fin$0 at 0@main@@"(i1 zeroext false, i8* %1)
   ret i32 0
 
@@ -65,7 +65,7 @@ lpad:
   store i8* %3, i8** %exn.slot
   %4 = extractvalue { i8*, i32 } %2, 1
   store i32 %4, i32* %ehselector.slot
-  %5 = call i8* @llvm.frameaddress(i32 0)
+  %5 = call i8* @llvm.localaddress()
   invoke void @"\01?fin$1 at 0@main@@"(i1 zeroext true, i8* %5) #4
           to label %invoke.cont3 unwind label %lpad1
 
@@ -82,7 +82,7 @@ invoke.cont3:
   br label %ehcleanup
 
 ehcleanup:                                        ; preds = %invoke.cont3, %lpad1
-  %9 = call i8* @llvm.frameaddress(i32 0)
+  %9 = call i8* @llvm.localaddress()
   call void @"\01?fin$0 at 0@main@@"(i1 zeroext true, i8* %9)
   br label %eh.resume
 
@@ -146,7 +146,7 @@ entry:
 declare i32 @__C_specific_handler(...)
 
 ; Function Attrs: nounwind readnone
-declare i8* @llvm.frameaddress(i32) #3
+declare i8* @llvm.localaddress() #3
 
 attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }
 attributes #1 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "unsafe-fp-math"="false" "use-soft-float"="false" }

Modified: llvm/trunk/test/CodeGen/X86/seh-except-finally.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-except-finally.ll?rev=241643&r1=241642&r2=241643&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-except-finally.ll (original)
+++ llvm/trunk/test/CodeGen/X86/seh-except-finally.ll Tue Jul  7 18:23:03 2015
@@ -41,7 +41,7 @@ entry:
           to label %invoke.cont unwind label %lpad
 
 invoke.cont:                                      ; preds = %entry
-  %0 = call i8* @llvm.frameaddress(i32 0)
+  %0 = call i8* @llvm.localaddress()
   invoke void @"\01?fin$0 at 0@use_both@@"(i1 zeroext false, i8* %0) #5
           to label %invoke.cont2 unwind label %lpad1
 
@@ -56,7 +56,7 @@ lpad:
   store i8* %2, i8** %exn.slot
   %3 = extractvalue { i8*, i32 } %1, 1
   store i32 %3, i32* %ehselector.slot
-  %4 = call i8* @llvm.frameaddress(i32 0)
+  %4 = call i8* @llvm.localaddress()
   invoke void @"\01?fin$0 at 0@use_both@@"(i1 zeroext true, i8* %4) #5
           to label %invoke.cont3 unwind label %lpad1
 
@@ -153,7 +153,7 @@ declare i32 @puts(i8*) #3
 declare i32 @__C_specific_handler(...)
 
 ; Function Attrs: nounwind readnone
-declare i8* @llvm.frameaddress(i32) #4
+declare i8* @llvm.localaddress() #4
 
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.eh.typeid.for(i8*) #4





More information about the llvm-commits mailing list