diff options
author | Ramkumar Ramachandra <artagnon@gmail.com> | 2015-02-26 00:35:56 +0000 |
---|---|---|
committer | Ramkumar Ramachandra <artagnon@gmail.com> | 2015-02-26 00:35:56 +0000 |
commit | 3408f3e296ccad04b7a3d0406bf5da1bca0bf40e (patch) | |
tree | 32eaa165215f1eb386568da40cf31622321a23f9 /llvm/lib/Transforms | |
parent | d6aab731e086374504f41469a61a142592561430 (diff) | |
download | bcm5719-llvm-3408f3e296ccad04b7a3d0406bf5da1bca0bf40e.tar.gz bcm5719-llvm-3408f3e296ccad04b7a3d0406bf5da1bca0bf40e.zip |
PlaceSafepoints: use IRBuilder helpers
Use the IRBuilder helpers for gc.statepoint and gc.result, instead of
coding the construction by hand. Note that the gc.statepoint IRBuilder
handles only CallInst, not InvokeInst; retain that part of hand-coding.
Differential Revision: http://reviews.llvm.org/D7518
llvm-svn: 230591
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp | 83 |
1 files changed, 39 insertions, 44 deletions
diff --git a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp index 376be88fe8a..944725a6667 100644 --- a/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/llvm/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -873,37 +873,12 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ // this logic out to the initialization of the pass. Doesn't appear to // matter in practice. - // 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); - // Then go ahead and use the builder do actually do the inserts. We insert // immediately before the previous instruction under the assumption that all // arguments will be available here. We can't insert afterwards since we may // be replacing a terminator. Instruction *insertBefore = CS.getInstruction(); IRBuilder<> Builder(insertBefore); - // First, create the statepoint (with all live ptrs as arguments). - std::vector<llvm::Value *> args; - // target, #call args, unused, call args..., #deopt args, deopt args..., gc args... - Value *Target = CS.getCalledValue(); - args.push_back(Target); - int callArgSize = CS.arg_size(); - args.push_back( - ConstantInt::get(Type::getInt32Ty(M->getContext()), callArgSize)); - // TODO: add a 'Needs GC-rewrite' later flag - args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0)); - - // Copy all the arguments of the original call - args.insert(args.end(), CS.arg_begin(), CS.arg_end()); - - // # of deopt arguments: this pass currently does not support the - // identification of deopt arguments. If this is interesting to you, - // please ask on llvm-dev. - args.push_back(ConstantInt::get(Type::getInt32Ty(M->getContext()), 0)); // Note: The gc args are not filled in at this time, that's handled by // RewriteStatepointsForGC (which is currently under review). @@ -913,20 +888,21 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ AttributeSet return_attributes; if (CS.isCall()) { CallInst *toReplace = cast<CallInst>(CS.getInstruction()); - CallInst *call = - Builder.CreateCall(gc_statepoint_decl, args, "safepoint_token"); - call->setTailCall(toReplace->isTailCall()); - call->setCallingConv(toReplace->getCallingConv()); + CallInst *Call = Builder.CreateGCStatepoint( + CS.getCalledValue(), makeArrayRef(CS.arg_begin(), CS.arg_end()), None, + None, "safepoint_token"); + Call->setTailCall(toReplace->isTailCall()); + Call->setCallingConv(toReplace->getCallingConv()); // Before we have to worry about GC semantics, all attributes are legal AttributeSet new_attrs = toReplace->getAttributes(); // In case if we can handle this set of sttributes - set up function attrs // directly on statepoint and return attrs later for gc_result intrinsic. - call->setAttributes(new_attrs.getFnAttributes()); + Call->setAttributes(new_attrs.getFnAttributes()); return_attributes = new_attrs.getRetAttributes(); // TODO: handle param attributes - token = call; + token = Call; // Put the following gc_result and gc_relocate calls immediately after the // the old call (which we're about to delete) @@ -938,6 +914,33 @@ 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 @@ -973,19 +976,11 @@ static Value *ReplaceWithStatepoint(const CallSite &CS, /* to replace */ // Only add the gc_result iff there is actually a used result if (!CS.getType()->isVoidTy() && !CS.getInstruction()->use_empty()) { - Instruction *gc_result = nullptr; - std::vector<Type *> types; // one per 'any' type - types.push_back(CS.getType()); // result type - Intrinsic::ID Id = Intrinsic::experimental_gc_result; - Value *gc_result_func = Intrinsic::getDeclaration(M, Id, types); - - std::vector<Value *> args; - args.push_back(token); - gc_result = Builder.CreateCall( - gc_result_func, args, - CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""); - - cast<CallInst>(gc_result)->setAttributes(return_attributes); + std::string takenName = + CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""; + CallInst *gc_result = + Builder.CreateGCResult(token, CS.getType(), takenName); + gc_result->setAttributes(return_attributes); return gc_result; } else { // No return value for the call. |