diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-04-06 01:33:49 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2016-04-06 01:33:49 +0000 |
commit | 65a60670e8a8e8380284d45f831f38baf6faba60 (patch) | |
tree | c826446d9f8c66f121eec90809b20c330cc58e22 /llvm | |
parent | 66a69ceed9d35d932892c58b683a21451bf92e5a (diff) | |
download | bcm5719-llvm-65a60670e8a8e8380284d45f831f38baf6faba60.tar.gz bcm5719-llvm-65a60670e8a8e8380284d45f831f38baf6faba60.zip |
Lower @llvm.experimental.deoptimize as a noreturn call
While preserving the return value for @llvm.experimental.deoptimize at
the IR level is useful during mid-level optimization, doing so at the
machine instruction level requires generating some extra code and a
return that is non-ideal. This change has LLVM lower
```
%val = call @llvm.experimental.deoptimize
ret %val
```
to effectively
```
call @__llvm_deoptimize()
unreachable
```
instead.
llvm-svn: 265502
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp | 26 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/deopt-intrinsic.ll | 6 |
4 files changed, 35 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 91c0a04a3b4..f6b4262ffd7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1377,6 +1377,18 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) { SmallVector<ISD::OutputArg, 8> Outs; SmallVector<SDValue, 8> OutVals; + // Calls to @llvm.experimental.deoptimize don't generate a return value, so + // lower + // + // %val = call <ty> @llvm.experimental.deoptimize() + // ret <ty> %val + // + // differently. + if (I.getParent()->getTerminatingDeoptimizeCall()) { + LowerDeoptimizingReturn(); + return; + } + if (!FuncInfo.CanLowerReturn) { unsigned DemoteReg = FuncInfo.DemoteRegister; const Function *F = I.getParent()->getParent(); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 214c5107041..2d2002680ba 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -779,10 +779,12 @@ public: const BasicBlock *EHPadBB); void LowerDeoptimizeCall(const CallInst *CI); + void LowerDeoptimizingReturn(); void LowerCallSiteWithDeoptBundleImpl(ImmutableCallSite CS, SDValue Callee, const BasicBlock *EHPadBB, - bool VarArgDisallowed); + bool VarArgDisallowed, + bool ForceVoidReturnTy); private: // Terminator instructions. diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index edec366aeaa..f489e3b1c8c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -823,11 +823,13 @@ SelectionDAGBuilder::LowerStatepoint(ImmutableStatepoint ISP, void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl( ImmutableCallSite CS, SDValue Callee, const BasicBlock *EHPadBB, - bool VarArgDisallowed) { + bool VarArgDisallowed, bool ForceVoidReturnTy) { StatepointLoweringInfo SI(DAG); unsigned ArgBeginIndex = CS.arg_begin() - CS.getInstruction()->op_begin(); - populateCallLoweringInfo(SI.CLI, CS, ArgBeginIndex, CS.getNumArgOperands(), - Callee, CS.getType(), false); + populateCallLoweringInfo( + SI.CLI, CS, ArgBeginIndex, CS.getNumArgOperands(), Callee, + ForceVoidReturnTy ? Type::getVoidTy(*DAG.getContext()) : CS.getType(), + false); if (!VarArgDisallowed) SI.CLI.IsVarArg = CS.getFunctionType()->isVarArg(); @@ -856,7 +858,8 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl( void SelectionDAGBuilder::LowerCallSiteWithDeoptBundle( ImmutableCallSite CS, SDValue Callee, const BasicBlock *EHPadBB) { LowerCallSiteWithDeoptBundleImpl(CS, Callee, EHPadBB, - /* VarArgDisallowed = */ false); + /* VarArgDisallowed = */ false, + /* ForceVoidReturnTy = */ false); } void SelectionDAGBuilder::visitGCResult(const CallInst &CI) { @@ -941,7 +944,18 @@ void SelectionDAGBuilder::LowerDeoptimizeCall(const CallInst *CI) { TLI.getPointerTy(DAG.getDataLayout())); // We don't lower calls to __llvm_deoptimize as varargs, but as a regular - // call. + // call. We also do not lower the return value to any virtual register, and + // change the immediately following return to a trap instruction. LowerCallSiteWithDeoptBundleImpl(CI, Callee, /* EHPadBB = */ nullptr, - /* VarArgDisallowed = */ true); + /* VarArgDisallowed = */ true, + /* ForceVoidReturnTy = */ true); +} + +void SelectionDAGBuilder::LowerDeoptimizingReturn() { + // We do not lower the return value from llvm.deoptimize to any virtual + // register, and change the immediately following return to a trap + // instruction. + if (DAG.getTarget().Options.TrapUnreachable) + DAG.setRoot( + DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot())); } diff --git a/llvm/test/CodeGen/X86/deopt-intrinsic.ll b/llvm/test/CodeGen/X86/deopt-intrinsic.ll index f9d7527e764..008075bfeae 100644 --- a/llvm/test/CodeGen/X86/deopt-intrinsic.ll +++ b/llvm/test/CodeGen/X86/deopt-intrinsic.ll @@ -18,8 +18,6 @@ define i32 @caller_0() { ; CHECK-NEXT: {{.+cfi.+}} ; CHECK-NEXT: callq ___llvm_deoptimize ; CHECK-NEXT: {{Ltmp[0-9]+}}: -; CHECK-NEXT: popq %rcx -; CHECK-NEXT: retq entry: %v = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 0) ] ret i32 %v @@ -36,8 +34,6 @@ define i8 @caller_1() { ; CHECK-NEXT: movl $42, %edi ; CHECK-NEXT: callq ___llvm_deoptimize ; CHECK-NEXT: {{Ltmp[0-9]+}}: -; CHECK-NEXT: popq %rcx -; CHECK-NEXT: retq entry: %v = call i8(...) @llvm.experimental.deoptimize.i8(i32 42, float 500.0) [ "deopt"(i32 1) ] @@ -55,8 +51,6 @@ define i64 @caller_2() { ; CHECK-NEXT: movl $42, %eax ; CHECK-NEXT: callq ___llvm_deoptimize ; CHECK-NEXT: {{Ltmp[0-9]+}}: -; CHECK-NEXT: popq %rcx -; CHECK-NEXT: retq entry: %v = call webkit_jscc i64(...) @llvm.experimental.deoptimize.i64(i32 42, float 500.0) [ "deopt"(i32 3) ] |