109467b48Spatrick //===- RewriteStatepointsForGC.cpp - Make GC relocations explicit ---------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // Rewrite call/invoke instructions so as to make potential relocations
1009467b48Spatrick // performed by the garbage collector explicit in the IR.
1109467b48Spatrick //
1209467b48Spatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick
1409467b48Spatrick #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
1509467b48Spatrick
1609467b48Spatrick #include "llvm/ADT/ArrayRef.h"
1709467b48Spatrick #include "llvm/ADT/DenseMap.h"
1809467b48Spatrick #include "llvm/ADT/DenseSet.h"
1909467b48Spatrick #include "llvm/ADT/MapVector.h"
2009467b48Spatrick #include "llvm/ADT/STLExtras.h"
2109467b48Spatrick #include "llvm/ADT/SetVector.h"
2209467b48Spatrick #include "llvm/ADT/SmallSet.h"
2309467b48Spatrick #include "llvm/ADT/SmallVector.h"
2409467b48Spatrick #include "llvm/ADT/StringRef.h"
2509467b48Spatrick #include "llvm/ADT/iterator_range.h"
2609467b48Spatrick #include "llvm/Analysis/DomTreeUpdater.h"
2709467b48Spatrick #include "llvm/Analysis/TargetLibraryInfo.h"
2809467b48Spatrick #include "llvm/Analysis/TargetTransformInfo.h"
2909467b48Spatrick #include "llvm/IR/Argument.h"
3009467b48Spatrick #include "llvm/IR/Attributes.h"
3109467b48Spatrick #include "llvm/IR/BasicBlock.h"
3209467b48Spatrick #include "llvm/IR/CallingConv.h"
3309467b48Spatrick #include "llvm/IR/Constant.h"
3409467b48Spatrick #include "llvm/IR/Constants.h"
3509467b48Spatrick #include "llvm/IR/DataLayout.h"
3609467b48Spatrick #include "llvm/IR/DerivedTypes.h"
3709467b48Spatrick #include "llvm/IR/Dominators.h"
3809467b48Spatrick #include "llvm/IR/Function.h"
3909467b48Spatrick #include "llvm/IR/IRBuilder.h"
4009467b48Spatrick #include "llvm/IR/InstIterator.h"
4109467b48Spatrick #include "llvm/IR/InstrTypes.h"
4209467b48Spatrick #include "llvm/IR/Instruction.h"
4309467b48Spatrick #include "llvm/IR/Instructions.h"
4409467b48Spatrick #include "llvm/IR/IntrinsicInst.h"
4509467b48Spatrick #include "llvm/IR/Intrinsics.h"
4609467b48Spatrick #include "llvm/IR/LLVMContext.h"
4709467b48Spatrick #include "llvm/IR/MDBuilder.h"
4809467b48Spatrick #include "llvm/IR/Metadata.h"
4909467b48Spatrick #include "llvm/IR/Module.h"
5009467b48Spatrick #include "llvm/IR/Statepoint.h"
5109467b48Spatrick #include "llvm/IR/Type.h"
5209467b48Spatrick #include "llvm/IR/User.h"
5309467b48Spatrick #include "llvm/IR/Value.h"
5409467b48Spatrick #include "llvm/IR/ValueHandle.h"
5509467b48Spatrick #include "llvm/InitializePasses.h"
5609467b48Spatrick #include "llvm/Pass.h"
5709467b48Spatrick #include "llvm/Support/Casting.h"
5809467b48Spatrick #include "llvm/Support/CommandLine.h"
5909467b48Spatrick #include "llvm/Support/Compiler.h"
6009467b48Spatrick #include "llvm/Support/Debug.h"
6109467b48Spatrick #include "llvm/Support/ErrorHandling.h"
6209467b48Spatrick #include "llvm/Support/raw_ostream.h"
6309467b48Spatrick #include "llvm/Transforms/Scalar.h"
6409467b48Spatrick #include "llvm/Transforms/Utils/BasicBlockUtils.h"
6509467b48Spatrick #include "llvm/Transforms/Utils/Local.h"
6609467b48Spatrick #include "llvm/Transforms/Utils/PromoteMemToReg.h"
6709467b48Spatrick #include <algorithm>
6809467b48Spatrick #include <cassert>
6909467b48Spatrick #include <cstddef>
7009467b48Spatrick #include <cstdint>
7109467b48Spatrick #include <iterator>
72*d415bd75Srobert #include <optional>
7309467b48Spatrick #include <set>
7409467b48Spatrick #include <string>
7509467b48Spatrick #include <utility>
7609467b48Spatrick #include <vector>
7709467b48Spatrick
7809467b48Spatrick #define DEBUG_TYPE "rewrite-statepoints-for-gc"
7909467b48Spatrick
8009467b48Spatrick using namespace llvm;
8109467b48Spatrick
8209467b48Spatrick // Print the liveset found at the insert location
8309467b48Spatrick static cl::opt<bool> PrintLiveSet("spp-print-liveset", cl::Hidden,
8409467b48Spatrick cl::init(false));
8509467b48Spatrick static cl::opt<bool> PrintLiveSetSize("spp-print-liveset-size", cl::Hidden,
8609467b48Spatrick cl::init(false));
8709467b48Spatrick
8809467b48Spatrick // Print out the base pointers for debugging
8909467b48Spatrick static cl::opt<bool> PrintBasePointers("spp-print-base-pointers", cl::Hidden,
9009467b48Spatrick cl::init(false));
9109467b48Spatrick
9209467b48Spatrick // Cost threshold measuring when it is profitable to rematerialize value instead
9309467b48Spatrick // of relocating it
9409467b48Spatrick static cl::opt<unsigned>
9509467b48Spatrick RematerializationThreshold("spp-rematerialization-threshold", cl::Hidden,
9609467b48Spatrick cl::init(6));
9709467b48Spatrick
9809467b48Spatrick #ifdef EXPENSIVE_CHECKS
9909467b48Spatrick static bool ClobberNonLive = true;
10009467b48Spatrick #else
10109467b48Spatrick static bool ClobberNonLive = false;
10209467b48Spatrick #endif
10309467b48Spatrick
10409467b48Spatrick static cl::opt<bool, true> ClobberNonLiveOverride("rs4gc-clobber-non-live",
10509467b48Spatrick cl::location(ClobberNonLive),
10609467b48Spatrick cl::Hidden);
10709467b48Spatrick
10809467b48Spatrick static cl::opt<bool>
10909467b48Spatrick AllowStatepointWithNoDeoptInfo("rs4gc-allow-statepoint-with-no-deopt-info",
11009467b48Spatrick cl::Hidden, cl::init(true));
11109467b48Spatrick
112*d415bd75Srobert static cl::opt<bool> RematDerivedAtUses("rs4gc-remat-derived-at-uses",
113*d415bd75Srobert cl::Hidden, cl::init(true));
114*d415bd75Srobert
11509467b48Spatrick /// The IR fed into RewriteStatepointsForGC may have had attributes and
11609467b48Spatrick /// metadata implying dereferenceability that are no longer valid/correct after
11709467b48Spatrick /// RewriteStatepointsForGC has run. This is because semantically, after
11809467b48Spatrick /// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
11909467b48Spatrick /// heap. stripNonValidData (conservatively) restores
12009467b48Spatrick /// correctness by erasing all attributes in the module that externally imply
12109467b48Spatrick /// dereferenceability. Similar reasoning also applies to the noalias
12209467b48Spatrick /// attributes and metadata. gc.statepoint can touch the entire heap including
12309467b48Spatrick /// noalias objects.
12409467b48Spatrick /// Apart from attributes and metadata, we also remove instructions that imply
12509467b48Spatrick /// constant physical memory: llvm.invariant.start.
12609467b48Spatrick static void stripNonValidData(Module &M);
12709467b48Spatrick
12809467b48Spatrick static bool shouldRewriteStatepointsIn(Function &F);
12909467b48Spatrick
run(Module & M,ModuleAnalysisManager & AM)13009467b48Spatrick PreservedAnalyses RewriteStatepointsForGC::run(Module &M,
13109467b48Spatrick ModuleAnalysisManager &AM) {
13209467b48Spatrick bool Changed = false;
13309467b48Spatrick auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
13409467b48Spatrick for (Function &F : M) {
13509467b48Spatrick // Nothing to do for declarations.
13609467b48Spatrick if (F.isDeclaration() || F.empty())
13709467b48Spatrick continue;
13809467b48Spatrick
13909467b48Spatrick // Policy choice says not to rewrite - the most common reason is that we're
14009467b48Spatrick // compiling code without a GCStrategy.
14109467b48Spatrick if (!shouldRewriteStatepointsIn(F))
14209467b48Spatrick continue;
14309467b48Spatrick
14409467b48Spatrick auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
14509467b48Spatrick auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
14609467b48Spatrick auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
14709467b48Spatrick Changed |= runOnFunction(F, DT, TTI, TLI);
14809467b48Spatrick }
14909467b48Spatrick if (!Changed)
15009467b48Spatrick return PreservedAnalyses::all();
15109467b48Spatrick
15209467b48Spatrick // stripNonValidData asserts that shouldRewriteStatepointsIn
15309467b48Spatrick // returns true for at least one function in the module. Since at least
15409467b48Spatrick // one function changed, we know that the precondition is satisfied.
15509467b48Spatrick stripNonValidData(M);
15609467b48Spatrick
15709467b48Spatrick PreservedAnalyses PA;
15809467b48Spatrick PA.preserve<TargetIRAnalysis>();
15909467b48Spatrick PA.preserve<TargetLibraryAnalysis>();
16009467b48Spatrick return PA;
16109467b48Spatrick }
16209467b48Spatrick
16309467b48Spatrick namespace {
16409467b48Spatrick
16509467b48Spatrick class RewriteStatepointsForGCLegacyPass : public ModulePass {
16609467b48Spatrick RewriteStatepointsForGC Impl;
16709467b48Spatrick
16809467b48Spatrick public:
16909467b48Spatrick static char ID; // Pass identification, replacement for typeid
17009467b48Spatrick
RewriteStatepointsForGCLegacyPass()17109467b48Spatrick RewriteStatepointsForGCLegacyPass() : ModulePass(ID), Impl() {
17209467b48Spatrick initializeRewriteStatepointsForGCLegacyPassPass(
17309467b48Spatrick *PassRegistry::getPassRegistry());
17409467b48Spatrick }
17509467b48Spatrick
runOnModule(Module & M)17609467b48Spatrick bool runOnModule(Module &M) override {
17709467b48Spatrick bool Changed = false;
17809467b48Spatrick for (Function &F : M) {
17909467b48Spatrick // Nothing to do for declarations.
18009467b48Spatrick if (F.isDeclaration() || F.empty())
18109467b48Spatrick continue;
18209467b48Spatrick
18309467b48Spatrick // Policy choice says not to rewrite - the most common reason is that
18409467b48Spatrick // we're compiling code without a GCStrategy.
18509467b48Spatrick if (!shouldRewriteStatepointsIn(F))
18609467b48Spatrick continue;
18709467b48Spatrick
18809467b48Spatrick TargetTransformInfo &TTI =
18909467b48Spatrick getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
19009467b48Spatrick const TargetLibraryInfo &TLI =
19109467b48Spatrick getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
19209467b48Spatrick auto &DT = getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
19309467b48Spatrick
19409467b48Spatrick Changed |= Impl.runOnFunction(F, DT, TTI, TLI);
19509467b48Spatrick }
19609467b48Spatrick
19709467b48Spatrick if (!Changed)
19809467b48Spatrick return false;
19909467b48Spatrick
20009467b48Spatrick // stripNonValidData asserts that shouldRewriteStatepointsIn
20109467b48Spatrick // returns true for at least one function in the module. Since at least
20209467b48Spatrick // one function changed, we know that the precondition is satisfied.
20309467b48Spatrick stripNonValidData(M);
20409467b48Spatrick return true;
20509467b48Spatrick }
20609467b48Spatrick
getAnalysisUsage(AnalysisUsage & AU) const20709467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override {
20809467b48Spatrick // We add and rewrite a bunch of instructions, but don't really do much
20909467b48Spatrick // else. We could in theory preserve a lot more analyses here.
21009467b48Spatrick AU.addRequired<DominatorTreeWrapperPass>();
21109467b48Spatrick AU.addRequired<TargetTransformInfoWrapperPass>();
21209467b48Spatrick AU.addRequired<TargetLibraryInfoWrapperPass>();
21309467b48Spatrick }
21409467b48Spatrick };
21509467b48Spatrick
21609467b48Spatrick } // end anonymous namespace
21709467b48Spatrick
21809467b48Spatrick char RewriteStatepointsForGCLegacyPass::ID = 0;
21909467b48Spatrick
createRewriteStatepointsForGCLegacyPass()22009467b48Spatrick ModulePass *llvm::createRewriteStatepointsForGCLegacyPass() {
22109467b48Spatrick return new RewriteStatepointsForGCLegacyPass();
22209467b48Spatrick }
22309467b48Spatrick
22409467b48Spatrick INITIALIZE_PASS_BEGIN(RewriteStatepointsForGCLegacyPass,
22509467b48Spatrick "rewrite-statepoints-for-gc",
22609467b48Spatrick "Make relocations explicit at statepoints", false, false)
22709467b48Spatrick INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
22809467b48Spatrick INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
22909467b48Spatrick INITIALIZE_PASS_END(RewriteStatepointsForGCLegacyPass,
23009467b48Spatrick "rewrite-statepoints-for-gc",
23109467b48Spatrick "Make relocations explicit at statepoints", false, false)
23209467b48Spatrick
23309467b48Spatrick namespace {
23409467b48Spatrick
23509467b48Spatrick struct GCPtrLivenessData {
23609467b48Spatrick /// Values defined in this block.
23709467b48Spatrick MapVector<BasicBlock *, SetVector<Value *>> KillSet;
23809467b48Spatrick
23909467b48Spatrick /// Values used in this block (and thus live); does not included values
24009467b48Spatrick /// killed within this block.
24109467b48Spatrick MapVector<BasicBlock *, SetVector<Value *>> LiveSet;
24209467b48Spatrick
24309467b48Spatrick /// Values live into this basic block (i.e. used by any
24409467b48Spatrick /// instruction in this basic block or ones reachable from here)
24509467b48Spatrick MapVector<BasicBlock *, SetVector<Value *>> LiveIn;
24609467b48Spatrick
24709467b48Spatrick /// Values live out of this basic block (i.e. live into
24809467b48Spatrick /// any successor block)
24909467b48Spatrick MapVector<BasicBlock *, SetVector<Value *>> LiveOut;
25009467b48Spatrick };
25109467b48Spatrick
25209467b48Spatrick // The type of the internal cache used inside the findBasePointers family
25309467b48Spatrick // of functions. From the callers perspective, this is an opaque type and
25409467b48Spatrick // should not be inspected.
25509467b48Spatrick //
25609467b48Spatrick // In the actual implementation this caches two relations:
25709467b48Spatrick // - The base relation itself (i.e. this pointer is based on that one)
25809467b48Spatrick // - The base defining value relation (i.e. before base_phi insertion)
25909467b48Spatrick // Generally, after the execution of a full findBasePointer call, only the
26009467b48Spatrick // base relation will remain. Internally, we add a mixture of the two
26109467b48Spatrick // types, then update all the second type to the first type
26209467b48Spatrick using DefiningValueMapTy = MapVector<Value *, Value *>;
263*d415bd75Srobert using IsKnownBaseMapTy = MapVector<Value *, bool>;
264*d415bd75Srobert using PointerToBaseTy = MapVector<Value *, Value *>;
26509467b48Spatrick using StatepointLiveSetTy = SetVector<Value *>;
26609467b48Spatrick using RematerializedValueMapTy =
26709467b48Spatrick MapVector<AssertingVH<Instruction>, AssertingVH<Value>>;
26809467b48Spatrick
26909467b48Spatrick struct PartiallyConstructedSafepointRecord {
27009467b48Spatrick /// The set of values known to be live across this safepoint
27109467b48Spatrick StatepointLiveSetTy LiveSet;
27209467b48Spatrick
27309467b48Spatrick /// The *new* gc.statepoint instruction itself. This produces the token
27409467b48Spatrick /// that normal path gc.relocates and the gc.result are tied to.
275097a140dSpatrick GCStatepointInst *StatepointToken;
27609467b48Spatrick
27709467b48Spatrick /// Instruction to which exceptional gc relocates are attached
27809467b48Spatrick /// Makes it easier to iterate through them during relocationViaAlloca.
27909467b48Spatrick Instruction *UnwindToken;
28009467b48Spatrick
28109467b48Spatrick /// Record live values we are rematerialized instead of relocating.
28209467b48Spatrick /// They are not included into 'LiveSet' field.
28309467b48Spatrick /// Maps rematerialized copy to it's original value.
28409467b48Spatrick RematerializedValueMapTy RematerializedValues;
28509467b48Spatrick };
28609467b48Spatrick
287*d415bd75Srobert struct RematerizlizationCandidateRecord {
288*d415bd75Srobert // Chain from derived pointer to base.
289*d415bd75Srobert SmallVector<Instruction *, 3> ChainToBase;
290*d415bd75Srobert // Original base.
291*d415bd75Srobert Value *RootOfChain;
292*d415bd75Srobert // Cost of chain.
293*d415bd75Srobert InstructionCost Cost;
294*d415bd75Srobert };
295*d415bd75Srobert using RematCandTy = MapVector<Value *, RematerizlizationCandidateRecord>;
296*d415bd75Srobert
29709467b48Spatrick } // end anonymous namespace
29809467b48Spatrick
GetDeoptBundleOperands(const CallBase * Call)29909467b48Spatrick static ArrayRef<Use> GetDeoptBundleOperands(const CallBase *Call) {
300*d415bd75Srobert std::optional<OperandBundleUse> DeoptBundle =
30109467b48Spatrick Call->getOperandBundle(LLVMContext::OB_deopt);
30209467b48Spatrick
303*d415bd75Srobert if (!DeoptBundle) {
30409467b48Spatrick assert(AllowStatepointWithNoDeoptInfo &&
30509467b48Spatrick "Found non-leaf call without deopt info!");
306*d415bd75Srobert return std::nullopt;
30709467b48Spatrick }
30809467b48Spatrick
309*d415bd75Srobert return DeoptBundle->Inputs;
31009467b48Spatrick }
31109467b48Spatrick
31209467b48Spatrick /// Compute the live-in set for every basic block in the function
31309467b48Spatrick static void computeLiveInValues(DominatorTree &DT, Function &F,
31409467b48Spatrick GCPtrLivenessData &Data);
31509467b48Spatrick
31609467b48Spatrick /// Given results from the dataflow liveness computation, find the set of live
31709467b48Spatrick /// Values at a particular instruction.
31809467b48Spatrick static void findLiveSetAtInst(Instruction *inst, GCPtrLivenessData &Data,
31909467b48Spatrick StatepointLiveSetTy &out);
32009467b48Spatrick
32109467b48Spatrick // TODO: Once we can get to the GCStrategy, this becomes
322*d415bd75Srobert // std::optional<bool> isGCManagedPointer(const Type *Ty) const override {
32309467b48Spatrick
isGCPointerType(Type * T)32409467b48Spatrick static bool isGCPointerType(Type *T) {
32509467b48Spatrick if (auto *PT = dyn_cast<PointerType>(T))
32609467b48Spatrick // For the sake of this example GC, we arbitrarily pick addrspace(1) as our
32709467b48Spatrick // GC managed heap. We know that a pointer into this heap needs to be
32809467b48Spatrick // updated and that no other pointer does.
32909467b48Spatrick return PT->getAddressSpace() == 1;
33009467b48Spatrick return false;
33109467b48Spatrick }
33209467b48Spatrick
33309467b48Spatrick // Return true if this type is one which a) is a gc pointer or contains a GC
33409467b48Spatrick // pointer and b) is of a type this code expects to encounter as a live value.
33509467b48Spatrick // (The insertion code will assert that a type which matches (a) and not (b)
33609467b48Spatrick // is not encountered.)
isHandledGCPointerType(Type * T)33709467b48Spatrick static bool isHandledGCPointerType(Type *T) {
33809467b48Spatrick // We fully support gc pointers
33909467b48Spatrick if (isGCPointerType(T))
34009467b48Spatrick return true;
34109467b48Spatrick // We partially support vectors of gc pointers. The code will assert if it
34209467b48Spatrick // can't handle something.
34309467b48Spatrick if (auto VT = dyn_cast<VectorType>(T))
34409467b48Spatrick if (isGCPointerType(VT->getElementType()))
34509467b48Spatrick return true;
34609467b48Spatrick return false;
34709467b48Spatrick }
34809467b48Spatrick
34909467b48Spatrick #ifndef NDEBUG
35009467b48Spatrick /// Returns true if this type contains a gc pointer whether we know how to
35109467b48Spatrick /// handle that type or not.
containsGCPtrType(Type * Ty)35209467b48Spatrick static bool containsGCPtrType(Type *Ty) {
35309467b48Spatrick if (isGCPointerType(Ty))
35409467b48Spatrick return true;
35509467b48Spatrick if (VectorType *VT = dyn_cast<VectorType>(Ty))
35609467b48Spatrick return isGCPointerType(VT->getScalarType());
35709467b48Spatrick if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
35809467b48Spatrick return containsGCPtrType(AT->getElementType());
35909467b48Spatrick if (StructType *ST = dyn_cast<StructType>(Ty))
36009467b48Spatrick return llvm::any_of(ST->elements(), containsGCPtrType);
36109467b48Spatrick return false;
36209467b48Spatrick }
36309467b48Spatrick
36409467b48Spatrick // Returns true if this is a type which a) is a gc pointer or contains a GC
36509467b48Spatrick // pointer and b) is of a type which the code doesn't expect (i.e. first class
36609467b48Spatrick // aggregates). Used to trip assertions.
isUnhandledGCPointerType(Type * Ty)36709467b48Spatrick static bool isUnhandledGCPointerType(Type *Ty) {
36809467b48Spatrick return containsGCPtrType(Ty) && !isHandledGCPointerType(Ty);
36909467b48Spatrick }
37009467b48Spatrick #endif
37109467b48Spatrick
37209467b48Spatrick // Return the name of the value suffixed with the provided value, or if the
37309467b48Spatrick // value didn't have a name, the default value specified.
suffixed_name_or(Value * V,StringRef Suffix,StringRef DefaultName)37409467b48Spatrick static std::string suffixed_name_or(Value *V, StringRef Suffix,
37509467b48Spatrick StringRef DefaultName) {
37609467b48Spatrick return V->hasName() ? (V->getName() + Suffix).str() : DefaultName.str();
37709467b48Spatrick }
37809467b48Spatrick
37909467b48Spatrick // Conservatively identifies any definitions which might be live at the
38009467b48Spatrick // given instruction. The analysis is performed immediately before the
38109467b48Spatrick // given instruction. Values defined by that instruction are not considered
38209467b48Spatrick // live. Values used by that instruction are considered live.
analyzeParsePointLiveness(DominatorTree & DT,GCPtrLivenessData & OriginalLivenessData,CallBase * Call,PartiallyConstructedSafepointRecord & Result)38309467b48Spatrick static void analyzeParsePointLiveness(
38409467b48Spatrick DominatorTree &DT, GCPtrLivenessData &OriginalLivenessData, CallBase *Call,
38509467b48Spatrick PartiallyConstructedSafepointRecord &Result) {
38609467b48Spatrick StatepointLiveSetTy LiveSet;
38709467b48Spatrick findLiveSetAtInst(Call, OriginalLivenessData, LiveSet);
38809467b48Spatrick
38909467b48Spatrick if (PrintLiveSet) {
39009467b48Spatrick dbgs() << "Live Variables:\n";
39109467b48Spatrick for (Value *V : LiveSet)
39209467b48Spatrick dbgs() << " " << V->getName() << " " << *V << "\n";
39309467b48Spatrick }
39409467b48Spatrick if (PrintLiveSetSize) {
395097a140dSpatrick dbgs() << "Safepoint For: " << Call->getCalledOperand()->getName() << "\n";
39609467b48Spatrick dbgs() << "Number live values: " << LiveSet.size() << "\n";
39709467b48Spatrick }
39809467b48Spatrick Result.LiveSet = LiveSet;
39909467b48Spatrick }
40009467b48Spatrick
401*d415bd75Srobert /// Returns true if V is a known base.
402*d415bd75Srobert static bool isKnownBase(Value *V, const IsKnownBaseMapTy &KnownBases);
40309467b48Spatrick
404*d415bd75Srobert /// Caches the IsKnownBase flag for a value and asserts that it wasn't present
405*d415bd75Srobert /// in the cache before.
406*d415bd75Srobert static void setKnownBase(Value *V, bool IsKnownBase,
407*d415bd75Srobert IsKnownBaseMapTy &KnownBases);
408097a140dSpatrick
409*d415bd75Srobert static Value *findBaseDefiningValue(Value *I, DefiningValueMapTy &Cache,
410*d415bd75Srobert IsKnownBaseMapTy &KnownBases);
41109467b48Spatrick
41209467b48Spatrick /// Return a base defining value for the 'Index' element of the given vector
41309467b48Spatrick /// instruction 'I'. If Index is null, returns a BDV for the entire vector
41409467b48Spatrick /// 'I'. As an optimization, this method will try to determine when the
41509467b48Spatrick /// element is known to already be a base pointer. If this can be established,
41609467b48Spatrick /// the second value in the returned pair will be true. Note that either a
41709467b48Spatrick /// vector or a pointer typed value can be returned. For the former, the
41809467b48Spatrick /// vector returned is a BDV (and possibly a base) of the entire vector 'I'.
41909467b48Spatrick /// If the later, the return pointer is a BDV (or possibly a base) for the
42009467b48Spatrick /// particular element in 'I'.
findBaseDefiningValueOfVector(Value * I,DefiningValueMapTy & Cache,IsKnownBaseMapTy & KnownBases)421*d415bd75Srobert static Value *findBaseDefiningValueOfVector(Value *I, DefiningValueMapTy &Cache,
422*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
42309467b48Spatrick // Each case parallels findBaseDefiningValue below, see that code for
42409467b48Spatrick // detailed motivation.
42509467b48Spatrick
426*d415bd75Srobert auto Cached = Cache.find(I);
427*d415bd75Srobert if (Cached != Cache.end())
428*d415bd75Srobert return Cached->second;
42909467b48Spatrick
430*d415bd75Srobert if (isa<Argument>(I)) {
431*d415bd75Srobert // An incoming argument to the function is a base pointer
432*d415bd75Srobert Cache[I] = I;
433*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
434*d415bd75Srobert return I;
435*d415bd75Srobert }
436*d415bd75Srobert
437*d415bd75Srobert if (isa<Constant>(I)) {
43809467b48Spatrick // Base of constant vector consists only of constant null pointers.
43909467b48Spatrick // For reasoning see similar case inside 'findBaseDefiningValue' function.
440*d415bd75Srobert auto *CAZ = ConstantAggregateZero::get(I->getType());
441*d415bd75Srobert Cache[I] = CAZ;
442*d415bd75Srobert setKnownBase(CAZ, /* IsKnownBase */true, KnownBases);
443*d415bd75Srobert return CAZ;
444*d415bd75Srobert }
44509467b48Spatrick
446*d415bd75Srobert if (isa<LoadInst>(I)) {
447*d415bd75Srobert Cache[I] = I;
448*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
449*d415bd75Srobert return I;
450*d415bd75Srobert }
45109467b48Spatrick
452*d415bd75Srobert if (isa<InsertElementInst>(I)) {
45309467b48Spatrick // We don't know whether this vector contains entirely base pointers or
45409467b48Spatrick // not. To be conservatively correct, we treat it as a BDV and will
45509467b48Spatrick // duplicate code as needed to construct a parallel vector of bases.
456*d415bd75Srobert Cache[I] = I;
457*d415bd75Srobert setKnownBase(I, /* IsKnownBase */false, KnownBases);
458*d415bd75Srobert return I;
459*d415bd75Srobert }
46009467b48Spatrick
461*d415bd75Srobert if (isa<ShuffleVectorInst>(I)) {
46209467b48Spatrick // We don't know whether this vector contains entirely base pointers or
46309467b48Spatrick // not. To be conservatively correct, we treat it as a BDV and will
46409467b48Spatrick // duplicate code as needed to construct a parallel vector of bases.
46509467b48Spatrick // TODO: There a number of local optimizations which could be applied here
46609467b48Spatrick // for particular sufflevector patterns.
467*d415bd75Srobert Cache[I] = I;
468*d415bd75Srobert setKnownBase(I, /* IsKnownBase */false, KnownBases);
469*d415bd75Srobert return I;
470*d415bd75Srobert }
47109467b48Spatrick
47209467b48Spatrick // The behavior of getelementptr instructions is the same for vector and
47309467b48Spatrick // non-vector data types.
474*d415bd75Srobert if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
475*d415bd75Srobert auto *BDV =
476*d415bd75Srobert findBaseDefiningValue(GEP->getPointerOperand(), Cache, KnownBases);
477*d415bd75Srobert Cache[GEP] = BDV;
478*d415bd75Srobert return BDV;
479*d415bd75Srobert }
480*d415bd75Srobert
481*d415bd75Srobert // The behavior of freeze instructions is the same for vector and
482*d415bd75Srobert // non-vector data types.
483*d415bd75Srobert if (auto *Freeze = dyn_cast<FreezeInst>(I)) {
484*d415bd75Srobert auto *BDV = findBaseDefiningValue(Freeze->getOperand(0), Cache, KnownBases);
485*d415bd75Srobert Cache[Freeze] = BDV;
486*d415bd75Srobert return BDV;
487*d415bd75Srobert }
48809467b48Spatrick
48909467b48Spatrick // If the pointer comes through a bitcast of a vector of pointers to
49009467b48Spatrick // a vector of another type of pointer, then look through the bitcast
491*d415bd75Srobert if (auto *BC = dyn_cast<BitCastInst>(I)) {
492*d415bd75Srobert auto *BDV = findBaseDefiningValue(BC->getOperand(0), Cache, KnownBases);
493*d415bd75Srobert Cache[BC] = BDV;
494*d415bd75Srobert return BDV;
495*d415bd75Srobert }
49609467b48Spatrick
49709467b48Spatrick // We assume that functions in the source language only return base
49809467b48Spatrick // pointers. This should probably be generalized via attributes to support
49909467b48Spatrick // both source language and internal functions.
500*d415bd75Srobert if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
501*d415bd75Srobert Cache[I] = I;
502*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
503*d415bd75Srobert return I;
504*d415bd75Srobert }
50509467b48Spatrick
50609467b48Spatrick // A PHI or Select is a base defining value. The outer findBasePointer
50709467b48Spatrick // algorithm is responsible for constructing a base value for this BDV.
50809467b48Spatrick assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
50909467b48Spatrick "unknown vector instruction - no base found for vector element");
510*d415bd75Srobert Cache[I] = I;
511*d415bd75Srobert setKnownBase(I, /* IsKnownBase */false, KnownBases);
512*d415bd75Srobert return I;
51309467b48Spatrick }
51409467b48Spatrick
51509467b48Spatrick /// Helper function for findBasePointer - Will return a value which either a)
51609467b48Spatrick /// defines the base pointer for the input, b) blocks the simple search
51709467b48Spatrick /// (i.e. a PHI or Select of two derived pointers), or c) involves a change
51809467b48Spatrick /// from pointer to vector type or back.
findBaseDefiningValue(Value * I,DefiningValueMapTy & Cache,IsKnownBaseMapTy & KnownBases)519*d415bd75Srobert static Value *findBaseDefiningValue(Value *I, DefiningValueMapTy &Cache,
520*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
52109467b48Spatrick assert(I->getType()->isPtrOrPtrVectorTy() &&
52209467b48Spatrick "Illegal to ask for the base pointer of a non-pointer type");
523*d415bd75Srobert auto Cached = Cache.find(I);
524*d415bd75Srobert if (Cached != Cache.end())
525*d415bd75Srobert return Cached->second;
52609467b48Spatrick
52709467b48Spatrick if (I->getType()->isVectorTy())
528*d415bd75Srobert return findBaseDefiningValueOfVector(I, Cache, KnownBases);
52909467b48Spatrick
530*d415bd75Srobert if (isa<Argument>(I)) {
53109467b48Spatrick // An incoming argument to the function is a base pointer
53209467b48Spatrick // We should have never reached here if this argument isn't an gc value
533*d415bd75Srobert Cache[I] = I;
534*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
535*d415bd75Srobert return I;
536*d415bd75Srobert }
53709467b48Spatrick
53809467b48Spatrick if (isa<Constant>(I)) {
53909467b48Spatrick // We assume that objects with a constant base (e.g. a global) can't move
54009467b48Spatrick // and don't need to be reported to the collector because they are always
54109467b48Spatrick // live. Besides global references, all kinds of constants (e.g. undef,
54209467b48Spatrick // constant expressions, null pointers) can be introduced by the inliner or
54309467b48Spatrick // the optimizer, especially on dynamically dead paths.
54409467b48Spatrick // Here we treat all of them as having single null base. By doing this we
54509467b48Spatrick // trying to avoid problems reporting various conflicts in a form of
54609467b48Spatrick // "phi (const1, const2)" or "phi (const, regular gc ptr)".
54709467b48Spatrick // See constant.ll file for relevant test cases.
54809467b48Spatrick
549*d415bd75Srobert auto *CPN = ConstantPointerNull::get(cast<PointerType>(I->getType()));
550*d415bd75Srobert Cache[I] = CPN;
551*d415bd75Srobert setKnownBase(CPN, /* IsKnownBase */true, KnownBases);
552*d415bd75Srobert return CPN;
55309467b48Spatrick }
55409467b48Spatrick
55573471bf0Spatrick // inttoptrs in an integral address space are currently ill-defined. We
55673471bf0Spatrick // treat them as defining base pointers here for consistency with the
55773471bf0Spatrick // constant rule above and because we don't really have a better semantic
55873471bf0Spatrick // to give them. Note that the optimizer is always free to insert undefined
55973471bf0Spatrick // behavior on dynamically dead paths as well.
560*d415bd75Srobert if (isa<IntToPtrInst>(I)) {
561*d415bd75Srobert Cache[I] = I;
562*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
563*d415bd75Srobert return I;
564*d415bd75Srobert }
56573471bf0Spatrick
56609467b48Spatrick if (CastInst *CI = dyn_cast<CastInst>(I)) {
56709467b48Spatrick Value *Def = CI->stripPointerCasts();
56809467b48Spatrick // If stripping pointer casts changes the address space there is an
56909467b48Spatrick // addrspacecast in between.
57009467b48Spatrick assert(cast<PointerType>(Def->getType())->getAddressSpace() ==
57109467b48Spatrick cast<PointerType>(CI->getType())->getAddressSpace() &&
57209467b48Spatrick "unsupported addrspacecast");
57309467b48Spatrick // If we find a cast instruction here, it means we've found a cast which is
57409467b48Spatrick // not simply a pointer cast (i.e. an inttoptr). We don't know how to
57509467b48Spatrick // handle int->ptr conversion.
57609467b48Spatrick assert(!isa<CastInst>(Def) && "shouldn't find another cast here");
577*d415bd75Srobert auto *BDV = findBaseDefiningValue(Def, Cache, KnownBases);
578*d415bd75Srobert Cache[CI] = BDV;
579*d415bd75Srobert return BDV;
58009467b48Spatrick }
58109467b48Spatrick
582*d415bd75Srobert if (isa<LoadInst>(I)) {
58309467b48Spatrick // The value loaded is an gc base itself
584*d415bd75Srobert Cache[I] = I;
585*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
586*d415bd75Srobert return I;
587*d415bd75Srobert }
58809467b48Spatrick
589*d415bd75Srobert if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
59009467b48Spatrick // The base of this GEP is the base
591*d415bd75Srobert auto *BDV =
592*d415bd75Srobert findBaseDefiningValue(GEP->getPointerOperand(), Cache, KnownBases);
593*d415bd75Srobert Cache[GEP] = BDV;
594*d415bd75Srobert return BDV;
595*d415bd75Srobert }
596*d415bd75Srobert
597*d415bd75Srobert if (auto *Freeze = dyn_cast<FreezeInst>(I)) {
598*d415bd75Srobert auto *BDV = findBaseDefiningValue(Freeze->getOperand(0), Cache, KnownBases);
599*d415bd75Srobert Cache[Freeze] = BDV;
600*d415bd75Srobert return BDV;
601*d415bd75Srobert }
60209467b48Spatrick
60309467b48Spatrick if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
60409467b48Spatrick switch (II->getIntrinsicID()) {
60509467b48Spatrick default:
60609467b48Spatrick // fall through to general call handling
60709467b48Spatrick break;
60809467b48Spatrick case Intrinsic::experimental_gc_statepoint:
60909467b48Spatrick llvm_unreachable("statepoints don't produce pointers");
61009467b48Spatrick case Intrinsic::experimental_gc_relocate:
61109467b48Spatrick // Rerunning safepoint insertion after safepoints are already
61209467b48Spatrick // inserted is not supported. It could probably be made to work,
61309467b48Spatrick // but why are you doing this? There's no good reason.
61409467b48Spatrick llvm_unreachable("repeat safepoint insertion is not supported");
61509467b48Spatrick case Intrinsic::gcroot:
61609467b48Spatrick // Currently, this mechanism hasn't been extended to work with gcroot.
61709467b48Spatrick // There's no reason it couldn't be, but I haven't thought about the
61809467b48Spatrick // implications much.
61909467b48Spatrick llvm_unreachable(
62009467b48Spatrick "interaction with the gcroot mechanism is not supported");
62173471bf0Spatrick case Intrinsic::experimental_gc_get_pointer_base:
622*d415bd75Srobert auto *BDV = findBaseDefiningValue(II->getOperand(0), Cache, KnownBases);
623*d415bd75Srobert Cache[II] = BDV;
624*d415bd75Srobert return BDV;
62509467b48Spatrick }
62609467b48Spatrick }
62709467b48Spatrick // We assume that functions in the source language only return base
62809467b48Spatrick // pointers. This should probably be generalized via attributes to support
62909467b48Spatrick // both source language and internal functions.
630*d415bd75Srobert if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
631*d415bd75Srobert Cache[I] = I;
632*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
633*d415bd75Srobert return I;
634*d415bd75Srobert }
63509467b48Spatrick
63609467b48Spatrick // TODO: I have absolutely no idea how to implement this part yet. It's not
63709467b48Spatrick // necessarily hard, I just haven't really looked at it yet.
63809467b48Spatrick assert(!isa<LandingPadInst>(I) && "Landing Pad is unimplemented");
63909467b48Spatrick
640*d415bd75Srobert if (isa<AtomicCmpXchgInst>(I)) {
64109467b48Spatrick // A CAS is effectively a atomic store and load combined under a
64209467b48Spatrick // predicate. From the perspective of base pointers, we just treat it
64309467b48Spatrick // like a load.
644*d415bd75Srobert Cache[I] = I;
645*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
646*d415bd75Srobert return I;
647*d415bd75Srobert }
64809467b48Spatrick
64909467b48Spatrick assert(!isa<AtomicRMWInst>(I) && "Xchg handled above, all others are "
65009467b48Spatrick "binary ops which don't apply to pointers");
65109467b48Spatrick
65209467b48Spatrick // The aggregate ops. Aggregates can either be in the heap or on the
65309467b48Spatrick // stack, but in either case, this is simply a field load. As a result,
65409467b48Spatrick // this is a defining definition of the base just like a load is.
655*d415bd75Srobert if (isa<ExtractValueInst>(I)) {
656*d415bd75Srobert Cache[I] = I;
657*d415bd75Srobert setKnownBase(I, /* IsKnownBase */true, KnownBases);
658*d415bd75Srobert return I;
659*d415bd75Srobert }
66009467b48Spatrick
66109467b48Spatrick // We should never see an insert vector since that would require we be
66209467b48Spatrick // tracing back a struct value not a pointer value.
66309467b48Spatrick assert(!isa<InsertValueInst>(I) &&
66409467b48Spatrick "Base pointer for a struct is meaningless");
66509467b48Spatrick
66673471bf0Spatrick // This value might have been generated by findBasePointer() called when
66773471bf0Spatrick // substituting gc.get.pointer.base() intrinsic.
66873471bf0Spatrick bool IsKnownBase =
66973471bf0Spatrick isa<Instruction>(I) && cast<Instruction>(I)->getMetadata("is_base_value");
670*d415bd75Srobert setKnownBase(I, /* IsKnownBase */IsKnownBase, KnownBases);
671*d415bd75Srobert Cache[I] = I;
67273471bf0Spatrick
67309467b48Spatrick // An extractelement produces a base result exactly when it's input does.
67409467b48Spatrick // We may need to insert a parallel instruction to extract the appropriate
67509467b48Spatrick // element out of the base vector corresponding to the input. Given this,
67609467b48Spatrick // it's analogous to the phi and select case even though it's not a merge.
67709467b48Spatrick if (isa<ExtractElementInst>(I))
67809467b48Spatrick // Note: There a lot of obvious peephole cases here. This are deliberately
67909467b48Spatrick // handled after the main base pointer inference algorithm to make writing
68009467b48Spatrick // test cases to exercise that code easier.
681*d415bd75Srobert return I;
68209467b48Spatrick
68309467b48Spatrick // The last two cases here don't return a base pointer. Instead, they
68409467b48Spatrick // return a value which dynamically selects from among several base
68509467b48Spatrick // derived pointers (each with it's own base potentially). It's the job of
68609467b48Spatrick // the caller to resolve these.
68709467b48Spatrick assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
688*d415bd75Srobert "missing instruction case in findBaseDefiningValue");
689*d415bd75Srobert return I;
69009467b48Spatrick }
69109467b48Spatrick
69209467b48Spatrick /// Returns the base defining value for this value.
findBaseDefiningValueCached(Value * I,DefiningValueMapTy & Cache,IsKnownBaseMapTy & KnownBases)693*d415bd75Srobert static Value *findBaseDefiningValueCached(Value *I, DefiningValueMapTy &Cache,
694*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
695*d415bd75Srobert if (Cache.find(I) == Cache.end()) {
696*d415bd75Srobert auto *BDV = findBaseDefiningValue(I, Cache, KnownBases);
697*d415bd75Srobert Cache[I] = BDV;
69809467b48Spatrick LLVM_DEBUG(dbgs() << "fBDV-cached: " << I->getName() << " -> "
699*d415bd75Srobert << Cache[I]->getName() << ", is known base = "
700*d415bd75Srobert << KnownBases[I] << "\n");
70109467b48Spatrick }
70209467b48Spatrick assert(Cache[I] != nullptr);
703*d415bd75Srobert assert(KnownBases.find(Cache[I]) != KnownBases.end() &&
704*d415bd75Srobert "Cached value must be present in known bases map");
705*d415bd75Srobert return Cache[I];
70609467b48Spatrick }
70709467b48Spatrick
70809467b48Spatrick /// Return a base pointer for this value if known. Otherwise, return it's
70909467b48Spatrick /// base defining value.
findBaseOrBDV(Value * I,DefiningValueMapTy & Cache,IsKnownBaseMapTy & KnownBases)710*d415bd75Srobert static Value *findBaseOrBDV(Value *I, DefiningValueMapTy &Cache,
711*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
712*d415bd75Srobert Value *Def = findBaseDefiningValueCached(I, Cache, KnownBases);
71309467b48Spatrick auto Found = Cache.find(Def);
71409467b48Spatrick if (Found != Cache.end()) {
71509467b48Spatrick // Either a base-of relation, or a self reference. Caller must check.
71609467b48Spatrick return Found->second;
71709467b48Spatrick }
71809467b48Spatrick // Only a BDV available
71909467b48Spatrick return Def;
72009467b48Spatrick }
72109467b48Spatrick
722*d415bd75Srobert #ifndef NDEBUG
723097a140dSpatrick /// This value is a base pointer that is not generated by RS4GC, i.e. it already
724097a140dSpatrick /// exists in the code.
isOriginalBaseResult(Value * V)725097a140dSpatrick static bool isOriginalBaseResult(Value *V) {
726097a140dSpatrick // no recursion possible
727097a140dSpatrick return !isa<PHINode>(V) && !isa<SelectInst>(V) &&
728097a140dSpatrick !isa<ExtractElementInst>(V) && !isa<InsertElementInst>(V) &&
729097a140dSpatrick !isa<ShuffleVectorInst>(V);
730097a140dSpatrick }
731*d415bd75Srobert #endif
732097a140dSpatrick
isKnownBase(Value * V,const IsKnownBaseMapTy & KnownBases)733*d415bd75Srobert static bool isKnownBase(Value *V, const IsKnownBaseMapTy &KnownBases) {
734*d415bd75Srobert auto It = KnownBases.find(V);
735*d415bd75Srobert assert(It != KnownBases.end() && "Value not present in the map");
736*d415bd75Srobert return It->second;
73709467b48Spatrick }
73809467b48Spatrick
setKnownBase(Value * V,bool IsKnownBase,IsKnownBaseMapTy & KnownBases)739*d415bd75Srobert static void setKnownBase(Value *V, bool IsKnownBase,
740*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
741*d415bd75Srobert #ifndef NDEBUG
742*d415bd75Srobert auto It = KnownBases.find(V);
743*d415bd75Srobert if (It != KnownBases.end())
744*d415bd75Srobert assert(It->second == IsKnownBase && "Changing already present value");
745*d415bd75Srobert #endif
746*d415bd75Srobert KnownBases[V] = IsKnownBase;
74709467b48Spatrick }
74809467b48Spatrick
749097a140dSpatrick // Returns true if First and Second values are both scalar or both vector.
areBothVectorOrScalar(Value * First,Value * Second)750097a140dSpatrick static bool areBothVectorOrScalar(Value *First, Value *Second) {
751097a140dSpatrick return isa<VectorType>(First->getType()) ==
752097a140dSpatrick isa<VectorType>(Second->getType());
753097a140dSpatrick }
754097a140dSpatrick
75509467b48Spatrick namespace {
75609467b48Spatrick
75709467b48Spatrick /// Models the state of a single base defining value in the findBasePointer
75809467b48Spatrick /// algorithm for determining where a new instruction is needed to propagate
75909467b48Spatrick /// the base of this BDV.
76009467b48Spatrick class BDVState {
76109467b48Spatrick public:
76273471bf0Spatrick enum StatusTy {
76373471bf0Spatrick // Starting state of lattice
76473471bf0Spatrick Unknown,
76573471bf0Spatrick // Some specific base value -- does *not* mean that instruction
76673471bf0Spatrick // propagates the base of the object
76773471bf0Spatrick // ex: gep %arg, 16 -> %arg is the base value
76873471bf0Spatrick Base,
76973471bf0Spatrick // Need to insert a node to represent a merge.
77073471bf0Spatrick Conflict
77173471bf0Spatrick };
77209467b48Spatrick
BDVState()77373471bf0Spatrick BDVState() {
77473471bf0Spatrick llvm_unreachable("missing state in map");
77573471bf0Spatrick }
77609467b48Spatrick
BDVState(Value * OriginalValue)77773471bf0Spatrick explicit BDVState(Value *OriginalValue)
77873471bf0Spatrick : OriginalValue(OriginalValue) {}
BDVState(Value * OriginalValue,StatusTy Status,Value * BaseValue=nullptr)77973471bf0Spatrick explicit BDVState(Value *OriginalValue, StatusTy Status, Value *BaseValue = nullptr)
78073471bf0Spatrick : OriginalValue(OriginalValue), Status(Status), BaseValue(BaseValue) {
78109467b48Spatrick assert(Status != Base || BaseValue);
78209467b48Spatrick }
78309467b48Spatrick
getStatus() const78473471bf0Spatrick StatusTy getStatus() const { return Status; }
getOriginalValue() const78573471bf0Spatrick Value *getOriginalValue() const { return OriginalValue; }
getBaseValue() const78609467b48Spatrick Value *getBaseValue() const { return BaseValue; }
78709467b48Spatrick
isBase() const78809467b48Spatrick bool isBase() const { return getStatus() == Base; }
isUnknown() const78909467b48Spatrick bool isUnknown() const { return getStatus() == Unknown; }
isConflict() const79009467b48Spatrick bool isConflict() const { return getStatus() == Conflict; }
79109467b48Spatrick
79273471bf0Spatrick // Values of type BDVState form a lattice, and this function implements the
79373471bf0Spatrick // meet
79473471bf0Spatrick // operation.
meet(const BDVState & Other)79573471bf0Spatrick void meet(const BDVState &Other) {
79673471bf0Spatrick auto markConflict = [&]() {
79773471bf0Spatrick Status = BDVState::Conflict;
79873471bf0Spatrick BaseValue = nullptr;
79973471bf0Spatrick };
80073471bf0Spatrick // Conflict is a final state.
80173471bf0Spatrick if (isConflict())
80273471bf0Spatrick return;
80373471bf0Spatrick // if we are not known - just take other state.
80473471bf0Spatrick if (isUnknown()) {
80573471bf0Spatrick Status = Other.getStatus();
80673471bf0Spatrick BaseValue = Other.getBaseValue();
80773471bf0Spatrick return;
80873471bf0Spatrick }
80973471bf0Spatrick // We are base.
81073471bf0Spatrick assert(isBase() && "Unknown state");
81173471bf0Spatrick // If other is unknown - just keep our state.
81273471bf0Spatrick if (Other.isUnknown())
81373471bf0Spatrick return;
81473471bf0Spatrick // If other is conflict - it is a final state.
81573471bf0Spatrick if (Other.isConflict())
81673471bf0Spatrick return markConflict();
81773471bf0Spatrick // Other is base as well.
81873471bf0Spatrick assert(Other.isBase() && "Unknown state");
81973471bf0Spatrick // If bases are different - Conflict.
82073471bf0Spatrick if (getBaseValue() != Other.getBaseValue())
82173471bf0Spatrick return markConflict();
82273471bf0Spatrick // We are identical, do nothing.
82373471bf0Spatrick }
82473471bf0Spatrick
operator ==(const BDVState & Other) const82509467b48Spatrick bool operator==(const BDVState &Other) const {
826*d415bd75Srobert return OriginalValue == Other.OriginalValue && BaseValue == Other.BaseValue &&
82773471bf0Spatrick Status == Other.Status;
82809467b48Spatrick }
82909467b48Spatrick
operator !=(const BDVState & other) const83009467b48Spatrick bool operator!=(const BDVState &other) const { return !(*this == other); }
83109467b48Spatrick
83209467b48Spatrick LLVM_DUMP_METHOD
dump() const83309467b48Spatrick void dump() const {
83409467b48Spatrick print(dbgs());
83509467b48Spatrick dbgs() << '\n';
83609467b48Spatrick }
83709467b48Spatrick
print(raw_ostream & OS) const83809467b48Spatrick void print(raw_ostream &OS) const {
83909467b48Spatrick switch (getStatus()) {
84009467b48Spatrick case Unknown:
84109467b48Spatrick OS << "U";
84209467b48Spatrick break;
84309467b48Spatrick case Base:
84409467b48Spatrick OS << "B";
84509467b48Spatrick break;
84609467b48Spatrick case Conflict:
84709467b48Spatrick OS << "C";
84809467b48Spatrick break;
84909467b48Spatrick }
85073471bf0Spatrick OS << " (base " << getBaseValue() << " - "
85173471bf0Spatrick << (getBaseValue() ? getBaseValue()->getName() : "nullptr") << ")"
85273471bf0Spatrick << " for " << OriginalValue->getName() << ":";
85309467b48Spatrick }
85409467b48Spatrick
85509467b48Spatrick private:
85673471bf0Spatrick AssertingVH<Value> OriginalValue; // instruction this state corresponds to
85773471bf0Spatrick StatusTy Status = Unknown;
85873471bf0Spatrick AssertingVH<Value> BaseValue = nullptr; // Non-null only if Status == Base.
85909467b48Spatrick };
86009467b48Spatrick
86109467b48Spatrick } // end anonymous namespace
86209467b48Spatrick
86309467b48Spatrick #ifndef NDEBUG
operator <<(raw_ostream & OS,const BDVState & State)86409467b48Spatrick static raw_ostream &operator<<(raw_ostream &OS, const BDVState &State) {
86509467b48Spatrick State.print(OS);
86609467b48Spatrick return OS;
86709467b48Spatrick }
86809467b48Spatrick #endif
86909467b48Spatrick
87009467b48Spatrick /// For a given value or instruction, figure out what base ptr its derived from.
87109467b48Spatrick /// For gc objects, this is simply itself. On success, returns a value which is
87209467b48Spatrick /// the base pointer. (This is reliable and can be used for relocation.) On
87309467b48Spatrick /// failure, returns nullptr.
findBasePointer(Value * I,DefiningValueMapTy & Cache,IsKnownBaseMapTy & KnownBases)874*d415bd75Srobert static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
875*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
876*d415bd75Srobert Value *Def = findBaseOrBDV(I, Cache, KnownBases);
87709467b48Spatrick
878*d415bd75Srobert if (isKnownBase(Def, KnownBases) && areBothVectorOrScalar(Def, I))
87909467b48Spatrick return Def;
88009467b48Spatrick
88109467b48Spatrick // Here's the rough algorithm:
88209467b48Spatrick // - For every SSA value, construct a mapping to either an actual base
88309467b48Spatrick // pointer or a PHI which obscures the base pointer.
88409467b48Spatrick // - Construct a mapping from PHI to unknown TOP state. Use an
88509467b48Spatrick // optimistic algorithm to propagate base pointer information. Lattice
88609467b48Spatrick // looks like:
88709467b48Spatrick // UNKNOWN
88809467b48Spatrick // b1 b2 b3 b4
88909467b48Spatrick // CONFLICT
89009467b48Spatrick // When algorithm terminates, all PHIs will either have a single concrete
89109467b48Spatrick // base or be in a conflict state.
89209467b48Spatrick // - For every conflict, insert a dummy PHI node without arguments. Add
89309467b48Spatrick // these to the base[Instruction] = BasePtr mapping. For every
89409467b48Spatrick // non-conflict, add the actual base.
89509467b48Spatrick // - For every conflict, add arguments for the base[a] of each input
89609467b48Spatrick // arguments.
89709467b48Spatrick //
89809467b48Spatrick // Note: A simpler form of this would be to add the conflict form of all
89909467b48Spatrick // PHIs without running the optimistic algorithm. This would be
90009467b48Spatrick // analogous to pessimistic data flow and would likely lead to an
90109467b48Spatrick // overall worse solution.
90209467b48Spatrick
90309467b48Spatrick #ifndef NDEBUG
90409467b48Spatrick auto isExpectedBDVType = [](Value *BDV) {
90509467b48Spatrick return isa<PHINode>(BDV) || isa<SelectInst>(BDV) ||
90609467b48Spatrick isa<ExtractElementInst>(BDV) || isa<InsertElementInst>(BDV) ||
90709467b48Spatrick isa<ShuffleVectorInst>(BDV);
90809467b48Spatrick };
90909467b48Spatrick #endif
91009467b48Spatrick
91109467b48Spatrick // Once populated, will contain a mapping from each potentially non-base BDV
91209467b48Spatrick // to a lattice value (described above) which corresponds to that BDV.
91309467b48Spatrick // We use the order of insertion (DFS over the def/use graph) to provide a
91409467b48Spatrick // stable deterministic ordering for visiting DenseMaps (which are unordered)
91509467b48Spatrick // below. This is important for deterministic compilation.
91609467b48Spatrick MapVector<Value *, BDVState> States;
91709467b48Spatrick
91873471bf0Spatrick #ifndef NDEBUG
91973471bf0Spatrick auto VerifyStates = [&]() {
92073471bf0Spatrick for (auto &Entry : States) {
92173471bf0Spatrick assert(Entry.first == Entry.second.getOriginalValue());
92273471bf0Spatrick }
92373471bf0Spatrick };
92473471bf0Spatrick #endif
92573471bf0Spatrick
92673471bf0Spatrick auto visitBDVOperands = [](Value *BDV, std::function<void (Value*)> F) {
92773471bf0Spatrick if (PHINode *PN = dyn_cast<PHINode>(BDV)) {
92873471bf0Spatrick for (Value *InVal : PN->incoming_values())
92973471bf0Spatrick F(InVal);
93073471bf0Spatrick } else if (SelectInst *SI = dyn_cast<SelectInst>(BDV)) {
93173471bf0Spatrick F(SI->getTrueValue());
93273471bf0Spatrick F(SI->getFalseValue());
93373471bf0Spatrick } else if (auto *EE = dyn_cast<ExtractElementInst>(BDV)) {
93473471bf0Spatrick F(EE->getVectorOperand());
93573471bf0Spatrick } else if (auto *IE = dyn_cast<InsertElementInst>(BDV)) {
93673471bf0Spatrick F(IE->getOperand(0));
93773471bf0Spatrick F(IE->getOperand(1));
93873471bf0Spatrick } else if (auto *SV = dyn_cast<ShuffleVectorInst>(BDV)) {
93973471bf0Spatrick // For a canonical broadcast, ignore the undef argument
94073471bf0Spatrick // (without this, we insert a parallel base shuffle for every broadcast)
94173471bf0Spatrick F(SV->getOperand(0));
94273471bf0Spatrick if (!SV->isZeroEltSplat())
94373471bf0Spatrick F(SV->getOperand(1));
94473471bf0Spatrick } else {
94573471bf0Spatrick llvm_unreachable("unexpected BDV type");
94673471bf0Spatrick }
94773471bf0Spatrick };
94873471bf0Spatrick
94973471bf0Spatrick
95009467b48Spatrick // Recursively fill in all base defining values reachable from the initial
95109467b48Spatrick // one for which we don't already know a definite base value for
95209467b48Spatrick /* scope */ {
95309467b48Spatrick SmallVector<Value*, 16> Worklist;
95409467b48Spatrick Worklist.push_back(Def);
95573471bf0Spatrick States.insert({Def, BDVState(Def)});
95609467b48Spatrick while (!Worklist.empty()) {
95709467b48Spatrick Value *Current = Worklist.pop_back_val();
958097a140dSpatrick assert(!isOriginalBaseResult(Current) && "why did it get added?");
95909467b48Spatrick
96009467b48Spatrick auto visitIncomingValue = [&](Value *InVal) {
961*d415bd75Srobert Value *Base = findBaseOrBDV(InVal, Cache, KnownBases);
962*d415bd75Srobert if (isKnownBase(Base, KnownBases) && areBothVectorOrScalar(Base, InVal))
96309467b48Spatrick // Known bases won't need new instructions introduced and can be
964097a140dSpatrick // ignored safely. However, this can only be done when InVal and Base
965097a140dSpatrick // are both scalar or both vector. Otherwise, we need to find a
966097a140dSpatrick // correct BDV for InVal, by creating an entry in the lattice
967097a140dSpatrick // (States).
96809467b48Spatrick return;
96909467b48Spatrick assert(isExpectedBDVType(Base) && "the only non-base values "
97009467b48Spatrick "we see should be base defining values");
97173471bf0Spatrick if (States.insert(std::make_pair(Base, BDVState(Base))).second)
97209467b48Spatrick Worklist.push_back(Base);
97309467b48Spatrick };
97473471bf0Spatrick
97573471bf0Spatrick visitBDVOperands(Current, visitIncomingValue);
97609467b48Spatrick }
97709467b48Spatrick }
97809467b48Spatrick
97909467b48Spatrick #ifndef NDEBUG
98073471bf0Spatrick VerifyStates();
98109467b48Spatrick LLVM_DEBUG(dbgs() << "States after initialization:\n");
982*d415bd75Srobert for (const auto &Pair : States) {
98309467b48Spatrick LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
98409467b48Spatrick }
98509467b48Spatrick #endif
98609467b48Spatrick
98773471bf0Spatrick // Iterate forward through the value graph pruning any node from the state
98873471bf0Spatrick // list where all of the inputs are base pointers. The purpose of this is to
98973471bf0Spatrick // reuse existing values when the derived pointer we were asked to materialize
99073471bf0Spatrick // a base pointer for happens to be a base pointer itself. (Or a sub-graph
99173471bf0Spatrick // feeding it does.)
99273471bf0Spatrick SmallVector<Value *> ToRemove;
99373471bf0Spatrick do {
99473471bf0Spatrick ToRemove.clear();
99573471bf0Spatrick for (auto Pair : States) {
99673471bf0Spatrick Value *BDV = Pair.first;
99773471bf0Spatrick auto canPruneInput = [&](Value *V) {
998*d415bd75Srobert // If the input of the BDV is the BDV itself we can prune it. This is
999*d415bd75Srobert // only possible if the BDV is a PHI node.
1000*d415bd75Srobert if (V->stripPointerCasts() == BDV)
1001*d415bd75Srobert return true;
1002*d415bd75Srobert Value *VBDV = findBaseOrBDV(V, Cache, KnownBases);
1003*d415bd75Srobert if (V->stripPointerCasts() != VBDV)
100473471bf0Spatrick return false;
100573471bf0Spatrick // The assumption is that anything not in the state list is
100673471bf0Spatrick // propagates a base pointer.
1007*d415bd75Srobert return States.count(VBDV) == 0;
100873471bf0Spatrick };
100973471bf0Spatrick
101073471bf0Spatrick bool CanPrune = true;
101173471bf0Spatrick visitBDVOperands(BDV, [&](Value *Op) {
101273471bf0Spatrick CanPrune = CanPrune && canPruneInput(Op);
101373471bf0Spatrick });
101473471bf0Spatrick if (CanPrune)
101573471bf0Spatrick ToRemove.push_back(BDV);
101673471bf0Spatrick }
101773471bf0Spatrick for (Value *V : ToRemove) {
101873471bf0Spatrick States.erase(V);
101973471bf0Spatrick // Cache the fact V is it's own base for later usage.
102073471bf0Spatrick Cache[V] = V;
102173471bf0Spatrick }
102273471bf0Spatrick } while (!ToRemove.empty());
102373471bf0Spatrick
102473471bf0Spatrick // Did we manage to prove that Def itself must be a base pointer?
102573471bf0Spatrick if (!States.count(Def))
102673471bf0Spatrick return Def;
102773471bf0Spatrick
102809467b48Spatrick // Return a phi state for a base defining value. We'll generate a new
102909467b48Spatrick // base state for known bases and expect to find a cached state otherwise.
1030097a140dSpatrick auto GetStateForBDV = [&](Value *BaseValue, Value *Input) {
1031097a140dSpatrick auto I = States.find(BaseValue);
103273471bf0Spatrick if (I != States.end())
103309467b48Spatrick return I->second;
103473471bf0Spatrick assert(areBothVectorOrScalar(BaseValue, Input));
103573471bf0Spatrick return BDVState(BaseValue, BDVState::Base, BaseValue);
103609467b48Spatrick };
103709467b48Spatrick
103809467b48Spatrick bool Progress = true;
103909467b48Spatrick while (Progress) {
104009467b48Spatrick #ifndef NDEBUG
104109467b48Spatrick const size_t OldSize = States.size();
104209467b48Spatrick #endif
104309467b48Spatrick Progress = false;
104409467b48Spatrick // We're only changing values in this loop, thus safe to keep iterators.
104509467b48Spatrick // Since this is computing a fixed point, the order of visit does not
104609467b48Spatrick // effect the result. TODO: We could use a worklist here and make this run
104709467b48Spatrick // much faster.
104809467b48Spatrick for (auto Pair : States) {
104909467b48Spatrick Value *BDV = Pair.first;
1050097a140dSpatrick // Only values that do not have known bases or those that have differing
1051097a140dSpatrick // type (scalar versus vector) from a possible known base should be in the
1052097a140dSpatrick // lattice.
1053*d415bd75Srobert assert((!isKnownBase(BDV, KnownBases) ||
1054097a140dSpatrick !areBothVectorOrScalar(BDV, Pair.second.getBaseValue())) &&
1055097a140dSpatrick "why did it get added?");
105609467b48Spatrick
105773471bf0Spatrick BDVState NewState(BDV);
105873471bf0Spatrick visitBDVOperands(BDV, [&](Value *Op) {
1059*d415bd75Srobert Value *BDV = findBaseOrBDV(Op, Cache, KnownBases);
106073471bf0Spatrick auto OpState = GetStateForBDV(BDV, Op);
106173471bf0Spatrick NewState.meet(OpState);
106273471bf0Spatrick });
106309467b48Spatrick
106409467b48Spatrick BDVState OldState = States[BDV];
106509467b48Spatrick if (OldState != NewState) {
106609467b48Spatrick Progress = true;
106709467b48Spatrick States[BDV] = NewState;
106809467b48Spatrick }
106909467b48Spatrick }
107009467b48Spatrick
107109467b48Spatrick assert(OldSize == States.size() &&
107209467b48Spatrick "fixed point shouldn't be adding any new nodes to state");
107309467b48Spatrick }
107409467b48Spatrick
107509467b48Spatrick #ifndef NDEBUG
107673471bf0Spatrick VerifyStates();
107709467b48Spatrick LLVM_DEBUG(dbgs() << "States after meet iteration:\n");
1078*d415bd75Srobert for (const auto &Pair : States) {
107909467b48Spatrick LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
108009467b48Spatrick }
108109467b48Spatrick #endif
108209467b48Spatrick
1083097a140dSpatrick // Handle all instructions that have a vector BDV, but the instruction itself
1084097a140dSpatrick // is of scalar type.
108509467b48Spatrick for (auto Pair : States) {
108609467b48Spatrick Instruction *I = cast<Instruction>(Pair.first);
108709467b48Spatrick BDVState State = Pair.second;
1088097a140dSpatrick auto *BaseValue = State.getBaseValue();
1089097a140dSpatrick // Only values that do not have known bases or those that have differing
1090097a140dSpatrick // type (scalar versus vector) from a possible known base should be in the
1091097a140dSpatrick // lattice.
1092*d415bd75Srobert assert(
1093*d415bd75Srobert (!isKnownBase(I, KnownBases) || !areBothVectorOrScalar(I, BaseValue)) &&
1094097a140dSpatrick "why did it get added?");
109509467b48Spatrick assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
109609467b48Spatrick
1097097a140dSpatrick if (!State.isBase() || !isa<VectorType>(BaseValue->getType()))
1098097a140dSpatrick continue;
109909467b48Spatrick // extractelement instructions are a bit special in that we may need to
110009467b48Spatrick // insert an extract even when we know an exact base for the instruction.
110109467b48Spatrick // The problem is that we need to convert from a vector base to a scalar
110209467b48Spatrick // base for the particular indice we're interested in.
1103097a140dSpatrick if (isa<ExtractElementInst>(I)) {
110409467b48Spatrick auto *EE = cast<ExtractElementInst>(I);
110509467b48Spatrick // TODO: In many cases, the new instruction is just EE itself. We should
110609467b48Spatrick // exploit this, but can't do it here since it would break the invariant
110709467b48Spatrick // about the BDV not being known to be a base.
110809467b48Spatrick auto *BaseInst = ExtractElementInst::Create(
110909467b48Spatrick State.getBaseValue(), EE->getIndexOperand(), "base_ee", EE);
111009467b48Spatrick BaseInst->setMetadata("is_base_value", MDNode::get(I->getContext(), {}));
111173471bf0Spatrick States[I] = BDVState(I, BDVState::Base, BaseInst);
1112*d415bd75Srobert setKnownBase(BaseInst, /* IsKnownBase */true, KnownBases);
1113097a140dSpatrick } else if (!isa<VectorType>(I->getType())) {
1114097a140dSpatrick // We need to handle cases that have a vector base but the instruction is
1115097a140dSpatrick // a scalar type (these could be phis or selects or any instruction that
1116097a140dSpatrick // are of scalar type, but the base can be a vector type). We
1117097a140dSpatrick // conservatively set this as conflict. Setting the base value for these
1118097a140dSpatrick // conflicts is handled in the next loop which traverses States.
111973471bf0Spatrick States[I] = BDVState(I, BDVState::Conflict);
112009467b48Spatrick }
1121097a140dSpatrick }
1122097a140dSpatrick
112373471bf0Spatrick #ifndef NDEBUG
112473471bf0Spatrick VerifyStates();
112573471bf0Spatrick #endif
112673471bf0Spatrick
1127097a140dSpatrick // Insert Phis for all conflicts
1128097a140dSpatrick // TODO: adjust naming patterns to avoid this order of iteration dependency
1129097a140dSpatrick for (auto Pair : States) {
1130097a140dSpatrick Instruction *I = cast<Instruction>(Pair.first);
1131097a140dSpatrick BDVState State = Pair.second;
1132097a140dSpatrick // Only values that do not have known bases or those that have differing
1133097a140dSpatrick // type (scalar versus vector) from a possible known base should be in the
1134097a140dSpatrick // lattice.
1135*d415bd75Srobert assert((!isKnownBase(I, KnownBases) ||
1136*d415bd75Srobert !areBothVectorOrScalar(I, State.getBaseValue())) &&
1137097a140dSpatrick "why did it get added?");
1138097a140dSpatrick assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
113909467b48Spatrick
114009467b48Spatrick // Since we're joining a vector and scalar base, they can never be the
114109467b48Spatrick // same. As a result, we should always see insert element having reached
114209467b48Spatrick // the conflict state.
114309467b48Spatrick assert(!isa<InsertElementInst>(I) || State.isConflict());
114409467b48Spatrick
114509467b48Spatrick if (!State.isConflict())
114609467b48Spatrick continue;
114709467b48Spatrick
114873471bf0Spatrick auto getMangledName = [](Instruction *I) -> std::string {
114909467b48Spatrick if (isa<PHINode>(I)) {
115073471bf0Spatrick return suffixed_name_or(I, ".base", "base_phi");
115173471bf0Spatrick } else if (isa<SelectInst>(I)) {
115273471bf0Spatrick return suffixed_name_or(I, ".base", "base_select");
115373471bf0Spatrick } else if (isa<ExtractElementInst>(I)) {
115473471bf0Spatrick return suffixed_name_or(I, ".base", "base_ee");
115573471bf0Spatrick } else if (isa<InsertElementInst>(I)) {
115673471bf0Spatrick return suffixed_name_or(I, ".base", "base_ie");
115709467b48Spatrick } else {
115873471bf0Spatrick return suffixed_name_or(I, ".base", "base_sv");
115909467b48Spatrick }
116009467b48Spatrick };
116173471bf0Spatrick
116273471bf0Spatrick Instruction *BaseInst = I->clone();
116373471bf0Spatrick BaseInst->insertBefore(I);
116473471bf0Spatrick BaseInst->setName(getMangledName(I));
116509467b48Spatrick // Add metadata marking this as a base value
116609467b48Spatrick BaseInst->setMetadata("is_base_value", MDNode::get(I->getContext(), {}));
116773471bf0Spatrick States[I] = BDVState(I, BDVState::Conflict, BaseInst);
1168*d415bd75Srobert setKnownBase(BaseInst, /* IsKnownBase */true, KnownBases);
116909467b48Spatrick }
117009467b48Spatrick
117173471bf0Spatrick #ifndef NDEBUG
117273471bf0Spatrick VerifyStates();
117373471bf0Spatrick #endif
117473471bf0Spatrick
117509467b48Spatrick // Returns a instruction which produces the base pointer for a given
117609467b48Spatrick // instruction. The instruction is assumed to be an input to one of the BDVs
117709467b48Spatrick // seen in the inference algorithm above. As such, we must either already
117809467b48Spatrick // know it's base defining value is a base, or have inserted a new
117909467b48Spatrick // instruction to propagate the base of it's BDV and have entered that newly
118009467b48Spatrick // introduced instruction into the state table. In either case, we are
118109467b48Spatrick // assured to be able to determine an instruction which produces it's base
118209467b48Spatrick // pointer.
118309467b48Spatrick auto getBaseForInput = [&](Value *Input, Instruction *InsertPt) {
1184*d415bd75Srobert Value *BDV = findBaseOrBDV(Input, Cache, KnownBases);
118509467b48Spatrick Value *Base = nullptr;
118673471bf0Spatrick if (!States.count(BDV)) {
118773471bf0Spatrick assert(areBothVectorOrScalar(BDV, Input));
118809467b48Spatrick Base = BDV;
118909467b48Spatrick } else {
119009467b48Spatrick // Either conflict or base.
119109467b48Spatrick assert(States.count(BDV));
119209467b48Spatrick Base = States[BDV].getBaseValue();
119309467b48Spatrick }
119409467b48Spatrick assert(Base && "Can't be null");
119509467b48Spatrick // The cast is needed since base traversal may strip away bitcasts
119609467b48Spatrick if (Base->getType() != Input->getType() && InsertPt)
119709467b48Spatrick Base = new BitCastInst(Base, Input->getType(), "cast", InsertPt);
119809467b48Spatrick return Base;
119909467b48Spatrick };
120009467b48Spatrick
120109467b48Spatrick // Fixup all the inputs of the new PHIs. Visit order needs to be
120209467b48Spatrick // deterministic and predictable because we're naming newly created
120309467b48Spatrick // instructions.
120409467b48Spatrick for (auto Pair : States) {
120509467b48Spatrick Instruction *BDV = cast<Instruction>(Pair.first);
120609467b48Spatrick BDVState State = Pair.second;
120709467b48Spatrick
1208097a140dSpatrick // Only values that do not have known bases or those that have differing
1209097a140dSpatrick // type (scalar versus vector) from a possible known base should be in the
1210097a140dSpatrick // lattice.
1211*d415bd75Srobert assert((!isKnownBase(BDV, KnownBases) ||
1212097a140dSpatrick !areBothVectorOrScalar(BDV, State.getBaseValue())) &&
1213097a140dSpatrick "why did it get added?");
121409467b48Spatrick assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
121509467b48Spatrick if (!State.isConflict())
121609467b48Spatrick continue;
121709467b48Spatrick
121809467b48Spatrick if (PHINode *BasePHI = dyn_cast<PHINode>(State.getBaseValue())) {
121909467b48Spatrick PHINode *PN = cast<PHINode>(BDV);
122073471bf0Spatrick const unsigned NumPHIValues = PN->getNumIncomingValues();
122173471bf0Spatrick
122273471bf0Spatrick // The IR verifier requires phi nodes with multiple entries from the
122373471bf0Spatrick // same basic block to have the same incoming value for each of those
122473471bf0Spatrick // entries. Since we're inserting bitcasts in the loop, make sure we
122573471bf0Spatrick // do so at least once per incoming block.
122673471bf0Spatrick DenseMap<BasicBlock *, Value*> BlockToValue;
122709467b48Spatrick for (unsigned i = 0; i < NumPHIValues; i++) {
122809467b48Spatrick Value *InVal = PN->getIncomingValue(i);
122909467b48Spatrick BasicBlock *InBB = PN->getIncomingBlock(i);
123073471bf0Spatrick if (!BlockToValue.count(InBB))
123173471bf0Spatrick BlockToValue[InBB] = getBaseForInput(InVal, InBB->getTerminator());
123273471bf0Spatrick else {
123309467b48Spatrick #ifndef NDEBUG
123473471bf0Spatrick Value *OldBase = BlockToValue[InBB];
123509467b48Spatrick Value *Base = getBaseForInput(InVal, nullptr);
1236*d415bd75Srobert
1237*d415bd75Srobert // We can't use `stripPointerCasts` instead of this function because
1238*d415bd75Srobert // `stripPointerCasts` doesn't handle vectors of pointers.
1239*d415bd75Srobert auto StripBitCasts = [](Value *V) -> Value * {
1240*d415bd75Srobert while (auto *BC = dyn_cast<BitCastInst>(V))
1241*d415bd75Srobert V = BC->getOperand(0);
1242*d415bd75Srobert return V;
1243*d415bd75Srobert };
124409467b48Spatrick // In essence this assert states: the only way two values
124509467b48Spatrick // incoming from the same basic block may be different is by
124609467b48Spatrick // being different bitcasts of the same value. A cleanup
124709467b48Spatrick // that remains TODO is changing findBaseOrBDV to return an
124809467b48Spatrick // llvm::Value of the correct type (and still remain pure).
124909467b48Spatrick // This will remove the need to add bitcasts.
1250*d415bd75Srobert assert(StripBitCasts(Base) == StripBitCasts(OldBase) &&
1251*d415bd75Srobert "findBaseOrBDV should be pure!");
125209467b48Spatrick #endif
125309467b48Spatrick }
125473471bf0Spatrick Value *Base = BlockToValue[InBB];
125573471bf0Spatrick BasePHI->setIncomingValue(i, Base);
125609467b48Spatrick }
125709467b48Spatrick } else if (SelectInst *BaseSI =
125809467b48Spatrick dyn_cast<SelectInst>(State.getBaseValue())) {
125909467b48Spatrick SelectInst *SI = cast<SelectInst>(BDV);
126009467b48Spatrick
126109467b48Spatrick // Find the instruction which produces the base for each input.
126209467b48Spatrick // We may need to insert a bitcast.
126309467b48Spatrick BaseSI->setTrueValue(getBaseForInput(SI->getTrueValue(), BaseSI));
126409467b48Spatrick BaseSI->setFalseValue(getBaseForInput(SI->getFalseValue(), BaseSI));
126509467b48Spatrick } else if (auto *BaseEE =
126609467b48Spatrick dyn_cast<ExtractElementInst>(State.getBaseValue())) {
126709467b48Spatrick Value *InVal = cast<ExtractElementInst>(BDV)->getVectorOperand();
126809467b48Spatrick // Find the instruction which produces the base for each input. We may
126909467b48Spatrick // need to insert a bitcast.
127009467b48Spatrick BaseEE->setOperand(0, getBaseForInput(InVal, BaseEE));
127109467b48Spatrick } else if (auto *BaseIE = dyn_cast<InsertElementInst>(State.getBaseValue())){
127209467b48Spatrick auto *BdvIE = cast<InsertElementInst>(BDV);
127309467b48Spatrick auto UpdateOperand = [&](int OperandIdx) {
127409467b48Spatrick Value *InVal = BdvIE->getOperand(OperandIdx);
127509467b48Spatrick Value *Base = getBaseForInput(InVal, BaseIE);
127609467b48Spatrick BaseIE->setOperand(OperandIdx, Base);
127709467b48Spatrick };
127809467b48Spatrick UpdateOperand(0); // vector operand
127909467b48Spatrick UpdateOperand(1); // scalar operand
128009467b48Spatrick } else {
128109467b48Spatrick auto *BaseSV = cast<ShuffleVectorInst>(State.getBaseValue());
128209467b48Spatrick auto *BdvSV = cast<ShuffleVectorInst>(BDV);
128309467b48Spatrick auto UpdateOperand = [&](int OperandIdx) {
128409467b48Spatrick Value *InVal = BdvSV->getOperand(OperandIdx);
128509467b48Spatrick Value *Base = getBaseForInput(InVal, BaseSV);
128609467b48Spatrick BaseSV->setOperand(OperandIdx, Base);
128709467b48Spatrick };
128809467b48Spatrick UpdateOperand(0); // vector operand
128973471bf0Spatrick if (!BdvSV->isZeroEltSplat())
129009467b48Spatrick UpdateOperand(1); // vector operand
129173471bf0Spatrick else {
129273471bf0Spatrick // Never read, so just use undef
129373471bf0Spatrick Value *InVal = BdvSV->getOperand(1);
129473471bf0Spatrick BaseSV->setOperand(1, UndefValue::get(InVal->getType()));
129509467b48Spatrick }
129609467b48Spatrick }
129773471bf0Spatrick }
129873471bf0Spatrick
129973471bf0Spatrick #ifndef NDEBUG
130073471bf0Spatrick VerifyStates();
130173471bf0Spatrick #endif
130209467b48Spatrick
130309467b48Spatrick // Cache all of our results so we can cheaply reuse them
130409467b48Spatrick // NOTE: This is actually two caches: one of the base defining value
130509467b48Spatrick // relation and one of the base pointer relation! FIXME
130609467b48Spatrick for (auto Pair : States) {
130709467b48Spatrick auto *BDV = Pair.first;
130809467b48Spatrick Value *Base = Pair.second.getBaseValue();
130909467b48Spatrick assert(BDV && Base);
1310097a140dSpatrick // Only values that do not have known bases or those that have differing
1311097a140dSpatrick // type (scalar versus vector) from a possible known base should be in the
1312097a140dSpatrick // lattice.
1313*d415bd75Srobert assert(
1314*d415bd75Srobert (!isKnownBase(BDV, KnownBases) || !areBothVectorOrScalar(BDV, Base)) &&
1315097a140dSpatrick "why did it get added?");
131609467b48Spatrick
131709467b48Spatrick LLVM_DEBUG(
131809467b48Spatrick dbgs() << "Updating base value cache"
131909467b48Spatrick << " for: " << BDV->getName() << " from: "
132009467b48Spatrick << (Cache.count(BDV) ? Cache[BDV]->getName().str() : "none")
132109467b48Spatrick << " to: " << Base->getName() << "\n");
132209467b48Spatrick
132309467b48Spatrick Cache[BDV] = Base;
132409467b48Spatrick }
132509467b48Spatrick assert(Cache.count(Def));
132609467b48Spatrick return Cache[Def];
132709467b48Spatrick }
132809467b48Spatrick
132909467b48Spatrick // For a set of live pointers (base and/or derived), identify the base
133009467b48Spatrick // pointer of the object which they are derived from. This routine will
133109467b48Spatrick // mutate the IR graph as needed to make the 'base' pointer live at the
133209467b48Spatrick // definition site of 'derived'. This ensures that any use of 'derived' can
133309467b48Spatrick // also use 'base'. This may involve the insertion of a number of
133409467b48Spatrick // additional PHI nodes.
133509467b48Spatrick //
133609467b48Spatrick // preconditions: live is a set of pointer type Values
133709467b48Spatrick //
133809467b48Spatrick // side effects: may insert PHI nodes into the existing CFG, will preserve
133909467b48Spatrick // CFG, will not remove or mutate any existing nodes
134009467b48Spatrick //
134109467b48Spatrick // post condition: PointerToBase contains one (derived, base) pair for every
134209467b48Spatrick // pointer in live. Note that derived can be equal to base if the original
134309467b48Spatrick // pointer was a base pointer.
findBasePointers(const StatepointLiveSetTy & live,PointerToBaseTy & PointerToBase,DominatorTree * DT,DefiningValueMapTy & DVCache,IsKnownBaseMapTy & KnownBases)1344*d415bd75Srobert static void findBasePointers(const StatepointLiveSetTy &live,
1345*d415bd75Srobert PointerToBaseTy &PointerToBase, DominatorTree *DT,
1346*d415bd75Srobert DefiningValueMapTy &DVCache,
1347*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
134809467b48Spatrick for (Value *ptr : live) {
1349*d415bd75Srobert Value *base = findBasePointer(ptr, DVCache, KnownBases);
135009467b48Spatrick assert(base && "failed to find base pointer");
135109467b48Spatrick PointerToBase[ptr] = base;
135209467b48Spatrick assert((!isa<Instruction>(base) || !isa<Instruction>(ptr) ||
135309467b48Spatrick DT->dominates(cast<Instruction>(base)->getParent(),
135409467b48Spatrick cast<Instruction>(ptr)->getParent())) &&
135509467b48Spatrick "The base we found better dominate the derived pointer");
135609467b48Spatrick }
135709467b48Spatrick }
135809467b48Spatrick
135909467b48Spatrick /// Find the required based pointers (and adjust the live set) for the given
136009467b48Spatrick /// parse point.
findBasePointers(DominatorTree & DT,DefiningValueMapTy & DVCache,CallBase * Call,PartiallyConstructedSafepointRecord & result,PointerToBaseTy & PointerToBase,IsKnownBaseMapTy & KnownBases)136109467b48Spatrick static void findBasePointers(DominatorTree &DT, DefiningValueMapTy &DVCache,
136209467b48Spatrick CallBase *Call,
1363*d415bd75Srobert PartiallyConstructedSafepointRecord &result,
1364*d415bd75Srobert PointerToBaseTy &PointerToBase,
1365*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
136673471bf0Spatrick StatepointLiveSetTy PotentiallyDerivedPointers = result.LiveSet;
136773471bf0Spatrick // We assume that all pointers passed to deopt are base pointers; as an
136873471bf0Spatrick // optimization, we can use this to avoid seperately materializing the base
136973471bf0Spatrick // pointer graph. This is only relevant since we're very conservative about
137073471bf0Spatrick // generating new conflict nodes during base pointer insertion. If we were
137173471bf0Spatrick // smarter there, this would be irrelevant.
137273471bf0Spatrick if (auto Opt = Call->getOperandBundle(LLVMContext::OB_deopt))
137373471bf0Spatrick for (Value *V : Opt->Inputs) {
137473471bf0Spatrick if (!PotentiallyDerivedPointers.count(V))
137573471bf0Spatrick continue;
137673471bf0Spatrick PotentiallyDerivedPointers.remove(V);
137773471bf0Spatrick PointerToBase[V] = V;
137873471bf0Spatrick }
1379*d415bd75Srobert findBasePointers(PotentiallyDerivedPointers, PointerToBase, &DT, DVCache,
1380*d415bd75Srobert KnownBases);
138109467b48Spatrick }
138209467b48Spatrick
138309467b48Spatrick /// Given an updated version of the dataflow liveness results, update the
138409467b48Spatrick /// liveset and base pointer maps for the call site CS.
138509467b48Spatrick static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
138609467b48Spatrick CallBase *Call,
1387*d415bd75Srobert PartiallyConstructedSafepointRecord &result,
1388*d415bd75Srobert PointerToBaseTy &PointerToBase);
138909467b48Spatrick
recomputeLiveInValues(Function & F,DominatorTree & DT,ArrayRef<CallBase * > toUpdate,MutableArrayRef<struct PartiallyConstructedSafepointRecord> records,PointerToBaseTy & PointerToBase)139009467b48Spatrick static void recomputeLiveInValues(
139109467b48Spatrick Function &F, DominatorTree &DT, ArrayRef<CallBase *> toUpdate,
1392*d415bd75Srobert MutableArrayRef<struct PartiallyConstructedSafepointRecord> records,
1393*d415bd75Srobert PointerToBaseTy &PointerToBase) {
139409467b48Spatrick // TODO-PERF: reuse the original liveness, then simply run the dataflow
139509467b48Spatrick // again. The old values are still live and will help it stabilize quickly.
139609467b48Spatrick GCPtrLivenessData RevisedLivenessData;
139709467b48Spatrick computeLiveInValues(DT, F, RevisedLivenessData);
139809467b48Spatrick for (size_t i = 0; i < records.size(); i++) {
139909467b48Spatrick struct PartiallyConstructedSafepointRecord &info = records[i];
1400*d415bd75Srobert recomputeLiveInValues(RevisedLivenessData, toUpdate[i], info,
1401*d415bd75Srobert PointerToBase);
140209467b48Spatrick }
140309467b48Spatrick }
140409467b48Spatrick
1405*d415bd75Srobert // Utility function which clones all instructions from "ChainToBase"
1406*d415bd75Srobert // and inserts them before "InsertBefore". Returns rematerialized value
1407*d415bd75Srobert // which should be used after statepoint.
rematerializeChain(ArrayRef<Instruction * > ChainToBase,Instruction * InsertBefore,Value * RootOfChain,Value * AlternateLiveBase)1408*d415bd75Srobert static Instruction *rematerializeChain(ArrayRef<Instruction *> ChainToBase,
1409*d415bd75Srobert Instruction *InsertBefore,
1410*d415bd75Srobert Value *RootOfChain,
1411*d415bd75Srobert Value *AlternateLiveBase) {
1412*d415bd75Srobert Instruction *LastClonedValue = nullptr;
1413*d415bd75Srobert Instruction *LastValue = nullptr;
1414*d415bd75Srobert // Walk backwards to visit top-most instructions first.
1415*d415bd75Srobert for (Instruction *Instr :
1416*d415bd75Srobert make_range(ChainToBase.rbegin(), ChainToBase.rend())) {
1417*d415bd75Srobert // Only GEP's and casts are supported as we need to be careful to not
1418*d415bd75Srobert // introduce any new uses of pointers not in the liveset.
1419*d415bd75Srobert // Note that it's fine to introduce new uses of pointers which were
1420*d415bd75Srobert // otherwise not used after this statepoint.
1421*d415bd75Srobert assert(isa<GetElementPtrInst>(Instr) || isa<CastInst>(Instr));
1422*d415bd75Srobert
1423*d415bd75Srobert Instruction *ClonedValue = Instr->clone();
1424*d415bd75Srobert ClonedValue->insertBefore(InsertBefore);
1425*d415bd75Srobert ClonedValue->setName(Instr->getName() + ".remat");
1426*d415bd75Srobert
1427*d415bd75Srobert // If it is not first instruction in the chain then it uses previously
1428*d415bd75Srobert // cloned value. We should update it to use cloned value.
1429*d415bd75Srobert if (LastClonedValue) {
1430*d415bd75Srobert assert(LastValue);
1431*d415bd75Srobert ClonedValue->replaceUsesOfWith(LastValue, LastClonedValue);
1432*d415bd75Srobert #ifndef NDEBUG
1433*d415bd75Srobert for (auto *OpValue : ClonedValue->operand_values()) {
1434*d415bd75Srobert // Assert that cloned instruction does not use any instructions from
1435*d415bd75Srobert // this chain other than LastClonedValue
1436*d415bd75Srobert assert(!is_contained(ChainToBase, OpValue) &&
1437*d415bd75Srobert "incorrect use in rematerialization chain");
1438*d415bd75Srobert // Assert that the cloned instruction does not use the RootOfChain
1439*d415bd75Srobert // or the AlternateLiveBase.
1440*d415bd75Srobert assert(OpValue != RootOfChain && OpValue != AlternateLiveBase);
1441*d415bd75Srobert }
1442*d415bd75Srobert #endif
1443*d415bd75Srobert } else {
1444*d415bd75Srobert // For the first instruction, replace the use of unrelocated base i.e.
1445*d415bd75Srobert // RootOfChain/OrigRootPhi, with the corresponding PHI present in the
1446*d415bd75Srobert // live set. They have been proved to be the same PHI nodes. Note
1447*d415bd75Srobert // that the *only* use of the RootOfChain in the ChainToBase list is
1448*d415bd75Srobert // the first Value in the list.
1449*d415bd75Srobert if (RootOfChain != AlternateLiveBase)
1450*d415bd75Srobert ClonedValue->replaceUsesOfWith(RootOfChain, AlternateLiveBase);
1451*d415bd75Srobert }
1452*d415bd75Srobert
1453*d415bd75Srobert LastClonedValue = ClonedValue;
1454*d415bd75Srobert LastValue = Instr;
1455*d415bd75Srobert }
1456*d415bd75Srobert assert(LastClonedValue);
1457*d415bd75Srobert return LastClonedValue;
1458*d415bd75Srobert }
1459*d415bd75Srobert
146009467b48Spatrick // When inserting gc.relocate and gc.result calls, we need to ensure there are
146109467b48Spatrick // no uses of the original value / return value between the gc.statepoint and
146209467b48Spatrick // the gc.relocate / gc.result call. One case which can arise is a phi node
146309467b48Spatrick // starting one of the successor blocks. We also need to be able to insert the
146409467b48Spatrick // gc.relocates only on the path which goes through the statepoint. We might
146509467b48Spatrick // need to split an edge to make this possible.
146609467b48Spatrick static BasicBlock *
normalizeForInvokeSafepoint(BasicBlock * BB,BasicBlock * InvokeParent,DominatorTree & DT)146709467b48Spatrick normalizeForInvokeSafepoint(BasicBlock *BB, BasicBlock *InvokeParent,
146809467b48Spatrick DominatorTree &DT) {
146909467b48Spatrick BasicBlock *Ret = BB;
147009467b48Spatrick if (!BB->getUniquePredecessor())
147109467b48Spatrick Ret = SplitBlockPredecessors(BB, InvokeParent, "", &DT);
147209467b48Spatrick
147309467b48Spatrick // Now that 'Ret' has unique predecessor we can safely remove all phi nodes
147409467b48Spatrick // from it
147509467b48Spatrick FoldSingleEntryPHINodes(Ret);
147609467b48Spatrick assert(!isa<PHINode>(Ret->begin()) &&
147709467b48Spatrick "All PHI nodes should have been removed!");
147809467b48Spatrick
147909467b48Spatrick // At this point, we can safely insert a gc.relocate or gc.result as the first
148009467b48Spatrick // instruction in Ret if needed.
148109467b48Spatrick return Ret;
148209467b48Spatrick }
148309467b48Spatrick
148473471bf0Spatrick // List of all function attributes which must be stripped when lowering from
148573471bf0Spatrick // abstract machine model to physical machine model. Essentially, these are
148673471bf0Spatrick // all the effects a safepoint might have which we ignored in the abstract
148773471bf0Spatrick // machine model for purposes of optimization. We have to strip these on
148873471bf0Spatrick // both function declarations and call sites.
148973471bf0Spatrick static constexpr Attribute::AttrKind FnAttrsToStrip[] =
1490*d415bd75Srobert {Attribute::Memory, Attribute::NoSync, Attribute::NoFree};
149173471bf0Spatrick
149209467b48Spatrick // Create new attribute set containing only attributes which can be transferred
149309467b48Spatrick // from original call to the safepoint.
legalizeCallAttributes(LLVMContext & Ctx,AttributeList OrigAL,AttributeList StatepointAL)1494097a140dSpatrick static AttributeList legalizeCallAttributes(LLVMContext &Ctx,
1495*d415bd75Srobert AttributeList OrigAL,
1496*d415bd75Srobert AttributeList StatepointAL) {
1497*d415bd75Srobert if (OrigAL.isEmpty())
1498*d415bd75Srobert return StatepointAL;
149909467b48Spatrick
150009467b48Spatrick // Remove the readonly, readnone, and statepoint function attributes.
1501*d415bd75Srobert AttrBuilder FnAttrs(Ctx, OrigAL.getFnAttrs());
150273471bf0Spatrick for (auto Attr : FnAttrsToStrip)
150373471bf0Spatrick FnAttrs.removeAttribute(Attr);
150473471bf0Spatrick
1505*d415bd75Srobert for (Attribute A : OrigAL.getFnAttrs()) {
150609467b48Spatrick if (isStatepointDirectiveAttr(A))
1507*d415bd75Srobert FnAttrs.removeAttribute(A);
150809467b48Spatrick }
150909467b48Spatrick
151009467b48Spatrick // Just skip parameter and return attributes for now
1511*d415bd75Srobert return StatepointAL.addFnAttributes(Ctx, FnAttrs);
151209467b48Spatrick }
151309467b48Spatrick
151409467b48Spatrick /// Helper function to place all gc relocates necessary for the given
151509467b48Spatrick /// statepoint.
151609467b48Spatrick /// Inputs:
151709467b48Spatrick /// liveVariables - list of variables to be relocated.
151809467b48Spatrick /// basePtrs - base pointers.
151909467b48Spatrick /// statepointToken - statepoint instruction to which relocates should be
152009467b48Spatrick /// bound.
152109467b48Spatrick /// Builder - Llvm IR builder to be used to construct new calls.
CreateGCRelocates(ArrayRef<Value * > LiveVariables,ArrayRef<Value * > BasePtrs,Instruction * StatepointToken,IRBuilder<> & Builder)152209467b48Spatrick static void CreateGCRelocates(ArrayRef<Value *> LiveVariables,
152309467b48Spatrick ArrayRef<Value *> BasePtrs,
152409467b48Spatrick Instruction *StatepointToken,
1525097a140dSpatrick IRBuilder<> &Builder) {
152609467b48Spatrick if (LiveVariables.empty())
152709467b48Spatrick return;
152809467b48Spatrick
152909467b48Spatrick auto FindIndex = [](ArrayRef<Value *> LiveVec, Value *Val) {
153009467b48Spatrick auto ValIt = llvm::find(LiveVec, Val);
153109467b48Spatrick assert(ValIt != LiveVec.end() && "Val not found in LiveVec!");
153209467b48Spatrick size_t Index = std::distance(LiveVec.begin(), ValIt);
153309467b48Spatrick assert(Index < LiveVec.size() && "Bug in std::find?");
153409467b48Spatrick return Index;
153509467b48Spatrick };
153609467b48Spatrick Module *M = StatepointToken->getModule();
153709467b48Spatrick
153809467b48Spatrick // All gc_relocate are generated as i8 addrspace(1)* (or a vector type whose
153909467b48Spatrick // element type is i8 addrspace(1)*). We originally generated unique
154009467b48Spatrick // declarations for each pointer type, but this proved problematic because
154109467b48Spatrick // the intrinsic mangling code is incomplete and fragile. Since we're moving
154209467b48Spatrick // towards a single unified pointer type anyways, we can just cast everything
154309467b48Spatrick // to an i8* of the right address space. A bitcast is added later to convert
154409467b48Spatrick // gc_relocate to the actual value's type.
154509467b48Spatrick auto getGCRelocateDecl = [&] (Type *Ty) {
154609467b48Spatrick assert(isHandledGCPointerType(Ty));
154709467b48Spatrick auto AS = Ty->getScalarType()->getPointerAddressSpace();
154809467b48Spatrick Type *NewTy = Type::getInt8PtrTy(M->getContext(), AS);
154909467b48Spatrick if (auto *VT = dyn_cast<VectorType>(Ty))
1550097a140dSpatrick NewTy = FixedVectorType::get(NewTy,
1551097a140dSpatrick cast<FixedVectorType>(VT)->getNumElements());
155209467b48Spatrick return Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate,
155309467b48Spatrick {NewTy});
155409467b48Spatrick };
155509467b48Spatrick
155609467b48Spatrick // Lazily populated map from input types to the canonicalized form mentioned
155709467b48Spatrick // in the comment above. This should probably be cached somewhere more
155809467b48Spatrick // broadly.
155909467b48Spatrick DenseMap<Type *, Function *> TypeToDeclMap;
156009467b48Spatrick
156109467b48Spatrick for (unsigned i = 0; i < LiveVariables.size(); i++) {
156209467b48Spatrick // Generate the gc.relocate call and save the result
1563097a140dSpatrick Value *BaseIdx = Builder.getInt32(FindIndex(LiveVariables, BasePtrs[i]));
1564097a140dSpatrick Value *LiveIdx = Builder.getInt32(i);
156509467b48Spatrick
156609467b48Spatrick Type *Ty = LiveVariables[i]->getType();
156709467b48Spatrick if (!TypeToDeclMap.count(Ty))
156809467b48Spatrick TypeToDeclMap[Ty] = getGCRelocateDecl(Ty);
156909467b48Spatrick Function *GCRelocateDecl = TypeToDeclMap[Ty];
157009467b48Spatrick
157109467b48Spatrick // only specify a debug name if we can give a useful one
157209467b48Spatrick CallInst *Reloc = Builder.CreateCall(
157309467b48Spatrick GCRelocateDecl, {StatepointToken, BaseIdx, LiveIdx},
157409467b48Spatrick suffixed_name_or(LiveVariables[i], ".relocated", ""));
157509467b48Spatrick // Trick CodeGen into thinking there are lots of free registers at this
157609467b48Spatrick // fake call.
157709467b48Spatrick Reloc->setCallingConv(CallingConv::Cold);
157809467b48Spatrick }
157909467b48Spatrick }
158009467b48Spatrick
158109467b48Spatrick namespace {
158209467b48Spatrick
158309467b48Spatrick /// This struct is used to defer RAUWs and `eraseFromParent` s. Using this
158409467b48Spatrick /// avoids having to worry about keeping around dangling pointers to Values.
158509467b48Spatrick class DeferredReplacement {
158609467b48Spatrick AssertingVH<Instruction> Old;
158709467b48Spatrick AssertingVH<Instruction> New;
158809467b48Spatrick bool IsDeoptimize = false;
158909467b48Spatrick
159009467b48Spatrick DeferredReplacement() = default;
159109467b48Spatrick
159209467b48Spatrick public:
createRAUW(Instruction * Old,Instruction * New)159309467b48Spatrick static DeferredReplacement createRAUW(Instruction *Old, Instruction *New) {
159409467b48Spatrick assert(Old != New && Old && New &&
159509467b48Spatrick "Cannot RAUW equal values or to / from null!");
159609467b48Spatrick
159709467b48Spatrick DeferredReplacement D;
159809467b48Spatrick D.Old = Old;
159909467b48Spatrick D.New = New;
160009467b48Spatrick return D;
160109467b48Spatrick }
160209467b48Spatrick
createDelete(Instruction * ToErase)160309467b48Spatrick static DeferredReplacement createDelete(Instruction *ToErase) {
160409467b48Spatrick DeferredReplacement D;
160509467b48Spatrick D.Old = ToErase;
160609467b48Spatrick return D;
160709467b48Spatrick }
160809467b48Spatrick
createDeoptimizeReplacement(Instruction * Old)160909467b48Spatrick static DeferredReplacement createDeoptimizeReplacement(Instruction *Old) {
161009467b48Spatrick #ifndef NDEBUG
161109467b48Spatrick auto *F = cast<CallInst>(Old)->getCalledFunction();
161209467b48Spatrick assert(F && F->getIntrinsicID() == Intrinsic::experimental_deoptimize &&
161309467b48Spatrick "Only way to construct a deoptimize deferred replacement");
161409467b48Spatrick #endif
161509467b48Spatrick DeferredReplacement D;
161609467b48Spatrick D.Old = Old;
161709467b48Spatrick D.IsDeoptimize = true;
161809467b48Spatrick return D;
161909467b48Spatrick }
162009467b48Spatrick
162109467b48Spatrick /// Does the task represented by this instance.
doReplacement()162209467b48Spatrick void doReplacement() {
162309467b48Spatrick Instruction *OldI = Old;
162409467b48Spatrick Instruction *NewI = New;
162509467b48Spatrick
162609467b48Spatrick assert(OldI != NewI && "Disallowed at construction?!");
162709467b48Spatrick assert((!IsDeoptimize || !New) &&
162809467b48Spatrick "Deoptimize intrinsics are not replaced!");
162909467b48Spatrick
163009467b48Spatrick Old = nullptr;
163109467b48Spatrick New = nullptr;
163209467b48Spatrick
163309467b48Spatrick if (NewI)
163409467b48Spatrick OldI->replaceAllUsesWith(NewI);
163509467b48Spatrick
163609467b48Spatrick if (IsDeoptimize) {
163709467b48Spatrick // Note: we've inserted instructions, so the call to llvm.deoptimize may
163809467b48Spatrick // not necessarily be followed by the matching return.
163909467b48Spatrick auto *RI = cast<ReturnInst>(OldI->getParent()->getTerminator());
164009467b48Spatrick new UnreachableInst(RI->getContext(), RI);
164109467b48Spatrick RI->eraseFromParent();
164209467b48Spatrick }
164309467b48Spatrick
164409467b48Spatrick OldI->eraseFromParent();
164509467b48Spatrick }
164609467b48Spatrick };
164709467b48Spatrick
164809467b48Spatrick } // end anonymous namespace
164909467b48Spatrick
getDeoptLowering(CallBase * Call)165009467b48Spatrick static StringRef getDeoptLowering(CallBase *Call) {
165109467b48Spatrick const char *DeoptLowering = "deopt-lowering";
165209467b48Spatrick if (Call->hasFnAttr(DeoptLowering)) {
165309467b48Spatrick // FIXME: Calls have a *really* confusing interface around attributes
165409467b48Spatrick // with values.
165509467b48Spatrick const AttributeList &CSAS = Call->getAttributes();
1656*d415bd75Srobert if (CSAS.hasFnAttr(DeoptLowering))
1657*d415bd75Srobert return CSAS.getFnAttr(DeoptLowering).getValueAsString();
165809467b48Spatrick Function *F = Call->getCalledFunction();
165909467b48Spatrick assert(F && F->hasFnAttribute(DeoptLowering));
166009467b48Spatrick return F->getFnAttribute(DeoptLowering).getValueAsString();
166109467b48Spatrick }
166209467b48Spatrick return "live-through";
166309467b48Spatrick }
166409467b48Spatrick
166509467b48Spatrick static void
makeStatepointExplicitImpl(CallBase * Call,const SmallVectorImpl<Value * > & BasePtrs,const SmallVectorImpl<Value * > & LiveVariables,PartiallyConstructedSafepointRecord & Result,std::vector<DeferredReplacement> & Replacements,const PointerToBaseTy & PointerToBase)166609467b48Spatrick makeStatepointExplicitImpl(CallBase *Call, /* to replace */
166709467b48Spatrick const SmallVectorImpl<Value *> &BasePtrs,
166809467b48Spatrick const SmallVectorImpl<Value *> &LiveVariables,
166909467b48Spatrick PartiallyConstructedSafepointRecord &Result,
1670*d415bd75Srobert std::vector<DeferredReplacement> &Replacements,
1671*d415bd75Srobert const PointerToBaseTy &PointerToBase) {
167209467b48Spatrick assert(BasePtrs.size() == LiveVariables.size());
167309467b48Spatrick
167409467b48Spatrick // Then go ahead and use the builder do actually do the inserts. We insert
167509467b48Spatrick // immediately before the previous instruction under the assumption that all
167609467b48Spatrick // arguments will be available here. We can't insert afterwards since we may
167709467b48Spatrick // be replacing a terminator.
167809467b48Spatrick IRBuilder<> Builder(Call);
167909467b48Spatrick
168009467b48Spatrick ArrayRef<Value *> GCArgs(LiveVariables);
168109467b48Spatrick uint64_t StatepointID = StatepointDirectives::DefaultStatepointID;
168209467b48Spatrick uint32_t NumPatchBytes = 0;
168309467b48Spatrick uint32_t Flags = uint32_t(StatepointFlags::None);
168409467b48Spatrick
168573471bf0Spatrick SmallVector<Value *, 8> CallArgs(Call->args());
1686*d415bd75Srobert std::optional<ArrayRef<Use>> DeoptArgs;
1687097a140dSpatrick if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deopt))
1688097a140dSpatrick DeoptArgs = Bundle->Inputs;
1689*d415bd75Srobert std::optional<ArrayRef<Use>> TransitionArgs;
1690097a140dSpatrick if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_gc_transition)) {
1691097a140dSpatrick TransitionArgs = Bundle->Inputs;
1692097a140dSpatrick // TODO: This flag no longer serves a purpose and can be removed later
169309467b48Spatrick Flags |= uint32_t(StatepointFlags::GCTransition);
169409467b48Spatrick }
169509467b48Spatrick
169609467b48Spatrick // Instead of lowering calls to @llvm.experimental.deoptimize as normal calls
169709467b48Spatrick // with a return value, we lower then as never returning calls to
169809467b48Spatrick // __llvm_deoptimize that are followed by unreachable to get better codegen.
169909467b48Spatrick bool IsDeoptimize = false;
170009467b48Spatrick
170109467b48Spatrick StatepointDirectives SD =
170209467b48Spatrick parseStatepointDirectivesFromAttrs(Call->getAttributes());
170309467b48Spatrick if (SD.NumPatchBytes)
170409467b48Spatrick NumPatchBytes = *SD.NumPatchBytes;
170509467b48Spatrick if (SD.StatepointID)
170609467b48Spatrick StatepointID = *SD.StatepointID;
170709467b48Spatrick
170809467b48Spatrick // Pass through the requested lowering if any. The default is live-through.
170909467b48Spatrick StringRef DeoptLowering = getDeoptLowering(Call);
171009467b48Spatrick if (DeoptLowering.equals("live-in"))
171109467b48Spatrick Flags |= uint32_t(StatepointFlags::DeoptLiveIn);
171209467b48Spatrick else {
171309467b48Spatrick assert(DeoptLowering.equals("live-through") && "Unsupported value!");
171409467b48Spatrick }
171509467b48Spatrick
1716*d415bd75Srobert FunctionCallee CallTarget(Call->getFunctionType(), Call->getCalledOperand());
1717*d415bd75Srobert if (Function *F = dyn_cast<Function>(CallTarget.getCallee())) {
171873471bf0Spatrick auto IID = F->getIntrinsicID();
171973471bf0Spatrick if (IID == Intrinsic::experimental_deoptimize) {
172009467b48Spatrick // Calls to llvm.experimental.deoptimize are lowered to calls to the
172109467b48Spatrick // __llvm_deoptimize symbol. We want to resolve this now, since the
172209467b48Spatrick // verifier does not allow taking the address of an intrinsic function.
172309467b48Spatrick
172409467b48Spatrick SmallVector<Type *, 8> DomainTy;
172509467b48Spatrick for (Value *Arg : CallArgs)
172609467b48Spatrick DomainTy.push_back(Arg->getType());
172709467b48Spatrick auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
172809467b48Spatrick /* isVarArg = */ false);
172909467b48Spatrick
173009467b48Spatrick // Note: CallTarget can be a bitcast instruction of a symbol if there are
173109467b48Spatrick // calls to @llvm.experimental.deoptimize with different argument types in
173209467b48Spatrick // the same module. This is fine -- we assume the frontend knew what it
173309467b48Spatrick // was doing when generating this kind of IR.
173409467b48Spatrick CallTarget = F->getParent()
1735*d415bd75Srobert ->getOrInsertFunction("__llvm_deoptimize", FTy);
173609467b48Spatrick
173709467b48Spatrick IsDeoptimize = true;
173873471bf0Spatrick } else if (IID == Intrinsic::memcpy_element_unordered_atomic ||
173973471bf0Spatrick IID == Intrinsic::memmove_element_unordered_atomic) {
174073471bf0Spatrick // Unordered atomic memcpy and memmove intrinsics which are not explicitly
174173471bf0Spatrick // marked as "gc-leaf-function" should be lowered in a GC parseable way.
174273471bf0Spatrick // Specifically, these calls should be lowered to the
174373471bf0Spatrick // __llvm_{memcpy|memmove}_element_unordered_atomic_safepoint symbols.
174473471bf0Spatrick // Similarly to __llvm_deoptimize we want to resolve this now, since the
174573471bf0Spatrick // verifier does not allow taking the address of an intrinsic function.
174673471bf0Spatrick //
174773471bf0Spatrick // Moreover we need to shuffle the arguments for the call in order to
174873471bf0Spatrick // accommodate GC. The underlying source and destination objects might be
174973471bf0Spatrick // relocated during copy operation should the GC occur. To relocate the
175073471bf0Spatrick // derived source and destination pointers the implementation of the
175173471bf0Spatrick // intrinsic should know the corresponding base pointers.
175273471bf0Spatrick //
175373471bf0Spatrick // To make the base pointers available pass them explicitly as arguments:
175473471bf0Spatrick // memcpy(dest_derived, source_derived, ...) =>
175573471bf0Spatrick // memcpy(dest_base, dest_offset, source_base, source_offset, ...)
175673471bf0Spatrick auto &Context = Call->getContext();
175773471bf0Spatrick auto &DL = Call->getModule()->getDataLayout();
175873471bf0Spatrick auto GetBaseAndOffset = [&](Value *Derived) {
1759*d415bd75Srobert Value *Base = nullptr;
1760*d415bd75Srobert // Optimizations in unreachable code might substitute the real pointer
1761*d415bd75Srobert // with undef, poison or null-derived constant. Return null base for
1762*d415bd75Srobert // them to be consistent with the handling in the main algorithm in
1763*d415bd75Srobert // findBaseDefiningValue.
1764*d415bd75Srobert if (isa<Constant>(Derived))
1765*d415bd75Srobert Base =
1766*d415bd75Srobert ConstantPointerNull::get(cast<PointerType>(Derived->getType()));
1767*d415bd75Srobert else {
1768*d415bd75Srobert assert(PointerToBase.count(Derived));
1769*d415bd75Srobert Base = PointerToBase.find(Derived)->second;
1770*d415bd75Srobert }
177173471bf0Spatrick unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
177273471bf0Spatrick unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
177373471bf0Spatrick Value *Base_int = Builder.CreatePtrToInt(
177473471bf0Spatrick Base, Type::getIntNTy(Context, IntPtrSize));
177573471bf0Spatrick Value *Derived_int = Builder.CreatePtrToInt(
177673471bf0Spatrick Derived, Type::getIntNTy(Context, IntPtrSize));
177773471bf0Spatrick return std::make_pair(Base, Builder.CreateSub(Derived_int, Base_int));
177873471bf0Spatrick };
177973471bf0Spatrick
178073471bf0Spatrick auto *Dest = CallArgs[0];
178173471bf0Spatrick Value *DestBase, *DestOffset;
178273471bf0Spatrick std::tie(DestBase, DestOffset) = GetBaseAndOffset(Dest);
178373471bf0Spatrick
178473471bf0Spatrick auto *Source = CallArgs[1];
178573471bf0Spatrick Value *SourceBase, *SourceOffset;
178673471bf0Spatrick std::tie(SourceBase, SourceOffset) = GetBaseAndOffset(Source);
178773471bf0Spatrick
178873471bf0Spatrick auto *LengthInBytes = CallArgs[2];
178973471bf0Spatrick auto *ElementSizeCI = cast<ConstantInt>(CallArgs[3]);
179073471bf0Spatrick
179173471bf0Spatrick CallArgs.clear();
179273471bf0Spatrick CallArgs.push_back(DestBase);
179373471bf0Spatrick CallArgs.push_back(DestOffset);
179473471bf0Spatrick CallArgs.push_back(SourceBase);
179573471bf0Spatrick CallArgs.push_back(SourceOffset);
179673471bf0Spatrick CallArgs.push_back(LengthInBytes);
179773471bf0Spatrick
179873471bf0Spatrick SmallVector<Type *, 8> DomainTy;
179973471bf0Spatrick for (Value *Arg : CallArgs)
180073471bf0Spatrick DomainTy.push_back(Arg->getType());
180173471bf0Spatrick auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
180273471bf0Spatrick /* isVarArg = */ false);
180373471bf0Spatrick
180473471bf0Spatrick auto GetFunctionName = [](Intrinsic::ID IID, ConstantInt *ElementSizeCI) {
180573471bf0Spatrick uint64_t ElementSize = ElementSizeCI->getZExtValue();
180673471bf0Spatrick if (IID == Intrinsic::memcpy_element_unordered_atomic) {
180773471bf0Spatrick switch (ElementSize) {
180873471bf0Spatrick case 1:
180973471bf0Spatrick return "__llvm_memcpy_element_unordered_atomic_safepoint_1";
181073471bf0Spatrick case 2:
181173471bf0Spatrick return "__llvm_memcpy_element_unordered_atomic_safepoint_2";
181273471bf0Spatrick case 4:
181373471bf0Spatrick return "__llvm_memcpy_element_unordered_atomic_safepoint_4";
181473471bf0Spatrick case 8:
181573471bf0Spatrick return "__llvm_memcpy_element_unordered_atomic_safepoint_8";
181673471bf0Spatrick case 16:
181773471bf0Spatrick return "__llvm_memcpy_element_unordered_atomic_safepoint_16";
181873471bf0Spatrick default:
181973471bf0Spatrick llvm_unreachable("unexpected element size!");
182073471bf0Spatrick }
182173471bf0Spatrick }
182273471bf0Spatrick assert(IID == Intrinsic::memmove_element_unordered_atomic);
182373471bf0Spatrick switch (ElementSize) {
182473471bf0Spatrick case 1:
182573471bf0Spatrick return "__llvm_memmove_element_unordered_atomic_safepoint_1";
182673471bf0Spatrick case 2:
182773471bf0Spatrick return "__llvm_memmove_element_unordered_atomic_safepoint_2";
182873471bf0Spatrick case 4:
182973471bf0Spatrick return "__llvm_memmove_element_unordered_atomic_safepoint_4";
183073471bf0Spatrick case 8:
183173471bf0Spatrick return "__llvm_memmove_element_unordered_atomic_safepoint_8";
183273471bf0Spatrick case 16:
183373471bf0Spatrick return "__llvm_memmove_element_unordered_atomic_safepoint_16";
183473471bf0Spatrick default:
183573471bf0Spatrick llvm_unreachable("unexpected element size!");
183673471bf0Spatrick }
183773471bf0Spatrick };
183873471bf0Spatrick
183973471bf0Spatrick CallTarget =
184073471bf0Spatrick F->getParent()
1841*d415bd75Srobert ->getOrInsertFunction(GetFunctionName(IID, ElementSizeCI), FTy);
184209467b48Spatrick }
184309467b48Spatrick }
184409467b48Spatrick
184509467b48Spatrick // Create the statepoint given all the arguments
1846097a140dSpatrick GCStatepointInst *Token = nullptr;
184709467b48Spatrick if (auto *CI = dyn_cast<CallInst>(Call)) {
184809467b48Spatrick CallInst *SPCall = Builder.CreateGCStatepointCall(
184909467b48Spatrick StatepointID, NumPatchBytes, CallTarget, Flags, CallArgs,
185009467b48Spatrick TransitionArgs, DeoptArgs, GCArgs, "safepoint_token");
185109467b48Spatrick
185209467b48Spatrick SPCall->setTailCallKind(CI->getTailCallKind());
185309467b48Spatrick SPCall->setCallingConv(CI->getCallingConv());
185409467b48Spatrick
185509467b48Spatrick // Currently we will fail on parameter attributes and on certain
185609467b48Spatrick // function attributes. In case if we can handle this set of attributes -
185709467b48Spatrick // set up function attrs directly on statepoint and return attrs later for
185809467b48Spatrick // gc_result intrinsic.
1859*d415bd75Srobert SPCall->setAttributes(legalizeCallAttributes(
1860*d415bd75Srobert CI->getContext(), CI->getAttributes(), SPCall->getAttributes()));
186109467b48Spatrick
1862097a140dSpatrick Token = cast<GCStatepointInst>(SPCall);
186309467b48Spatrick
186409467b48Spatrick // Put the following gc_result and gc_relocate calls immediately after the
186509467b48Spatrick // the old call (which we're about to delete)
186609467b48Spatrick assert(CI->getNextNode() && "Not a terminator, must have next!");
186709467b48Spatrick Builder.SetInsertPoint(CI->getNextNode());
186809467b48Spatrick Builder.SetCurrentDebugLocation(CI->getNextNode()->getDebugLoc());
186909467b48Spatrick } else {
187009467b48Spatrick auto *II = cast<InvokeInst>(Call);
187109467b48Spatrick
187209467b48Spatrick // Insert the new invoke into the old block. We'll remove the old one in a
187309467b48Spatrick // moment at which point this will become the new terminator for the
187409467b48Spatrick // original block.
187509467b48Spatrick InvokeInst *SPInvoke = Builder.CreateGCStatepointInvoke(
187609467b48Spatrick StatepointID, NumPatchBytes, CallTarget, II->getNormalDest(),
187709467b48Spatrick II->getUnwindDest(), Flags, CallArgs, TransitionArgs, DeoptArgs, GCArgs,
187809467b48Spatrick "statepoint_token");
187909467b48Spatrick
188009467b48Spatrick SPInvoke->setCallingConv(II->getCallingConv());
188109467b48Spatrick
188209467b48Spatrick // Currently we will fail on parameter attributes and on certain
188309467b48Spatrick // function attributes. In case if we can handle this set of attributes -
188409467b48Spatrick // set up function attrs directly on statepoint and return attrs later for
188509467b48Spatrick // gc_result intrinsic.
1886*d415bd75Srobert SPInvoke->setAttributes(legalizeCallAttributes(
1887*d415bd75Srobert II->getContext(), II->getAttributes(), SPInvoke->getAttributes()));
188809467b48Spatrick
1889097a140dSpatrick Token = cast<GCStatepointInst>(SPInvoke);
189009467b48Spatrick
189109467b48Spatrick // Generate gc relocates in exceptional path
189209467b48Spatrick BasicBlock *UnwindBlock = II->getUnwindDest();
189309467b48Spatrick assert(!isa<PHINode>(UnwindBlock->begin()) &&
189409467b48Spatrick UnwindBlock->getUniquePredecessor() &&
189509467b48Spatrick "can't safely insert in this block!");
189609467b48Spatrick
189709467b48Spatrick Builder.SetInsertPoint(&*UnwindBlock->getFirstInsertionPt());
189809467b48Spatrick Builder.SetCurrentDebugLocation(II->getDebugLoc());
189909467b48Spatrick
190009467b48Spatrick // Attach exceptional gc relocates to the landingpad.
190109467b48Spatrick Instruction *ExceptionalToken = UnwindBlock->getLandingPadInst();
190209467b48Spatrick Result.UnwindToken = ExceptionalToken;
190309467b48Spatrick
1904097a140dSpatrick CreateGCRelocates(LiveVariables, BasePtrs, ExceptionalToken, Builder);
190509467b48Spatrick
190609467b48Spatrick // Generate gc relocates and returns for normal block
190709467b48Spatrick BasicBlock *NormalDest = II->getNormalDest();
190809467b48Spatrick assert(!isa<PHINode>(NormalDest->begin()) &&
190909467b48Spatrick NormalDest->getUniquePredecessor() &&
191009467b48Spatrick "can't safely insert in this block!");
191109467b48Spatrick
191209467b48Spatrick Builder.SetInsertPoint(&*NormalDest->getFirstInsertionPt());
191309467b48Spatrick
191409467b48Spatrick // gc relocates will be generated later as if it were regular call
191509467b48Spatrick // statepoint
191609467b48Spatrick }
191709467b48Spatrick assert(Token && "Should be set in one of the above branches!");
191809467b48Spatrick
191909467b48Spatrick if (IsDeoptimize) {
192009467b48Spatrick // If we're wrapping an @llvm.experimental.deoptimize in a statepoint, we
192109467b48Spatrick // transform the tail-call like structure to a call to a void function
192209467b48Spatrick // followed by unreachable to get better codegen.
192309467b48Spatrick Replacements.push_back(
192409467b48Spatrick DeferredReplacement::createDeoptimizeReplacement(Call));
192509467b48Spatrick } else {
192609467b48Spatrick Token->setName("statepoint_token");
192709467b48Spatrick if (!Call->getType()->isVoidTy() && !Call->use_empty()) {
192809467b48Spatrick StringRef Name = Call->hasName() ? Call->getName() : "";
192909467b48Spatrick CallInst *GCResult = Builder.CreateGCResult(Token, Call->getType(), Name);
193009467b48Spatrick GCResult->setAttributes(
193109467b48Spatrick AttributeList::get(GCResult->getContext(), AttributeList::ReturnIndex,
1932*d415bd75Srobert Call->getAttributes().getRetAttrs()));
193309467b48Spatrick
193409467b48Spatrick // We cannot RAUW or delete CS.getInstruction() because it could be in the
193509467b48Spatrick // live set of some other safepoint, in which case that safepoint's
193609467b48Spatrick // PartiallyConstructedSafepointRecord will hold a raw pointer to this
193709467b48Spatrick // llvm::Instruction. Instead, we defer the replacement and deletion to
193809467b48Spatrick // after the live sets have been made explicit in the IR, and we no longer
193909467b48Spatrick // have raw pointers to worry about.
194009467b48Spatrick Replacements.emplace_back(
194109467b48Spatrick DeferredReplacement::createRAUW(Call, GCResult));
194209467b48Spatrick } else {
194309467b48Spatrick Replacements.emplace_back(DeferredReplacement::createDelete(Call));
194409467b48Spatrick }
194509467b48Spatrick }
194609467b48Spatrick
194709467b48Spatrick Result.StatepointToken = Token;
194809467b48Spatrick
194909467b48Spatrick // Second, create a gc.relocate for every live variable
1950097a140dSpatrick CreateGCRelocates(LiveVariables, BasePtrs, Token, Builder);
195109467b48Spatrick }
195209467b48Spatrick
195309467b48Spatrick // Replace an existing gc.statepoint with a new one and a set of gc.relocates
195409467b48Spatrick // which make the relocations happening at this safepoint explicit.
195509467b48Spatrick //
195609467b48Spatrick // WARNING: Does not do any fixup to adjust users of the original live
195709467b48Spatrick // values. That's the callers responsibility.
195809467b48Spatrick static void
makeStatepointExplicit(DominatorTree & DT,CallBase * Call,PartiallyConstructedSafepointRecord & Result,std::vector<DeferredReplacement> & Replacements,const PointerToBaseTy & PointerToBase)195909467b48Spatrick makeStatepointExplicit(DominatorTree &DT, CallBase *Call,
196009467b48Spatrick PartiallyConstructedSafepointRecord &Result,
1961*d415bd75Srobert std::vector<DeferredReplacement> &Replacements,
1962*d415bd75Srobert const PointerToBaseTy &PointerToBase) {
196309467b48Spatrick const auto &LiveSet = Result.LiveSet;
196409467b48Spatrick
196509467b48Spatrick // Convert to vector for efficient cross referencing.
196609467b48Spatrick SmallVector<Value *, 64> BaseVec, LiveVec;
196709467b48Spatrick LiveVec.reserve(LiveSet.size());
196809467b48Spatrick BaseVec.reserve(LiveSet.size());
196909467b48Spatrick for (Value *L : LiveSet) {
197009467b48Spatrick LiveVec.push_back(L);
197109467b48Spatrick assert(PointerToBase.count(L));
197209467b48Spatrick Value *Base = PointerToBase.find(L)->second;
197309467b48Spatrick BaseVec.push_back(Base);
197409467b48Spatrick }
197509467b48Spatrick assert(LiveVec.size() == BaseVec.size());
197609467b48Spatrick
197709467b48Spatrick // Do the actual rewriting and delete the old statepoint
1978*d415bd75Srobert makeStatepointExplicitImpl(Call, BaseVec, LiveVec, Result, Replacements,
1979*d415bd75Srobert PointerToBase);
198009467b48Spatrick }
198109467b48Spatrick
198209467b48Spatrick // Helper function for the relocationViaAlloca.
198309467b48Spatrick //
198409467b48Spatrick // It receives iterator to the statepoint gc relocates and emits a store to the
198509467b48Spatrick // assigned location (via allocaMap) for the each one of them. It adds the
198609467b48Spatrick // visited values into the visitedLiveValues set, which we will later use them
1987*d415bd75Srobert // for validation checking.
198809467b48Spatrick static void
insertRelocationStores(iterator_range<Value::user_iterator> GCRelocs,DenseMap<Value *,AllocaInst * > & AllocaMap,DenseSet<Value * > & VisitedLiveValues)198909467b48Spatrick insertRelocationStores(iterator_range<Value::user_iterator> GCRelocs,
199009467b48Spatrick DenseMap<Value *, AllocaInst *> &AllocaMap,
199109467b48Spatrick DenseSet<Value *> &VisitedLiveValues) {
199209467b48Spatrick for (User *U : GCRelocs) {
199309467b48Spatrick GCRelocateInst *Relocate = dyn_cast<GCRelocateInst>(U);
199409467b48Spatrick if (!Relocate)
199509467b48Spatrick continue;
199609467b48Spatrick
199709467b48Spatrick Value *OriginalValue = Relocate->getDerivedPtr();
199809467b48Spatrick assert(AllocaMap.count(OriginalValue));
199909467b48Spatrick Value *Alloca = AllocaMap[OriginalValue];
200009467b48Spatrick
200109467b48Spatrick // Emit store into the related alloca
200209467b48Spatrick // All gc_relocates are i8 addrspace(1)* typed, and it must be bitcasted to
200309467b48Spatrick // the correct type according to alloca.
200409467b48Spatrick assert(Relocate->getNextNode() &&
200509467b48Spatrick "Should always have one since it's not a terminator");
200609467b48Spatrick IRBuilder<> Builder(Relocate->getNextNode());
200709467b48Spatrick Value *CastedRelocatedValue =
200809467b48Spatrick Builder.CreateBitCast(Relocate,
200909467b48Spatrick cast<AllocaInst>(Alloca)->getAllocatedType(),
201009467b48Spatrick suffixed_name_or(Relocate, ".casted", ""));
201109467b48Spatrick
2012097a140dSpatrick new StoreInst(CastedRelocatedValue, Alloca,
2013097a140dSpatrick cast<Instruction>(CastedRelocatedValue)->getNextNode());
201409467b48Spatrick
201509467b48Spatrick #ifndef NDEBUG
201609467b48Spatrick VisitedLiveValues.insert(OriginalValue);
201709467b48Spatrick #endif
201809467b48Spatrick }
201909467b48Spatrick }
202009467b48Spatrick
202109467b48Spatrick // Helper function for the "relocationViaAlloca". Similar to the
202209467b48Spatrick // "insertRelocationStores" but works for rematerialized values.
insertRematerializationStores(const RematerializedValueMapTy & RematerializedValues,DenseMap<Value *,AllocaInst * > & AllocaMap,DenseSet<Value * > & VisitedLiveValues)202309467b48Spatrick static void insertRematerializationStores(
202409467b48Spatrick const RematerializedValueMapTy &RematerializedValues,
202509467b48Spatrick DenseMap<Value *, AllocaInst *> &AllocaMap,
202609467b48Spatrick DenseSet<Value *> &VisitedLiveValues) {
202709467b48Spatrick for (auto RematerializedValuePair: RematerializedValues) {
202809467b48Spatrick Instruction *RematerializedValue = RematerializedValuePair.first;
202909467b48Spatrick Value *OriginalValue = RematerializedValuePair.second;
203009467b48Spatrick
203109467b48Spatrick assert(AllocaMap.count(OriginalValue) &&
203209467b48Spatrick "Can not find alloca for rematerialized value");
203309467b48Spatrick Value *Alloca = AllocaMap[OriginalValue];
203409467b48Spatrick
2035097a140dSpatrick new StoreInst(RematerializedValue, Alloca,
2036097a140dSpatrick RematerializedValue->getNextNode());
203709467b48Spatrick
203809467b48Spatrick #ifndef NDEBUG
203909467b48Spatrick VisitedLiveValues.insert(OriginalValue);
204009467b48Spatrick #endif
204109467b48Spatrick }
204209467b48Spatrick }
204309467b48Spatrick
204409467b48Spatrick /// Do all the relocation update via allocas and mem2reg
relocationViaAlloca(Function & F,DominatorTree & DT,ArrayRef<Value * > Live,ArrayRef<PartiallyConstructedSafepointRecord> Records)204509467b48Spatrick static void relocationViaAlloca(
204609467b48Spatrick Function &F, DominatorTree &DT, ArrayRef<Value *> Live,
204709467b48Spatrick ArrayRef<PartiallyConstructedSafepointRecord> Records) {
204809467b48Spatrick #ifndef NDEBUG
204909467b48Spatrick // record initial number of (static) allocas; we'll check we have the same
205009467b48Spatrick // number when we get done.
205109467b48Spatrick int InitialAllocaNum = 0;
205209467b48Spatrick for (Instruction &I : F.getEntryBlock())
205309467b48Spatrick if (isa<AllocaInst>(I))
205409467b48Spatrick InitialAllocaNum++;
205509467b48Spatrick #endif
205609467b48Spatrick
205709467b48Spatrick // TODO-PERF: change data structures, reserve
205809467b48Spatrick DenseMap<Value *, AllocaInst *> AllocaMap;
205909467b48Spatrick SmallVector<AllocaInst *, 200> PromotableAllocas;
206009467b48Spatrick // Used later to chack that we have enough allocas to store all values
206109467b48Spatrick std::size_t NumRematerializedValues = 0;
206209467b48Spatrick PromotableAllocas.reserve(Live.size());
206309467b48Spatrick
206409467b48Spatrick // Emit alloca for "LiveValue" and record it in "allocaMap" and
206509467b48Spatrick // "PromotableAllocas"
206609467b48Spatrick const DataLayout &DL = F.getParent()->getDataLayout();
206709467b48Spatrick auto emitAllocaFor = [&](Value *LiveValue) {
206809467b48Spatrick AllocaInst *Alloca = new AllocaInst(LiveValue->getType(),
206909467b48Spatrick DL.getAllocaAddrSpace(), "",
207009467b48Spatrick F.getEntryBlock().getFirstNonPHI());
207109467b48Spatrick AllocaMap[LiveValue] = Alloca;
207209467b48Spatrick PromotableAllocas.push_back(Alloca);
207309467b48Spatrick };
207409467b48Spatrick
207509467b48Spatrick // Emit alloca for each live gc pointer
207609467b48Spatrick for (Value *V : Live)
207709467b48Spatrick emitAllocaFor(V);
207809467b48Spatrick
207909467b48Spatrick // Emit allocas for rematerialized values
208009467b48Spatrick for (const auto &Info : Records)
208109467b48Spatrick for (auto RematerializedValuePair : Info.RematerializedValues) {
208209467b48Spatrick Value *OriginalValue = RematerializedValuePair.second;
208309467b48Spatrick if (AllocaMap.count(OriginalValue) != 0)
208409467b48Spatrick continue;
208509467b48Spatrick
208609467b48Spatrick emitAllocaFor(OriginalValue);
208709467b48Spatrick ++NumRematerializedValues;
208809467b48Spatrick }
208909467b48Spatrick
209009467b48Spatrick // The next two loops are part of the same conceptual operation. We need to
209109467b48Spatrick // insert a store to the alloca after the original def and at each
209209467b48Spatrick // redefinition. We need to insert a load before each use. These are split
209309467b48Spatrick // into distinct loops for performance reasons.
209409467b48Spatrick
209509467b48Spatrick // Update gc pointer after each statepoint: either store a relocated value or
209609467b48Spatrick // null (if no relocated value was found for this gc pointer and it is not a
209709467b48Spatrick // gc_result). This must happen before we update the statepoint with load of
209809467b48Spatrick // alloca otherwise we lose the link between statepoint and old def.
209909467b48Spatrick for (const auto &Info : Records) {
210009467b48Spatrick Value *Statepoint = Info.StatepointToken;
210109467b48Spatrick
210209467b48Spatrick // This will be used for consistency check
210309467b48Spatrick DenseSet<Value *> VisitedLiveValues;
210409467b48Spatrick
210509467b48Spatrick // Insert stores for normal statepoint gc relocates
210609467b48Spatrick insertRelocationStores(Statepoint->users(), AllocaMap, VisitedLiveValues);
210709467b48Spatrick
210809467b48Spatrick // In case if it was invoke statepoint
210909467b48Spatrick // we will insert stores for exceptional path gc relocates.
211009467b48Spatrick if (isa<InvokeInst>(Statepoint)) {
211109467b48Spatrick insertRelocationStores(Info.UnwindToken->users(), AllocaMap,
211209467b48Spatrick VisitedLiveValues);
211309467b48Spatrick }
211409467b48Spatrick
211509467b48Spatrick // Do similar thing with rematerialized values
211609467b48Spatrick insertRematerializationStores(Info.RematerializedValues, AllocaMap,
211709467b48Spatrick VisitedLiveValues);
211809467b48Spatrick
211909467b48Spatrick if (ClobberNonLive) {
212009467b48Spatrick // As a debugging aid, pretend that an unrelocated pointer becomes null at
212109467b48Spatrick // the gc.statepoint. This will turn some subtle GC problems into
212209467b48Spatrick // slightly easier to debug SEGVs. Note that on large IR files with
212309467b48Spatrick // lots of gc.statepoints this is extremely costly both memory and time
212409467b48Spatrick // wise.
212509467b48Spatrick SmallVector<AllocaInst *, 64> ToClobber;
212609467b48Spatrick for (auto Pair : AllocaMap) {
212709467b48Spatrick Value *Def = Pair.first;
212809467b48Spatrick AllocaInst *Alloca = Pair.second;
212909467b48Spatrick
213009467b48Spatrick // This value was relocated
213109467b48Spatrick if (VisitedLiveValues.count(Def)) {
213209467b48Spatrick continue;
213309467b48Spatrick }
213409467b48Spatrick ToClobber.push_back(Alloca);
213509467b48Spatrick }
213609467b48Spatrick
213709467b48Spatrick auto InsertClobbersAt = [&](Instruction *IP) {
213809467b48Spatrick for (auto *AI : ToClobber) {
2139*d415bd75Srobert auto AT = AI->getAllocatedType();
2140*d415bd75Srobert Constant *CPN;
2141*d415bd75Srobert if (AT->isVectorTy())
2142*d415bd75Srobert CPN = ConstantAggregateZero::get(AT);
2143*d415bd75Srobert else
2144*d415bd75Srobert CPN = ConstantPointerNull::get(cast<PointerType>(AT));
2145097a140dSpatrick new StoreInst(CPN, AI, IP);
214609467b48Spatrick }
214709467b48Spatrick };
214809467b48Spatrick
214909467b48Spatrick // Insert the clobbering stores. These may get intermixed with the
215009467b48Spatrick // gc.results and gc.relocates, but that's fine.
215109467b48Spatrick if (auto II = dyn_cast<InvokeInst>(Statepoint)) {
215209467b48Spatrick InsertClobbersAt(&*II->getNormalDest()->getFirstInsertionPt());
215309467b48Spatrick InsertClobbersAt(&*II->getUnwindDest()->getFirstInsertionPt());
215409467b48Spatrick } else {
215509467b48Spatrick InsertClobbersAt(cast<Instruction>(Statepoint)->getNextNode());
215609467b48Spatrick }
215709467b48Spatrick }
215809467b48Spatrick }
215909467b48Spatrick
216009467b48Spatrick // Update use with load allocas and add store for gc_relocated.
216109467b48Spatrick for (auto Pair : AllocaMap) {
216209467b48Spatrick Value *Def = Pair.first;
216309467b48Spatrick AllocaInst *Alloca = Pair.second;
216409467b48Spatrick
216509467b48Spatrick // We pre-record the uses of allocas so that we dont have to worry about
216609467b48Spatrick // later update that changes the user information..
216709467b48Spatrick
216809467b48Spatrick SmallVector<Instruction *, 20> Uses;
216909467b48Spatrick // PERF: trade a linear scan for repeated reallocation
217009467b48Spatrick Uses.reserve(Def->getNumUses());
217109467b48Spatrick for (User *U : Def->users()) {
217209467b48Spatrick if (!isa<ConstantExpr>(U)) {
217309467b48Spatrick // If the def has a ConstantExpr use, then the def is either a
217409467b48Spatrick // ConstantExpr use itself or null. In either case
217509467b48Spatrick // (recursively in the first, directly in the second), the oop
217609467b48Spatrick // it is ultimately dependent on is null and this particular
217709467b48Spatrick // use does not need to be fixed up.
217809467b48Spatrick Uses.push_back(cast<Instruction>(U));
217909467b48Spatrick }
218009467b48Spatrick }
218109467b48Spatrick
218209467b48Spatrick llvm::sort(Uses);
218309467b48Spatrick auto Last = std::unique(Uses.begin(), Uses.end());
218409467b48Spatrick Uses.erase(Last, Uses.end());
218509467b48Spatrick
218609467b48Spatrick for (Instruction *Use : Uses) {
218709467b48Spatrick if (isa<PHINode>(Use)) {
218809467b48Spatrick PHINode *Phi = cast<PHINode>(Use);
218909467b48Spatrick for (unsigned i = 0; i < Phi->getNumIncomingValues(); i++) {
219009467b48Spatrick if (Def == Phi->getIncomingValue(i)) {
219109467b48Spatrick LoadInst *Load =
219209467b48Spatrick new LoadInst(Alloca->getAllocatedType(), Alloca, "",
219309467b48Spatrick Phi->getIncomingBlock(i)->getTerminator());
219409467b48Spatrick Phi->setIncomingValue(i, Load);
219509467b48Spatrick }
219609467b48Spatrick }
219709467b48Spatrick } else {
219809467b48Spatrick LoadInst *Load =
219909467b48Spatrick new LoadInst(Alloca->getAllocatedType(), Alloca, "", Use);
220009467b48Spatrick Use->replaceUsesOfWith(Def, Load);
220109467b48Spatrick }
220209467b48Spatrick }
220309467b48Spatrick
220409467b48Spatrick // Emit store for the initial gc value. Store must be inserted after load,
220509467b48Spatrick // otherwise store will be in alloca's use list and an extra load will be
220609467b48Spatrick // inserted before it.
2207097a140dSpatrick StoreInst *Store = new StoreInst(Def, Alloca, /*volatile*/ false,
2208097a140dSpatrick DL.getABITypeAlign(Def->getType()));
220909467b48Spatrick if (Instruction *Inst = dyn_cast<Instruction>(Def)) {
221009467b48Spatrick if (InvokeInst *Invoke = dyn_cast<InvokeInst>(Inst)) {
221109467b48Spatrick // InvokeInst is a terminator so the store need to be inserted into its
221209467b48Spatrick // normal destination block.
221309467b48Spatrick BasicBlock *NormalDest = Invoke->getNormalDest();
221409467b48Spatrick Store->insertBefore(NormalDest->getFirstNonPHI());
221509467b48Spatrick } else {
221609467b48Spatrick assert(!Inst->isTerminator() &&
221709467b48Spatrick "The only terminator that can produce a value is "
221809467b48Spatrick "InvokeInst which is handled above.");
221909467b48Spatrick Store->insertAfter(Inst);
222009467b48Spatrick }
222109467b48Spatrick } else {
222209467b48Spatrick assert(isa<Argument>(Def));
222309467b48Spatrick Store->insertAfter(cast<Instruction>(Alloca));
222409467b48Spatrick }
222509467b48Spatrick }
222609467b48Spatrick
222709467b48Spatrick assert(PromotableAllocas.size() == Live.size() + NumRematerializedValues &&
222809467b48Spatrick "we must have the same allocas with lives");
2229*d415bd75Srobert (void) NumRematerializedValues;
223009467b48Spatrick if (!PromotableAllocas.empty()) {
223109467b48Spatrick // Apply mem2reg to promote alloca to SSA
223209467b48Spatrick PromoteMemToReg(PromotableAllocas, DT);
223309467b48Spatrick }
223409467b48Spatrick
223509467b48Spatrick #ifndef NDEBUG
223609467b48Spatrick for (auto &I : F.getEntryBlock())
223709467b48Spatrick if (isa<AllocaInst>(I))
223809467b48Spatrick InitialAllocaNum--;
223909467b48Spatrick assert(InitialAllocaNum == 0 && "We must not introduce any extra allocas");
224009467b48Spatrick #endif
224109467b48Spatrick }
224209467b48Spatrick
224309467b48Spatrick /// Implement a unique function which doesn't require we sort the input
224409467b48Spatrick /// vector. Doing so has the effect of changing the output of a couple of
224509467b48Spatrick /// tests in ways which make them less useful in testing fused safepoints.
unique_unsorted(SmallVectorImpl<T> & Vec)224609467b48Spatrick template <typename T> static void unique_unsorted(SmallVectorImpl<T> &Vec) {
224709467b48Spatrick SmallSet<T, 8> Seen;
224873471bf0Spatrick erase_if(Vec, [&](const T &V) { return !Seen.insert(V).second; });
224909467b48Spatrick }
225009467b48Spatrick
225109467b48Spatrick /// Insert holders so that each Value is obviously live through the entire
225209467b48Spatrick /// lifetime of the call.
insertUseHolderAfter(CallBase * Call,const ArrayRef<Value * > Values,SmallVectorImpl<CallInst * > & Holders)225309467b48Spatrick static void insertUseHolderAfter(CallBase *Call, const ArrayRef<Value *> Values,
225409467b48Spatrick SmallVectorImpl<CallInst *> &Holders) {
225509467b48Spatrick if (Values.empty())
225609467b48Spatrick // No values to hold live, might as well not insert the empty holder
225709467b48Spatrick return;
225809467b48Spatrick
225909467b48Spatrick Module *M = Call->getModule();
226009467b48Spatrick // Use a dummy vararg function to actually hold the values live
226109467b48Spatrick FunctionCallee Func = M->getOrInsertFunction(
226209467b48Spatrick "__tmp_use", FunctionType::get(Type::getVoidTy(M->getContext()), true));
226309467b48Spatrick if (isa<CallInst>(Call)) {
226409467b48Spatrick // For call safepoints insert dummy calls right after safepoint
226509467b48Spatrick Holders.push_back(
226609467b48Spatrick CallInst::Create(Func, Values, "", &*++Call->getIterator()));
226709467b48Spatrick return;
226809467b48Spatrick }
226909467b48Spatrick // For invoke safepooints insert dummy calls both in normal and
227009467b48Spatrick // exceptional destination blocks
227109467b48Spatrick auto *II = cast<InvokeInst>(Call);
227209467b48Spatrick Holders.push_back(CallInst::Create(
227309467b48Spatrick Func, Values, "", &*II->getNormalDest()->getFirstInsertionPt()));
227409467b48Spatrick Holders.push_back(CallInst::Create(
227509467b48Spatrick Func, Values, "", &*II->getUnwindDest()->getFirstInsertionPt()));
227609467b48Spatrick }
227709467b48Spatrick
findLiveReferences(Function & F,DominatorTree & DT,ArrayRef<CallBase * > toUpdate,MutableArrayRef<struct PartiallyConstructedSafepointRecord> records)227809467b48Spatrick static void findLiveReferences(
227909467b48Spatrick Function &F, DominatorTree &DT, ArrayRef<CallBase *> toUpdate,
228009467b48Spatrick MutableArrayRef<struct PartiallyConstructedSafepointRecord> records) {
228109467b48Spatrick GCPtrLivenessData OriginalLivenessData;
228209467b48Spatrick computeLiveInValues(DT, F, OriginalLivenessData);
228309467b48Spatrick for (size_t i = 0; i < records.size(); i++) {
228409467b48Spatrick struct PartiallyConstructedSafepointRecord &info = records[i];
228509467b48Spatrick analyzeParsePointLiveness(DT, OriginalLivenessData, toUpdate[i], info);
228609467b48Spatrick }
228709467b48Spatrick }
228809467b48Spatrick
228909467b48Spatrick // Helper function for the "rematerializeLiveValues". It walks use chain
229009467b48Spatrick // starting from the "CurrentValue" until it reaches the root of the chain, i.e.
229109467b48Spatrick // the base or a value it cannot process. Only "simple" values are processed
229209467b48Spatrick // (currently it is GEP's and casts). The returned root is examined by the
229309467b48Spatrick // callers of findRematerializableChainToBasePointer. Fills "ChainToBase" array
229409467b48Spatrick // with all visited values.
findRematerializableChainToBasePointer(SmallVectorImpl<Instruction * > & ChainToBase,Value * CurrentValue)229509467b48Spatrick static Value* findRematerializableChainToBasePointer(
229609467b48Spatrick SmallVectorImpl<Instruction*> &ChainToBase,
229709467b48Spatrick Value *CurrentValue) {
229809467b48Spatrick if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurrentValue)) {
229909467b48Spatrick ChainToBase.push_back(GEP);
230009467b48Spatrick return findRematerializableChainToBasePointer(ChainToBase,
230109467b48Spatrick GEP->getPointerOperand());
230209467b48Spatrick }
230309467b48Spatrick
230409467b48Spatrick if (CastInst *CI = dyn_cast<CastInst>(CurrentValue)) {
230509467b48Spatrick if (!CI->isNoopCast(CI->getModule()->getDataLayout()))
230609467b48Spatrick return CI;
230709467b48Spatrick
230809467b48Spatrick ChainToBase.push_back(CI);
230909467b48Spatrick return findRematerializableChainToBasePointer(ChainToBase,
231009467b48Spatrick CI->getOperand(0));
231109467b48Spatrick }
231209467b48Spatrick
231309467b48Spatrick // We have reached the root of the chain, which is either equal to the base or
231409467b48Spatrick // is the first unsupported value along the use chain.
231509467b48Spatrick return CurrentValue;
231609467b48Spatrick }
231709467b48Spatrick
231809467b48Spatrick // Helper function for the "rematerializeLiveValues". Compute cost of the use
231909467b48Spatrick // chain we are going to rematerialize.
232073471bf0Spatrick static InstructionCost
chainToBasePointerCost(SmallVectorImpl<Instruction * > & Chain,TargetTransformInfo & TTI)232109467b48Spatrick chainToBasePointerCost(SmallVectorImpl<Instruction *> &Chain,
232209467b48Spatrick TargetTransformInfo &TTI) {
232373471bf0Spatrick InstructionCost Cost = 0;
232409467b48Spatrick
232509467b48Spatrick for (Instruction *Instr : Chain) {
232609467b48Spatrick if (CastInst *CI = dyn_cast<CastInst>(Instr)) {
232709467b48Spatrick assert(CI->isNoopCast(CI->getModule()->getDataLayout()) &&
232809467b48Spatrick "non noop cast is found during rematerialization");
232909467b48Spatrick
233009467b48Spatrick Type *SrcTy = CI->getOperand(0)->getType();
2331097a140dSpatrick Cost += TTI.getCastInstrCost(CI->getOpcode(), CI->getType(), SrcTy,
233273471bf0Spatrick TTI::getCastContextHint(CI),
233373471bf0Spatrick TargetTransformInfo::TCK_SizeAndLatency, CI);
233409467b48Spatrick
233509467b48Spatrick } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Instr)) {
233609467b48Spatrick // Cost of the address calculation
233709467b48Spatrick Type *ValTy = GEP->getSourceElementType();
233809467b48Spatrick Cost += TTI.getAddressComputationCost(ValTy);
233909467b48Spatrick
234009467b48Spatrick // And cost of the GEP itself
234109467b48Spatrick // TODO: Use TTI->getGEPCost here (it exists, but appears to be not
234209467b48Spatrick // allowed for the external usage)
234309467b48Spatrick if (!GEP->hasAllConstantIndices())
234409467b48Spatrick Cost += 2;
234509467b48Spatrick
234609467b48Spatrick } else {
234709467b48Spatrick llvm_unreachable("unsupported instruction type during rematerialization");
234809467b48Spatrick }
234909467b48Spatrick }
235009467b48Spatrick
235109467b48Spatrick return Cost;
235209467b48Spatrick }
235309467b48Spatrick
AreEquivalentPhiNodes(PHINode & OrigRootPhi,PHINode & AlternateRootPhi)235409467b48Spatrick static bool AreEquivalentPhiNodes(PHINode &OrigRootPhi, PHINode &AlternateRootPhi) {
235509467b48Spatrick unsigned PhiNum = OrigRootPhi.getNumIncomingValues();
235609467b48Spatrick if (PhiNum != AlternateRootPhi.getNumIncomingValues() ||
235709467b48Spatrick OrigRootPhi.getParent() != AlternateRootPhi.getParent())
235809467b48Spatrick return false;
235909467b48Spatrick // Map of incoming values and their corresponding basic blocks of
236009467b48Spatrick // OrigRootPhi.
236109467b48Spatrick SmallDenseMap<Value *, BasicBlock *, 8> CurrentIncomingValues;
236209467b48Spatrick for (unsigned i = 0; i < PhiNum; i++)
236309467b48Spatrick CurrentIncomingValues[OrigRootPhi.getIncomingValue(i)] =
236409467b48Spatrick OrigRootPhi.getIncomingBlock(i);
236509467b48Spatrick
236609467b48Spatrick // Both current and base PHIs should have same incoming values and
236709467b48Spatrick // the same basic blocks corresponding to the incoming values.
236809467b48Spatrick for (unsigned i = 0; i < PhiNum; i++) {
236909467b48Spatrick auto CIVI =
237009467b48Spatrick CurrentIncomingValues.find(AlternateRootPhi.getIncomingValue(i));
237109467b48Spatrick if (CIVI == CurrentIncomingValues.end())
237209467b48Spatrick return false;
237309467b48Spatrick BasicBlock *CurrentIncomingBB = CIVI->second;
237409467b48Spatrick if (CurrentIncomingBB != AlternateRootPhi.getIncomingBlock(i))
237509467b48Spatrick return false;
237609467b48Spatrick }
237709467b48Spatrick return true;
237809467b48Spatrick }
237909467b48Spatrick
2380*d415bd75Srobert // Find derived pointers that can be recomputed cheap enough and fill
2381*d415bd75Srobert // RematerizationCandidates with such candidates.
2382*d415bd75Srobert static void
findRematerializationCandidates(PointerToBaseTy PointerToBase,RematCandTy & RematerizationCandidates,TargetTransformInfo & TTI)2383*d415bd75Srobert findRematerializationCandidates(PointerToBaseTy PointerToBase,
2384*d415bd75Srobert RematCandTy &RematerizationCandidates,
238509467b48Spatrick TargetTransformInfo &TTI) {
238609467b48Spatrick const unsigned int ChainLengthThreshold = 10;
238709467b48Spatrick
2388*d415bd75Srobert for (auto P2B : PointerToBase) {
2389*d415bd75Srobert auto *Derived = P2B.first;
2390*d415bd75Srobert auto *Base = P2B.second;
2391*d415bd75Srobert // Consider only derived pointers.
2392*d415bd75Srobert if (Derived == Base)
2393*d415bd75Srobert continue;
239409467b48Spatrick
2395*d415bd75Srobert // For each live pointer find its defining chain.
239609467b48Spatrick SmallVector<Instruction *, 3> ChainToBase;
239709467b48Spatrick Value *RootOfChain =
2398*d415bd75Srobert findRematerializableChainToBasePointer(ChainToBase, Derived);
239909467b48Spatrick
240009467b48Spatrick // Nothing to do, or chain is too long
240109467b48Spatrick if ( ChainToBase.size() == 0 ||
240209467b48Spatrick ChainToBase.size() > ChainLengthThreshold)
240309467b48Spatrick continue;
240409467b48Spatrick
240509467b48Spatrick // Handle the scenario where the RootOfChain is not equal to the
240609467b48Spatrick // Base Value, but they are essentially the same phi values.
2407*d415bd75Srobert if (RootOfChain != PointerToBase[Derived]) {
240809467b48Spatrick PHINode *OrigRootPhi = dyn_cast<PHINode>(RootOfChain);
2409*d415bd75Srobert PHINode *AlternateRootPhi = dyn_cast<PHINode>(PointerToBase[Derived]);
241009467b48Spatrick if (!OrigRootPhi || !AlternateRootPhi)
241109467b48Spatrick continue;
241209467b48Spatrick // PHI nodes that have the same incoming values, and belonging to the same
241309467b48Spatrick // basic blocks are essentially the same SSA value. When the original phi
241409467b48Spatrick // has incoming values with different base pointers, the original phi is
241509467b48Spatrick // marked as conflict, and an additional `AlternateRootPhi` with the same
241609467b48Spatrick // incoming values get generated by the findBasePointer function. We need
241709467b48Spatrick // to identify the newly generated AlternateRootPhi (.base version of phi)
241809467b48Spatrick // and RootOfChain (the original phi node itself) are the same, so that we
241909467b48Spatrick // can rematerialize the gep and casts. This is a workaround for the
242009467b48Spatrick // deficiency in the findBasePointer algorithm.
242109467b48Spatrick if (!AreEquivalentPhiNodes(*OrigRootPhi, *AlternateRootPhi))
242209467b48Spatrick continue;
242309467b48Spatrick }
2424*d415bd75Srobert // Compute cost of this chain.
242573471bf0Spatrick InstructionCost Cost = chainToBasePointerCost(ChainToBase, TTI);
242609467b48Spatrick // TODO: We can also account for cases when we will be able to remove some
242709467b48Spatrick // of the rematerialized values by later optimization passes. I.e if
242809467b48Spatrick // we rematerialized several intersecting chains. Or if original values
242909467b48Spatrick // don't have any uses besides this statepoint.
243009467b48Spatrick
2431*d415bd75Srobert // Ok, there is a candidate.
2432*d415bd75Srobert RematerizlizationCandidateRecord Record;
2433*d415bd75Srobert Record.ChainToBase = ChainToBase;
2434*d415bd75Srobert Record.RootOfChain = RootOfChain;
2435*d415bd75Srobert Record.Cost = Cost;
2436*d415bd75Srobert RematerizationCandidates.insert({ Derived, Record });
2437*d415bd75Srobert }
2438*d415bd75Srobert }
2439*d415bd75Srobert
2440*d415bd75Srobert // Try to rematerialize derived pointers immediately before their uses
2441*d415bd75Srobert // (instead of rematerializing after every statepoint it is live through).
2442*d415bd75Srobert // This can be beneficial when derived pointer is live across many
2443*d415bd75Srobert // statepoints, but uses are rare.
rematerializeLiveValuesAtUses(RematCandTy & RematerizationCandidates,MutableArrayRef<PartiallyConstructedSafepointRecord> Records,PointerToBaseTy & PointerToBase)2444*d415bd75Srobert static void rematerializeLiveValuesAtUses(
2445*d415bd75Srobert RematCandTy &RematerizationCandidates,
2446*d415bd75Srobert MutableArrayRef<PartiallyConstructedSafepointRecord> Records,
2447*d415bd75Srobert PointerToBaseTy &PointerToBase) {
2448*d415bd75Srobert if (!RematDerivedAtUses)
2449*d415bd75Srobert return;
2450*d415bd75Srobert
2451*d415bd75Srobert SmallVector<Instruction *, 32> LiveValuesToBeDeleted;
2452*d415bd75Srobert
2453*d415bd75Srobert LLVM_DEBUG(dbgs() << "Rematerialize derived pointers at uses, "
2454*d415bd75Srobert << "Num statepoints: " << Records.size() << '\n');
2455*d415bd75Srobert
2456*d415bd75Srobert for (auto &It : RematerizationCandidates) {
2457*d415bd75Srobert Instruction *Cand = cast<Instruction>(It.first);
2458*d415bd75Srobert auto &Record = It.second;
2459*d415bd75Srobert
2460*d415bd75Srobert if (Record.Cost >= RematerializationThreshold)
2461*d415bd75Srobert continue;
2462*d415bd75Srobert
2463*d415bd75Srobert if (Cand->user_empty())
2464*d415bd75Srobert continue;
2465*d415bd75Srobert
2466*d415bd75Srobert if (Cand->hasOneUse())
2467*d415bd75Srobert if (auto *U = dyn_cast<Instruction>(Cand->getUniqueUndroppableUser()))
2468*d415bd75Srobert if (U->getParent() == Cand->getParent())
2469*d415bd75Srobert continue;
2470*d415bd75Srobert
2471*d415bd75Srobert // Rematerialization before PHI nodes is not implemented.
2472*d415bd75Srobert if (llvm::any_of(Cand->users(),
2473*d415bd75Srobert [](const auto *U) { return isa<PHINode>(U); }))
2474*d415bd75Srobert continue;
2475*d415bd75Srobert
2476*d415bd75Srobert LLVM_DEBUG(dbgs() << "Trying cand " << *Cand << " ... ");
2477*d415bd75Srobert
2478*d415bd75Srobert // Count of rematerialization instructions we introduce is equal to number
2479*d415bd75Srobert // of candidate uses.
2480*d415bd75Srobert // Count of rematerialization instructions we eliminate is equal to number
2481*d415bd75Srobert // of statepoints it is live through.
2482*d415bd75Srobert // Consider transformation profitable if latter is greater than former
2483*d415bd75Srobert // (in other words, we create less than eliminate).
2484*d415bd75Srobert unsigned NumLiveStatepoints = llvm::count_if(
2485*d415bd75Srobert Records, [Cand](const auto &R) { return R.LiveSet.contains(Cand); });
2486*d415bd75Srobert unsigned NumUses = Cand->getNumUses();
2487*d415bd75Srobert
2488*d415bd75Srobert LLVM_DEBUG(dbgs() << "Num uses: " << NumUses << " Num live statepoints: "
2489*d415bd75Srobert << NumLiveStatepoints << " ");
2490*d415bd75Srobert
2491*d415bd75Srobert if (NumLiveStatepoints < NumUses) {
2492*d415bd75Srobert LLVM_DEBUG(dbgs() << "not profitable\n");
2493*d415bd75Srobert continue;
2494*d415bd75Srobert }
2495*d415bd75Srobert
2496*d415bd75Srobert // If rematerialization is 'free', then favor rematerialization at
2497*d415bd75Srobert // uses as it generally shortens live ranges.
2498*d415bd75Srobert // TODO: Short (size ==1) chains only?
2499*d415bd75Srobert if (NumLiveStatepoints == NumUses && Record.Cost > 0) {
2500*d415bd75Srobert LLVM_DEBUG(dbgs() << "not profitable\n");
2501*d415bd75Srobert continue;
2502*d415bd75Srobert }
2503*d415bd75Srobert
2504*d415bd75Srobert LLVM_DEBUG(dbgs() << "looks profitable\n");
2505*d415bd75Srobert
2506*d415bd75Srobert // ChainToBase may contain another remat candidate (as a sub chain) which
2507*d415bd75Srobert // has been rewritten by now. Need to recollect chain to have up to date
2508*d415bd75Srobert // value.
2509*d415bd75Srobert // TODO: sort records in findRematerializationCandidates() in
2510*d415bd75Srobert // decreasing chain size order?
2511*d415bd75Srobert if (Record.ChainToBase.size() > 1) {
2512*d415bd75Srobert Record.ChainToBase.clear();
2513*d415bd75Srobert findRematerializableChainToBasePointer(Record.ChainToBase, Cand);
2514*d415bd75Srobert }
2515*d415bd75Srobert
2516*d415bd75Srobert // Current rematerialization algorithm is very simple: we rematerialize
2517*d415bd75Srobert // immediately before EVERY use, even if there are several uses in same
2518*d415bd75Srobert // block or if use is local to Cand Def. The reason is that this allows
2519*d415bd75Srobert // us to avoid recomputing liveness without complicated analysis:
2520*d415bd75Srobert // - If we did not eliminate all uses of original Candidate, we do not
2521*d415bd75Srobert // know exaclty in what BBs it is still live.
2522*d415bd75Srobert // - If we rematerialize once per BB, we need to find proper insertion
2523*d415bd75Srobert // place (first use in block, but after Def) and analyze if there is
2524*d415bd75Srobert // statepoint between uses in the block.
2525*d415bd75Srobert while (!Cand->user_empty()) {
2526*d415bd75Srobert Instruction *UserI = cast<Instruction>(*Cand->user_begin());
2527*d415bd75Srobert Instruction *RematChain = rematerializeChain(
2528*d415bd75Srobert Record.ChainToBase, UserI, Record.RootOfChain, PointerToBase[Cand]);
2529*d415bd75Srobert UserI->replaceUsesOfWith(Cand, RematChain);
2530*d415bd75Srobert PointerToBase[RematChain] = PointerToBase[Cand];
2531*d415bd75Srobert }
2532*d415bd75Srobert LiveValuesToBeDeleted.push_back(Cand);
2533*d415bd75Srobert }
2534*d415bd75Srobert
2535*d415bd75Srobert LLVM_DEBUG(dbgs() << "Rematerialized " << LiveValuesToBeDeleted.size()
2536*d415bd75Srobert << " derived pointers\n");
2537*d415bd75Srobert for (auto *Cand : LiveValuesToBeDeleted) {
2538*d415bd75Srobert assert(Cand->use_empty() && "Unexpected user remain");
2539*d415bd75Srobert RematerizationCandidates.erase(Cand);
2540*d415bd75Srobert for (auto &R : Records) {
2541*d415bd75Srobert assert(!R.LiveSet.contains(Cand) ||
2542*d415bd75Srobert R.LiveSet.contains(PointerToBase[Cand]));
2543*d415bd75Srobert R.LiveSet.remove(Cand);
2544*d415bd75Srobert }
2545*d415bd75Srobert }
2546*d415bd75Srobert
2547*d415bd75Srobert // Recollect not rematerialized chains - we might have rewritten
2548*d415bd75Srobert // their sub-chains.
2549*d415bd75Srobert if (!LiveValuesToBeDeleted.empty()) {
2550*d415bd75Srobert for (auto &P : RematerizationCandidates) {
2551*d415bd75Srobert auto &R = P.second;
2552*d415bd75Srobert if (R.ChainToBase.size() > 1) {
2553*d415bd75Srobert R.ChainToBase.clear();
2554*d415bd75Srobert findRematerializableChainToBasePointer(R.ChainToBase, P.first);
2555*d415bd75Srobert }
2556*d415bd75Srobert }
2557*d415bd75Srobert }
2558*d415bd75Srobert }
2559*d415bd75Srobert
2560*d415bd75Srobert // From the statepoint live set pick values that are cheaper to recompute then
2561*d415bd75Srobert // to relocate. Remove this values from the live set, rematerialize them after
2562*d415bd75Srobert // statepoint and record them in "Info" structure. Note that similar to
2563*d415bd75Srobert // relocated values we don't do any user adjustments here.
rematerializeLiveValues(CallBase * Call,PartiallyConstructedSafepointRecord & Info,PointerToBaseTy & PointerToBase,RematCandTy & RematerizationCandidates,TargetTransformInfo & TTI)2564*d415bd75Srobert static void rematerializeLiveValues(CallBase *Call,
2565*d415bd75Srobert PartiallyConstructedSafepointRecord &Info,
2566*d415bd75Srobert PointerToBaseTy &PointerToBase,
2567*d415bd75Srobert RematCandTy &RematerizationCandidates,
2568*d415bd75Srobert TargetTransformInfo &TTI) {
2569*d415bd75Srobert // Record values we are going to delete from this statepoint live set.
2570*d415bd75Srobert // We can not di this in following loop due to iterator invalidation.
2571*d415bd75Srobert SmallVector<Value *, 32> LiveValuesToBeDeleted;
2572*d415bd75Srobert
2573*d415bd75Srobert for (Value *LiveValue : Info.LiveSet) {
2574*d415bd75Srobert auto It = RematerizationCandidates.find(LiveValue);
2575*d415bd75Srobert if (It == RematerizationCandidates.end())
2576*d415bd75Srobert continue;
2577*d415bd75Srobert
2578*d415bd75Srobert RematerizlizationCandidateRecord &Record = It->second;
2579*d415bd75Srobert
2580*d415bd75Srobert InstructionCost Cost = Record.Cost;
258109467b48Spatrick // For invokes we need to rematerialize each chain twice - for normal and
258209467b48Spatrick // for unwind basic blocks. Model this by multiplying cost by two.
2583*d415bd75Srobert if (isa<InvokeInst>(Call))
258409467b48Spatrick Cost *= 2;
2585*d415bd75Srobert
2586*d415bd75Srobert // If it's too expensive - skip it.
258709467b48Spatrick if (Cost >= RematerializationThreshold)
258809467b48Spatrick continue;
258909467b48Spatrick
259009467b48Spatrick // Remove value from the live set
259109467b48Spatrick LiveValuesToBeDeleted.push_back(LiveValue);
259209467b48Spatrick
2593*d415bd75Srobert // Clone instructions and record them inside "Info" structure.
259409467b48Spatrick
259509467b48Spatrick // Different cases for calls and invokes. For invokes we need to clone
259609467b48Spatrick // instructions both on normal and unwind path.
259709467b48Spatrick if (isa<CallInst>(Call)) {
259809467b48Spatrick Instruction *InsertBefore = Call->getNextNode();
259909467b48Spatrick assert(InsertBefore);
2600*d415bd75Srobert Instruction *RematerializedValue =
2601*d415bd75Srobert rematerializeChain(Record.ChainToBase, InsertBefore,
2602*d415bd75Srobert Record.RootOfChain, PointerToBase[LiveValue]);
260309467b48Spatrick Info.RematerializedValues[RematerializedValue] = LiveValue;
260409467b48Spatrick } else {
260509467b48Spatrick auto *Invoke = cast<InvokeInst>(Call);
260609467b48Spatrick
260709467b48Spatrick Instruction *NormalInsertBefore =
260809467b48Spatrick &*Invoke->getNormalDest()->getFirstInsertionPt();
260909467b48Spatrick Instruction *UnwindInsertBefore =
261009467b48Spatrick &*Invoke->getUnwindDest()->getFirstInsertionPt();
261109467b48Spatrick
2612*d415bd75Srobert Instruction *NormalRematerializedValue =
2613*d415bd75Srobert rematerializeChain(Record.ChainToBase, NormalInsertBefore,
2614*d415bd75Srobert Record.RootOfChain, PointerToBase[LiveValue]);
2615*d415bd75Srobert Instruction *UnwindRematerializedValue =
2616*d415bd75Srobert rematerializeChain(Record.ChainToBase, UnwindInsertBefore,
2617*d415bd75Srobert Record.RootOfChain, PointerToBase[LiveValue]);
261809467b48Spatrick
261909467b48Spatrick Info.RematerializedValues[NormalRematerializedValue] = LiveValue;
262009467b48Spatrick Info.RematerializedValues[UnwindRematerializedValue] = LiveValue;
262109467b48Spatrick }
262209467b48Spatrick }
262309467b48Spatrick
2624*d415bd75Srobert // Remove rematerialized values from the live set.
2625*d415bd75Srobert for (auto *LiveValue: LiveValuesToBeDeleted) {
262609467b48Spatrick Info.LiveSet.remove(LiveValue);
262709467b48Spatrick }
262809467b48Spatrick }
262909467b48Spatrick
inlineGetBaseAndOffset(Function & F,SmallVectorImpl<CallInst * > & Intrinsics,DefiningValueMapTy & DVCache,IsKnownBaseMapTy & KnownBases)263073471bf0Spatrick static bool inlineGetBaseAndOffset(Function &F,
263173471bf0Spatrick SmallVectorImpl<CallInst *> &Intrinsics,
2632*d415bd75Srobert DefiningValueMapTy &DVCache,
2633*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
263473471bf0Spatrick auto &Context = F.getContext();
263573471bf0Spatrick auto &DL = F.getParent()->getDataLayout();
263673471bf0Spatrick bool Changed = false;
263773471bf0Spatrick
263873471bf0Spatrick for (auto *Callsite : Intrinsics)
263973471bf0Spatrick switch (Callsite->getIntrinsicID()) {
264073471bf0Spatrick case Intrinsic::experimental_gc_get_pointer_base: {
264173471bf0Spatrick Changed = true;
2642*d415bd75Srobert Value *Base =
2643*d415bd75Srobert findBasePointer(Callsite->getOperand(0), DVCache, KnownBases);
264473471bf0Spatrick assert(!DVCache.count(Callsite));
264573471bf0Spatrick auto *BaseBC = IRBuilder<>(Callsite).CreateBitCast(
264673471bf0Spatrick Base, Callsite->getType(), suffixed_name_or(Base, ".cast", ""));
264773471bf0Spatrick if (BaseBC != Base)
264873471bf0Spatrick DVCache[BaseBC] = Base;
264973471bf0Spatrick Callsite->replaceAllUsesWith(BaseBC);
265073471bf0Spatrick if (!BaseBC->hasName())
265173471bf0Spatrick BaseBC->takeName(Callsite);
265273471bf0Spatrick Callsite->eraseFromParent();
265373471bf0Spatrick break;
265473471bf0Spatrick }
265573471bf0Spatrick case Intrinsic::experimental_gc_get_pointer_offset: {
265673471bf0Spatrick Changed = true;
265773471bf0Spatrick Value *Derived = Callsite->getOperand(0);
2658*d415bd75Srobert Value *Base = findBasePointer(Derived, DVCache, KnownBases);
265973471bf0Spatrick assert(!DVCache.count(Callsite));
266073471bf0Spatrick unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
266173471bf0Spatrick unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
266273471bf0Spatrick IRBuilder<> Builder(Callsite);
266373471bf0Spatrick Value *BaseInt =
266473471bf0Spatrick Builder.CreatePtrToInt(Base, Type::getIntNTy(Context, IntPtrSize),
266573471bf0Spatrick suffixed_name_or(Base, ".int", ""));
266673471bf0Spatrick Value *DerivedInt =
266773471bf0Spatrick Builder.CreatePtrToInt(Derived, Type::getIntNTy(Context, IntPtrSize),
266873471bf0Spatrick suffixed_name_or(Derived, ".int", ""));
266973471bf0Spatrick Value *Offset = Builder.CreateSub(DerivedInt, BaseInt);
267073471bf0Spatrick Callsite->replaceAllUsesWith(Offset);
267173471bf0Spatrick Offset->takeName(Callsite);
267273471bf0Spatrick Callsite->eraseFromParent();
267373471bf0Spatrick break;
267473471bf0Spatrick }
267573471bf0Spatrick default:
267673471bf0Spatrick llvm_unreachable("Unknown intrinsic");
267773471bf0Spatrick }
267873471bf0Spatrick
267973471bf0Spatrick return Changed;
268073471bf0Spatrick }
268173471bf0Spatrick
insertParsePoints(Function & F,DominatorTree & DT,TargetTransformInfo & TTI,SmallVectorImpl<CallBase * > & ToUpdate,DefiningValueMapTy & DVCache,IsKnownBaseMapTy & KnownBases)268209467b48Spatrick static bool insertParsePoints(Function &F, DominatorTree &DT,
268309467b48Spatrick TargetTransformInfo &TTI,
268473471bf0Spatrick SmallVectorImpl<CallBase *> &ToUpdate,
2685*d415bd75Srobert DefiningValueMapTy &DVCache,
2686*d415bd75Srobert IsKnownBaseMapTy &KnownBases) {
268709467b48Spatrick #ifndef NDEBUG
2688*d415bd75Srobert // Validate the input
268909467b48Spatrick std::set<CallBase *> Uniqued;
269009467b48Spatrick Uniqued.insert(ToUpdate.begin(), ToUpdate.end());
269109467b48Spatrick assert(Uniqued.size() == ToUpdate.size() && "no duplicates please!");
269209467b48Spatrick
269309467b48Spatrick for (CallBase *Call : ToUpdate)
269409467b48Spatrick assert(Call->getFunction() == &F);
269509467b48Spatrick #endif
269609467b48Spatrick
269709467b48Spatrick // When inserting gc.relocates for invokes, we need to be able to insert at
269809467b48Spatrick // the top of the successor blocks. See the comment on
269909467b48Spatrick // normalForInvokeSafepoint on exactly what is needed. Note that this step
270009467b48Spatrick // may restructure the CFG.
270109467b48Spatrick for (CallBase *Call : ToUpdate) {
270209467b48Spatrick auto *II = dyn_cast<InvokeInst>(Call);
270309467b48Spatrick if (!II)
270409467b48Spatrick continue;
270509467b48Spatrick normalizeForInvokeSafepoint(II->getNormalDest(), II->getParent(), DT);
270609467b48Spatrick normalizeForInvokeSafepoint(II->getUnwindDest(), II->getParent(), DT);
270709467b48Spatrick }
270809467b48Spatrick
270909467b48Spatrick // A list of dummy calls added to the IR to keep various values obviously
271009467b48Spatrick // live in the IR. We'll remove all of these when done.
271109467b48Spatrick SmallVector<CallInst *, 64> Holders;
271209467b48Spatrick
271309467b48Spatrick // Insert a dummy call with all of the deopt operands we'll need for the
271409467b48Spatrick // actual safepoint insertion as arguments. This ensures reference operands
271509467b48Spatrick // in the deopt argument list are considered live through the safepoint (and
271609467b48Spatrick // thus makes sure they get relocated.)
271709467b48Spatrick for (CallBase *Call : ToUpdate) {
271809467b48Spatrick SmallVector<Value *, 64> DeoptValues;
271909467b48Spatrick
272009467b48Spatrick for (Value *Arg : GetDeoptBundleOperands(Call)) {
272109467b48Spatrick assert(!isUnhandledGCPointerType(Arg->getType()) &&
272209467b48Spatrick "support for FCA unimplemented");
272309467b48Spatrick if (isHandledGCPointerType(Arg->getType()))
272409467b48Spatrick DeoptValues.push_back(Arg);
272509467b48Spatrick }
272609467b48Spatrick
272709467b48Spatrick insertUseHolderAfter(Call, DeoptValues, Holders);
272809467b48Spatrick }
272909467b48Spatrick
273009467b48Spatrick SmallVector<PartiallyConstructedSafepointRecord, 64> Records(ToUpdate.size());
273109467b48Spatrick
273209467b48Spatrick // A) Identify all gc pointers which are statically live at the given call
273309467b48Spatrick // site.
273409467b48Spatrick findLiveReferences(F, DT, ToUpdate, Records);
273509467b48Spatrick
2736*d415bd75Srobert /// Global mapping from live pointers to a base-defining-value.
2737*d415bd75Srobert PointerToBaseTy PointerToBase;
2738*d415bd75Srobert
273909467b48Spatrick // B) Find the base pointers for each live pointer
274009467b48Spatrick for (size_t i = 0; i < Records.size(); i++) {
274109467b48Spatrick PartiallyConstructedSafepointRecord &info = Records[i];
2742*d415bd75Srobert findBasePointers(DT, DVCache, ToUpdate[i], info, PointerToBase, KnownBases);
2743*d415bd75Srobert }
2744*d415bd75Srobert if (PrintBasePointers) {
2745*d415bd75Srobert errs() << "Base Pairs (w/o Relocation):\n";
2746*d415bd75Srobert for (auto &Pair : PointerToBase) {
2747*d415bd75Srobert errs() << " derived ";
2748*d415bd75Srobert Pair.first->printAsOperand(errs(), false);
2749*d415bd75Srobert errs() << " base ";
2750*d415bd75Srobert Pair.second->printAsOperand(errs(), false);
2751*d415bd75Srobert errs() << "\n";
2752*d415bd75Srobert ;
2753*d415bd75Srobert }
275409467b48Spatrick }
275509467b48Spatrick
275609467b48Spatrick // The base phi insertion logic (for any safepoint) may have inserted new
275709467b48Spatrick // instructions which are now live at some safepoint. The simplest such
275809467b48Spatrick // example is:
275909467b48Spatrick // loop:
276009467b48Spatrick // phi a <-- will be a new base_phi here
276109467b48Spatrick // safepoint 1 <-- that needs to be live here
276209467b48Spatrick // gep a + 1
276309467b48Spatrick // safepoint 2
276409467b48Spatrick // br loop
276509467b48Spatrick // We insert some dummy calls after each safepoint to definitely hold live
276609467b48Spatrick // the base pointers which were identified for that safepoint. We'll then
276709467b48Spatrick // ask liveness for _every_ base inserted to see what is now live. Then we
276809467b48Spatrick // remove the dummy calls.
276909467b48Spatrick Holders.reserve(Holders.size() + Records.size());
277009467b48Spatrick for (size_t i = 0; i < Records.size(); i++) {
277109467b48Spatrick PartiallyConstructedSafepointRecord &Info = Records[i];
277209467b48Spatrick
277309467b48Spatrick SmallVector<Value *, 128> Bases;
2774*d415bd75Srobert for (auto *Derived : Info.LiveSet) {
2775*d415bd75Srobert assert(PointerToBase.count(Derived) && "Missed base for derived pointer");
2776*d415bd75Srobert Bases.push_back(PointerToBase[Derived]);
2777*d415bd75Srobert }
277809467b48Spatrick
277909467b48Spatrick insertUseHolderAfter(ToUpdate[i], Bases, Holders);
278009467b48Spatrick }
278109467b48Spatrick
278209467b48Spatrick // By selecting base pointers, we've effectively inserted new uses. Thus, we
278309467b48Spatrick // need to rerun liveness. We may *also* have inserted new defs, but that's
278409467b48Spatrick // not the key issue.
2785*d415bd75Srobert recomputeLiveInValues(F, DT, ToUpdate, Records, PointerToBase);
278609467b48Spatrick
278709467b48Spatrick if (PrintBasePointers) {
278809467b48Spatrick errs() << "Base Pairs: (w/Relocation)\n";
2789*d415bd75Srobert for (auto Pair : PointerToBase) {
279009467b48Spatrick errs() << " derived ";
279109467b48Spatrick Pair.first->printAsOperand(errs(), false);
279209467b48Spatrick errs() << " base ";
279309467b48Spatrick Pair.second->printAsOperand(errs(), false);
279409467b48Spatrick errs() << "\n";
279509467b48Spatrick }
279609467b48Spatrick }
279709467b48Spatrick
279809467b48Spatrick // It is possible that non-constant live variables have a constant base. For
279909467b48Spatrick // example, a GEP with a variable offset from a global. In this case we can
280009467b48Spatrick // remove it from the liveset. We already don't add constants to the liveset
280109467b48Spatrick // because we assume they won't move at runtime and the GC doesn't need to be
280209467b48Spatrick // informed about them. The same reasoning applies if the base is constant.
280309467b48Spatrick // Note that the relocation placement code relies on this filtering for
280409467b48Spatrick // correctness as it expects the base to be in the liveset, which isn't true
280509467b48Spatrick // if the base is constant.
2806*d415bd75Srobert for (auto &Info : Records) {
2807*d415bd75Srobert Info.LiveSet.remove_if([&](Value *LiveV) {
2808*d415bd75Srobert assert(PointerToBase.count(LiveV) && "Missed base for derived pointer");
2809*d415bd75Srobert return isa<Constant>(PointerToBase[LiveV]);
2810*d415bd75Srobert });
2811*d415bd75Srobert }
281209467b48Spatrick
281309467b48Spatrick for (CallInst *CI : Holders)
281409467b48Spatrick CI->eraseFromParent();
281509467b48Spatrick
281609467b48Spatrick Holders.clear();
281709467b48Spatrick
2818*d415bd75Srobert // Compute the cost of possible re-materialization of derived pointers.
2819*d415bd75Srobert RematCandTy RematerizationCandidates;
2820*d415bd75Srobert findRematerializationCandidates(PointerToBase, RematerizationCandidates, TTI);
2821*d415bd75Srobert
282209467b48Spatrick // In order to reduce live set of statepoint we might choose to rematerialize
282309467b48Spatrick // some values instead of relocating them. This is purely an optimization and
282409467b48Spatrick // does not influence correctness.
2825*d415bd75Srobert // First try rematerialization at uses, then after statepoints.
2826*d415bd75Srobert rematerializeLiveValuesAtUses(RematerizationCandidates, Records,
2827*d415bd75Srobert PointerToBase);
282809467b48Spatrick for (size_t i = 0; i < Records.size(); i++)
2829*d415bd75Srobert rematerializeLiveValues(ToUpdate[i], Records[i], PointerToBase,
2830*d415bd75Srobert RematerizationCandidates, TTI);
283109467b48Spatrick
283209467b48Spatrick // We need this to safely RAUW and delete call or invoke return values that
283309467b48Spatrick // may themselves be live over a statepoint. For details, please see usage in
283409467b48Spatrick // makeStatepointExplicitImpl.
283509467b48Spatrick std::vector<DeferredReplacement> Replacements;
283609467b48Spatrick
283709467b48Spatrick // Now run through and replace the existing statepoints with new ones with
283809467b48Spatrick // the live variables listed. We do not yet update uses of the values being
283909467b48Spatrick // relocated. We have references to live variables that need to
284009467b48Spatrick // survive to the last iteration of this loop. (By construction, the
284109467b48Spatrick // previous statepoint can not be a live variable, thus we can and remove
284209467b48Spatrick // the old statepoint calls as we go.)
284309467b48Spatrick for (size_t i = 0; i < Records.size(); i++)
2844*d415bd75Srobert makeStatepointExplicit(DT, ToUpdate[i], Records[i], Replacements,
2845*d415bd75Srobert PointerToBase);
284609467b48Spatrick
284709467b48Spatrick ToUpdate.clear(); // prevent accident use of invalid calls.
284809467b48Spatrick
284909467b48Spatrick for (auto &PR : Replacements)
285009467b48Spatrick PR.doReplacement();
285109467b48Spatrick
285209467b48Spatrick Replacements.clear();
285309467b48Spatrick
285409467b48Spatrick for (auto &Info : Records) {
285509467b48Spatrick // These live sets may contain state Value pointers, since we replaced calls
285609467b48Spatrick // with operand bundles with calls wrapped in gc.statepoint, and some of
285709467b48Spatrick // those calls may have been def'ing live gc pointers. Clear these out to
285809467b48Spatrick // avoid accidentally using them.
285909467b48Spatrick //
286009467b48Spatrick // TODO: We should create a separate data structure that does not contain
286109467b48Spatrick // these live sets, and migrate to using that data structure from this point
286209467b48Spatrick // onward.
286309467b48Spatrick Info.LiveSet.clear();
286409467b48Spatrick }
2865*d415bd75Srobert PointerToBase.clear();
286609467b48Spatrick
286709467b48Spatrick // Do all the fixups of the original live variables to their relocated selves
286809467b48Spatrick SmallVector<Value *, 128> Live;
286909467b48Spatrick for (size_t i = 0; i < Records.size(); i++) {
287009467b48Spatrick PartiallyConstructedSafepointRecord &Info = Records[i];
287109467b48Spatrick
287209467b48Spatrick // We can't simply save the live set from the original insertion. One of
287309467b48Spatrick // the live values might be the result of a call which needs a safepoint.
287409467b48Spatrick // That Value* no longer exists and we need to use the new gc_result.
287509467b48Spatrick // Thankfully, the live set is embedded in the statepoint (and updated), so
287609467b48Spatrick // we just grab that.
287773471bf0Spatrick llvm::append_range(Live, Info.StatepointToken->gc_args());
287809467b48Spatrick #ifndef NDEBUG
2879*d415bd75Srobert // Do some basic validation checking on our liveness results before
2880*d415bd75Srobert // performing relocation. Relocation can and will turn mistakes in liveness
2881*d415bd75Srobert // results into non-sensical code which is must harder to debug.
288209467b48Spatrick // TODO: It would be nice to test consistency as well
288309467b48Spatrick assert(DT.isReachableFromEntry(Info.StatepointToken->getParent()) &&
288409467b48Spatrick "statepoint must be reachable or liveness is meaningless");
2885097a140dSpatrick for (Value *V : Info.StatepointToken->gc_args()) {
288609467b48Spatrick if (!isa<Instruction>(V))
288709467b48Spatrick // Non-instruction values trivial dominate all possible uses
288809467b48Spatrick continue;
288909467b48Spatrick auto *LiveInst = cast<Instruction>(V);
289009467b48Spatrick assert(DT.isReachableFromEntry(LiveInst->getParent()) &&
289109467b48Spatrick "unreachable values should never be live");
289209467b48Spatrick assert(DT.dominates(LiveInst, Info.StatepointToken) &&
289309467b48Spatrick "basic SSA liveness expectation violated by liveness analysis");
289409467b48Spatrick }
289509467b48Spatrick #endif
289609467b48Spatrick }
289709467b48Spatrick unique_unsorted(Live);
289809467b48Spatrick
289909467b48Spatrick #ifndef NDEBUG
2900*d415bd75Srobert // Validation check
290109467b48Spatrick for (auto *Ptr : Live)
290209467b48Spatrick assert(isHandledGCPointerType(Ptr->getType()) &&
290309467b48Spatrick "must be a gc pointer type");
290409467b48Spatrick #endif
290509467b48Spatrick
290609467b48Spatrick relocationViaAlloca(F, DT, Live, Records);
290709467b48Spatrick return !Records.empty();
290809467b48Spatrick }
290909467b48Spatrick
2910*d415bd75Srobert // List of all parameter and return attributes which must be stripped when
2911*d415bd75Srobert // lowering from the abstract machine model. Note that we list attributes
2912*d415bd75Srobert // here which aren't valid as return attributes, that is okay.
getParamAndReturnAttributesToRemove()2913*d415bd75Srobert static AttributeMask getParamAndReturnAttributesToRemove() {
2914*d415bd75Srobert AttributeMask R;
2915*d415bd75Srobert R.addAttribute(Attribute::Dereferenceable);
2916*d415bd75Srobert R.addAttribute(Attribute::DereferenceableOrNull);
2917*d415bd75Srobert R.addAttribute(Attribute::ReadNone);
2918*d415bd75Srobert R.addAttribute(Attribute::ReadOnly);
2919*d415bd75Srobert R.addAttribute(Attribute::WriteOnly);
2920*d415bd75Srobert R.addAttribute(Attribute::NoAlias);
2921*d415bd75Srobert R.addAttribute(Attribute::NoFree);
2922*d415bd75Srobert return R;
292309467b48Spatrick }
292409467b48Spatrick
stripNonValidAttributesFromPrototype(Function & F)292509467b48Spatrick static void stripNonValidAttributesFromPrototype(Function &F) {
292609467b48Spatrick LLVMContext &Ctx = F.getContext();
292709467b48Spatrick
292873471bf0Spatrick // Intrinsics are very delicate. Lowering sometimes depends the presence
292973471bf0Spatrick // of certain attributes for correctness, but we may have also inferred
293073471bf0Spatrick // additional ones in the abstract machine model which need stripped. This
293173471bf0Spatrick // assumes that the attributes defined in Intrinsic.td are conservatively
293273471bf0Spatrick // correct for both physical and abstract model.
293373471bf0Spatrick if (Intrinsic::ID id = F.getIntrinsicID()) {
293473471bf0Spatrick F.setAttributes(Intrinsic::getAttributes(Ctx, id));
293573471bf0Spatrick return;
293673471bf0Spatrick }
293773471bf0Spatrick
2938*d415bd75Srobert AttributeMask R = getParamAndReturnAttributesToRemove();
293909467b48Spatrick for (Argument &A : F.args())
294009467b48Spatrick if (isa<PointerType>(A.getType()))
2941*d415bd75Srobert F.removeParamAttrs(A.getArgNo(), R);
294209467b48Spatrick
294309467b48Spatrick if (isa<PointerType>(F.getReturnType()))
2944*d415bd75Srobert F.removeRetAttrs(R);
294573471bf0Spatrick
294673471bf0Spatrick for (auto Attr : FnAttrsToStrip)
294773471bf0Spatrick F.removeFnAttr(Attr);
294809467b48Spatrick }
294909467b48Spatrick
295009467b48Spatrick /// Certain metadata on instructions are invalid after running RS4GC.
295109467b48Spatrick /// Optimizations that run after RS4GC can incorrectly use this metadata to
295209467b48Spatrick /// optimize functions. We drop such metadata on the instruction.
stripInvalidMetadataFromInstruction(Instruction & I)295309467b48Spatrick static void stripInvalidMetadataFromInstruction(Instruction &I) {
295409467b48Spatrick if (!isa<LoadInst>(I) && !isa<StoreInst>(I))
295509467b48Spatrick return;
295609467b48Spatrick // These are the attributes that are still valid on loads and stores after
295709467b48Spatrick // RS4GC.
295809467b48Spatrick // The metadata implying dereferenceability and noalias are (conservatively)
295909467b48Spatrick // dropped. This is because semantically, after RewriteStatepointsForGC runs,
296009467b48Spatrick // all calls to gc.statepoint "free" the entire heap. Also, gc.statepoint can
296109467b48Spatrick // touch the entire heap including noalias objects. Note: The reasoning is
296209467b48Spatrick // same as stripping the dereferenceability and noalias attributes that are
296309467b48Spatrick // analogous to the metadata counterparts.
296409467b48Spatrick // We also drop the invariant.load metadata on the load because that metadata
296509467b48Spatrick // implies the address operand to the load points to memory that is never
296609467b48Spatrick // changed once it became dereferenceable. This is no longer true after RS4GC.
296709467b48Spatrick // Similar reasoning applies to invariant.group metadata, which applies to
296809467b48Spatrick // loads within a group.
296909467b48Spatrick unsigned ValidMetadataAfterRS4GC[] = {LLVMContext::MD_tbaa,
297009467b48Spatrick LLVMContext::MD_range,
297109467b48Spatrick LLVMContext::MD_alias_scope,
297209467b48Spatrick LLVMContext::MD_nontemporal,
297309467b48Spatrick LLVMContext::MD_nonnull,
297409467b48Spatrick LLVMContext::MD_align,
297509467b48Spatrick LLVMContext::MD_type};
297609467b48Spatrick
297709467b48Spatrick // Drops all metadata on the instruction other than ValidMetadataAfterRS4GC.
297809467b48Spatrick I.dropUnknownNonDebugMetadata(ValidMetadataAfterRS4GC);
297909467b48Spatrick }
298009467b48Spatrick
stripNonValidDataFromBody(Function & F)298109467b48Spatrick static void stripNonValidDataFromBody(Function &F) {
298209467b48Spatrick if (F.empty())
298309467b48Spatrick return;
298409467b48Spatrick
298509467b48Spatrick LLVMContext &Ctx = F.getContext();
298609467b48Spatrick MDBuilder Builder(Ctx);
298709467b48Spatrick
298809467b48Spatrick // Set of invariantstart instructions that we need to remove.
298909467b48Spatrick // Use this to avoid invalidating the instruction iterator.
299009467b48Spatrick SmallVector<IntrinsicInst*, 12> InvariantStartInstructions;
299109467b48Spatrick
299209467b48Spatrick for (Instruction &I : instructions(F)) {
299309467b48Spatrick // invariant.start on memory location implies that the referenced memory
299409467b48Spatrick // location is constant and unchanging. This is no longer true after
299509467b48Spatrick // RewriteStatepointsForGC runs because there can be calls to gc.statepoint
299609467b48Spatrick // which frees the entire heap and the presence of invariant.start allows
299709467b48Spatrick // the optimizer to sink the load of a memory location past a statepoint,
299809467b48Spatrick // which is incorrect.
299909467b48Spatrick if (auto *II = dyn_cast<IntrinsicInst>(&I))
300009467b48Spatrick if (II->getIntrinsicID() == Intrinsic::invariant_start) {
300109467b48Spatrick InvariantStartInstructions.push_back(II);
300209467b48Spatrick continue;
300309467b48Spatrick }
300409467b48Spatrick
300509467b48Spatrick if (MDNode *Tag = I.getMetadata(LLVMContext::MD_tbaa)) {
300609467b48Spatrick MDNode *MutableTBAA = Builder.createMutableTBAAAccessTag(Tag);
300709467b48Spatrick I.setMetadata(LLVMContext::MD_tbaa, MutableTBAA);
300809467b48Spatrick }
300909467b48Spatrick
301009467b48Spatrick stripInvalidMetadataFromInstruction(I);
301109467b48Spatrick
3012*d415bd75Srobert AttributeMask R = getParamAndReturnAttributesToRemove();
301309467b48Spatrick if (auto *Call = dyn_cast<CallBase>(&I)) {
301409467b48Spatrick for (int i = 0, e = Call->arg_size(); i != e; i++)
301509467b48Spatrick if (isa<PointerType>(Call->getArgOperand(i)->getType()))
3016*d415bd75Srobert Call->removeParamAttrs(i, R);
301709467b48Spatrick if (isa<PointerType>(Call->getType()))
3018*d415bd75Srobert Call->removeRetAttrs(R);
301909467b48Spatrick }
302009467b48Spatrick }
302109467b48Spatrick
302209467b48Spatrick // Delete the invariant.start instructions and RAUW undef.
302309467b48Spatrick for (auto *II : InvariantStartInstructions) {
302409467b48Spatrick II->replaceAllUsesWith(UndefValue::get(II->getType()));
302509467b48Spatrick II->eraseFromParent();
302609467b48Spatrick }
302709467b48Spatrick }
302809467b48Spatrick
302909467b48Spatrick /// Returns true if this function should be rewritten by this pass. The main
303009467b48Spatrick /// point of this function is as an extension point for custom logic.
shouldRewriteStatepointsIn(Function & F)303109467b48Spatrick static bool shouldRewriteStatepointsIn(Function &F) {
303209467b48Spatrick // TODO: This should check the GCStrategy
303309467b48Spatrick if (F.hasGC()) {
303409467b48Spatrick const auto &FunctionGCName = F.getGC();
303509467b48Spatrick const StringRef StatepointExampleName("statepoint-example");
303609467b48Spatrick const StringRef CoreCLRName("coreclr");
303709467b48Spatrick return (StatepointExampleName == FunctionGCName) ||
303809467b48Spatrick (CoreCLRName == FunctionGCName);
303909467b48Spatrick } else
304009467b48Spatrick return false;
304109467b48Spatrick }
304209467b48Spatrick
stripNonValidData(Module & M)304309467b48Spatrick static void stripNonValidData(Module &M) {
304409467b48Spatrick #ifndef NDEBUG
304509467b48Spatrick assert(llvm::any_of(M, shouldRewriteStatepointsIn) && "precondition!");
304609467b48Spatrick #endif
304709467b48Spatrick
304809467b48Spatrick for (Function &F : M)
304909467b48Spatrick stripNonValidAttributesFromPrototype(F);
305009467b48Spatrick
305109467b48Spatrick for (Function &F : M)
305209467b48Spatrick stripNonValidDataFromBody(F);
305309467b48Spatrick }
305409467b48Spatrick
runOnFunction(Function & F,DominatorTree & DT,TargetTransformInfo & TTI,const TargetLibraryInfo & TLI)305509467b48Spatrick bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
305609467b48Spatrick TargetTransformInfo &TTI,
305709467b48Spatrick const TargetLibraryInfo &TLI) {
305809467b48Spatrick assert(!F.isDeclaration() && !F.empty() &&
305909467b48Spatrick "need function body to rewrite statepoints in");
306009467b48Spatrick assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
306109467b48Spatrick
306209467b48Spatrick auto NeedsRewrite = [&TLI](Instruction &I) {
306373471bf0Spatrick if (const auto *Call = dyn_cast<CallBase>(&I)) {
306473471bf0Spatrick if (isa<GCStatepointInst>(Call))
306573471bf0Spatrick return false;
306673471bf0Spatrick if (callsGCLeafFunction(Call, TLI))
306773471bf0Spatrick return false;
306873471bf0Spatrick
306973471bf0Spatrick // Normally it's up to the frontend to make sure that non-leaf calls also
307073471bf0Spatrick // have proper deopt state if it is required. We make an exception for
307173471bf0Spatrick // element atomic memcpy/memmove intrinsics here. Unlike other intrinsics
307273471bf0Spatrick // these are non-leaf by default. They might be generated by the optimizer
307373471bf0Spatrick // which doesn't know how to produce a proper deopt state. So if we see a
307473471bf0Spatrick // non-leaf memcpy/memmove without deopt state just treat it as a leaf
307573471bf0Spatrick // copy and don't produce a statepoint.
307673471bf0Spatrick if (!AllowStatepointWithNoDeoptInfo &&
307773471bf0Spatrick !Call->getOperandBundle(LLVMContext::OB_deopt)) {
307873471bf0Spatrick assert((isa<AtomicMemCpyInst>(Call) || isa<AtomicMemMoveInst>(Call)) &&
307973471bf0Spatrick "Don't expect any other calls here!");
308073471bf0Spatrick return false;
308173471bf0Spatrick }
308273471bf0Spatrick return true;
308373471bf0Spatrick }
308409467b48Spatrick return false;
308509467b48Spatrick };
308609467b48Spatrick
308709467b48Spatrick // Delete any unreachable statepoints so that we don't have unrewritten
308809467b48Spatrick // statepoints surviving this pass. This makes testing easier and the
308909467b48Spatrick // resulting IR less confusing to human readers.
309009467b48Spatrick DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
309109467b48Spatrick bool MadeChange = removeUnreachableBlocks(F, &DTU);
309209467b48Spatrick // Flush the Dominator Tree.
309309467b48Spatrick DTU.getDomTree();
309409467b48Spatrick
309509467b48Spatrick // Gather all the statepoints which need rewritten. Be careful to only
309609467b48Spatrick // consider those in reachable code since we need to ask dominance queries
309709467b48Spatrick // when rewriting. We'll delete the unreachable ones in a moment.
309809467b48Spatrick SmallVector<CallBase *, 64> ParsePointNeeded;
309973471bf0Spatrick SmallVector<CallInst *, 64> Intrinsics;
310009467b48Spatrick for (Instruction &I : instructions(F)) {
310109467b48Spatrick // TODO: only the ones with the flag set!
310209467b48Spatrick if (NeedsRewrite(I)) {
310309467b48Spatrick // NOTE removeUnreachableBlocks() is stronger than
310409467b48Spatrick // DominatorTree::isReachableFromEntry(). In other words
310509467b48Spatrick // removeUnreachableBlocks can remove some blocks for which
310609467b48Spatrick // isReachableFromEntry() returns true.
310709467b48Spatrick assert(DT.isReachableFromEntry(I.getParent()) &&
310809467b48Spatrick "no unreachable blocks expected");
310909467b48Spatrick ParsePointNeeded.push_back(cast<CallBase>(&I));
311009467b48Spatrick }
311173471bf0Spatrick if (auto *CI = dyn_cast<CallInst>(&I))
311273471bf0Spatrick if (CI->getIntrinsicID() == Intrinsic::experimental_gc_get_pointer_base ||
311373471bf0Spatrick CI->getIntrinsicID() == Intrinsic::experimental_gc_get_pointer_offset)
311473471bf0Spatrick Intrinsics.emplace_back(CI);
311509467b48Spatrick }
311609467b48Spatrick
311709467b48Spatrick // Return early if no work to do.
311873471bf0Spatrick if (ParsePointNeeded.empty() && Intrinsics.empty())
311909467b48Spatrick return MadeChange;
312009467b48Spatrick
312109467b48Spatrick // As a prepass, go ahead and aggressively destroy single entry phi nodes.
312209467b48Spatrick // These are created by LCSSA. They have the effect of increasing the size
312309467b48Spatrick // of liveness sets for no good reason. It may be harder to do this post
312409467b48Spatrick // insertion since relocations and base phis can confuse things.
312509467b48Spatrick for (BasicBlock &BB : F)
312673471bf0Spatrick if (BB.getUniquePredecessor())
312773471bf0Spatrick MadeChange |= FoldSingleEntryPHINodes(&BB);
312809467b48Spatrick
312909467b48Spatrick // Before we start introducing relocations, we want to tweak the IR a bit to
313009467b48Spatrick // avoid unfortunate code generation effects. The main example is that we
313109467b48Spatrick // want to try to make sure the comparison feeding a branch is after any
313209467b48Spatrick // safepoints. Otherwise, we end up with a comparison of pre-relocation
313309467b48Spatrick // values feeding a branch after relocation. This is semantically correct,
313409467b48Spatrick // but results in extra register pressure since both the pre-relocation and
313509467b48Spatrick // post-relocation copies must be available in registers. For code without
313609467b48Spatrick // relocations this is handled elsewhere, but teaching the scheduler to
313709467b48Spatrick // reverse the transform we're about to do would be slightly complex.
313809467b48Spatrick // Note: This may extend the live range of the inputs to the icmp and thus
313909467b48Spatrick // increase the liveset of any statepoint we move over. This is profitable
314009467b48Spatrick // as long as all statepoints are in rare blocks. If we had in-register
314109467b48Spatrick // lowering for live values this would be a much safer transform.
314209467b48Spatrick auto getConditionInst = [](Instruction *TI) -> Instruction * {
314309467b48Spatrick if (auto *BI = dyn_cast<BranchInst>(TI))
314409467b48Spatrick if (BI->isConditional())
314509467b48Spatrick return dyn_cast<Instruction>(BI->getCondition());
314609467b48Spatrick // TODO: Extend this to handle switches
314709467b48Spatrick return nullptr;
314809467b48Spatrick };
314909467b48Spatrick for (BasicBlock &BB : F) {
315009467b48Spatrick Instruction *TI = BB.getTerminator();
315109467b48Spatrick if (auto *Cond = getConditionInst(TI))
315209467b48Spatrick // TODO: Handle more than just ICmps here. We should be able to move
315309467b48Spatrick // most instructions without side effects or memory access.
315409467b48Spatrick if (isa<ICmpInst>(Cond) && Cond->hasOneUse()) {
315509467b48Spatrick MadeChange = true;
315609467b48Spatrick Cond->moveBefore(TI);
315709467b48Spatrick }
315809467b48Spatrick }
315909467b48Spatrick
316009467b48Spatrick // Nasty workaround - The base computation code in the main algorithm doesn't
316109467b48Spatrick // consider the fact that a GEP can be used to convert a scalar to a vector.
316209467b48Spatrick // The right fix for this is to integrate GEPs into the base rewriting
316309467b48Spatrick // algorithm properly, this is just a short term workaround to prevent
316409467b48Spatrick // crashes by canonicalizing such GEPs into fully vector GEPs.
316509467b48Spatrick for (Instruction &I : instructions(F)) {
316609467b48Spatrick if (!isa<GetElementPtrInst>(I))
316709467b48Spatrick continue;
316809467b48Spatrick
316909467b48Spatrick unsigned VF = 0;
317009467b48Spatrick for (unsigned i = 0; i < I.getNumOperands(); i++)
3171097a140dSpatrick if (auto *OpndVTy = dyn_cast<VectorType>(I.getOperand(i)->getType())) {
317209467b48Spatrick assert(VF == 0 ||
3173097a140dSpatrick VF == cast<FixedVectorType>(OpndVTy)->getNumElements());
3174097a140dSpatrick VF = cast<FixedVectorType>(OpndVTy)->getNumElements();
317509467b48Spatrick }
317609467b48Spatrick
317709467b48Spatrick // It's the vector to scalar traversal through the pointer operand which
317809467b48Spatrick // confuses base pointer rewriting, so limit ourselves to that case.
317909467b48Spatrick if (!I.getOperand(0)->getType()->isVectorTy() && VF != 0) {
318009467b48Spatrick IRBuilder<> B(&I);
318109467b48Spatrick auto *Splat = B.CreateVectorSplat(VF, I.getOperand(0));
318209467b48Spatrick I.setOperand(0, Splat);
318309467b48Spatrick MadeChange = true;
318409467b48Spatrick }
318509467b48Spatrick }
318609467b48Spatrick
318773471bf0Spatrick // Cache the 'defining value' relation used in the computation and
318873471bf0Spatrick // insertion of base phis and selects. This ensures that we don't insert
318973471bf0Spatrick // large numbers of duplicate base_phis. Use one cache for both
319073471bf0Spatrick // inlineGetBaseAndOffset() and insertParsePoints().
319173471bf0Spatrick DefiningValueMapTy DVCache;
319273471bf0Spatrick
3193*d415bd75Srobert // Mapping between a base values and a flag indicating whether it's a known
3194*d415bd75Srobert // base or not.
3195*d415bd75Srobert IsKnownBaseMapTy KnownBases;
3196*d415bd75Srobert
319773471bf0Spatrick if (!Intrinsics.empty())
319873471bf0Spatrick // Inline @gc.get.pointer.base() and @gc.get.pointer.offset() before finding
319973471bf0Spatrick // live references.
3200*d415bd75Srobert MadeChange |= inlineGetBaseAndOffset(F, Intrinsics, DVCache, KnownBases);
320173471bf0Spatrick
320273471bf0Spatrick if (!ParsePointNeeded.empty())
3203*d415bd75Srobert MadeChange |=
3204*d415bd75Srobert insertParsePoints(F, DT, TTI, ParsePointNeeded, DVCache, KnownBases);
320573471bf0Spatrick
320609467b48Spatrick return MadeChange;
320709467b48Spatrick }
320809467b48Spatrick
320909467b48Spatrick // liveness computation via standard dataflow
321009467b48Spatrick // -------------------------------------------------------------------
321109467b48Spatrick
321209467b48Spatrick // TODO: Consider using bitvectors for liveness, the set of potentially
321309467b48Spatrick // interesting values should be small and easy to pre-compute.
321409467b48Spatrick
321509467b48Spatrick /// Compute the live-in set for the location rbegin starting from
321609467b48Spatrick /// the live-out set of the basic block
computeLiveInValues(BasicBlock::reverse_iterator Begin,BasicBlock::reverse_iterator End,SetVector<Value * > & LiveTmp)321709467b48Spatrick static void computeLiveInValues(BasicBlock::reverse_iterator Begin,
321809467b48Spatrick BasicBlock::reverse_iterator End,
321909467b48Spatrick SetVector<Value *> &LiveTmp) {
322009467b48Spatrick for (auto &I : make_range(Begin, End)) {
322109467b48Spatrick // KILL/Def - Remove this definition from LiveIn
322209467b48Spatrick LiveTmp.remove(&I);
322309467b48Spatrick
322409467b48Spatrick // Don't consider *uses* in PHI nodes, we handle their contribution to
322509467b48Spatrick // predecessor blocks when we seed the LiveOut sets
322609467b48Spatrick if (isa<PHINode>(I))
322709467b48Spatrick continue;
322809467b48Spatrick
322909467b48Spatrick // USE - Add to the LiveIn set for this instruction
323009467b48Spatrick for (Value *V : I.operands()) {
323109467b48Spatrick assert(!isUnhandledGCPointerType(V->getType()) &&
323209467b48Spatrick "support for FCA unimplemented");
323309467b48Spatrick if (isHandledGCPointerType(V->getType()) && !isa<Constant>(V)) {
323409467b48Spatrick // The choice to exclude all things constant here is slightly subtle.
323509467b48Spatrick // There are two independent reasons:
323609467b48Spatrick // - We assume that things which are constant (from LLVM's definition)
323709467b48Spatrick // do not move at runtime. For example, the address of a global
323809467b48Spatrick // variable is fixed, even though it's contents may not be.
323909467b48Spatrick // - Second, we can't disallow arbitrary inttoptr constants even
324009467b48Spatrick // if the language frontend does. Optimization passes are free to
324109467b48Spatrick // locally exploit facts without respect to global reachability. This
324209467b48Spatrick // can create sections of code which are dynamically unreachable and
324309467b48Spatrick // contain just about anything. (see constants.ll in tests)
324409467b48Spatrick LiveTmp.insert(V);
324509467b48Spatrick }
324609467b48Spatrick }
324709467b48Spatrick }
324809467b48Spatrick }
324909467b48Spatrick
computeLiveOutSeed(BasicBlock * BB,SetVector<Value * > & LiveTmp)325009467b48Spatrick static void computeLiveOutSeed(BasicBlock *BB, SetVector<Value *> &LiveTmp) {
325109467b48Spatrick for (BasicBlock *Succ : successors(BB)) {
325209467b48Spatrick for (auto &I : *Succ) {
325309467b48Spatrick PHINode *PN = dyn_cast<PHINode>(&I);
325409467b48Spatrick if (!PN)
325509467b48Spatrick break;
325609467b48Spatrick
325709467b48Spatrick Value *V = PN->getIncomingValueForBlock(BB);
325809467b48Spatrick assert(!isUnhandledGCPointerType(V->getType()) &&
325909467b48Spatrick "support for FCA unimplemented");
326009467b48Spatrick if (isHandledGCPointerType(V->getType()) && !isa<Constant>(V))
326109467b48Spatrick LiveTmp.insert(V);
326209467b48Spatrick }
326309467b48Spatrick }
326409467b48Spatrick }
326509467b48Spatrick
computeKillSet(BasicBlock * BB)326609467b48Spatrick static SetVector<Value *> computeKillSet(BasicBlock *BB) {
326709467b48Spatrick SetVector<Value *> KillSet;
326809467b48Spatrick for (Instruction &I : *BB)
326909467b48Spatrick if (isHandledGCPointerType(I.getType()))
327009467b48Spatrick KillSet.insert(&I);
327109467b48Spatrick return KillSet;
327209467b48Spatrick }
327309467b48Spatrick
327409467b48Spatrick #ifndef NDEBUG
327509467b48Spatrick /// Check that the items in 'Live' dominate 'TI'. This is used as a basic
3276*d415bd75Srobert /// validation check for the liveness computation.
checkBasicSSA(DominatorTree & DT,SetVector<Value * > & Live,Instruction * TI,bool TermOkay=false)327709467b48Spatrick static void checkBasicSSA(DominatorTree &DT, SetVector<Value *> &Live,
327809467b48Spatrick Instruction *TI, bool TermOkay = false) {
327909467b48Spatrick for (Value *V : Live) {
328009467b48Spatrick if (auto *I = dyn_cast<Instruction>(V)) {
328109467b48Spatrick // The terminator can be a member of the LiveOut set. LLVM's definition
328209467b48Spatrick // of instruction dominance states that V does not dominate itself. As
328309467b48Spatrick // such, we need to special case this to allow it.
328409467b48Spatrick if (TermOkay && TI == I)
328509467b48Spatrick continue;
328609467b48Spatrick assert(DT.dominates(I, TI) &&
328709467b48Spatrick "basic SSA liveness expectation violated by liveness analysis");
328809467b48Spatrick }
328909467b48Spatrick }
329009467b48Spatrick }
329109467b48Spatrick
329209467b48Spatrick /// Check that all the liveness sets used during the computation of liveness
329309467b48Spatrick /// obey basic SSA properties. This is useful for finding cases where we miss
329409467b48Spatrick /// a def.
checkBasicSSA(DominatorTree & DT,GCPtrLivenessData & Data,BasicBlock & BB)329509467b48Spatrick static void checkBasicSSA(DominatorTree &DT, GCPtrLivenessData &Data,
329609467b48Spatrick BasicBlock &BB) {
329709467b48Spatrick checkBasicSSA(DT, Data.LiveSet[&BB], BB.getTerminator());
329809467b48Spatrick checkBasicSSA(DT, Data.LiveOut[&BB], BB.getTerminator(), true);
329909467b48Spatrick checkBasicSSA(DT, Data.LiveIn[&BB], BB.getTerminator());
330009467b48Spatrick }
330109467b48Spatrick #endif
330209467b48Spatrick
computeLiveInValues(DominatorTree & DT,Function & F,GCPtrLivenessData & Data)330309467b48Spatrick static void computeLiveInValues(DominatorTree &DT, Function &F,
330409467b48Spatrick GCPtrLivenessData &Data) {
330509467b48Spatrick SmallSetVector<BasicBlock *, 32> Worklist;
330609467b48Spatrick
330709467b48Spatrick // Seed the liveness for each individual block
330809467b48Spatrick for (BasicBlock &BB : F) {
330909467b48Spatrick Data.KillSet[&BB] = computeKillSet(&BB);
331009467b48Spatrick Data.LiveSet[&BB].clear();
331109467b48Spatrick computeLiveInValues(BB.rbegin(), BB.rend(), Data.LiveSet[&BB]);
331209467b48Spatrick
331309467b48Spatrick #ifndef NDEBUG
331409467b48Spatrick for (Value *Kill : Data.KillSet[&BB])
331509467b48Spatrick assert(!Data.LiveSet[&BB].count(Kill) && "live set contains kill");
331609467b48Spatrick #endif
331709467b48Spatrick
331809467b48Spatrick Data.LiveOut[&BB] = SetVector<Value *>();
331909467b48Spatrick computeLiveOutSeed(&BB, Data.LiveOut[&BB]);
332009467b48Spatrick Data.LiveIn[&BB] = Data.LiveSet[&BB];
332109467b48Spatrick Data.LiveIn[&BB].set_union(Data.LiveOut[&BB]);
332209467b48Spatrick Data.LiveIn[&BB].set_subtract(Data.KillSet[&BB]);
332309467b48Spatrick if (!Data.LiveIn[&BB].empty())
332409467b48Spatrick Worklist.insert(pred_begin(&BB), pred_end(&BB));
332509467b48Spatrick }
332609467b48Spatrick
332709467b48Spatrick // Propagate that liveness until stable
332809467b48Spatrick while (!Worklist.empty()) {
332909467b48Spatrick BasicBlock *BB = Worklist.pop_back_val();
333009467b48Spatrick
333109467b48Spatrick // Compute our new liveout set, then exit early if it hasn't changed despite
333209467b48Spatrick // the contribution of our successor.
333309467b48Spatrick SetVector<Value *> LiveOut = Data.LiveOut[BB];
333409467b48Spatrick const auto OldLiveOutSize = LiveOut.size();
333509467b48Spatrick for (BasicBlock *Succ : successors(BB)) {
333609467b48Spatrick assert(Data.LiveIn.count(Succ));
333709467b48Spatrick LiveOut.set_union(Data.LiveIn[Succ]);
333809467b48Spatrick }
333909467b48Spatrick // assert OutLiveOut is a subset of LiveOut
334009467b48Spatrick if (OldLiveOutSize == LiveOut.size()) {
334109467b48Spatrick // If the sets are the same size, then we didn't actually add anything
334209467b48Spatrick // when unioning our successors LiveIn. Thus, the LiveIn of this block
334309467b48Spatrick // hasn't changed.
334409467b48Spatrick continue;
334509467b48Spatrick }
334609467b48Spatrick Data.LiveOut[BB] = LiveOut;
334709467b48Spatrick
334809467b48Spatrick // Apply the effects of this basic block
334909467b48Spatrick SetVector<Value *> LiveTmp = LiveOut;
335009467b48Spatrick LiveTmp.set_union(Data.LiveSet[BB]);
335109467b48Spatrick LiveTmp.set_subtract(Data.KillSet[BB]);
335209467b48Spatrick
335309467b48Spatrick assert(Data.LiveIn.count(BB));
335409467b48Spatrick const SetVector<Value *> &OldLiveIn = Data.LiveIn[BB];
335509467b48Spatrick // assert: OldLiveIn is a subset of LiveTmp
335609467b48Spatrick if (OldLiveIn.size() != LiveTmp.size()) {
335709467b48Spatrick Data.LiveIn[BB] = LiveTmp;
335809467b48Spatrick Worklist.insert(pred_begin(BB), pred_end(BB));
335909467b48Spatrick }
336009467b48Spatrick } // while (!Worklist.empty())
336109467b48Spatrick
336209467b48Spatrick #ifndef NDEBUG
3363*d415bd75Srobert // Verify our output against SSA properties. This helps catch any
336409467b48Spatrick // missing kills during the above iteration.
336509467b48Spatrick for (BasicBlock &BB : F)
336609467b48Spatrick checkBasicSSA(DT, Data, BB);
336709467b48Spatrick #endif
336809467b48Spatrick }
336909467b48Spatrick
findLiveSetAtInst(Instruction * Inst,GCPtrLivenessData & Data,StatepointLiveSetTy & Out)337009467b48Spatrick static void findLiveSetAtInst(Instruction *Inst, GCPtrLivenessData &Data,
337109467b48Spatrick StatepointLiveSetTy &Out) {
337209467b48Spatrick BasicBlock *BB = Inst->getParent();
337309467b48Spatrick
337409467b48Spatrick // Note: The copy is intentional and required
337509467b48Spatrick assert(Data.LiveOut.count(BB));
337609467b48Spatrick SetVector<Value *> LiveOut = Data.LiveOut[BB];
337709467b48Spatrick
337809467b48Spatrick // We want to handle the statepoint itself oddly. It's
337909467b48Spatrick // call result is not live (normal), nor are it's arguments
338009467b48Spatrick // (unless they're used again later). This adjustment is
338109467b48Spatrick // specifically what we need to relocate
338209467b48Spatrick computeLiveInValues(BB->rbegin(), ++Inst->getIterator().getReverse(),
338309467b48Spatrick LiveOut);
338409467b48Spatrick LiveOut.remove(Inst);
338509467b48Spatrick Out.insert(LiveOut.begin(), LiveOut.end());
338609467b48Spatrick }
338709467b48Spatrick
recomputeLiveInValues(GCPtrLivenessData & RevisedLivenessData,CallBase * Call,PartiallyConstructedSafepointRecord & Info,PointerToBaseTy & PointerToBase)338809467b48Spatrick static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
338909467b48Spatrick CallBase *Call,
3390*d415bd75Srobert PartiallyConstructedSafepointRecord &Info,
3391*d415bd75Srobert PointerToBaseTy &PointerToBase) {
339209467b48Spatrick StatepointLiveSetTy Updated;
339309467b48Spatrick findLiveSetAtInst(Call, RevisedLivenessData, Updated);
339409467b48Spatrick
339509467b48Spatrick // We may have base pointers which are now live that weren't before. We need
339609467b48Spatrick // to update the PointerToBase structure to reflect this.
3397*d415bd75Srobert for (auto *V : Updated)
3398*d415bd75Srobert PointerToBase.insert({ V, V });
339909467b48Spatrick
340009467b48Spatrick Info.LiveSet = Updated;
340109467b48Spatrick }
3402