mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
[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
This commit is contained in:
parent
39fe55270a
commit
4fe74caa61
@ -7811,10 +7811,10 @@ bitcasted pointer to a function defined in the current module. The code
|
||||
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.
|
||||
|
@ -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]>,
|
||||
|
@ -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(ValueToValueMapTy &VMap, Value *EHPtrValue,
|
||||
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 WinEHCloningDirectorBase::handleInstruction(
|
||||
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(LandingPadActions &Actions,
|
||||
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;
|
||||
}
|
||||
|
@ -15737,6 +15737,19 @@ static SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, const X86Subtarget *Subtarget
|
||||
"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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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: ; preds = %entry
|
||||
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)
|
||||
|
@ -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@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@0@main@@"(i1 zeroext false, i8* %1)
|
||||
ret i32 0
|
||||
|
||||
@ -65,7 +65,7 @@ lpad: ; preds = %entry
|
||||
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@0@main@@"(i1 zeroext true, i8* %5) #4
|
||||
to label %invoke.cont3 unwind label %lpad1
|
||||
|
||||
@ -82,7 +82,7 @@ invoke.cont3: ; preds = %lpad
|
||||
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@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" }
|
||||
|
@ -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@0@use_both@@"(i1 zeroext false, i8* %0) #5
|
||||
to label %invoke.cont2 unwind label %lpad1
|
||||
|
||||
@ -56,7 +56,7 @@ lpad: ; preds = %entry
|
||||
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@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
|
||||
|
Loading…
Reference in New Issue
Block a user