Index: include/llvm/Transforms/Utils/Cloning.h =================================================================== --- include/llvm/Transforms/Utils/Cloning.h +++ include/llvm/Transforms/Utils/Cloning.h @@ -20,6 +20,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" +#include "llvm/IR/Statepoint.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -232,6 +233,8 @@ bool InsertLifetime = true); bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, bool InsertLifetime = true); +bool InlineFunction(Statepoint SP, InlineFunctionInfo &IFI, + bool InsertLifetime = true); } // namespace llvm Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -94,6 +94,15 @@ verify(); } + explicit InlineSite(Statepoint SP) + : CalledFunction(cast(SP.getActualCallee())), + CallSiteInst(SP.getCallSite().getInstruction()), + ArgBegin(SP.call_args_begin()), ArgEnd(SP.call_args_end()), + ArgSize(SP.getNumCallArgs()), + DoesNotThrow(cast(SP.getActualCallee())->doesNotThrow()) { + verify(); + } + Function *getCalledFunction() const { return CalledFunction; } Function *getCaller() const; @@ -146,6 +155,33 @@ return true; } +bool llvm::InlineFunction(Statepoint SP, InlineFunctionInfo &IFI, + bool InsertLifetime) { + if (SP.gc_args_begin() != SP.gc_args_begin() || + SP.vm_state_begin() != SP.vm_state_end() || + SP.gc_transition_args_begin() != SP.gc_transition_args_end()) + return false; + + Value *ReturnValOut = nullptr; + bool InlinedMustTailCalls = false; + if (!InlineFunctionImpl(InlineSite(SP), IFI, InsertLifetime, ReturnValOut, + InlinedMustTailCalls)) + return false; + + // TODO: add handling for unreachable code that may violate + // defs-dominate-uses. + if (CallInst *Result = cast_or_null(SP.getGCResult())) { + Result->replaceAllUsesWith(ReturnValOut); + Result->removeFromParent(); + } + + Instruction *StatepointInst = SP.getCallSite().getInstruction(); + assert(StatepointInst->use_empty() && "gc_result should be the only use!"); + StatepointInst->eraseFromParent(); + + return true; +} + namespace { /// A class for recording information about inlining through an invoke. class InvokeInliningInfo {