Skip to content

Commit

Permalink
Lower @llvm.experimental.deoptimize as a noreturn call
Browse files Browse the repository at this point in the history
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265502 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
sanjoy committed Apr 6, 2016
1 parent 43f537f commit 6dd7334
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 13 deletions.
12 changes: 12 additions & 0 deletions lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 3 additions & 1 deletion lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,10 +779,12 @@ class SelectionDAGBuilder {
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.
Expand Down
26 changes: 20 additions & 6 deletions lib/CodeGen/SelectionDAG/StatepointLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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()));
}
6 changes: 0 additions & 6 deletions test/CodeGen/X86/deopt-intrinsic.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) ]
Expand All @@ -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) ]
Expand Down

0 comments on commit 6dd7334

Please sign in to comment.