diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /lib/Transforms/Scalar/PlaceSafepoints.cpp | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
download | src-01095a5d43bbfde13731688ddcf6048ebb8b7721.tar.gz src-01095a5d43bbfde13731688ddcf6048ebb8b7721.zip |
Vendor import of llvm release_39 branch r276489:vendor/llvm/llvm-release_39-r276489
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=303231
svn path=/vendor/llvm/llvm-release_39-r276489/; revision=303232; tag=vendor/llvm/llvm-release_39-r276489
Diffstat (limited to 'lib/Transforms/Scalar/PlaceSafepoints.cpp')
-rw-r--r-- | lib/Transforms/Scalar/PlaceSafepoints.cpp | 471 |
1 files changed, 99 insertions, 372 deletions
diff --git a/lib/Transforms/Scalar/PlaceSafepoints.cpp b/lib/Transforms/Scalar/PlaceSafepoints.cpp index b56b35599120..e47b636348e3 100644 --- a/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -49,45 +49,32 @@ //===----------------------------------------------------------------------===// #include "llvm/Pass.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/ADT/SetOperations.h" + #include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/CFG.h" -#include "llvm/Analysis/InstructionSimplify.h" -#include "llvm/IR/BasicBlock.h" +#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Dominators.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Module.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Statepoint.h" -#include "llvm/IR/Value.h" -#include "llvm/IR/Verifier.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Debug.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #define DEBUG_TYPE "safepoint-placement" + STATISTIC(NumEntrySafepoints, "Number of entry safepoints inserted"); -STATISTIC(NumCallSafepoints, "Number of call safepoints inserted"); STATISTIC(NumBackedgeSafepoints, "Number of backedge safepoints inserted"); -STATISTIC(CallInLoop, "Number of loops w/o safepoints due to calls in loop"); -STATISTIC(FiniteExecution, "Number of loops w/o safepoints finite execution"); +STATISTIC(CallInLoop, + "Number of loops without safepoints due to calls in loop"); +STATISTIC(FiniteExecution, + "Number of loops without safepoints finite execution"); using namespace llvm; @@ -108,9 +95,6 @@ static cl::opt<int> CountedLoopTripWidth("spp-counted-loop-trip-width", static cl::opt<bool> SplitBackedge("spp-split-backedge", cl::Hidden, cl::init(false)); -// Print tracing output -static cl::opt<bool> TraceLSP("spp-trace", cl::Hidden, cl::init(false)); - namespace { /// An analysis pass whose purpose is to identify each of the backedges in @@ -138,8 +122,8 @@ struct PlaceBackedgeSafepointsImpl : public FunctionPass { bool runOnLoop(Loop *); void runOnLoopAndSubLoops(Loop *L) { // Visit all the subloops - for (auto I = L->begin(), E = L->end(); I != E; I++) - runOnLoopAndSubLoops(*I); + for (Loop *I : *L) + runOnLoopAndSubLoops(I); runOnLoop(L); } @@ -147,8 +131,8 @@ struct PlaceBackedgeSafepointsImpl : public FunctionPass { SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - for (auto I = LI->begin(), E = LI->end(); I != E; I++) { - runOnLoopAndSubLoops(*I); + for (Loop *I : *LI) { + runOnLoopAndSubLoops(I); } return false; } @@ -200,13 +184,9 @@ static bool needsStatepoint(const CallSite &CS) { if (call->isInlineAsm()) return false; } - if (isStatepoint(CS) || isGCRelocate(CS) || isGCResult(CS)) { - return false; - } - return true; -} -static Value *ReplaceWithStatepoint(const CallSite &CS); + return !(isStatepoint(CS) || isGCRelocate(CS) || isGCResult(CS)); +} /// Returns true if this loop is known to contain a call safepoint which /// must unconditionally execute on any iteration of the loop which returns @@ -278,43 +258,44 @@ static bool mustBeFiniteCountedLoop(Loop *L, ScalarEvolution *SE, return /* not finite */ false; } -static void scanOneBB(Instruction *start, Instruction *end, - std::vector<CallInst *> &calls, - std::set<BasicBlock *> &seen, - std::vector<BasicBlock *> &worklist) { - for (BasicBlock::iterator itr(start); - itr != start->getParent()->end() && itr != BasicBlock::iterator(end); - itr++) { - if (CallInst *CI = dyn_cast<CallInst>(&*itr)) { - calls.push_back(CI); - } +static void scanOneBB(Instruction *Start, Instruction *End, + std::vector<CallInst *> &Calls, + DenseSet<BasicBlock *> &Seen, + std::vector<BasicBlock *> &Worklist) { + for (BasicBlock::iterator BBI(Start), BBE0 = Start->getParent()->end(), + BBE1 = BasicBlock::iterator(End); + BBI != BBE0 && BBI != BBE1; BBI++) { + if (CallInst *CI = dyn_cast<CallInst>(&*BBI)) + Calls.push_back(CI); + // FIXME: This code does not handle invokes - assert(!dyn_cast<InvokeInst>(&*itr) && + assert(!isa<InvokeInst>(&*BBI) && "support for invokes in poll code needed"); + // Only add the successor blocks if we reach the terminator instruction // without encountering end first - if (itr->isTerminator()) { - BasicBlock *BB = itr->getParent(); + if (BBI->isTerminator()) { + BasicBlock *BB = BBI->getParent(); for (BasicBlock *Succ : successors(BB)) { - if (seen.count(Succ) == 0) { - worklist.push_back(Succ); - seen.insert(Succ); + if (Seen.insert(Succ).second) { + Worklist.push_back(Succ); } } } } } -static void scanInlinedCode(Instruction *start, Instruction *end, - std::vector<CallInst *> &calls, - std::set<BasicBlock *> &seen) { - calls.clear(); - std::vector<BasicBlock *> worklist; - seen.insert(start->getParent()); - scanOneBB(start, end, calls, seen, worklist); - while (!worklist.empty()) { - BasicBlock *BB = worklist.back(); - worklist.pop_back(); - scanOneBB(&*BB->begin(), end, calls, seen, worklist); + +static void scanInlinedCode(Instruction *Start, Instruction *End, + std::vector<CallInst *> &Calls, + DenseSet<BasicBlock *> &Seen) { + Calls.clear(); + std::vector<BasicBlock *> Worklist; + Seen.insert(Start->getParent()); + scanOneBB(Start, End, Calls, Seen, Worklist); + while (!Worklist.empty()) { + BasicBlock *BB = Worklist.back(); + Worklist.pop_back(); + scanOneBB(&*BB->begin(), End, Calls, Seen, Worklist); } } @@ -324,29 +305,27 @@ bool PlaceBackedgeSafepointsImpl::runOnLoop(Loop *L) { // Note: In common usage, there will be only one edge due to LoopSimplify // having run sometime earlier in the pipeline, but this code must be correct // w.r.t. loops with multiple backedges. - BasicBlock *header = L->getHeader(); + BasicBlock *Header = L->getHeader(); SmallVector<BasicBlock*, 16> LoopLatches; L->getLoopLatches(LoopLatches); - for (BasicBlock *pred : LoopLatches) { - assert(L->contains(pred)); + for (BasicBlock *Pred : LoopLatches) { + assert(L->contains(Pred)); // Make a policy decision about whether this loop needs a safepoint or // not. Note that this is about unburdening the optimizer in loops, not // avoiding the runtime cost of the actual safepoint. if (!AllBackedges) { - if (mustBeFiniteCountedLoop(L, SE, pred)) { - if (TraceLSP) - errs() << "skipping safepoint placement in finite loop\n"; + if (mustBeFiniteCountedLoop(L, SE, Pred)) { + DEBUG(dbgs() << "skipping safepoint placement in finite loop\n"); FiniteExecution++; continue; } if (CallSafepointsEnabled && - containsUnconditionalCallSafepoint(L, header, pred, *DT)) { + containsUnconditionalCallSafepoint(L, Header, Pred, *DT)) { // Note: This is only semantically legal since we won't do any further // IPO or inlining before the actual call insertion.. If we hadn't, we // might latter loose this call safepoint. - if (TraceLSP) - errs() << "skipping safepoint placement due to unconditional call\n"; + DEBUG(dbgs() << "skipping safepoint placement due to unconditional call\n"); CallInLoop++; continue; } @@ -360,14 +339,11 @@ bool PlaceBackedgeSafepointsImpl::runOnLoop(Loop *L) { // Safepoint insertion would involve creating a new basic block (as the // target of the current backedge) which does the safepoint (of all live // variables) and branches to the true header - TerminatorInst *term = pred->getTerminator(); + TerminatorInst *Term = Pred->getTerminator(); - if (TraceLSP) { - errs() << "[LSP] terminator instruction: "; - term->dump(); - } + DEBUG(dbgs() << "[LSP] terminator instruction: " << *Term); - PollLocations.push_back(term); + PollLocations.push_back(Term); } return false; @@ -411,27 +387,26 @@ static Instruction *findLocationForEntrySafepoint(Function &F, // hasNextInstruction and nextInstruction are used to iterate // through a "straight line" execution sequence. - auto hasNextInstruction = [](Instruction *I) { - if (!I->isTerminator()) { + auto HasNextInstruction = [](Instruction *I) { + if (!I->isTerminator()) return true; - } + BasicBlock *nextBB = I->getParent()->getUniqueSuccessor(); return nextBB && (nextBB->getUniquePredecessor() != nullptr); }; - auto nextInstruction = [&hasNextInstruction](Instruction *I) { - assert(hasNextInstruction(I) && + auto NextInstruction = [&](Instruction *I) { + assert(HasNextInstruction(I) && "first check if there is a next instruction!"); - if (I->isTerminator()) { + + if (I->isTerminator()) return &I->getParent()->getUniqueSuccessor()->front(); - } else { - return &*++I->getIterator(); - } + return &*++I->getIterator(); }; - Instruction *cursor = nullptr; - for (cursor = &F.getEntryBlock().front(); hasNextInstruction(cursor); - cursor = nextInstruction(cursor)) { + Instruction *Cursor = nullptr; + for (Cursor = &F.getEntryBlock().front(); HasNextInstruction(Cursor); + Cursor = NextInstruction(Cursor)) { // We need to ensure a safepoint poll occurs before any 'real' call. The // easiest way to ensure finite execution between safepoints in the face of @@ -440,51 +415,17 @@ static Instruction *findLocationForEntrySafepoint(Function &F, // which can grow the stack by an unbounded amount. This isn't required // for GC semantics per se, but is a common requirement for languages // which detect stack overflow via guard pages and then throw exceptions. - if (auto CS = CallSite(cursor)) { + if (auto CS = CallSite(Cursor)) { if (doesNotRequireEntrySafepointBefore(CS)) continue; break; } } - assert((hasNextInstruction(cursor) || cursor->isTerminator()) && + assert((HasNextInstruction(Cursor) || Cursor->isTerminator()) && "either we stopped because of a call, or because of terminator"); - return cursor; -} - -/// Identify the list of call sites which need to be have parseable state -static void findCallSafepoints(Function &F, - std::vector<CallSite> &Found /*rval*/) { - assert(Found.empty() && "must be empty!"); - for (Instruction &I : instructions(F)) { - Instruction *inst = &I; - if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) { - CallSite CS(inst); - - // No safepoint needed or wanted - if (!needsStatepoint(CS)) { - continue; - } - - Found.push_back(CS); - } - } -} - -/// Implement a unique function which doesn't require we sort the input -/// vector. Doing so has the effect of changing the output of a couple of -/// tests in ways which make them less useful in testing fused safepoints. -template <typename T> static void unique_unsorted(std::vector<T> &vec) { - std::set<T> seen; - std::vector<T> tmp; - vec.reserve(vec.size()); - std::swap(tmp, vec); - for (auto V : tmp) { - if (seen.insert(V).second) { - vec.push_back(V); - } - } + return Cursor; } static const char *const GCSafepointPollName = "gc.safepoint_poll"; @@ -514,24 +455,6 @@ static bool enableEntrySafepoints(Function &F) { return !NoEntry; } static bool enableBackedgeSafepoints(Function &F) { return !NoBackedge; } static bool enableCallSafepoints(Function &F) { return !NoCall; } -// Normalize basic block to make it ready to be target of invoke statepoint. -// Ensure that 'BB' does not have phi nodes. It may require spliting it. -static BasicBlock *normalizeForInvokeSafepoint(BasicBlock *BB, - BasicBlock *InvokeParent) { - BasicBlock *ret = BB; - - if (!BB->getUniquePredecessor()) { - ret = SplitBlockPredecessors(BB, InvokeParent, ""); - } - - // Now that 'ret' has unique predecessor we can safely remove all phi nodes - // from it - FoldSingleEntryPHINodes(ret); - assert(!isa<PHINode>(ret->begin())); - - return ret; -} - bool PlaceSafepoints::runOnFunction(Function &F) { if (F.isDeclaration() || F.empty()) { // This is a declaration, nothing to do. Must exit early to avoid crash in @@ -549,13 +472,13 @@ bool PlaceSafepoints::runOnFunction(Function &F) { if (!shouldRewriteFunction(F)) return false; - bool modified = false; + bool Modified = false; // In various bits below, we rely on the fact that uses are reachable from // defs. When there are basic blocks unreachable from the entry, dominance // and reachablity queries return non-sensical results. Thus, we preprocess // the function to ensure these properties hold. - modified |= removeUnreachableBlocks(F); + Modified |= removeUnreachableBlocks(F); // STEP 1 - Insert the safepoint polling locations. We do not need to // actually insert parse points yet. That will be done for all polls and @@ -574,8 +497,7 @@ bool PlaceSafepoints::runOnFunction(Function &F) { // with for the moment. legacy::FunctionPassManager FPM(F.getParent()); bool CanAssumeCallSafepoints = enableCallSafepoints(F); - PlaceBackedgeSafepointsImpl *PBS = - new PlaceBackedgeSafepointsImpl(CanAssumeCallSafepoints); + auto *PBS = new PlaceBackedgeSafepointsImpl(CanAssumeCallSafepoints); FPM.add(PBS); FPM.run(F); @@ -603,7 +525,7 @@ bool PlaceSafepoints::runOnFunction(Function &F) { // The poll location must be the terminator of a loop latch block. for (TerminatorInst *Term : PollLocations) { // We are inserting a poll, the function is modified - modified = true; + Modified = true; if (SplitBackedge) { // Split the backedge of the loop and insert the poll within that new @@ -643,14 +565,13 @@ bool PlaceSafepoints::runOnFunction(Function &F) { } if (enableEntrySafepoints(F)) { - Instruction *Location = findLocationForEntrySafepoint(F, DT); - if (!Location) { - // policy choice not to insert? - } else { + if (Instruction *Location = findLocationForEntrySafepoint(F, DT)) { PollsNeeded.push_back(Location); - modified = true; + Modified = true; NumEntrySafepoints++; } + // TODO: else we should assert that there was, in fact, a policy choice to + // not insert a entry safepoint poll. } // Now that we've identified all the needed safepoint poll locations, insert @@ -661,71 +582,8 @@ bool PlaceSafepoints::runOnFunction(Function &F) { ParsePointNeeded.insert(ParsePointNeeded.end(), RuntimeCalls.begin(), RuntimeCalls.end()); } - PollsNeeded.clear(); // make sure we don't accidentally use - // The dominator tree has been invalidated by the inlining performed in the - // above loop. TODO: Teach the inliner how to update the dom tree? - DT.recalculate(F); - - if (enableCallSafepoints(F)) { - std::vector<CallSite> Calls; - findCallSafepoints(F, Calls); - NumCallSafepoints += Calls.size(); - ParsePointNeeded.insert(ParsePointNeeded.end(), Calls.begin(), Calls.end()); - } - - // Unique the vectors since we can end up with duplicates if we scan the call - // site for call safepoints after we add it for entry or backedge. The - // only reason we need tracking at all is that some functions might have - // polls but not call safepoints and thus we might miss marking the runtime - // calls for the polls. (This is useful in test cases!) - unique_unsorted(ParsePointNeeded); - - // Any parse point (no matter what source) will be handled here - - // We're about to start modifying the function - if (!ParsePointNeeded.empty()) - modified = true; - - // Now run through and insert the safepoints, but do _NOT_ update or remove - // any existing uses. We have references to live variables that need to - // survive to the last iteration of this loop. - std::vector<Value *> Results; - Results.reserve(ParsePointNeeded.size()); - for (size_t i = 0; i < ParsePointNeeded.size(); i++) { - CallSite &CS = ParsePointNeeded[i]; - - // For invoke statepoints we need to remove all phi nodes at the normal - // destination block. - // Reason for this is that we can place gc_result only after last phi node - // in basic block. We will get malformed code after RAUW for the - // gc_result if one of this phi nodes uses result from the invoke. - if (InvokeInst *Invoke = dyn_cast<InvokeInst>(CS.getInstruction())) { - normalizeForInvokeSafepoint(Invoke->getNormalDest(), - Invoke->getParent()); - } - - Value *GCResult = ReplaceWithStatepoint(CS); - Results.push_back(GCResult); - } - assert(Results.size() == ParsePointNeeded.size()); - - // Adjust all users of the old call sites to use the new ones instead - for (size_t i = 0; i < ParsePointNeeded.size(); i++) { - CallSite &CS = ParsePointNeeded[i]; - Value *GCResult = Results[i]; - if (GCResult) { - // Can not RAUW for the invoke gc result in case of phi nodes preset. - assert(CS.isCall() || !isa<PHINode>(cast<Instruction>(GCResult)->getParent()->begin())); - - // Replace all uses with the new call - CS.getInstruction()->replaceAllUsesWith(GCResult); - } - // Now that we've handled all uses, remove the original call itself - // Note: The insert point can't be the deleted instruction! - CS.getInstruction()->eraseFromParent(); - } - return modified; + return Modified; } char PlaceBackedgeSafepointsImpl::ID = 0; @@ -763,191 +621,60 @@ InsertSafepointPoll(Instruction *InsertBefore, auto *F = M->getFunction(GCSafepointPollName); assert(F && "gc.safepoint_poll function is missing"); - assert(F->getType()->getElementType() == + assert(F->getValueType() == FunctionType::get(Type::getVoidTy(M->getContext()), false) && "gc.safepoint_poll declared with wrong type"); assert(!F->empty() && "gc.safepoint_poll must be a non-empty function"); CallInst *PollCall = CallInst::Create(F, "", InsertBefore); // Record some information about the call site we're replacing - BasicBlock::iterator before(PollCall), after(PollCall); - bool isBegin(false); - if (before == OrigBB->begin()) { - isBegin = true; - } else { - before--; - } - after++; - assert(after != OrigBB->end() && "must have successor"); + BasicBlock::iterator Before(PollCall), After(PollCall); + bool IsBegin = false; + if (Before == OrigBB->begin()) + IsBegin = true; + else + Before--; - // do the actual inlining + After++; + assert(After != OrigBB->end() && "must have successor"); + + // Do the actual inlining InlineFunctionInfo IFI; bool InlineStatus = InlineFunction(PollCall, IFI); assert(InlineStatus && "inline must succeed"); (void)InlineStatus; // suppress warning in release-asserts - // Check post conditions + // Check post-conditions assert(IFI.StaticAllocas.empty() && "can't have allocs"); - std::vector<CallInst *> calls; // new calls - std::set<BasicBlock *> BBs; // new BBs + insertee + std::vector<CallInst *> Calls; // new calls + DenseSet<BasicBlock *> BBs; // new BBs + insertee + // Include only the newly inserted instructions, Note: begin may not be valid // if we inserted to the beginning of the basic block - BasicBlock::iterator start; - if (isBegin) { - start = OrigBB->begin(); - } else { - start = before; - start++; - } + BasicBlock::iterator Start = IsBegin ? OrigBB->begin() : std::next(Before); // If your poll function includes an unreachable at the end, that's not // valid. Bugpoint likes to create this, so check for it. - assert(isPotentiallyReachable(&*start, &*after, nullptr, nullptr) && + assert(isPotentiallyReachable(&*Start, &*After) && "malformed poll function"); - scanInlinedCode(&*(start), &*(after), calls, BBs); - assert(!calls.empty() && "slow path not found for safepoint poll"); + scanInlinedCode(&*Start, &*After, Calls, BBs); + assert(!Calls.empty() && "slow path not found for safepoint poll"); // Record the fact we need a parsable state at the runtime call contained in // the poll function. This is required so that the runtime knows how to // parse the last frame when we actually take the safepoint (i.e. execute // the slow path) assert(ParsePointsNeeded.empty()); - for (size_t i = 0; i < calls.size(); i++) { - + for (auto *CI : Calls) { // No safepoint needed or wanted - if (!needsStatepoint(calls[i])) { + if (!needsStatepoint(CI)) continue; - } // These are likely runtime calls. Should we assert that via calling // convention or something? - ParsePointsNeeded.push_back(CallSite(calls[i])); - } - assert(ParsePointsNeeded.size() <= calls.size()); -} - -/// Replaces the given call site (Call or Invoke) with a gc.statepoint -/// intrinsic with an empty deoptimization arguments list. This does -/// NOT do explicit relocation for GC support. -static Value *ReplaceWithStatepoint(const CallSite &CS /* to replace */) { - assert(CS.getInstruction()->getModule() && "must be set"); - - // TODO: technically, a pass is not allowed to get functions from within a - // function pass since it might trigger a new function addition. Refactor - // this logic out to the initialization of the pass. Doesn't appear to - // matter in practice. - - // 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. - IRBuilder<> Builder(CS.getInstruction()); - - // Note: The gc args are not filled in at this time, that's handled by - // RewriteStatepointsForGC (which is currently under review). - - // Create the statepoint given all the arguments - Instruction *Token = nullptr; - - uint64_t ID; - uint32_t NumPatchBytes; - - AttributeSet OriginalAttrs = CS.getAttributes(); - Attribute AttrID = - OriginalAttrs.getAttribute(AttributeSet::FunctionIndex, "statepoint-id"); - Attribute AttrNumPatchBytes = OriginalAttrs.getAttribute( - AttributeSet::FunctionIndex, "statepoint-num-patch-bytes"); - - AttrBuilder AttrsToRemove; - bool HasID = AttrID.isStringAttribute() && - !AttrID.getValueAsString().getAsInteger(10, ID); - - if (HasID) - AttrsToRemove.addAttribute("statepoint-id"); - else - ID = 0xABCDEF00; - - bool HasNumPatchBytes = - AttrNumPatchBytes.isStringAttribute() && - !AttrNumPatchBytes.getValueAsString().getAsInteger(10, NumPatchBytes); - - if (HasNumPatchBytes) - AttrsToRemove.addAttribute("statepoint-num-patch-bytes"); - else - NumPatchBytes = 0; - - OriginalAttrs = OriginalAttrs.removeAttributes( - CS.getInstruction()->getContext(), AttributeSet::FunctionIndex, - AttrsToRemove); - - if (CS.isCall()) { - CallInst *ToReplace = cast<CallInst>(CS.getInstruction()); - CallInst *Call = Builder.CreateGCStatepointCall( - ID, NumPatchBytes, CS.getCalledValue(), - makeArrayRef(CS.arg_begin(), CS.arg_end()), None, None, - "safepoint_token"); - Call->setTailCall(ToReplace->isTailCall()); - Call->setCallingConv(ToReplace->getCallingConv()); - - // In case if we can handle this set of attributes - set up function - // attributes directly on statepoint and return attributes later for - // gc_result intrinsic. - Call->setAttributes(OriginalAttrs.getFnAttributes()); - - Token = Call; - - // Put the following gc_result and gc_relocate calls immediately after - // the old call (which we're about to delete). - assert(ToReplace->getNextNode() && "not a terminator, must have next"); - Builder.SetInsertPoint(ToReplace->getNextNode()); - Builder.SetCurrentDebugLocation(ToReplace->getNextNode()->getDebugLoc()); - } else if (CS.isInvoke()) { - 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. - Builder.SetInsertPoint(ToReplace->getParent()); - InvokeInst *Invoke = Builder.CreateGCStatepointInvoke( - ID, NumPatchBytes, CS.getCalledValue(), ToReplace->getNormalDest(), - ToReplace->getUnwindDest(), makeArrayRef(CS.arg_begin(), CS.arg_end()), - None, None, "safepoint_token"); - - Invoke->setCallingConv(ToReplace->getCallingConv()); - - // In case if we can handle this set of attributes - set up function - // attributes directly on statepoint and return attributes later for - // gc_result intrinsic. - Invoke->setAttributes(OriginalAttrs.getFnAttributes()); - - Token = Invoke; - - // We'll insert the gc.result into the normal block - BasicBlock *NormalDest = ToReplace->getNormalDest(); - // Can not insert gc.result in case of phi nodes preset. - // Should have removed this cases prior to running this function - assert(!isa<PHINode>(NormalDest->begin())); - Instruction *IP = &*(NormalDest->getFirstInsertionPt()); - Builder.SetInsertPoint(IP); - } else { - llvm_unreachable("unexpect type of CallSite"); - } - assert(Token); - - // Handle the return value of the original call - update all uses to use a - // gc_result hanging off the statepoint node we just inserted - - // Only add the gc_result iff there is actually a used result - if (!CS.getType()->isVoidTy() && !CS.getInstruction()->use_empty()) { - std::string TakenName = - CS.getInstruction()->hasName() ? CS.getInstruction()->getName() : ""; - CallInst *GCResult = Builder.CreateGCResult(Token, CS.getType(), TakenName); - GCResult->setAttributes(OriginalAttrs.getRetAttributes()); - return GCResult; - } else { - // No return value for the call. - return nullptr; + ParsePointsNeeded.push_back(CallSite(CI)); } + assert(ParsePointsNeeded.size() <= Calls.size()); } |