From 8d0851f509bfd63180ba2d96c9028cb54b30c595 Mon Sep 17 00:00:00 2001 From: Igor Laevsky Date: Thu, 5 Mar 2015 15:41:14 +0000 Subject: [PATCH] Revert change r231366 as it broke clang-native-arm-cortex-a9 Analysis/properties.m test. llvm-svn: 231374 --- .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 39 ++++--------- .../lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 8 +-- .../CodeGen/SelectionDAG/StatepointLowering.cpp | 67 ++++------------------ llvm/test/CodeGen/X86/statepoint-invoke.ll | 38 ------------ 4 files changed, 22 insertions(+), 130 deletions(-) delete mode 100644 llvm/test/CodeGen/X86/statepoint-invoke.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 61631f04..097b618 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -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::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::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); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index faf2274..719af41 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -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 lowerInvokable( TargetLowering::CallLoweringInfo &CLI, diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 3cc7a98..1271f6b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -224,7 +224,6 @@ static void removeDuplicatesGCPtrs(SmallVectorImpl &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 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(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( - ImmutableStatepoint(I).actualCallee()->getType()); - Type *RetTy = cast( - 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) { diff --git a/llvm/test/CodeGen/X86/statepoint-invoke.ll b/llvm/test/CodeGen/X86/statepoint-invoke.ll deleted file mode 100644 index 91bf46a..0000000 --- a/llvm/test/CodeGen/X86/statepoint-invoke.ll +++ /dev/null @@ -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) -- 2.7.4