llvm.org GIT mirror llvm / 4fe74ca
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241643 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
7 changed file(s) with 48 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
78107810 generator cannot determine the frame allocation offset of functions defined in
78117811 other modules.
78127812
7813 The ``fp`` argument to '``llvm.localrecover``' must be a frame
7814 pointer of a call frame that is currently live. The return value of
7815 '``llvm.frameaddress``' is one way to produce such a value, but most platforms
7816 also expose the frame pointer through stack unwinding mechanisms.
7813 The ``fp`` argument to '``llvm.localrecover``' must be a frame pointer of a
7814 call frame that is currently live. The return value of '``llvm.localaddress``'
7815 is one way to produce such a value, but various runtimes also expose a suitable
7816 pointer in platform-specific ways.
78177817
78187818 The ``idx`` argument to '``llvm.localrecover``' indicates which alloca passed to
78197819 '``llvm.localescape``' to recover. It is zero-indexed.
267267 //
268268 def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
269269 def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
270 def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
271 def int_localrecover : Intrinsic<[llvm_ptr_ty],
272 [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
273 [IntrNoMem]>;
274270 def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
275271 [IntrReadMem], "llvm.read_register">;
276272 def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
277273 [], "llvm.write_register">;
278274
275 // Gets the address of the local variable area. This is typically a copy of the
276 // stack, frame, or base pointer depending on the type of prologue.
277 def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
278
279 // Escapes local variables to allow access from other functions.
280 def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
281
282 // Given a function and the localaddress of a parent frame, returns a pointer
283 // to an escaped allocation indicated by the index.
284 def int_localrecover : Intrinsic<[llvm_ptr_ty],
285 [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
286 [IntrNoMem]>;
279287 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
280288 // model their dependencies on allocas.
281289 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
154154 // outlined but before the outlined code is pruned from the parent function.
155155 DenseMap LPadTargetBlocks;
156156
157 // Map from outlined handler to call to llvm.frameaddress(1). Only used for
157 // Map from outlined handler to call to parent local address. Only used for
158158 // 32-bit EH.
159159 DenseMap HandlerToParentFP;
160160
15941594 VMap[Extract] = SelectorValue;
15951595 }
15961596
1597 static bool isFrameAddressCall(const Value *V) {
1598 return match(const_cast(V),
1599 m_Intrinsic(m_SpecificInt(0)));
1597 static bool isLocalAddressCall(const Value *V) {
1598 return match(const_cast(V), m_Intrinsic());
16001599 }
16011600
16021601 CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction(
16381637 if (match(Inst, m_Intrinsic()))
16391638 return handleTypeIdFor(VMap, Inst, NewBB);
16401639
1641 // When outlining llvm.frameaddress(i32 0), remap that to the second argument,
1640 // When outlining llvm.localaddress(), remap that to the second argument,
16421641 // which is the FP of the parent.
1643 if (isFrameAddressCall(Inst)) {
1642 if (isLocalAddressCall(Inst)) {
16441643 VMap[Inst] = ParentFP;
16451644 return CloningDirector::SkipInstruction;
16461645 }
22322231 static CallSite matchOutlinedFinallyCall(BasicBlock *BB,
22332232 Instruction *MaybeCall) {
22342233 // Look for finally blocks that Clang has already outlined for us.
2235 // %fp = call i8* @llvm.frameaddress(i32 0)
2234 // %fp = call i8* @llvm.localaddress()
22362235 // call void @"fin$parent"(iN 1, i8* %fp)
2237 if (isFrameAddressCall(MaybeCall) && MaybeCall != BB->getTerminator())
2236 if (isLocalAddressCall(MaybeCall) && MaybeCall != BB->getTerminator())
22382237 MaybeCall = MaybeCall->getNextNode();
22392238 CallSite FinallyCall(MaybeCall);
22402239 if (!FinallyCall || FinallyCall.arg_size() != 2)
22412240 return CallSite();
22422241 if (!match(FinallyCall.getArgument(0), m_SpecificInt(1)))
22432242 return CallSite();
2244 if (!isFrameAddressCall(FinallyCall.getArgument(1)))
2243 if (!isLocalAddressCall(FinallyCall.getArgument(1)))
22452244 return CallSite();
22462245 return FinallyCall;
22472246 }
1573515735 report_fatal_error(
1573615736 "llvm.x86.seh.recoverfp must take a function as the first argument");
1573715737 return recoverFramePointer(DAG, Fn, IncomingFPOp);
15738 }
15739
15740 case Intrinsic::localaddress: {
15741 // Returns one of the stack, base, or frame pointer registers, depending on
15742 // which is used to reference local variables.
15743 MachineFunction &MF = DAG.getMachineFunction();
15744 const X86RegisterInfo *RegInfo = Subtarget->getRegisterInfo();
15745 unsigned Reg;
15746 if (RegInfo->hasBasePointer(MF))
15747 Reg = RegInfo->getBaseRegister();
15748 else // This function handles the SP or FP case.
15749 Reg = RegInfo->getPtrSizedFrameRegister(MF);
15750 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1573815751 }
1573915752 }
1574015753 }
1313 declare void @may_crash()
1414 declare i32 @__C_specific_handler(...)
1515 declare i8* @llvm.localrecover(i8*, i8*, i32) #1
16 declare i8* @llvm.frameaddress(i32)
16 declare i8* @llvm.localaddress()
1717 declare void @llvm.localescape(...)
1818 declare dllimport void @EnterCriticalSection(%struct._RTL_CRITICAL_SECTION*)
1919 declare dllimport void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION*)
5252 to label %invoke.cont unwind label %lpad
5353
5454 invoke.cont: ; preds = %entry
55 %tmp2 = call i8* @llvm.frameaddress(i32 0)
55 %tmp2 = call i8* @llvm.localaddress()
5656 %tmp3 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp2, i32 0) #2
5757 %tmp6 = bitcast i8* %tmp3 to %struct._RTL_CRITICAL_SECTION*
5858 call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp6)
6161 lpad: ; preds = %entry
6262 %tmp7 = landingpad { i8*, i32 }
6363 cleanup
64 %tmp8 = call i8* @llvm.frameaddress(i32 0)
64 %tmp8 = call i8* @llvm.localaddress()
6565 %tmp9 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @call_may_crash_locked to i8*), i8* %tmp8, i32 0)
6666 %tmp12 = bitcast i8* %tmp9 to %struct._RTL_CRITICAL_SECTION*
6767 call void @LeaveCriticalSection(%struct._RTL_CRITICAL_SECTION* %tmp12)
4848 to label %invoke.cont unwind label %lpad
4949
5050 invoke.cont: ; preds = %entry
51 %0 = call i8* @llvm.frameaddress(i32 0)
51 %0 = call i8* @llvm.localaddress()
5252 invoke void @"\01?fin$1@0@main@@"(i1 zeroext false, i8* %0) #4
5353 to label %invoke.cont2 unwind label %lpad1
5454
5555 invoke.cont2: ; preds = %invoke.cont
56 %1 = call i8* @llvm.frameaddress(i32 0)
56 %1 = call i8* @llvm.localaddress()
5757 call void @"\01?fin$0@0@main@@"(i1 zeroext false, i8* %1)
5858 ret i32 0
5959
6464 store i8* %3, i8** %exn.slot
6565 %4 = extractvalue { i8*, i32 } %2, 1
6666 store i32 %4, i32* %ehselector.slot
67 %5 = call i8* @llvm.frameaddress(i32 0)
67 %5 = call i8* @llvm.localaddress()
6868 invoke void @"\01?fin$1@0@main@@"(i1 zeroext true, i8* %5) #4
6969 to label %invoke.cont3 unwind label %lpad1
7070
8181 br label %ehcleanup
8282
8383 ehcleanup: ; preds = %invoke.cont3, %lpad1
84 %9 = call i8* @llvm.frameaddress(i32 0)
84 %9 = call i8* @llvm.localaddress()
8585 call void @"\01?fin$0@0@main@@"(i1 zeroext true, i8* %9)
8686 br label %eh.resume
8787
145145 declare i32 @__C_specific_handler(...)
146146
147147 ; Function Attrs: nounwind readnone
148 declare i8* @llvm.frameaddress(i32) #3
148 declare i8* @llvm.localaddress() #3
149149
150150 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" }
151151 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" }
4040 to label %invoke.cont unwind label %lpad
4141
4242 invoke.cont: ; preds = %entry
43 %0 = call i8* @llvm.frameaddress(i32 0)
43 %0 = call i8* @llvm.localaddress()
4444 invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext false, i8* %0) #5
4545 to label %invoke.cont2 unwind label %lpad1
4646
5555 store i8* %2, i8** %exn.slot
5656 %3 = extractvalue { i8*, i32 } %1, 1
5757 store i32 %3, i32* %ehselector.slot
58 %4 = call i8* @llvm.frameaddress(i32 0)
58 %4 = call i8* @llvm.localaddress()
5959 invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %4) #5
6060 to label %invoke.cont3 unwind label %lpad1
6161
152152 declare i32 @__C_specific_handler(...)
153153
154154 ; Function Attrs: nounwind readnone
155 declare i8* @llvm.frameaddress(i32) #4
155 declare i8* @llvm.localaddress() #4
156156
157157 ; Function Attrs: nounwind readnone
158158 declare i32 @llvm.eh.typeid.for(i8*) #4