mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-11 16:37:42 +00:00
Revert change r231366 as it broke clang-native-arm-cortex-a9 Analysis/properties.m test.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231374 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e670dc7848
commit
684d323b9b
@ -1016,24 +1016,6 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
|
||||
}
|
||||
}
|
||||
|
||||
/// getCopyFromRegs - If there was virtual register allocated for the value V
|
||||
/// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise.
|
||||
SDValue SelectionDAGBuilder::getCopyFromRegs(const Value *V, Type *Ty) {
|
||||
DenseMap<const Value *, unsigned>::iterator It = FuncInfo.ValueMap.find(V);
|
||||
SDValue res;
|
||||
|
||||
if (It != FuncInfo.ValueMap.end()) {
|
||||
unsigned InReg = It->second;
|
||||
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), InReg,
|
||||
Ty);
|
||||
SDValue Chain = DAG.getEntryNode();
|
||||
res = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
|
||||
resolveDanglingDebugInfo(V, res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// getValue - Return an SDValue for the given Value.
|
||||
SDValue SelectionDAGBuilder::getValue(const Value *V) {
|
||||
// If we already have an SDValue for this value, use it. It's important
|
||||
@ -1044,9 +1026,15 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
|
||||
|
||||
// If there's a virtual register allocated and initialized for this
|
||||
// value, use it.
|
||||
SDValue copyFromReg = getCopyFromRegs(V, V->getType());
|
||||
if (copyFromReg.getNode()) {
|
||||
return copyFromReg;
|
||||
DenseMap<const Value *, unsigned>::iterator It = FuncInfo.ValueMap.find(V);
|
||||
if (It != FuncInfo.ValueMap.end()) {
|
||||
unsigned InReg = It->second;
|
||||
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), InReg,
|
||||
V->getType());
|
||||
SDValue Chain = DAG.getEntryNode();
|
||||
N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
|
||||
resolveDanglingDebugInfo(V, N);
|
||||
return N;
|
||||
}
|
||||
|
||||
// Otherwise create a new SDValue and remember it.
|
||||
@ -2039,20 +2027,13 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
|
||||
case Intrinsic::experimental_patchpoint_i64:
|
||||
visitPatchpoint(&I, LandingPad);
|
||||
break;
|
||||
case Intrinsic::experimental_gc_statepoint:
|
||||
LowerStatepoint(ImmutableStatepoint(&I), LandingPad);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
LowerCallTo(&I, getValue(Callee), false, LandingPad);
|
||||
|
||||
// If the value of the invoke is used outside of its defining block, make it
|
||||
// available as a virtual register.
|
||||
// We already took care of the exported value for the statepoint instruction
|
||||
// during call to the LowerStatepoint.
|
||||
if (!isStatepoint(I)) {
|
||||
CopyToExportRegsIfNeeded(&I);
|
||||
}
|
||||
CopyToExportRegsIfNeeded(&I);
|
||||
|
||||
// Update successor info
|
||||
addSuccessorWithWeight(InvokeMBB, Return);
|
||||
|
@ -606,10 +606,6 @@ public:
|
||||
|
||||
void visit(unsigned Opcode, const User &I);
|
||||
|
||||
/// getCopyFromRegs - If there was virtual register allocated for the value V
|
||||
/// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise.
|
||||
SDValue getCopyFromRegs(const Value *V, Type *Ty);
|
||||
|
||||
// resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V,
|
||||
// generate the debug data structures now that we've seen its definition.
|
||||
void resolveDanglingDebugInfo(const Value *V, SDValue Val);
|
||||
@ -665,9 +661,7 @@ public:
|
||||
void UpdateSplitBlock(MachineBasicBlock *First, MachineBasicBlock *Last);
|
||||
|
||||
// This function is responsible for the whole statepoint lowering process.
|
||||
// It uniformly handles invoke and call statepoints.
|
||||
void LowerStatepoint(ImmutableStatepoint Statepoint,
|
||||
MachineBasicBlock *LandingPad = nullptr);
|
||||
void LowerStatepoint(ImmutableStatepoint Statepoint);
|
||||
private:
|
||||
std::pair<SDValue, SDValue> lowerInvokable(
|
||||
TargetLowering::CallLoweringInfo &CLI,
|
||||
|
@ -224,7 +224,6 @@ static void removeDuplicatesGCPtrs(SmallVectorImpl<const Value *> &Bases,
|
||||
/// call node. Also update NodeMap so that getValue(statepoint) will
|
||||
/// reference lowered call result
|
||||
static SDNode *lowerCallFromStatepoint(ImmutableStatepoint StatepointSite,
|
||||
MachineBasicBlock *LandingPad,
|
||||
SelectionDAGBuilder &Builder) {
|
||||
|
||||
ImmutableCallSite CS(StatepointSite.getCallSite());
|
||||
@ -246,29 +245,15 @@ static SDNode *lowerCallFromStatepoint(ImmutableStatepoint StatepointSite,
|
||||
Tmp->setTailCall(CS.isTailCall());
|
||||
Tmp->setCallingConv(CS.getCallingConv());
|
||||
Tmp->setAttributes(CS.getAttributes());
|
||||
Builder.LowerCallTo(Tmp, Builder.getValue(ActualCallee), false, LandingPad);
|
||||
Builder.LowerCallTo(Tmp, Builder.getValue(ActualCallee), false);
|
||||
|
||||
// Handle the return value of the call iff any.
|
||||
const bool HasDef = !Tmp->getType()->isVoidTy();
|
||||
if (HasDef) {
|
||||
if (CS.isInvoke()) {
|
||||
// Result value will be used in different basic block for invokes
|
||||
// so we need to export it now. But statepoint call has a different type
|
||||
// than the actuall call. It means that standart exporting mechanism will
|
||||
// create register of the wrong type. So instead we need to create
|
||||
// register with correct type and save value into it manually.
|
||||
// TODO: To eliminate this problem we can remove gc.result intrinsics
|
||||
// completelly and make statepoint call to return a tuple.
|
||||
unsigned reg = Builder.FuncInfo.CreateRegs(Tmp->getType());
|
||||
Builder.CopyValueToVirtualRegister(Tmp, reg);
|
||||
Builder.FuncInfo.ValueMap[CS.getInstruction()] = reg;
|
||||
}
|
||||
else {
|
||||
// The value of the statepoint itself will be the value of call itself.
|
||||
// We'll replace the actually call node shortly. gc_result will grab
|
||||
// this value.
|
||||
Builder.setValue(CS.getInstruction(), Builder.getValue(Tmp));
|
||||
}
|
||||
// The value of the statepoint itself will be the value of call itself.
|
||||
// We'll replace the actually call node shortly. gc_result will grab
|
||||
// this value.
|
||||
Builder.setValue(CS.getInstruction(), Builder.getValue(Tmp));
|
||||
} else {
|
||||
// The token value is never used from here on, just generate a poison value
|
||||
Builder.setValue(CS.getInstruction(), Builder.DAG.getIntPtrConstant(-1));
|
||||
@ -282,15 +267,6 @@ static SDNode *lowerCallFromStatepoint(ImmutableStatepoint StatepointSite,
|
||||
// Search for the call node
|
||||
// The following code is essentially reverse engineering X86's
|
||||
// LowerCallTo.
|
||||
// We are expecting DAG to have the following form:
|
||||
// ch = eh_label (only in case of invoke statepoint)
|
||||
// ch, glue = callseq_start ch
|
||||
// ch, glue = X86::Call ch, glue
|
||||
// ch, glue = callseq_end ch, glue
|
||||
// ch = eh_label ch (only in case of invoke statepoint)
|
||||
//
|
||||
// DAG root will be either last eh_label or callseq_end.
|
||||
|
||||
SDNode *CallNode = nullptr;
|
||||
|
||||
// We just emitted a call, so it should be last thing generated
|
||||
@ -300,11 +276,8 @@ static SDNode *lowerCallFromStatepoint(ImmutableStatepoint StatepointSite,
|
||||
SDNode *CallEnd = Chain.getNode();
|
||||
int Sanity = 0;
|
||||
while (CallEnd->getOpcode() != ISD::CALLSEQ_END) {
|
||||
assert(CallEnd->getNumOperands() >= 1 &&
|
||||
CallEnd->getOperand(0).getValueType() == MVT::Other);
|
||||
|
||||
CallEnd = CallEnd->getOperand(0).getNode();
|
||||
|
||||
CallEnd = CallEnd->getGluedNode();
|
||||
assert(CallEnd && "Can not find call node");
|
||||
assert(Sanity < 20 && "should have found call end already");
|
||||
Sanity++;
|
||||
}
|
||||
@ -533,9 +506,7 @@ void SelectionDAGBuilder::visitStatepoint(const CallInst &CI) {
|
||||
LowerStatepoint(ImmutableStatepoint(&CI));
|
||||
}
|
||||
|
||||
void
|
||||
SelectionDAGBuilder::LowerStatepoint(ImmutableStatepoint ISP,
|
||||
MachineBasicBlock *LandingPad/*=nullptr*/) {
|
||||
void SelectionDAGBuilder::LowerStatepoint(ImmutableStatepoint ISP) {
|
||||
// The basic scheme here is that information about both the original call and
|
||||
// the safepoint is encoded in the CallInst. We create a temporary call and
|
||||
// lower it, then reverse engineer the calling sequence.
|
||||
@ -571,12 +542,13 @@ SelectionDAGBuilder::LowerStatepoint(ImmutableStatepoint ISP,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Lower statepoint vmstate and gcstate arguments
|
||||
SmallVector<SDValue, 10> LoweredArgs;
|
||||
lowerStatepointMetaArgs(LoweredArgs, ISP, *this);
|
||||
|
||||
// Get call node, we will replace it later with statepoint
|
||||
SDNode *CallNode = lowerCallFromStatepoint(ISP, LandingPad, *this);
|
||||
SDNode *CallNode = lowerCallFromStatepoint(ISP, *this);
|
||||
|
||||
// Construct the actual STATEPOINT node with all the appropriate arguments
|
||||
// and return values.
|
||||
@ -662,24 +634,7 @@ void SelectionDAGBuilder::visitGCResult(const CallInst &CI) {
|
||||
assert(isStatepoint(I) &&
|
||||
"first argument must be a statepoint token");
|
||||
|
||||
if (isa<InvokeInst>(I)) {
|
||||
// For invokes we should have stored call result in a virtual register.
|
||||
// We can not use default getValue() functionality to copy value from this
|
||||
// register because statepoint and actuall call return types can be
|
||||
// different, and getValue() will use CopyFromReg of the wrong type,
|
||||
// which is always i32 in our case.
|
||||
PointerType *CalleeType = cast<PointerType>(
|
||||
ImmutableStatepoint(I).actualCallee()->getType());
|
||||
Type *RetTy = cast<FunctionType>(
|
||||
CalleeType->getElementType())->getReturnType();
|
||||
SDValue CopyFromReg = getCopyFromRegs(I, RetTy);
|
||||
|
||||
assert(CopyFromReg.getNode());
|
||||
setValue(&CI, CopyFromReg);
|
||||
}
|
||||
else {
|
||||
setValue(&CI, getValue(I));
|
||||
}
|
||||
setValue(&CI, getValue(I));
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitGCRelocate(const CallInst &CI) {
|
||||
|
@ -1,38 +0,0 @@
|
||||
; RUN: llc < %s 2>&1 | FileCheck %s
|
||||
|
||||
target triple = "x86_64-pc-linux-gnu"
|
||||
|
||||
declare i64 addrspace(1)* @"some_other_call"(i64 addrspace(1)*)
|
||||
|
||||
declare i32 @"personality_function"()
|
||||
|
||||
define i64 addrspace(1)* @test_result(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) {
|
||||
entry:
|
||||
; CHECK: .Ltmp{{[0-9]+}}:
|
||||
; CHECK: callq some_other_call
|
||||
; CHECK: .Ltmp{{[0-9]+}}:
|
||||
%0 = invoke i32 (i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
|
||||
to label %normal_return unwind label %exceptional_return
|
||||
|
||||
normal_return:
|
||||
; CHECK: popq
|
||||
; CHECK: retq
|
||||
%ret_val = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32 %0)
|
||||
ret i64 addrspace(1)* %ret_val
|
||||
|
||||
exceptional_return:
|
||||
; CHECK: .Ltmp{{[0-9]+}}:
|
||||
; CHECK: popq
|
||||
; CHECK: retq
|
||||
%landing_pad = landingpad { i8*, i32 } personality i32 ()* @personality_function
|
||||
cleanup
|
||||
ret i64 addrspace(1)* %obj
|
||||
}
|
||||
; CHECK-LABEL: GCC_except_table{{[0-9]+}}:
|
||||
; CHECK: .long .Ltmp{{[0-9]+}}-.Ltmp{{[0-9]+}}
|
||||
; CHECK: .long .Ltmp{{[0-9]+}}-.Lfunc_begin{{[0-9]+}}
|
||||
; CHECK: .byte 0
|
||||
; CHECK: .align 4
|
||||
|
||||
declare i32 @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...)
|
||||
declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(i32)
|
Loading…
x
Reference in New Issue
Block a user