llvm.org GIT mirror llvm / 4f28549
[RS4GC] Lower calls to @llvm.experimental.deoptimize This changes RS4GC to lower calls to ``@llvm.experimental.deoptimize`` to gc.statepoints wrapping ``__llvm_deoptimize``, and changes ``callsGCLeafFunction`` to recognize ``@llvm.experimental.deoptimize`` as a non GC leaf function. I've had to hard code the ``"__llvm_deoptimize"`` name in RewriteStatepointsForGC; since ``TargetLibraryInfo`` is available only during codegen. This isn't without precedent in the codebase, so I'm not overtly concerned. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@264456 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 3 years ago
3 changed file(s) with 53 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
13381338 StatepointID = *SD.StatepointID;
13391339
13401340 Value *CallTarget = CS.getCalledValue();
1341 if (Function *F = dyn_cast(CallTarget)) {
1342 if (F->getIntrinsicID() == Intrinsic::experimental_deoptimize) {
1343 // Calls to llvm.experimental.deoptimize are lowered to calls the the
1344 // __llvm_deoptimize symbol. We want to resolve this now, since the
1345 // verifier does not allow taking the address of an intrinsic function.
1346
1347 SmallVector DomainTy;
1348 for (Value *Arg : CallArgs)
1349 DomainTy.push_back(Arg->getType());
1350 auto *FTy = FunctionType::get(F->getReturnType(), DomainTy,
1351 /* isVarArg = */ false);
1352
1353 // Note: CallTarget can be a bitcast instruction of a symbol if there are
1354 // calls to @llvm.experimental.deoptimize with different argument types in
1355 // the same module. This is fine -- we assume the frontend knew what it
1356 // was doing when generating this kind of IR.
1357 CallTarget =
1358 F->getParent()->getOrInsertFunction("__llvm_deoptimize", FTy);
1359 }
1360 }
13411361
13421362 // Create the statepoint given all the arguments
13431363 Instruction *Token = nullptr;
23192339
23202340 auto NeedsRewrite = [](Instruction &I) {
23212341 if (ImmutableCallSite CS = ImmutableCallSite(&I))
2322 return !callsGCLeafFunction(CS);
2342 return !callsGCLeafFunction(CS) && !isStatepoint(CS);
23232343 return false;
23242344 };
23252345
16021602 }
16031603
16041604 bool llvm::callsGCLeafFunction(ImmutableCallSite CS) {
1605 if (isa(CS.getInstruction()))
1606 // Most LLVM intrinsics are things which can never take a safepoint.
1607 // As a result, we don't need to have the stack parsable at the
1608 // callsite. This is a highly useful optimization since intrinsic
1609 // calls are fairly prevalent, particularly in debug builds.
1610 return true;
1611
16121605 // Check if the function is specifically marked as a gc leaf function.
16131606 if (CS.hasFnAttr("gc-leaf-function"))
16141607 return true;
1615 if (const Function *F = CS.getCalledFunction())
1616 return F->hasFnAttribute("gc-leaf-function");
1608 if (const Function *F = CS.getCalledFunction()) {
1609 if (F->hasFnAttribute("gc-leaf-function"))
1610 return true;
1611
1612 if (auto IID = F->getIntrinsicID())
1613 // Most LLVM intrinsics do not take safepoints.
1614 return IID != Intrinsic::experimental_gc_statepoint &&
1615 IID != Intrinsic::experimental_deoptimize;
1616 }
16171617
16181618 return false;
16191619 }
0 ; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s
1
2 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-apple-macosx10.11.0"
4
5 declare i32 @llvm.experimental.deoptimize.i32(...)
6
7 define i32 @caller_0(i32 addrspace(1)* %ptr) gc "statepoint-example" {
8 ; CHECK-LABEL: @caller_0(
9 ; CHECK: @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @__llvm_deoptimize, i32 0
10 entry:
11 %v = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 0, i32 addrspace(1)* %ptr) ]
12 ret i32 %v
13 }
14
15
16 define i32 @caller_1(i32 addrspace(1)* %ptr) gc "statepoint-example" {
17 ; CHECK-LABEL: @caller_1
18 ; CHECK: @llvm.experimental.gc.statepoint.p0f_i32i32p1i32f(i64 2882400000, i32 0, i32 (i32, i32 addrspace(1)*)* bitcast (i32 ()* @__llvm_deoptimize to i32 (i32, i32 addrspace(1)*)*), i32 2, i32 0, i32 50, i32 addrspace(1)* %ptr
19 entry:
20 %v = call i32(...) @llvm.experimental.deoptimize.i32(i32 50, i32 addrspace(1)* %ptr) [ "deopt"(i32 0) ]
21 ret i32 %v
22 }