diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/IR/IRBuilder.cpp | 97 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp | 38 |
2 files changed, 82 insertions, 53 deletions
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index 001d10fd69e..c526c862bdc 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -62,6 +62,19 @@ static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops, return CI; } +static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, + ArrayRef<Value *> Ops, + IRBuilderBase *Builder, + const Twine &Name = "") { + InvokeInst *II = + InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name); + Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(), + II); + Builder->SetInstDebugLocation(II); + return II; +} + CallInst *IRBuilderBase:: CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, @@ -231,11 +244,28 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id, return createCallHelper(TheFn, Ops, this, Name); } -CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, - ArrayRef<Value *> CallArgs, - ArrayRef<Value *> DeoptArgs, - ArrayRef<Value *> GCArgs, - const Twine &Name) { +static std::vector<Value *> getStatepointArgs(IRBuilderBase &B, + Value *ActualCallee, + ArrayRef<Value *> CallArgs, + ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs) { + std::vector<Value *> Args; + Args.push_back(ActualCallee); + Args.push_back(B.getInt32(CallArgs.size())); + Args.push_back(B.getInt32(0)); // unused + Args.insert(Args.end(), CallArgs.begin(), CallArgs.end()); + Args.push_back(B.getInt32(DeoptArgs.size())); + Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end()); + Args.insert(Args.end(), GCArgs.begin(), GCArgs.end()); + + return Args; +} + +CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee, + ArrayRef<Value *> CallArgs, + ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, + const Twine &Name) { // Extract out the type of the callee. PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType()); assert(isa<FunctionType>(FuncPtrType->getElementType()) && @@ -248,27 +278,52 @@ CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint, ArgTypes); - std::vector<llvm::Value *> args; - args.push_back(ActualCallee); - args.push_back(getInt32(CallArgs.size())); - args.push_back(getInt32(0 /*unused*/)); - args.insert(args.end(), CallArgs.begin(), CallArgs.end()); - args.push_back(getInt32(DeoptArgs.size())); - args.insert(args.end(), DeoptArgs.begin(), DeoptArgs.end()); - args.insert(args.end(), GCArgs.begin(), GCArgs.end()); - - return createCallHelper(FnStatepoint, args, this, Name); + std::vector<llvm::Value *> Args = + getStatepointArgs(*this, ActualCallee, CallArgs, DeoptArgs, GCArgs); + return createCallHelper(FnStatepoint, Args, this, Name); } -CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, - ArrayRef<Use> CallArgs, - ArrayRef<Value *> DeoptArgs, - ArrayRef<Value *> GCArgs, - const Twine &Name) { +CallInst *IRBuilderBase::CreateGCStatepointCall(Value *ActualCallee, + ArrayRef<Use> CallArgs, + ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, + const Twine &Name) { std::vector<Value *> VCallArgs; for (auto &U : CallArgs) VCallArgs.push_back(U.get()); - return CreateGCStatepoint(ActualCallee, VCallArgs, DeoptArgs, GCArgs, Name); + return CreateGCStatepointCall(ActualCallee, VCallArgs, DeoptArgs, GCArgs, + Name); +} + +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, const Twine &Name) { + // Extract out the type of the callee. + PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->getType()); + assert(isa<FunctionType>(FuncPtrType->getElementType()) && + "actual callee must be a callable value"); + + Module *M = BB->getParent()->getParent(); + // Fill in the one generic type'd argument (the function is also vararg) + Function *FnStatepoint = Intrinsic::getDeclaration( + M, Intrinsic::experimental_gc_statepoint, {FuncPtrType}); + + std::vector<llvm::Value *> Args = + getStatepointArgs(*this, ActualInvokee, InvokeArgs, DeoptArgs, GCArgs); + return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, this, + Name); +} + +InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( + Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, + ArrayRef<Use> InvokeArgs, ArrayRef<Value *> DeoptArgs, + ArrayRef<Value *> GCArgs, const Twine &Name) { + std::vector<Value *> VCallArgs; + for (auto &U : InvokeArgs) + VCallArgs.push_back(U.get()); + return CreateGCStatepointInvoke(ActualInvokee, NormalDest, UnwindDest, + VCallArgs, DeoptArgs, GCArgs, Name); } CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, diff --git a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp index 08e41c27c5c..36a1fea4edc 100644 --- a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -893,7 +893,7 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ AttributeSet return_attributes; if (CS.isCall()) { CallInst *toReplace = cast<CallInst>(CS.getInstruction()); - CallInst *Call = Builder.CreateGCStatepoint( + CallInst *Call = Builder.CreateGCStatepointCall( CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None, "safepoint_token"); Call->setTailCall(toReplace->isTailCall()); @@ -919,42 +919,16 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ Builder.SetCurrentDebugLocation(IP->getDebugLoc()); } else if (CS.isInvoke()) { - // TODO: make CreateGCStatepoint return an Instruction that we can cast to a - // Call or Invoke, instead of doing this junk here. - - // Fill in the one generic type'd argument (the function is also - // vararg) - std::vector<Type *> argTypes; - argTypes.push_back(CS.getCalledValue()->getType()); - - Function *gc_statepoint_decl = Intrinsic::getDeclaration( - M, Intrinsic::experimental_gc_statepoint, argTypes); - - // First, create the statepoint (with all live ptrs as arguments). - std::vector<llvm::Value *> args; - // target, #call args, unused, ... call parameters, #deopt args, ... deopt - // parameters, ... gc parameters - Value *Target = CS.getCalledValue(); - args.push_back(Target); - int callArgSize = CS.arg_size(); - // #call args - args.push_back(Builder.getInt32(callArgSize)); - // unused - args.push_back(Builder.getInt32(0)); - // call parameters - args.insert(args.end(), CS.arg_begin(), CS.arg_end()); - // #deopt args: 0 - args.push_back(Builder.getInt32(0)); - InvokeInst *toReplace = cast<InvokeInst>(CS.getInstruction()); // Insert the new invoke into the old block. We'll remove the old one in a // moment at which point this will become the new terminator for the // original block. - InvokeInst *invoke = InvokeInst::Create( - gc_statepoint_decl, toReplace->getNormalDest(), - toReplace->getUnwindDest(), args, "", toReplace->getParent()); - invoke->setCallingConv(toReplace->getCallingConv()); + Builder.SetInsertPoint(toReplace->getParent()); + InvokeInst *invoke = Builder.CreateGCStatepointInvoke( + CS.getCalledValue(), toReplace->getNormalDest(), + toReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()), + Builder.getInt32(0), None, "safepoint_token"); // Currently we will fail on parameter attributes and on certain // function attributes. |

