xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- RewriteStatepointsForGC.cpp - Make GC relocations explicit ---------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Rewrite call/invoke instructions so as to make potential relocations
100b57cec5SDimitry Andric // performed by the garbage collector explicit in the IR.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
180b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h"
190b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
215f757f3fSDimitry Andric #include "llvm/ADT/Sequence.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
230b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
240b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
250b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
260b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
270b57cec5SDimitry Andric #include "llvm/Analysis/DomTreeUpdater.h"
280b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
290b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
300b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
3106c3fb27SDimitry Andric #include "llvm/IR/AttributeMask.h"
320b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
330b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
340b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
350b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
360b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
370b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
380b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
390b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
400b57cec5SDimitry Andric #include "llvm/IR/Function.h"
4106c3fb27SDimitry Andric #include "llvm/IR/GCStrategy.h"
420b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h"
430b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h"
440b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
450b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
460b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
470b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
480b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
490b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
500b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
510b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
520b57cec5SDimitry Andric #include "llvm/IR/Module.h"
530b57cec5SDimitry Andric #include "llvm/IR/Statepoint.h"
540b57cec5SDimitry Andric #include "llvm/IR/Type.h"
550b57cec5SDimitry Andric #include "llvm/IR/User.h"
560b57cec5SDimitry Andric #include "llvm/IR/Value.h"
570b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h"
580b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
590b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
600b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
610b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
620b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
630b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
640b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
650b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
660b57cec5SDimitry Andric #include "llvm/Transforms/Utils/PromoteMemToReg.h"
670b57cec5SDimitry Andric #include <algorithm>
680b57cec5SDimitry Andric #include <cassert>
690b57cec5SDimitry Andric #include <cstddef>
700b57cec5SDimitry Andric #include <cstdint>
710b57cec5SDimitry Andric #include <iterator>
72bdd1243dSDimitry Andric #include <optional>
730b57cec5SDimitry Andric #include <set>
740b57cec5SDimitry Andric #include <string>
750b57cec5SDimitry Andric #include <utility>
760b57cec5SDimitry Andric #include <vector>
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric #define DEBUG_TYPE "rewrite-statepoints-for-gc"
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric using namespace llvm;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric // Print the liveset found at the insert location
830b57cec5SDimitry Andric static cl::opt<bool> PrintLiveSet("spp-print-liveset", cl::Hidden,
840b57cec5SDimitry Andric                                   cl::init(false));
850b57cec5SDimitry Andric static cl::opt<bool> PrintLiveSetSize("spp-print-liveset-size", cl::Hidden,
860b57cec5SDimitry Andric                                       cl::init(false));
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric // Print out the base pointers for debugging
890b57cec5SDimitry Andric static cl::opt<bool> PrintBasePointers("spp-print-base-pointers", cl::Hidden,
900b57cec5SDimitry Andric                                        cl::init(false));
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric // Cost threshold measuring when it is profitable to rematerialize value instead
930b57cec5SDimitry Andric // of relocating it
940b57cec5SDimitry Andric static cl::opt<unsigned>
950b57cec5SDimitry Andric RematerializationThreshold("spp-rematerialization-threshold", cl::Hidden,
960b57cec5SDimitry Andric                            cl::init(6));
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
990b57cec5SDimitry Andric static bool ClobberNonLive = true;
1000b57cec5SDimitry Andric #else
1010b57cec5SDimitry Andric static bool ClobberNonLive = false;
1020b57cec5SDimitry Andric #endif
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric static cl::opt<bool, true> ClobberNonLiveOverride("rs4gc-clobber-non-live",
1050b57cec5SDimitry Andric                                                   cl::location(ClobberNonLive),
1060b57cec5SDimitry Andric                                                   cl::Hidden);
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric static cl::opt<bool>
1090b57cec5SDimitry Andric     AllowStatepointWithNoDeoptInfo("rs4gc-allow-statepoint-with-no-deopt-info",
1100b57cec5SDimitry Andric                                    cl::Hidden, cl::init(true));
1110b57cec5SDimitry Andric 
112bdd1243dSDimitry Andric static cl::opt<bool> RematDerivedAtUses("rs4gc-remat-derived-at-uses",
113bdd1243dSDimitry Andric                                         cl::Hidden, cl::init(true));
114bdd1243dSDimitry Andric 
1150b57cec5SDimitry Andric /// The IR fed into RewriteStatepointsForGC may have had attributes and
1160b57cec5SDimitry Andric /// metadata implying dereferenceability that are no longer valid/correct after
1170b57cec5SDimitry Andric /// RewriteStatepointsForGC has run. This is because semantically, after
1180b57cec5SDimitry Andric /// RewriteStatepointsForGC runs, all calls to gc.statepoint "free" the entire
1190b57cec5SDimitry Andric /// heap. stripNonValidData (conservatively) restores
1200b57cec5SDimitry Andric /// correctness by erasing all attributes in the module that externally imply
1210b57cec5SDimitry Andric /// dereferenceability. Similar reasoning also applies to the noalias
1220b57cec5SDimitry Andric /// attributes and metadata. gc.statepoint can touch the entire heap including
1230b57cec5SDimitry Andric /// noalias objects.
1240b57cec5SDimitry Andric /// Apart from attributes and metadata, we also remove instructions that imply
1250b57cec5SDimitry Andric /// constant physical memory: llvm.invariant.start.
1260b57cec5SDimitry Andric static void stripNonValidData(Module &M);
1270b57cec5SDimitry Andric 
12806c3fb27SDimitry Andric // Find the GC strategy for a function, or null if it doesn't have one.
12906c3fb27SDimitry Andric static std::unique_ptr<GCStrategy> findGCStrategy(Function &F);
13006c3fb27SDimitry Andric 
1310b57cec5SDimitry Andric static bool shouldRewriteStatepointsIn(Function &F);
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric PreservedAnalyses RewriteStatepointsForGC::run(Module &M,
1340b57cec5SDimitry Andric                                                ModuleAnalysisManager &AM) {
1350b57cec5SDimitry Andric   bool Changed = false;
1360b57cec5SDimitry Andric   auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
1370b57cec5SDimitry Andric   for (Function &F : M) {
1380b57cec5SDimitry Andric     // Nothing to do for declarations.
1390b57cec5SDimitry Andric     if (F.isDeclaration() || F.empty())
1400b57cec5SDimitry Andric       continue;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric     // Policy choice says not to rewrite - the most common reason is that we're
1430b57cec5SDimitry Andric     // compiling code without a GCStrategy.
1440b57cec5SDimitry Andric     if (!shouldRewriteStatepointsIn(F))
1450b57cec5SDimitry Andric       continue;
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric     auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
1480b57cec5SDimitry Andric     auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
1490b57cec5SDimitry Andric     auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
1500b57cec5SDimitry Andric     Changed |= runOnFunction(F, DT, TTI, TLI);
1510b57cec5SDimitry Andric   }
1520b57cec5SDimitry Andric   if (!Changed)
1530b57cec5SDimitry Andric     return PreservedAnalyses::all();
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   // stripNonValidData asserts that shouldRewriteStatepointsIn
1560b57cec5SDimitry Andric   // returns true for at least one function in the module.  Since at least
1570b57cec5SDimitry Andric   // one function changed, we know that the precondition is satisfied.
1580b57cec5SDimitry Andric   stripNonValidData(M);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   PreservedAnalyses PA;
1610b57cec5SDimitry Andric   PA.preserve<TargetIRAnalysis>();
1620b57cec5SDimitry Andric   PA.preserve<TargetLibraryAnalysis>();
1630b57cec5SDimitry Andric   return PA;
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric namespace {
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric struct GCPtrLivenessData {
1690b57cec5SDimitry Andric   /// Values defined in this block.
1700b57cec5SDimitry Andric   MapVector<BasicBlock *, SetVector<Value *>> KillSet;
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric   /// Values used in this block (and thus live); does not included values
1730b57cec5SDimitry Andric   /// killed within this block.
1740b57cec5SDimitry Andric   MapVector<BasicBlock *, SetVector<Value *>> LiveSet;
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   /// Values live into this basic block (i.e. used by any
1770b57cec5SDimitry Andric   /// instruction in this basic block or ones reachable from here)
1780b57cec5SDimitry Andric   MapVector<BasicBlock *, SetVector<Value *>> LiveIn;
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   /// Values live out of this basic block (i.e. live into
1810b57cec5SDimitry Andric   /// any successor block)
1820b57cec5SDimitry Andric   MapVector<BasicBlock *, SetVector<Value *>> LiveOut;
1830b57cec5SDimitry Andric };
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric // The type of the internal cache used inside the findBasePointers family
1860b57cec5SDimitry Andric // of functions.  From the callers perspective, this is an opaque type and
1870b57cec5SDimitry Andric // should not be inspected.
1880b57cec5SDimitry Andric //
1890b57cec5SDimitry Andric // In the actual implementation this caches two relations:
1900b57cec5SDimitry Andric // - The base relation itself (i.e. this pointer is based on that one)
1910b57cec5SDimitry Andric // - The base defining value relation (i.e. before base_phi insertion)
1920b57cec5SDimitry Andric // Generally, after the execution of a full findBasePointer call, only the
1930b57cec5SDimitry Andric // base relation will remain.  Internally, we add a mixture of the two
1940b57cec5SDimitry Andric // types, then update all the second type to the first type
1950b57cec5SDimitry Andric using DefiningValueMapTy = MapVector<Value *, Value *>;
19681ad6265SDimitry Andric using IsKnownBaseMapTy = MapVector<Value *, bool>;
1971fd87a68SDimitry Andric using PointerToBaseTy = MapVector<Value *, Value *>;
1980b57cec5SDimitry Andric using StatepointLiveSetTy = SetVector<Value *>;
1990b57cec5SDimitry Andric using RematerializedValueMapTy =
2000b57cec5SDimitry Andric     MapVector<AssertingVH<Instruction>, AssertingVH<Value>>;
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric struct PartiallyConstructedSafepointRecord {
2030b57cec5SDimitry Andric   /// The set of values known to be live across this safepoint
2040b57cec5SDimitry Andric   StatepointLiveSetTy LiveSet;
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   /// The *new* gc.statepoint instruction itself.  This produces the token
2070b57cec5SDimitry Andric   /// that normal path gc.relocates and the gc.result are tied to.
2085ffd83dbSDimitry Andric   GCStatepointInst *StatepointToken;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   /// Instruction to which exceptional gc relocates are attached
2110b57cec5SDimitry Andric   /// Makes it easier to iterate through them during relocationViaAlloca.
2120b57cec5SDimitry Andric   Instruction *UnwindToken;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   /// Record live values we are rematerialized instead of relocating.
2150b57cec5SDimitry Andric   /// They are not included into 'LiveSet' field.
2160b57cec5SDimitry Andric   /// Maps rematerialized copy to it's original value.
2170b57cec5SDimitry Andric   RematerializedValueMapTy RematerializedValues;
2180b57cec5SDimitry Andric };
2190b57cec5SDimitry Andric 
22081ad6265SDimitry Andric struct RematerizlizationCandidateRecord {
22181ad6265SDimitry Andric   // Chain from derived pointer to base.
22281ad6265SDimitry Andric   SmallVector<Instruction *, 3> ChainToBase;
22381ad6265SDimitry Andric   // Original base.
22481ad6265SDimitry Andric   Value *RootOfChain;
22581ad6265SDimitry Andric   // Cost of chain.
22681ad6265SDimitry Andric   InstructionCost Cost;
22781ad6265SDimitry Andric };
22881ad6265SDimitry Andric using RematCandTy = MapVector<Value *, RematerizlizationCandidateRecord>;
22981ad6265SDimitry Andric 
2300b57cec5SDimitry Andric } // end anonymous namespace
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric static ArrayRef<Use> GetDeoptBundleOperands(const CallBase *Call) {
233bdd1243dSDimitry Andric   std::optional<OperandBundleUse> DeoptBundle =
2340b57cec5SDimitry Andric       Call->getOperandBundle(LLVMContext::OB_deopt);
2350b57cec5SDimitry Andric 
23681ad6265SDimitry Andric   if (!DeoptBundle) {
2370b57cec5SDimitry Andric     assert(AllowStatepointWithNoDeoptInfo &&
2380b57cec5SDimitry Andric            "Found non-leaf call without deopt info!");
239bdd1243dSDimitry Andric     return std::nullopt;
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric 
24281ad6265SDimitry Andric   return DeoptBundle->Inputs;
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric /// Compute the live-in set for every basic block in the function
2460b57cec5SDimitry Andric static void computeLiveInValues(DominatorTree &DT, Function &F,
24706c3fb27SDimitry Andric                                 GCPtrLivenessData &Data, GCStrategy *GC);
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric /// Given results from the dataflow liveness computation, find the set of live
2500b57cec5SDimitry Andric /// Values at a particular instruction.
2510b57cec5SDimitry Andric static void findLiveSetAtInst(Instruction *inst, GCPtrLivenessData &Data,
25206c3fb27SDimitry Andric                               StatepointLiveSetTy &out, GCStrategy *GC);
2530b57cec5SDimitry Andric 
25406c3fb27SDimitry Andric static bool isGCPointerType(Type *T, GCStrategy *GC) {
25506c3fb27SDimitry Andric   assert(GC && "GC Strategy for isGCPointerType cannot be null");
2560b57cec5SDimitry Andric 
25706c3fb27SDimitry Andric   if (!isa<PointerType>(T))
2580b57cec5SDimitry Andric     return false;
25906c3fb27SDimitry Andric 
26006c3fb27SDimitry Andric   // conservative - same as StatepointLowering
26106c3fb27SDimitry Andric   return GC->isGCManagedPointer(T).value_or(true);
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric // Return true if this type is one which a) is a gc pointer or contains a GC
2650b57cec5SDimitry Andric // pointer and b) is of a type this code expects to encounter as a live value.
2660b57cec5SDimitry Andric // (The insertion code will assert that a type which matches (a) and not (b)
2670b57cec5SDimitry Andric // is not encountered.)
26806c3fb27SDimitry Andric static bool isHandledGCPointerType(Type *T, GCStrategy *GC) {
2690b57cec5SDimitry Andric   // We fully support gc pointers
27006c3fb27SDimitry Andric   if (isGCPointerType(T, GC))
2710b57cec5SDimitry Andric     return true;
2720b57cec5SDimitry Andric   // We partially support vectors of gc pointers. The code will assert if it
2730b57cec5SDimitry Andric   // can't handle something.
2740b57cec5SDimitry Andric   if (auto VT = dyn_cast<VectorType>(T))
27506c3fb27SDimitry Andric     if (isGCPointerType(VT->getElementType(), GC))
2760b57cec5SDimitry Andric       return true;
2770b57cec5SDimitry Andric   return false;
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric #ifndef NDEBUG
2810b57cec5SDimitry Andric /// Returns true if this type contains a gc pointer whether we know how to
2820b57cec5SDimitry Andric /// handle that type or not.
28306c3fb27SDimitry Andric static bool containsGCPtrType(Type *Ty, GCStrategy *GC) {
28406c3fb27SDimitry Andric   if (isGCPointerType(Ty, GC))
2850b57cec5SDimitry Andric     return true;
2860b57cec5SDimitry Andric   if (VectorType *VT = dyn_cast<VectorType>(Ty))
28706c3fb27SDimitry Andric     return isGCPointerType(VT->getScalarType(), GC);
2880b57cec5SDimitry Andric   if (ArrayType *AT = dyn_cast<ArrayType>(Ty))
28906c3fb27SDimitry Andric     return containsGCPtrType(AT->getElementType(), GC);
2900b57cec5SDimitry Andric   if (StructType *ST = dyn_cast<StructType>(Ty))
29106c3fb27SDimitry Andric     return llvm::any_of(ST->elements(),
29206c3fb27SDimitry Andric                         [GC](Type *Ty) { return containsGCPtrType(Ty, GC); });
2930b57cec5SDimitry Andric   return false;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric // Returns true if this is a type which a) is a gc pointer or contains a GC
2970b57cec5SDimitry Andric // pointer and b) is of a type which the code doesn't expect (i.e. first class
2980b57cec5SDimitry Andric // aggregates).  Used to trip assertions.
29906c3fb27SDimitry Andric static bool isUnhandledGCPointerType(Type *Ty, GCStrategy *GC) {
30006c3fb27SDimitry Andric   return containsGCPtrType(Ty, GC) && !isHandledGCPointerType(Ty, GC);
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric #endif
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric // Return the name of the value suffixed with the provided value, or if the
3050b57cec5SDimitry Andric // value didn't have a name, the default value specified.
3060b57cec5SDimitry Andric static std::string suffixed_name_or(Value *V, StringRef Suffix,
3070b57cec5SDimitry Andric                                     StringRef DefaultName) {
3080b57cec5SDimitry Andric   return V->hasName() ? (V->getName() + Suffix).str() : DefaultName.str();
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric // Conservatively identifies any definitions which might be live at the
3120b57cec5SDimitry Andric // given instruction. The  analysis is performed immediately before the
3130b57cec5SDimitry Andric // given instruction. Values defined by that instruction are not considered
3140b57cec5SDimitry Andric // live.  Values used by that instruction are considered live.
3150b57cec5SDimitry Andric static void analyzeParsePointLiveness(
3160b57cec5SDimitry Andric     DominatorTree &DT, GCPtrLivenessData &OriginalLivenessData, CallBase *Call,
31706c3fb27SDimitry Andric     PartiallyConstructedSafepointRecord &Result, GCStrategy *GC) {
3180b57cec5SDimitry Andric   StatepointLiveSetTy LiveSet;
31906c3fb27SDimitry Andric   findLiveSetAtInst(Call, OriginalLivenessData, LiveSet, GC);
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   if (PrintLiveSet) {
3220b57cec5SDimitry Andric     dbgs() << "Live Variables:\n";
3230b57cec5SDimitry Andric     for (Value *V : LiveSet)
3240b57cec5SDimitry Andric       dbgs() << " " << V->getName() << " " << *V << "\n";
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric   if (PrintLiveSetSize) {
3275ffd83dbSDimitry Andric     dbgs() << "Safepoint For: " << Call->getCalledOperand()->getName() << "\n";
3280b57cec5SDimitry Andric     dbgs() << "Number live values: " << LiveSet.size() << "\n";
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric   Result.LiveSet = LiveSet;
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric 
33381ad6265SDimitry Andric /// Returns true if V is a known base.
33481ad6265SDimitry Andric static bool isKnownBase(Value *V, const IsKnownBaseMapTy &KnownBases);
3350b57cec5SDimitry Andric 
33681ad6265SDimitry Andric /// Caches the IsKnownBase flag for a value and asserts that it wasn't present
33781ad6265SDimitry Andric /// in the cache before.
33881ad6265SDimitry Andric static void setKnownBase(Value *V, bool IsKnownBase,
33981ad6265SDimitry Andric                          IsKnownBaseMapTy &KnownBases);
3405ffd83dbSDimitry Andric 
34181ad6265SDimitry Andric static Value *findBaseDefiningValue(Value *I, DefiningValueMapTy &Cache,
34281ad6265SDimitry Andric                                     IsKnownBaseMapTy &KnownBases);
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric /// Return a base defining value for the 'Index' element of the given vector
3450b57cec5SDimitry Andric /// instruction 'I'.  If Index is null, returns a BDV for the entire vector
3460b57cec5SDimitry Andric /// 'I'.  As an optimization, this method will try to determine when the
3470b57cec5SDimitry Andric /// element is known to already be a base pointer.  If this can be established,
3480b57cec5SDimitry Andric /// the second value in the returned pair will be true.  Note that either a
3490b57cec5SDimitry Andric /// vector or a pointer typed value can be returned.  For the former, the
3500b57cec5SDimitry Andric /// vector returned is a BDV (and possibly a base) of the entire vector 'I'.
3510b57cec5SDimitry Andric /// If the later, the return pointer is a BDV (or possibly a base) for the
3520b57cec5SDimitry Andric /// particular element in 'I'.
35381ad6265SDimitry Andric static Value *findBaseDefiningValueOfVector(Value *I, DefiningValueMapTy &Cache,
35481ad6265SDimitry Andric                                             IsKnownBaseMapTy &KnownBases) {
3550b57cec5SDimitry Andric   // Each case parallels findBaseDefiningValue below, see that code for
3560b57cec5SDimitry Andric   // detailed motivation.
3570b57cec5SDimitry Andric 
35881ad6265SDimitry Andric   auto Cached = Cache.find(I);
35981ad6265SDimitry Andric   if (Cached != Cache.end())
36081ad6265SDimitry Andric     return Cached->second;
3610b57cec5SDimitry Andric 
36281ad6265SDimitry Andric   if (isa<Argument>(I)) {
36381ad6265SDimitry Andric     // An incoming argument to the function is a base pointer
36481ad6265SDimitry Andric     Cache[I] = I;
36581ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
36681ad6265SDimitry Andric     return I;
36781ad6265SDimitry Andric   }
36881ad6265SDimitry Andric 
36981ad6265SDimitry Andric   if (isa<Constant>(I)) {
3700b57cec5SDimitry Andric     // Base of constant vector consists only of constant null pointers.
3710b57cec5SDimitry Andric     // For reasoning see similar case inside 'findBaseDefiningValue' function.
37281ad6265SDimitry Andric     auto *CAZ = ConstantAggregateZero::get(I->getType());
37381ad6265SDimitry Andric     Cache[I] = CAZ;
37481ad6265SDimitry Andric     setKnownBase(CAZ, /* IsKnownBase */true, KnownBases);
37581ad6265SDimitry Andric     return CAZ;
37681ad6265SDimitry Andric   }
3770b57cec5SDimitry Andric 
37881ad6265SDimitry Andric   if (isa<LoadInst>(I)) {
37981ad6265SDimitry Andric     Cache[I] = I;
38081ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
38181ad6265SDimitry Andric     return I;
38281ad6265SDimitry Andric   }
3830b57cec5SDimitry Andric 
38481ad6265SDimitry Andric   if (isa<InsertElementInst>(I)) {
3850b57cec5SDimitry Andric     // We don't know whether this vector contains entirely base pointers or
3860b57cec5SDimitry Andric     // not.  To be conservatively correct, we treat it as a BDV and will
3870b57cec5SDimitry Andric     // duplicate code as needed to construct a parallel vector of bases.
38881ad6265SDimitry Andric     Cache[I] = I;
38981ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */false, KnownBases);
39081ad6265SDimitry Andric     return I;
39181ad6265SDimitry Andric   }
3920b57cec5SDimitry Andric 
39381ad6265SDimitry Andric   if (isa<ShuffleVectorInst>(I)) {
3940b57cec5SDimitry Andric     // We don't know whether this vector contains entirely base pointers or
3950b57cec5SDimitry Andric     // not.  To be conservatively correct, we treat it as a BDV and will
3960b57cec5SDimitry Andric     // duplicate code as needed to construct a parallel vector of bases.
3970b57cec5SDimitry Andric     // TODO: There a number of local optimizations which could be applied here
3980b57cec5SDimitry Andric     // for particular sufflevector patterns.
39981ad6265SDimitry Andric     Cache[I] = I;
40081ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */false, KnownBases);
40181ad6265SDimitry Andric     return I;
40281ad6265SDimitry Andric   }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   // The behavior of getelementptr instructions is the same for vector and
4050b57cec5SDimitry Andric   // non-vector data types.
40681ad6265SDimitry Andric   if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
40781ad6265SDimitry Andric     auto *BDV =
40881ad6265SDimitry Andric         findBaseDefiningValue(GEP->getPointerOperand(), Cache, KnownBases);
40981ad6265SDimitry Andric     Cache[GEP] = BDV;
41081ad6265SDimitry Andric     return BDV;
41181ad6265SDimitry Andric   }
41281ad6265SDimitry Andric 
41381ad6265SDimitry Andric   // The behavior of freeze instructions is the same for vector and
41481ad6265SDimitry Andric   // non-vector data types.
41581ad6265SDimitry Andric   if (auto *Freeze = dyn_cast<FreezeInst>(I)) {
41681ad6265SDimitry Andric     auto *BDV = findBaseDefiningValue(Freeze->getOperand(0), Cache, KnownBases);
41781ad6265SDimitry Andric     Cache[Freeze] = BDV;
41881ad6265SDimitry Andric     return BDV;
41981ad6265SDimitry Andric   }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   // If the pointer comes through a bitcast of a vector of pointers to
4220b57cec5SDimitry Andric   // a vector of another type of pointer, then look through the bitcast
42381ad6265SDimitry Andric   if (auto *BC = dyn_cast<BitCastInst>(I)) {
42481ad6265SDimitry Andric     auto *BDV = findBaseDefiningValue(BC->getOperand(0), Cache, KnownBases);
42581ad6265SDimitry Andric     Cache[BC] = BDV;
42681ad6265SDimitry Andric     return BDV;
42781ad6265SDimitry Andric   }
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   // We assume that functions in the source language only return base
4300b57cec5SDimitry Andric   // pointers.  This should probably be generalized via attributes to support
4310b57cec5SDimitry Andric   // both source language and internal functions.
43281ad6265SDimitry Andric   if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
43381ad6265SDimitry Andric     Cache[I] = I;
43481ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
43581ad6265SDimitry Andric     return I;
43681ad6265SDimitry Andric   }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric   // A PHI or Select is a base defining value.  The outer findBasePointer
4390b57cec5SDimitry Andric   // algorithm is responsible for constructing a base value for this BDV.
4400b57cec5SDimitry Andric   assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
4410b57cec5SDimitry Andric          "unknown vector instruction - no base found for vector element");
44281ad6265SDimitry Andric   Cache[I] = I;
44381ad6265SDimitry Andric   setKnownBase(I, /* IsKnownBase */false, KnownBases);
44481ad6265SDimitry Andric   return I;
4450b57cec5SDimitry Andric }
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric /// Helper function for findBasePointer - Will return a value which either a)
4480b57cec5SDimitry Andric /// defines the base pointer for the input, b) blocks the simple search
4490b57cec5SDimitry Andric /// (i.e. a PHI or Select of two derived pointers), or c) involves a change
4500b57cec5SDimitry Andric /// from pointer to vector type or back.
45181ad6265SDimitry Andric static Value *findBaseDefiningValue(Value *I, DefiningValueMapTy &Cache,
45281ad6265SDimitry Andric                                     IsKnownBaseMapTy &KnownBases) {
4530b57cec5SDimitry Andric   assert(I->getType()->isPtrOrPtrVectorTy() &&
4540b57cec5SDimitry Andric          "Illegal to ask for the base pointer of a non-pointer type");
45581ad6265SDimitry Andric   auto Cached = Cache.find(I);
45681ad6265SDimitry Andric   if (Cached != Cache.end())
45781ad6265SDimitry Andric     return Cached->second;
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   if (I->getType()->isVectorTy())
46081ad6265SDimitry Andric     return findBaseDefiningValueOfVector(I, Cache, KnownBases);
4610b57cec5SDimitry Andric 
46281ad6265SDimitry Andric   if (isa<Argument>(I)) {
4630b57cec5SDimitry Andric     // An incoming argument to the function is a base pointer
4640b57cec5SDimitry Andric     // We should have never reached here if this argument isn't an gc value
46581ad6265SDimitry Andric     Cache[I] = I;
46681ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
46781ad6265SDimitry Andric     return I;
46881ad6265SDimitry Andric   }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   if (isa<Constant>(I)) {
4710b57cec5SDimitry Andric     // We assume that objects with a constant base (e.g. a global) can't move
4720b57cec5SDimitry Andric     // and don't need to be reported to the collector because they are always
4730b57cec5SDimitry Andric     // live. Besides global references, all kinds of constants (e.g. undef,
4740b57cec5SDimitry Andric     // constant expressions, null pointers) can be introduced by the inliner or
4750b57cec5SDimitry Andric     // the optimizer, especially on dynamically dead paths.
4760b57cec5SDimitry Andric     // Here we treat all of them as having single null base. By doing this we
4770b57cec5SDimitry Andric     // trying to avoid problems reporting various conflicts in a form of
4780b57cec5SDimitry Andric     // "phi (const1, const2)" or "phi (const, regular gc ptr)".
4790b57cec5SDimitry Andric     // See constant.ll file for relevant test cases.
4800b57cec5SDimitry Andric 
48181ad6265SDimitry Andric     auto *CPN = ConstantPointerNull::get(cast<PointerType>(I->getType()));
48281ad6265SDimitry Andric     Cache[I] = CPN;
48381ad6265SDimitry Andric     setKnownBase(CPN, /* IsKnownBase */true, KnownBases);
48481ad6265SDimitry Andric     return CPN;
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric 
487fe6060f1SDimitry Andric   // inttoptrs in an integral address space are currently ill-defined.  We
488fe6060f1SDimitry Andric   // treat them as defining base pointers here for consistency with the
489fe6060f1SDimitry Andric   // constant rule above and because we don't really have a better semantic
490fe6060f1SDimitry Andric   // to give them.  Note that the optimizer is always free to insert undefined
491fe6060f1SDimitry Andric   // behavior on dynamically dead paths as well.
49281ad6265SDimitry Andric   if (isa<IntToPtrInst>(I)) {
49381ad6265SDimitry Andric     Cache[I] = I;
49481ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
49581ad6265SDimitry Andric     return I;
49681ad6265SDimitry Andric   }
497fe6060f1SDimitry Andric 
4980b57cec5SDimitry Andric   if (CastInst *CI = dyn_cast<CastInst>(I)) {
4990b57cec5SDimitry Andric     Value *Def = CI->stripPointerCasts();
5000b57cec5SDimitry Andric     // If stripping pointer casts changes the address space there is an
5010b57cec5SDimitry Andric     // addrspacecast in between.
5020b57cec5SDimitry Andric     assert(cast<PointerType>(Def->getType())->getAddressSpace() ==
5030b57cec5SDimitry Andric                cast<PointerType>(CI->getType())->getAddressSpace() &&
5040b57cec5SDimitry Andric            "unsupported addrspacecast");
5050b57cec5SDimitry Andric     // If we find a cast instruction here, it means we've found a cast which is
5060b57cec5SDimitry Andric     // not simply a pointer cast (i.e. an inttoptr).  We don't know how to
5070b57cec5SDimitry Andric     // handle int->ptr conversion.
5080b57cec5SDimitry Andric     assert(!isa<CastInst>(Def) && "shouldn't find another cast here");
50981ad6265SDimitry Andric     auto *BDV = findBaseDefiningValue(Def, Cache, KnownBases);
51081ad6265SDimitry Andric     Cache[CI] = BDV;
51181ad6265SDimitry Andric     return BDV;
5120b57cec5SDimitry Andric   }
5130b57cec5SDimitry Andric 
51481ad6265SDimitry Andric   if (isa<LoadInst>(I)) {
5150b57cec5SDimitry Andric     // The value loaded is an gc base itself
51681ad6265SDimitry Andric     Cache[I] = I;
51781ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
51881ad6265SDimitry Andric     return I;
51981ad6265SDimitry Andric   }
5200b57cec5SDimitry Andric 
52181ad6265SDimitry Andric   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
5220b57cec5SDimitry Andric     // The base of this GEP is the base
52381ad6265SDimitry Andric     auto *BDV =
52481ad6265SDimitry Andric         findBaseDefiningValue(GEP->getPointerOperand(), Cache, KnownBases);
52581ad6265SDimitry Andric     Cache[GEP] = BDV;
52681ad6265SDimitry Andric     return BDV;
52781ad6265SDimitry Andric   }
52881ad6265SDimitry Andric 
52981ad6265SDimitry Andric   if (auto *Freeze = dyn_cast<FreezeInst>(I)) {
53081ad6265SDimitry Andric     auto *BDV = findBaseDefiningValue(Freeze->getOperand(0), Cache, KnownBases);
53181ad6265SDimitry Andric     Cache[Freeze] = BDV;
53281ad6265SDimitry Andric     return BDV;
53381ad6265SDimitry Andric   }
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5360b57cec5SDimitry Andric     switch (II->getIntrinsicID()) {
5370b57cec5SDimitry Andric     default:
5380b57cec5SDimitry Andric       // fall through to general call handling
5390b57cec5SDimitry Andric       break;
5400b57cec5SDimitry Andric     case Intrinsic::experimental_gc_statepoint:
5410b57cec5SDimitry Andric       llvm_unreachable("statepoints don't produce pointers");
5420b57cec5SDimitry Andric     case Intrinsic::experimental_gc_relocate:
5430b57cec5SDimitry Andric       // Rerunning safepoint insertion after safepoints are already
5440b57cec5SDimitry Andric       // inserted is not supported.  It could probably be made to work,
5450b57cec5SDimitry Andric       // but why are you doing this?  There's no good reason.
5460b57cec5SDimitry Andric       llvm_unreachable("repeat safepoint insertion is not supported");
5470b57cec5SDimitry Andric     case Intrinsic::gcroot:
5480b57cec5SDimitry Andric       // Currently, this mechanism hasn't been extended to work with gcroot.
5490b57cec5SDimitry Andric       // There's no reason it couldn't be, but I haven't thought about the
5500b57cec5SDimitry Andric       // implications much.
5510b57cec5SDimitry Andric       llvm_unreachable(
5520b57cec5SDimitry Andric           "interaction with the gcroot mechanism is not supported");
553fe6060f1SDimitry Andric     case Intrinsic::experimental_gc_get_pointer_base:
55481ad6265SDimitry Andric       auto *BDV = findBaseDefiningValue(II->getOperand(0), Cache, KnownBases);
55581ad6265SDimitry Andric       Cache[II] = BDV;
55681ad6265SDimitry Andric       return BDV;
5570b57cec5SDimitry Andric     }
5580b57cec5SDimitry Andric   }
5590b57cec5SDimitry Andric   // We assume that functions in the source language only return base
5600b57cec5SDimitry Andric   // pointers.  This should probably be generalized via attributes to support
5610b57cec5SDimitry Andric   // both source language and internal functions.
56281ad6265SDimitry Andric   if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
56381ad6265SDimitry Andric     Cache[I] = I;
56481ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
56581ad6265SDimitry Andric     return I;
56681ad6265SDimitry Andric   }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   // TODO: I have absolutely no idea how to implement this part yet.  It's not
5690b57cec5SDimitry Andric   // necessarily hard, I just haven't really looked at it yet.
5700b57cec5SDimitry Andric   assert(!isa<LandingPadInst>(I) && "Landing Pad is unimplemented");
5710b57cec5SDimitry Andric 
57281ad6265SDimitry Andric   if (isa<AtomicCmpXchgInst>(I)) {
5730b57cec5SDimitry Andric     // A CAS is effectively a atomic store and load combined under a
5740b57cec5SDimitry Andric     // predicate.  From the perspective of base pointers, we just treat it
5750b57cec5SDimitry Andric     // like a load.
57681ad6265SDimitry Andric     Cache[I] = I;
57781ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
57881ad6265SDimitry Andric     return I;
57981ad6265SDimitry Andric   }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   assert(!isa<AtomicRMWInst>(I) && "Xchg handled above, all others are "
5820b57cec5SDimitry Andric                                    "binary ops which don't apply to pointers");
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   // The aggregate ops.  Aggregates can either be in the heap or on the
5850b57cec5SDimitry Andric   // stack, but in either case, this is simply a field load.  As a result,
5860b57cec5SDimitry Andric   // this is a defining definition of the base just like a load is.
58781ad6265SDimitry Andric   if (isa<ExtractValueInst>(I)) {
58881ad6265SDimitry Andric     Cache[I] = I;
58981ad6265SDimitry Andric     setKnownBase(I, /* IsKnownBase */true, KnownBases);
59081ad6265SDimitry Andric     return I;
59181ad6265SDimitry Andric   }
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   // We should never see an insert vector since that would require we be
5940b57cec5SDimitry Andric   // tracing back a struct value not a pointer value.
5950b57cec5SDimitry Andric   assert(!isa<InsertValueInst>(I) &&
5960b57cec5SDimitry Andric          "Base pointer for a struct is meaningless");
5970b57cec5SDimitry Andric 
598fe6060f1SDimitry Andric   // This value might have been generated by findBasePointer() called when
599fe6060f1SDimitry Andric   // substituting gc.get.pointer.base() intrinsic.
600fe6060f1SDimitry Andric   bool IsKnownBase =
601fe6060f1SDimitry Andric       isa<Instruction>(I) && cast<Instruction>(I)->getMetadata("is_base_value");
60281ad6265SDimitry Andric   setKnownBase(I, /* IsKnownBase */IsKnownBase, KnownBases);
60381ad6265SDimitry Andric   Cache[I] = I;
604fe6060f1SDimitry Andric 
6050b57cec5SDimitry Andric   // An extractelement produces a base result exactly when it's input does.
6060b57cec5SDimitry Andric   // We may need to insert a parallel instruction to extract the appropriate
6070b57cec5SDimitry Andric   // element out of the base vector corresponding to the input. Given this,
6080b57cec5SDimitry Andric   // it's analogous to the phi and select case even though it's not a merge.
6090b57cec5SDimitry Andric   if (isa<ExtractElementInst>(I))
6100b57cec5SDimitry Andric     // Note: There a lot of obvious peephole cases here.  This are deliberately
6110b57cec5SDimitry Andric     // handled after the main base pointer inference algorithm to make writing
6120b57cec5SDimitry Andric     // test cases to exercise that code easier.
61381ad6265SDimitry Andric     return I;
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric   // The last two cases here don't return a base pointer.  Instead, they
6160b57cec5SDimitry Andric   // return a value which dynamically selects from among several base
6170b57cec5SDimitry Andric   // derived pointers (each with it's own base potentially).  It's the job of
6180b57cec5SDimitry Andric   // the caller to resolve these.
6190b57cec5SDimitry Andric   assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
62081ad6265SDimitry Andric          "missing instruction case in findBaseDefiningValue");
62181ad6265SDimitry Andric   return I;
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric /// Returns the base defining value for this value.
62581ad6265SDimitry Andric static Value *findBaseDefiningValueCached(Value *I, DefiningValueMapTy &Cache,
62681ad6265SDimitry Andric                                           IsKnownBaseMapTy &KnownBases) {
62706c3fb27SDimitry Andric   if (!Cache.contains(I)) {
62881ad6265SDimitry Andric     auto *BDV = findBaseDefiningValue(I, Cache, KnownBases);
62981ad6265SDimitry Andric     Cache[I] = BDV;
6300b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "fBDV-cached: " << I->getName() << " -> "
63181ad6265SDimitry Andric                       << Cache[I]->getName() << ", is known base = "
63281ad6265SDimitry Andric                       << KnownBases[I] << "\n");
6330b57cec5SDimitry Andric   }
6340b57cec5SDimitry Andric   assert(Cache[I] != nullptr);
63506c3fb27SDimitry Andric   assert(KnownBases.contains(Cache[I]) &&
63681ad6265SDimitry Andric          "Cached value must be present in known bases map");
63781ad6265SDimitry Andric   return Cache[I];
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric /// Return a base pointer for this value if known.  Otherwise, return it's
6410b57cec5SDimitry Andric /// base defining value.
64281ad6265SDimitry Andric static Value *findBaseOrBDV(Value *I, DefiningValueMapTy &Cache,
64381ad6265SDimitry Andric                             IsKnownBaseMapTy &KnownBases) {
64481ad6265SDimitry Andric   Value *Def = findBaseDefiningValueCached(I, Cache, KnownBases);
6450b57cec5SDimitry Andric   auto Found = Cache.find(Def);
6460b57cec5SDimitry Andric   if (Found != Cache.end()) {
6470b57cec5SDimitry Andric     // Either a base-of relation, or a self reference.  Caller must check.
6480b57cec5SDimitry Andric     return Found->second;
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric   // Only a BDV available
6510b57cec5SDimitry Andric   return Def;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
65481ad6265SDimitry Andric #ifndef NDEBUG
6555ffd83dbSDimitry Andric /// This value is a base pointer that is not generated by RS4GC, i.e. it already
6565ffd83dbSDimitry Andric /// exists in the code.
6575ffd83dbSDimitry Andric static bool isOriginalBaseResult(Value *V) {
6585ffd83dbSDimitry Andric   // no recursion possible
6595ffd83dbSDimitry Andric   return !isa<PHINode>(V) && !isa<SelectInst>(V) &&
6605ffd83dbSDimitry Andric          !isa<ExtractElementInst>(V) && !isa<InsertElementInst>(V) &&
6615ffd83dbSDimitry Andric          !isa<ShuffleVectorInst>(V);
6625ffd83dbSDimitry Andric }
66381ad6265SDimitry Andric #endif
6645ffd83dbSDimitry Andric 
66581ad6265SDimitry Andric static bool isKnownBase(Value *V, const IsKnownBaseMapTy &KnownBases) {
66681ad6265SDimitry Andric   auto It = KnownBases.find(V);
66781ad6265SDimitry Andric   assert(It != KnownBases.end() && "Value not present in the map");
66881ad6265SDimitry Andric   return It->second;
6690b57cec5SDimitry Andric }
6700b57cec5SDimitry Andric 
67181ad6265SDimitry Andric static void setKnownBase(Value *V, bool IsKnownBase,
67281ad6265SDimitry Andric                          IsKnownBaseMapTy &KnownBases) {
67381ad6265SDimitry Andric #ifndef NDEBUG
67481ad6265SDimitry Andric   auto It = KnownBases.find(V);
67581ad6265SDimitry Andric   if (It != KnownBases.end())
67681ad6265SDimitry Andric     assert(It->second == IsKnownBase && "Changing already present value");
67781ad6265SDimitry Andric #endif
67881ad6265SDimitry Andric   KnownBases[V] = IsKnownBase;
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric 
6815ffd83dbSDimitry Andric // Returns true if First and Second values are both scalar or both vector.
6825ffd83dbSDimitry Andric static bool areBothVectorOrScalar(Value *First, Value *Second) {
6835ffd83dbSDimitry Andric   return isa<VectorType>(First->getType()) ==
6845ffd83dbSDimitry Andric          isa<VectorType>(Second->getType());
6855ffd83dbSDimitry Andric }
6865ffd83dbSDimitry Andric 
6870b57cec5SDimitry Andric namespace {
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric /// Models the state of a single base defining value in the findBasePointer
6900b57cec5SDimitry Andric /// algorithm for determining where a new instruction is needed to propagate
6910b57cec5SDimitry Andric /// the base of this BDV.
6920b57cec5SDimitry Andric class BDVState {
6930b57cec5SDimitry Andric public:
694fe6060f1SDimitry Andric   enum StatusTy {
695fe6060f1SDimitry Andric      // Starting state of lattice
696fe6060f1SDimitry Andric      Unknown,
697fe6060f1SDimitry Andric      // Some specific base value -- does *not* mean that instruction
698fe6060f1SDimitry Andric      // propagates the base of the object
699fe6060f1SDimitry Andric      // ex: gep %arg, 16 -> %arg is the base value
700fe6060f1SDimitry Andric      Base,
701fe6060f1SDimitry Andric      // Need to insert a node to represent a merge.
702fe6060f1SDimitry Andric      Conflict
703fe6060f1SDimitry Andric   };
7040b57cec5SDimitry Andric 
705fe6060f1SDimitry Andric   BDVState() {
706fe6060f1SDimitry Andric     llvm_unreachable("missing state in map");
707fe6060f1SDimitry Andric   }
7080b57cec5SDimitry Andric 
709fe6060f1SDimitry Andric   explicit BDVState(Value *OriginalValue)
710fe6060f1SDimitry Andric     : OriginalValue(OriginalValue) {}
711fe6060f1SDimitry Andric   explicit BDVState(Value *OriginalValue, StatusTy Status, Value *BaseValue = nullptr)
712fe6060f1SDimitry Andric     : OriginalValue(OriginalValue), Status(Status), BaseValue(BaseValue) {
7130b57cec5SDimitry Andric     assert(Status != Base || BaseValue);
7140b57cec5SDimitry Andric   }
7150b57cec5SDimitry Andric 
716fe6060f1SDimitry Andric   StatusTy getStatus() const { return Status; }
717fe6060f1SDimitry Andric   Value *getOriginalValue() const { return OriginalValue; }
7180b57cec5SDimitry Andric   Value *getBaseValue() const { return BaseValue; }
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   bool isBase() const { return getStatus() == Base; }
7210b57cec5SDimitry Andric   bool isUnknown() const { return getStatus() == Unknown; }
7220b57cec5SDimitry Andric   bool isConflict() const { return getStatus() == Conflict; }
7230b57cec5SDimitry Andric 
724fe6060f1SDimitry Andric   // Values of type BDVState form a lattice, and this function implements the
725fe6060f1SDimitry Andric   // meet
726fe6060f1SDimitry Andric   // operation.
727fe6060f1SDimitry Andric   void meet(const BDVState &Other) {
728fe6060f1SDimitry Andric     auto markConflict = [&]() {
729fe6060f1SDimitry Andric       Status = BDVState::Conflict;
730fe6060f1SDimitry Andric       BaseValue = nullptr;
731fe6060f1SDimitry Andric     };
732fe6060f1SDimitry Andric     // Conflict is a final state.
733fe6060f1SDimitry Andric     if (isConflict())
734fe6060f1SDimitry Andric       return;
735fe6060f1SDimitry Andric     // if we are not known - just take other state.
736fe6060f1SDimitry Andric     if (isUnknown()) {
737fe6060f1SDimitry Andric       Status = Other.getStatus();
738fe6060f1SDimitry Andric       BaseValue = Other.getBaseValue();
739fe6060f1SDimitry Andric       return;
740fe6060f1SDimitry Andric     }
741fe6060f1SDimitry Andric     // We are base.
742fe6060f1SDimitry Andric     assert(isBase() && "Unknown state");
743fe6060f1SDimitry Andric     // If other is unknown - just keep our state.
744fe6060f1SDimitry Andric     if (Other.isUnknown())
745fe6060f1SDimitry Andric       return;
746fe6060f1SDimitry Andric     // If other is conflict - it is a final state.
747fe6060f1SDimitry Andric     if (Other.isConflict())
748fe6060f1SDimitry Andric       return markConflict();
749fe6060f1SDimitry Andric     // Other is base as well.
750fe6060f1SDimitry Andric     assert(Other.isBase() && "Unknown state");
751fe6060f1SDimitry Andric     // If bases are different - Conflict.
752fe6060f1SDimitry Andric     if (getBaseValue() != Other.getBaseValue())
753fe6060f1SDimitry Andric       return markConflict();
754fe6060f1SDimitry Andric     // We are identical, do nothing.
755fe6060f1SDimitry Andric   }
756fe6060f1SDimitry Andric 
7570b57cec5SDimitry Andric   bool operator==(const BDVState &Other) const {
758349cc55cSDimitry Andric     return OriginalValue == Other.OriginalValue && BaseValue == Other.BaseValue &&
759fe6060f1SDimitry Andric       Status == Other.Status;
7600b57cec5SDimitry Andric   }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   bool operator!=(const BDVState &other) const { return !(*this == other); }
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   LLVM_DUMP_METHOD
7650b57cec5SDimitry Andric   void dump() const {
7660b57cec5SDimitry Andric     print(dbgs());
7670b57cec5SDimitry Andric     dbgs() << '\n';
7680b57cec5SDimitry Andric   }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric   void print(raw_ostream &OS) const {
7710b57cec5SDimitry Andric     switch (getStatus()) {
7720b57cec5SDimitry Andric     case Unknown:
7730b57cec5SDimitry Andric       OS << "U";
7740b57cec5SDimitry Andric       break;
7750b57cec5SDimitry Andric     case Base:
7760b57cec5SDimitry Andric       OS << "B";
7770b57cec5SDimitry Andric       break;
7780b57cec5SDimitry Andric     case Conflict:
7790b57cec5SDimitry Andric       OS << "C";
7800b57cec5SDimitry Andric       break;
7810b57cec5SDimitry Andric     }
782fe6060f1SDimitry Andric     OS << " (base " << getBaseValue() << " - "
783fe6060f1SDimitry Andric        << (getBaseValue() ? getBaseValue()->getName() : "nullptr") << ")"
784fe6060f1SDimitry Andric        << " for  "  << OriginalValue->getName() << ":";
7850b57cec5SDimitry Andric   }
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric private:
788fe6060f1SDimitry Andric   AssertingVH<Value> OriginalValue; // instruction this state corresponds to
789fe6060f1SDimitry Andric   StatusTy Status = Unknown;
790fe6060f1SDimitry Andric   AssertingVH<Value> BaseValue = nullptr; // Non-null only if Status == Base.
7910b57cec5SDimitry Andric };
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric } // end anonymous namespace
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric #ifndef NDEBUG
7960b57cec5SDimitry Andric static raw_ostream &operator<<(raw_ostream &OS, const BDVState &State) {
7970b57cec5SDimitry Andric   State.print(OS);
7980b57cec5SDimitry Andric   return OS;
7990b57cec5SDimitry Andric }
8000b57cec5SDimitry Andric #endif
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric /// For a given value or instruction, figure out what base ptr its derived from.
8030b57cec5SDimitry Andric /// For gc objects, this is simply itself.  On success, returns a value which is
8040b57cec5SDimitry Andric /// the base pointer.  (This is reliable and can be used for relocation.)  On
8050b57cec5SDimitry Andric /// failure, returns nullptr.
80681ad6265SDimitry Andric static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache,
80781ad6265SDimitry Andric                               IsKnownBaseMapTy &KnownBases) {
80881ad6265SDimitry Andric   Value *Def = findBaseOrBDV(I, Cache, KnownBases);
8090b57cec5SDimitry Andric 
81081ad6265SDimitry Andric   if (isKnownBase(Def, KnownBases) && areBothVectorOrScalar(Def, I))
8110b57cec5SDimitry Andric     return Def;
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric   // Here's the rough algorithm:
8140b57cec5SDimitry Andric   // - For every SSA value, construct a mapping to either an actual base
8150b57cec5SDimitry Andric   //   pointer or a PHI which obscures the base pointer.
8160b57cec5SDimitry Andric   // - Construct a mapping from PHI to unknown TOP state.  Use an
8170b57cec5SDimitry Andric   //   optimistic algorithm to propagate base pointer information.  Lattice
8180b57cec5SDimitry Andric   //   looks like:
8190b57cec5SDimitry Andric   //   UNKNOWN
8200b57cec5SDimitry Andric   //   b1 b2 b3 b4
8210b57cec5SDimitry Andric   //   CONFLICT
8220b57cec5SDimitry Andric   //   When algorithm terminates, all PHIs will either have a single concrete
8230b57cec5SDimitry Andric   //   base or be in a conflict state.
8240b57cec5SDimitry Andric   // - For every conflict, insert a dummy PHI node without arguments.  Add
8250b57cec5SDimitry Andric   //   these to the base[Instruction] = BasePtr mapping.  For every
8260b57cec5SDimitry Andric   //   non-conflict, add the actual base.
8270b57cec5SDimitry Andric   //  - For every conflict, add arguments for the base[a] of each input
8280b57cec5SDimitry Andric   //   arguments.
8290b57cec5SDimitry Andric   //
8300b57cec5SDimitry Andric   // Note: A simpler form of this would be to add the conflict form of all
8310b57cec5SDimitry Andric   // PHIs without running the optimistic algorithm.  This would be
8320b57cec5SDimitry Andric   // analogous to pessimistic data flow and would likely lead to an
8330b57cec5SDimitry Andric   // overall worse solution.
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric #ifndef NDEBUG
8360b57cec5SDimitry Andric   auto isExpectedBDVType = [](Value *BDV) {
8370b57cec5SDimitry Andric     return isa<PHINode>(BDV) || isa<SelectInst>(BDV) ||
8380b57cec5SDimitry Andric            isa<ExtractElementInst>(BDV) || isa<InsertElementInst>(BDV) ||
8390b57cec5SDimitry Andric            isa<ShuffleVectorInst>(BDV);
8400b57cec5SDimitry Andric   };
8410b57cec5SDimitry Andric #endif
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric   // Once populated, will contain a mapping from each potentially non-base BDV
8440b57cec5SDimitry Andric   // to a lattice value (described above) which corresponds to that BDV.
8450b57cec5SDimitry Andric   // We use the order of insertion (DFS over the def/use graph) to provide a
8460b57cec5SDimitry Andric   // stable deterministic ordering for visiting DenseMaps (which are unordered)
8470b57cec5SDimitry Andric   // below.  This is important for deterministic compilation.
8480b57cec5SDimitry Andric   MapVector<Value *, BDVState> States;
8490b57cec5SDimitry Andric 
850fe6060f1SDimitry Andric #ifndef NDEBUG
851fe6060f1SDimitry Andric   auto VerifyStates = [&]() {
852fe6060f1SDimitry Andric     for (auto &Entry : States) {
853fe6060f1SDimitry Andric       assert(Entry.first == Entry.second.getOriginalValue());
854fe6060f1SDimitry Andric     }
855fe6060f1SDimitry Andric   };
856fe6060f1SDimitry Andric #endif
857fe6060f1SDimitry Andric 
858fe6060f1SDimitry Andric   auto visitBDVOperands = [](Value *BDV, std::function<void (Value*)> F) {
859fe6060f1SDimitry Andric     if (PHINode *PN = dyn_cast<PHINode>(BDV)) {
860fe6060f1SDimitry Andric       for (Value *InVal : PN->incoming_values())
861fe6060f1SDimitry Andric         F(InVal);
862fe6060f1SDimitry Andric     } else if (SelectInst *SI = dyn_cast<SelectInst>(BDV)) {
863fe6060f1SDimitry Andric       F(SI->getTrueValue());
864fe6060f1SDimitry Andric       F(SI->getFalseValue());
865fe6060f1SDimitry Andric     } else if (auto *EE = dyn_cast<ExtractElementInst>(BDV)) {
866fe6060f1SDimitry Andric       F(EE->getVectorOperand());
867fe6060f1SDimitry Andric     } else if (auto *IE = dyn_cast<InsertElementInst>(BDV)) {
868fe6060f1SDimitry Andric       F(IE->getOperand(0));
869fe6060f1SDimitry Andric       F(IE->getOperand(1));
870fe6060f1SDimitry Andric     } else if (auto *SV = dyn_cast<ShuffleVectorInst>(BDV)) {
871fe6060f1SDimitry Andric       // For a canonical broadcast, ignore the undef argument
872fe6060f1SDimitry Andric       // (without this, we insert a parallel base shuffle for every broadcast)
873fe6060f1SDimitry Andric       F(SV->getOperand(0));
874fe6060f1SDimitry Andric       if (!SV->isZeroEltSplat())
875fe6060f1SDimitry Andric         F(SV->getOperand(1));
876fe6060f1SDimitry Andric     } else {
877fe6060f1SDimitry Andric       llvm_unreachable("unexpected BDV type");
878fe6060f1SDimitry Andric     }
879fe6060f1SDimitry Andric   };
880fe6060f1SDimitry Andric 
881fe6060f1SDimitry Andric 
8820b57cec5SDimitry Andric   // Recursively fill in all base defining values reachable from the initial
8830b57cec5SDimitry Andric   // one for which we don't already know a definite base value for
8840b57cec5SDimitry Andric   /* scope */ {
8850b57cec5SDimitry Andric     SmallVector<Value*, 16> Worklist;
8860b57cec5SDimitry Andric     Worklist.push_back(Def);
887fe6060f1SDimitry Andric     States.insert({Def, BDVState(Def)});
8880b57cec5SDimitry Andric     while (!Worklist.empty()) {
8890b57cec5SDimitry Andric       Value *Current = Worklist.pop_back_val();
8905ffd83dbSDimitry Andric       assert(!isOriginalBaseResult(Current) && "why did it get added?");
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric       auto visitIncomingValue = [&](Value *InVal) {
89381ad6265SDimitry Andric         Value *Base = findBaseOrBDV(InVal, Cache, KnownBases);
89481ad6265SDimitry Andric         if (isKnownBase(Base, KnownBases) && areBothVectorOrScalar(Base, InVal))
8950b57cec5SDimitry Andric           // Known bases won't need new instructions introduced and can be
8965ffd83dbSDimitry Andric           // ignored safely. However, this can only be done when InVal and Base
8975ffd83dbSDimitry Andric           // are both scalar or both vector. Otherwise, we need to find a
8985ffd83dbSDimitry Andric           // correct BDV for InVal, by creating an entry in the lattice
8995ffd83dbSDimitry Andric           // (States).
9000b57cec5SDimitry Andric           return;
9010b57cec5SDimitry Andric         assert(isExpectedBDVType(Base) && "the only non-base values "
9020b57cec5SDimitry Andric                "we see should be base defining values");
903fe6060f1SDimitry Andric         if (States.insert(std::make_pair(Base, BDVState(Base))).second)
9040b57cec5SDimitry Andric           Worklist.push_back(Base);
9050b57cec5SDimitry Andric       };
906fe6060f1SDimitry Andric 
907fe6060f1SDimitry Andric       visitBDVOperands(Current, visitIncomingValue);
9080b57cec5SDimitry Andric     }
9090b57cec5SDimitry Andric   }
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric #ifndef NDEBUG
912fe6060f1SDimitry Andric   VerifyStates();
9130b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "States after initialization:\n");
914349cc55cSDimitry Andric   for (const auto &Pair : States) {
9150b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
9160b57cec5SDimitry Andric   }
9170b57cec5SDimitry Andric #endif
9180b57cec5SDimitry Andric 
919fe6060f1SDimitry Andric   // Iterate forward through the value graph pruning any node from the state
920fe6060f1SDimitry Andric   // list where all of the inputs are base pointers.  The purpose of this is to
921fe6060f1SDimitry Andric   // reuse existing values when the derived pointer we were asked to materialize
922fe6060f1SDimitry Andric   // a base pointer for happens to be a base pointer itself.  (Or a sub-graph
923fe6060f1SDimitry Andric   // feeding it does.)
924fe6060f1SDimitry Andric   SmallVector<Value *> ToRemove;
925fe6060f1SDimitry Andric   do {
926fe6060f1SDimitry Andric     ToRemove.clear();
927fe6060f1SDimitry Andric     for (auto Pair : States) {
928fe6060f1SDimitry Andric       Value *BDV = Pair.first;
929fe6060f1SDimitry Andric       auto canPruneInput = [&](Value *V) {
93081ad6265SDimitry Andric         // If the input of the BDV is the BDV itself we can prune it. This is
93181ad6265SDimitry Andric         // only possible if the BDV is a PHI node.
93281ad6265SDimitry Andric         if (V->stripPointerCasts() == BDV)
93381ad6265SDimitry Andric           return true;
93481ad6265SDimitry Andric         Value *VBDV = findBaseOrBDV(V, Cache, KnownBases);
93581ad6265SDimitry Andric         if (V->stripPointerCasts() != VBDV)
936fe6060f1SDimitry Andric           return false;
937fe6060f1SDimitry Andric         // The assumption is that anything not in the state list is
938fe6060f1SDimitry Andric         // propagates a base pointer.
93981ad6265SDimitry Andric         return States.count(VBDV) == 0;
940fe6060f1SDimitry Andric       };
941fe6060f1SDimitry Andric 
942fe6060f1SDimitry Andric       bool CanPrune = true;
943fe6060f1SDimitry Andric       visitBDVOperands(BDV, [&](Value *Op) {
944fe6060f1SDimitry Andric         CanPrune = CanPrune && canPruneInput(Op);
945fe6060f1SDimitry Andric       });
946fe6060f1SDimitry Andric       if (CanPrune)
947fe6060f1SDimitry Andric         ToRemove.push_back(BDV);
948fe6060f1SDimitry Andric     }
949fe6060f1SDimitry Andric     for (Value *V : ToRemove) {
950fe6060f1SDimitry Andric       States.erase(V);
951fe6060f1SDimitry Andric       // Cache the fact V is it's own base for later usage.
952fe6060f1SDimitry Andric       Cache[V] = V;
953fe6060f1SDimitry Andric     }
954fe6060f1SDimitry Andric   } while (!ToRemove.empty());
955fe6060f1SDimitry Andric 
956fe6060f1SDimitry Andric   // Did we manage to prove that Def itself must be a base pointer?
957fe6060f1SDimitry Andric   if (!States.count(Def))
958fe6060f1SDimitry Andric     return Def;
959fe6060f1SDimitry Andric 
9600b57cec5SDimitry Andric   // Return a phi state for a base defining value.  We'll generate a new
9610b57cec5SDimitry Andric   // base state for known bases and expect to find a cached state otherwise.
9625ffd83dbSDimitry Andric   auto GetStateForBDV = [&](Value *BaseValue, Value *Input) {
9635ffd83dbSDimitry Andric     auto I = States.find(BaseValue);
964fe6060f1SDimitry Andric     if (I != States.end())
9650b57cec5SDimitry Andric       return I->second;
966fe6060f1SDimitry Andric     assert(areBothVectorOrScalar(BaseValue, Input));
967fe6060f1SDimitry Andric     return BDVState(BaseValue, BDVState::Base, BaseValue);
9680b57cec5SDimitry Andric   };
9690b57cec5SDimitry Andric 
9705f757f3fSDimitry Andric   // Even though we have identified a concrete base (or a conflict) for all live
9715f757f3fSDimitry Andric   // pointers at this point, there are cases where the base is of an
9725f757f3fSDimitry Andric   // incompatible type compared to the original instruction. We conservatively
9735f757f3fSDimitry Andric   // mark those as conflicts to ensure that corresponding BDVs will be generated
9745f757f3fSDimitry Andric   // in the next steps.
9755f757f3fSDimitry Andric 
9765f757f3fSDimitry Andric   // this is a rather explicit check for all cases where we should mark the
9775f757f3fSDimitry Andric   // state as a conflict to force the latter stages of the algorithm to emit
9785f757f3fSDimitry Andric   // the BDVs.
9795f757f3fSDimitry Andric   // TODO: in many cases the instructions emited for the conflicting states
9805f757f3fSDimitry Andric   // will be identical to the I itself (if the I's operate on their BDVs
9817a6dacacSDimitry Andric   // themselves). We should exploit this, but can't do it here since it would
9825f757f3fSDimitry Andric   // break the invariant about the BDVs not being known to be a base.
9835f757f3fSDimitry Andric   // TODO: the code also does not handle constants at all - the algorithm relies
9845f757f3fSDimitry Andric   // on all constants having the same BDV and therefore constant-only insns
9855f757f3fSDimitry Andric   // will never be in conflict, but this check is ignored here. If the
9865f757f3fSDimitry Andric   // constant conflicts will be to BDVs themselves, they will be identical
9875f757f3fSDimitry Andric   // instructions and will get optimized away (as in the above TODO)
9885f757f3fSDimitry Andric   auto MarkConflict = [&](Instruction *I, Value *BaseValue) {
9895f757f3fSDimitry Andric     // II and EE mixes vector & scalar so is always a conflict
9905f757f3fSDimitry Andric     if (isa<InsertElementInst>(I) || isa<ExtractElementInst>(I))
9915f757f3fSDimitry Andric       return true;
9925f757f3fSDimitry Andric     // Shuffle vector is always a conflict as it creates new vector from
9935f757f3fSDimitry Andric     // existing ones.
9945f757f3fSDimitry Andric     if (isa<ShuffleVectorInst>(I))
9955f757f3fSDimitry Andric       return true;
9965f757f3fSDimitry Andric     // Any  instructions where the computed base type differs from the
9975f757f3fSDimitry Andric     // instruction type. An example is where an extract instruction is used by a
9985f757f3fSDimitry Andric     // select. Here the select's BDV is a vector (because of extract's BDV),
9995f757f3fSDimitry Andric     // while the select itself is a scalar type. Note that the IE and EE
10005f757f3fSDimitry Andric     // instruction check is not fully subsumed by the vector<->scalar check at
10015f757f3fSDimitry Andric     // the end, this is due to the BDV algorithm being ignorant of BDV types at
10025f757f3fSDimitry Andric     // this junction.
10035f757f3fSDimitry Andric     if (!areBothVectorOrScalar(BaseValue, I))
10045f757f3fSDimitry Andric       return true;
10055f757f3fSDimitry Andric     return false;
10065f757f3fSDimitry Andric   };
10075f757f3fSDimitry Andric 
10087a6dacacSDimitry Andric   bool Progress = true;
10097a6dacacSDimitry Andric   while (Progress) {
10107a6dacacSDimitry Andric #ifndef NDEBUG
10117a6dacacSDimitry Andric     const size_t OldSize = States.size();
10127a6dacacSDimitry Andric #endif
10137a6dacacSDimitry Andric     Progress = false;
10147a6dacacSDimitry Andric     // We're only changing values in this loop, thus safe to keep iterators.
10157a6dacacSDimitry Andric     // Since this is computing a fixed point, the order of visit does not
10167a6dacacSDimitry Andric     // effect the result.  TODO: We could use a worklist here and make this run
10177a6dacacSDimitry Andric     // much faster.
10187a6dacacSDimitry Andric     for (auto Pair : States) {
10197a6dacacSDimitry Andric       Value *BDV = Pair.first;
10207a6dacacSDimitry Andric       // Only values that do not have known bases or those that have differing
10217a6dacacSDimitry Andric       // type (scalar versus vector) from a possible known base should be in the
10227a6dacacSDimitry Andric       // lattice.
10237a6dacacSDimitry Andric       assert((!isKnownBase(BDV, KnownBases) ||
10247a6dacacSDimitry Andric              !areBothVectorOrScalar(BDV, Pair.second.getBaseValue())) &&
10257a6dacacSDimitry Andric                  "why did it get added?");
10267a6dacacSDimitry Andric 
10277a6dacacSDimitry Andric       BDVState NewState(BDV);
10287a6dacacSDimitry Andric       visitBDVOperands(BDV, [&](Value *Op) {
10297a6dacacSDimitry Andric         Value *BDV = findBaseOrBDV(Op, Cache, KnownBases);
10307a6dacacSDimitry Andric         auto OpState = GetStateForBDV(BDV, Op);
10317a6dacacSDimitry Andric         NewState.meet(OpState);
10327a6dacacSDimitry Andric       });
10337a6dacacSDimitry Andric 
10347a6dacacSDimitry Andric       // if the instruction has known base, but should in fact be marked as
10357a6dacacSDimitry Andric       // conflict because of incompatible in/out types, we mark it as such
10367a6dacacSDimitry Andric       // ensuring that it will propagate through the fixpoint iteration
10377a6dacacSDimitry Andric       auto I = cast<Instruction>(BDV);
10387a6dacacSDimitry Andric       auto BV = NewState.getBaseValue();
10397a6dacacSDimitry Andric       if (BV && MarkConflict(I, BV))
10407a6dacacSDimitry Andric         NewState = BDVState(I, BDVState::Conflict);
10417a6dacacSDimitry Andric 
10427a6dacacSDimitry Andric       BDVState OldState = Pair.second;
10437a6dacacSDimitry Andric       if (OldState != NewState) {
10447a6dacacSDimitry Andric         Progress = true;
10457a6dacacSDimitry Andric         States[BDV] = NewState;
10467a6dacacSDimitry Andric       }
10477a6dacacSDimitry Andric     }
10487a6dacacSDimitry Andric 
10497a6dacacSDimitry Andric     assert(OldSize == States.size() &&
10507a6dacacSDimitry Andric            "fixed point shouldn't be adding any new nodes to state");
10517a6dacacSDimitry Andric   }
10527a6dacacSDimitry Andric 
10537a6dacacSDimitry Andric #ifndef NDEBUG
10547a6dacacSDimitry Andric   VerifyStates();
10557a6dacacSDimitry Andric   LLVM_DEBUG(dbgs() << "States after meet iteration:\n");
10567a6dacacSDimitry Andric   for (const auto &Pair : States) {
10577a6dacacSDimitry Andric     LLVM_DEBUG(dbgs() << " " << Pair.second << " for " << *Pair.first << "\n");
10587a6dacacSDimitry Andric   }
10597a6dacacSDimitry Andric 
10607a6dacacSDimitry Andric   // since we do the conflict marking as part of the fixpoint iteration this
10617a6dacacSDimitry Andric   // loop only asserts that invariants are met
10620b57cec5SDimitry Andric   for (auto Pair : States) {
10630b57cec5SDimitry Andric     Instruction *I = cast<Instruction>(Pair.first);
10640b57cec5SDimitry Andric     BDVState State = Pair.second;
10655ffd83dbSDimitry Andric     auto *BaseValue = State.getBaseValue();
10665ffd83dbSDimitry Andric     // Only values that do not have known bases or those that have differing
10675ffd83dbSDimitry Andric     // type (scalar versus vector) from a possible known base should be in the
10685ffd83dbSDimitry Andric     // lattice.
106981ad6265SDimitry Andric     assert(
107081ad6265SDimitry Andric         (!isKnownBase(I, KnownBases) || !areBothVectorOrScalar(I, BaseValue)) &&
10715ffd83dbSDimitry Andric         "why did it get added?");
10720b57cec5SDimitry Andric     assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
10730b57cec5SDimitry Andric   }
1074fe6060f1SDimitry Andric #endif
1075fe6060f1SDimitry Andric 
10765ffd83dbSDimitry Andric   // Insert Phis for all conflicts
10775ffd83dbSDimitry Andric   // TODO: adjust naming patterns to avoid this order of iteration dependency
10785ffd83dbSDimitry Andric   for (auto Pair : States) {
10795ffd83dbSDimitry Andric     Instruction *I = cast<Instruction>(Pair.first);
10805ffd83dbSDimitry Andric     BDVState State = Pair.second;
10815ffd83dbSDimitry Andric     // Only values that do not have known bases or those that have differing
10825ffd83dbSDimitry Andric     // type (scalar versus vector) from a possible known base should be in the
10835ffd83dbSDimitry Andric     // lattice.
108481ad6265SDimitry Andric     assert((!isKnownBase(I, KnownBases) ||
108581ad6265SDimitry Andric             !areBothVectorOrScalar(I, State.getBaseValue())) &&
10865ffd83dbSDimitry Andric            "why did it get added?");
10875ffd83dbSDimitry Andric     assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric     // Since we're joining a vector and scalar base, they can never be the
10900b57cec5SDimitry Andric     // same.  As a result, we should always see insert element having reached
10910b57cec5SDimitry Andric     // the conflict state.
10920b57cec5SDimitry Andric     assert(!isa<InsertElementInst>(I) || State.isConflict());
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric     if (!State.isConflict())
10950b57cec5SDimitry Andric       continue;
10960b57cec5SDimitry Andric 
1097fe6060f1SDimitry Andric     auto getMangledName = [](Instruction *I) -> std::string {
10980b57cec5SDimitry Andric       if (isa<PHINode>(I)) {
1099fe6060f1SDimitry Andric         return suffixed_name_or(I, ".base", "base_phi");
1100fe6060f1SDimitry Andric       } else if (isa<SelectInst>(I)) {
1101fe6060f1SDimitry Andric         return suffixed_name_or(I, ".base", "base_select");
1102fe6060f1SDimitry Andric       } else if (isa<ExtractElementInst>(I)) {
1103fe6060f1SDimitry Andric         return suffixed_name_or(I, ".base", "base_ee");
1104fe6060f1SDimitry Andric       } else if (isa<InsertElementInst>(I)) {
1105fe6060f1SDimitry Andric         return suffixed_name_or(I, ".base", "base_ie");
11060b57cec5SDimitry Andric       } else {
1107fe6060f1SDimitry Andric         return suffixed_name_or(I, ".base", "base_sv");
11080b57cec5SDimitry Andric       }
11090b57cec5SDimitry Andric     };
1110fe6060f1SDimitry Andric 
1111fe6060f1SDimitry Andric     Instruction *BaseInst = I->clone();
1112fe6060f1SDimitry Andric     BaseInst->insertBefore(I);
1113fe6060f1SDimitry Andric     BaseInst->setName(getMangledName(I));
11140b57cec5SDimitry Andric     // Add metadata marking this as a base value
11150b57cec5SDimitry Andric     BaseInst->setMetadata("is_base_value", MDNode::get(I->getContext(), {}));
1116fe6060f1SDimitry Andric     States[I] = BDVState(I, BDVState::Conflict, BaseInst);
111781ad6265SDimitry Andric     setKnownBase(BaseInst, /* IsKnownBase */true, KnownBases);
11180b57cec5SDimitry Andric   }
11190b57cec5SDimitry Andric 
1120fe6060f1SDimitry Andric #ifndef NDEBUG
1121fe6060f1SDimitry Andric   VerifyStates();
1122fe6060f1SDimitry Andric #endif
1123fe6060f1SDimitry Andric 
11240b57cec5SDimitry Andric   // Returns a instruction which produces the base pointer for a given
11250b57cec5SDimitry Andric   // instruction.  The instruction is assumed to be an input to one of the BDVs
11260b57cec5SDimitry Andric   // seen in the inference algorithm above.  As such, we must either already
11270b57cec5SDimitry Andric   // know it's base defining value is a base, or have inserted a new
11280b57cec5SDimitry Andric   // instruction to propagate the base of it's BDV and have entered that newly
11290b57cec5SDimitry Andric   // introduced instruction into the state table.  In either case, we are
11300b57cec5SDimitry Andric   // assured to be able to determine an instruction which produces it's base
11310b57cec5SDimitry Andric   // pointer.
11320b57cec5SDimitry Andric   auto getBaseForInput = [&](Value *Input, Instruction *InsertPt) {
113381ad6265SDimitry Andric     Value *BDV = findBaseOrBDV(Input, Cache, KnownBases);
11340b57cec5SDimitry Andric     Value *Base = nullptr;
1135fe6060f1SDimitry Andric     if (!States.count(BDV)) {
1136fe6060f1SDimitry Andric       assert(areBothVectorOrScalar(BDV, Input));
11370b57cec5SDimitry Andric       Base = BDV;
11380b57cec5SDimitry Andric     } else {
11390b57cec5SDimitry Andric       // Either conflict or base.
11400b57cec5SDimitry Andric       assert(States.count(BDV));
11410b57cec5SDimitry Andric       Base = States[BDV].getBaseValue();
11420b57cec5SDimitry Andric     }
11430b57cec5SDimitry Andric     assert(Base && "Can't be null");
11440b57cec5SDimitry Andric     // The cast is needed since base traversal may strip away bitcasts
11450b57cec5SDimitry Andric     if (Base->getType() != Input->getType() && InsertPt)
1146*0fca6ea1SDimitry Andric       Base = new BitCastInst(Base, Input->getType(), "cast",
1147*0fca6ea1SDimitry Andric                              InsertPt->getIterator());
11480b57cec5SDimitry Andric     return Base;
11490b57cec5SDimitry Andric   };
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric   // Fixup all the inputs of the new PHIs.  Visit order needs to be
11520b57cec5SDimitry Andric   // deterministic and predictable because we're naming newly created
11530b57cec5SDimitry Andric   // instructions.
11540b57cec5SDimitry Andric   for (auto Pair : States) {
11550b57cec5SDimitry Andric     Instruction *BDV = cast<Instruction>(Pair.first);
11560b57cec5SDimitry Andric     BDVState State = Pair.second;
11570b57cec5SDimitry Andric 
11585ffd83dbSDimitry Andric     // Only values that do not have known bases or those that have differing
11595ffd83dbSDimitry Andric     // type (scalar versus vector) from a possible known base should be in the
11605ffd83dbSDimitry Andric     // lattice.
116181ad6265SDimitry Andric     assert((!isKnownBase(BDV, KnownBases) ||
11625ffd83dbSDimitry Andric             !areBothVectorOrScalar(BDV, State.getBaseValue())) &&
11635ffd83dbSDimitry Andric            "why did it get added?");
11640b57cec5SDimitry Andric     assert(!State.isUnknown() && "Optimistic algorithm didn't complete!");
11650b57cec5SDimitry Andric     if (!State.isConflict())
11660b57cec5SDimitry Andric       continue;
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric     if (PHINode *BasePHI = dyn_cast<PHINode>(State.getBaseValue())) {
11690b57cec5SDimitry Andric       PHINode *PN = cast<PHINode>(BDV);
1170fe6060f1SDimitry Andric       const unsigned NumPHIValues = PN->getNumIncomingValues();
1171fe6060f1SDimitry Andric 
1172fe6060f1SDimitry Andric       // The IR verifier requires phi nodes with multiple entries from the
1173fe6060f1SDimitry Andric       // same basic block to have the same incoming value for each of those
1174fe6060f1SDimitry Andric       // entries.  Since we're inserting bitcasts in the loop, make sure we
1175fe6060f1SDimitry Andric       // do so at least once per incoming block.
1176fe6060f1SDimitry Andric       DenseMap<BasicBlock *, Value*> BlockToValue;
11770b57cec5SDimitry Andric       for (unsigned i = 0; i < NumPHIValues; i++) {
11780b57cec5SDimitry Andric         Value *InVal = PN->getIncomingValue(i);
11790b57cec5SDimitry Andric         BasicBlock *InBB = PN->getIncomingBlock(i);
1180fe6060f1SDimitry Andric         if (!BlockToValue.count(InBB))
1181fe6060f1SDimitry Andric           BlockToValue[InBB] = getBaseForInput(InVal, InBB->getTerminator());
1182fe6060f1SDimitry Andric         else {
11830b57cec5SDimitry Andric #ifndef NDEBUG
1184fe6060f1SDimitry Andric           Value *OldBase = BlockToValue[InBB];
11850b57cec5SDimitry Andric           Value *Base = getBaseForInput(InVal, nullptr);
118681ad6265SDimitry Andric 
118781ad6265SDimitry Andric           // We can't use `stripPointerCasts` instead of this function because
118881ad6265SDimitry Andric           // `stripPointerCasts` doesn't handle vectors of pointers.
118981ad6265SDimitry Andric           auto StripBitCasts = [](Value *V) -> Value * {
119081ad6265SDimitry Andric             while (auto *BC = dyn_cast<BitCastInst>(V))
119181ad6265SDimitry Andric               V = BC->getOperand(0);
119281ad6265SDimitry Andric             return V;
119381ad6265SDimitry Andric           };
11940b57cec5SDimitry Andric           // In essence this assert states: the only way two values
11950b57cec5SDimitry Andric           // incoming from the same basic block may be different is by
11960b57cec5SDimitry Andric           // being different bitcasts of the same value.  A cleanup
11970b57cec5SDimitry Andric           // that remains TODO is changing findBaseOrBDV to return an
11980b57cec5SDimitry Andric           // llvm::Value of the correct type (and still remain pure).
11990b57cec5SDimitry Andric           // This will remove the need to add bitcasts.
120081ad6265SDimitry Andric           assert(StripBitCasts(Base) == StripBitCasts(OldBase) &&
1201349cc55cSDimitry Andric                  "findBaseOrBDV should be pure!");
12020b57cec5SDimitry Andric #endif
12030b57cec5SDimitry Andric         }
1204fe6060f1SDimitry Andric         Value *Base = BlockToValue[InBB];
1205fe6060f1SDimitry Andric         BasePHI->setIncomingValue(i, Base);
12060b57cec5SDimitry Andric       }
12070b57cec5SDimitry Andric     } else if (SelectInst *BaseSI =
12080b57cec5SDimitry Andric                    dyn_cast<SelectInst>(State.getBaseValue())) {
12090b57cec5SDimitry Andric       SelectInst *SI = cast<SelectInst>(BDV);
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric       // Find the instruction which produces the base for each input.
12120b57cec5SDimitry Andric       // We may need to insert a bitcast.
12130b57cec5SDimitry Andric       BaseSI->setTrueValue(getBaseForInput(SI->getTrueValue(), BaseSI));
12140b57cec5SDimitry Andric       BaseSI->setFalseValue(getBaseForInput(SI->getFalseValue(), BaseSI));
12150b57cec5SDimitry Andric     } else if (auto *BaseEE =
12160b57cec5SDimitry Andric                    dyn_cast<ExtractElementInst>(State.getBaseValue())) {
12170b57cec5SDimitry Andric       Value *InVal = cast<ExtractElementInst>(BDV)->getVectorOperand();
12180b57cec5SDimitry Andric       // Find the instruction which produces the base for each input.  We may
12190b57cec5SDimitry Andric       // need to insert a bitcast.
12200b57cec5SDimitry Andric       BaseEE->setOperand(0, getBaseForInput(InVal, BaseEE));
12210b57cec5SDimitry Andric     } else if (auto *BaseIE = dyn_cast<InsertElementInst>(State.getBaseValue())){
12220b57cec5SDimitry Andric       auto *BdvIE = cast<InsertElementInst>(BDV);
12230b57cec5SDimitry Andric       auto UpdateOperand = [&](int OperandIdx) {
12240b57cec5SDimitry Andric         Value *InVal = BdvIE->getOperand(OperandIdx);
12250b57cec5SDimitry Andric         Value *Base = getBaseForInput(InVal, BaseIE);
12260b57cec5SDimitry Andric         BaseIE->setOperand(OperandIdx, Base);
12270b57cec5SDimitry Andric       };
12280b57cec5SDimitry Andric       UpdateOperand(0); // vector operand
12290b57cec5SDimitry Andric       UpdateOperand(1); // scalar operand
12300b57cec5SDimitry Andric     } else {
12310b57cec5SDimitry Andric       auto *BaseSV = cast<ShuffleVectorInst>(State.getBaseValue());
12320b57cec5SDimitry Andric       auto *BdvSV = cast<ShuffleVectorInst>(BDV);
12330b57cec5SDimitry Andric       auto UpdateOperand = [&](int OperandIdx) {
12340b57cec5SDimitry Andric         Value *InVal = BdvSV->getOperand(OperandIdx);
12350b57cec5SDimitry Andric         Value *Base = getBaseForInput(InVal, BaseSV);
12360b57cec5SDimitry Andric         BaseSV->setOperand(OperandIdx, Base);
12370b57cec5SDimitry Andric       };
12380b57cec5SDimitry Andric       UpdateOperand(0); // vector operand
1239fe6060f1SDimitry Andric       if (!BdvSV->isZeroEltSplat())
12400b57cec5SDimitry Andric         UpdateOperand(1); // vector operand
1241fe6060f1SDimitry Andric       else {
124206c3fb27SDimitry Andric         // Never read, so just use poison
1243fe6060f1SDimitry Andric         Value *InVal = BdvSV->getOperand(1);
124406c3fb27SDimitry Andric         BaseSV->setOperand(1, PoisonValue::get(InVal->getType()));
12450b57cec5SDimitry Andric       }
12460b57cec5SDimitry Andric     }
1247fe6060f1SDimitry Andric   }
1248fe6060f1SDimitry Andric 
1249fe6060f1SDimitry Andric #ifndef NDEBUG
1250fe6060f1SDimitry Andric   VerifyStates();
1251fe6060f1SDimitry Andric #endif
12520b57cec5SDimitry Andric 
12535f757f3fSDimitry Andric   // get the data layout to compare the sizes of base/derived pointer values
12545f757f3fSDimitry Andric   [[maybe_unused]] auto &DL =
1255*0fca6ea1SDimitry Andric       cast<llvm::Instruction>(Def)->getDataLayout();
12560b57cec5SDimitry Andric   // Cache all of our results so we can cheaply reuse them
12570b57cec5SDimitry Andric   // NOTE: This is actually two caches: one of the base defining value
12580b57cec5SDimitry Andric   // relation and one of the base pointer relation!  FIXME
12590b57cec5SDimitry Andric   for (auto Pair : States) {
12600b57cec5SDimitry Andric     auto *BDV = Pair.first;
12610b57cec5SDimitry Andric     Value *Base = Pair.second.getBaseValue();
12620b57cec5SDimitry Andric     assert(BDV && Base);
12635f757f3fSDimitry Andric     // Whenever we have a derived ptr(s), their base
12645f757f3fSDimitry Andric     // ptr(s) must be of the same size, not necessarily the same type
12655f757f3fSDimitry Andric     assert(DL.getTypeAllocSize(BDV->getType()) ==
12665f757f3fSDimitry Andric                DL.getTypeAllocSize(Base->getType()) &&
12675f757f3fSDimitry Andric            "Derived and base values should have same size");
12685ffd83dbSDimitry Andric     // Only values that do not have known bases or those that have differing
12695ffd83dbSDimitry Andric     // type (scalar versus vector) from a possible known base should be in the
12705ffd83dbSDimitry Andric     // lattice.
127181ad6265SDimitry Andric     assert(
127281ad6265SDimitry Andric         (!isKnownBase(BDV, KnownBases) || !areBothVectorOrScalar(BDV, Base)) &&
12735ffd83dbSDimitry Andric         "why did it get added?");
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric     LLVM_DEBUG(
12760b57cec5SDimitry Andric         dbgs() << "Updating base value cache"
12770b57cec5SDimitry Andric                << " for: " << BDV->getName() << " from: "
12780b57cec5SDimitry Andric                << (Cache.count(BDV) ? Cache[BDV]->getName().str() : "none")
12790b57cec5SDimitry Andric                << " to: " << Base->getName() << "\n");
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric     Cache[BDV] = Base;
12820b57cec5SDimitry Andric   }
12830b57cec5SDimitry Andric   assert(Cache.count(Def));
12840b57cec5SDimitry Andric   return Cache[Def];
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric // For a set of live pointers (base and/or derived), identify the base
12880b57cec5SDimitry Andric // pointer of the object which they are derived from.  This routine will
12890b57cec5SDimitry Andric // mutate the IR graph as needed to make the 'base' pointer live at the
12900b57cec5SDimitry Andric // definition site of 'derived'.  This ensures that any use of 'derived' can
12910b57cec5SDimitry Andric // also use 'base'.  This may involve the insertion of a number of
12920b57cec5SDimitry Andric // additional PHI nodes.
12930b57cec5SDimitry Andric //
12940b57cec5SDimitry Andric // preconditions: live is a set of pointer type Values
12950b57cec5SDimitry Andric //
12960b57cec5SDimitry Andric // side effects: may insert PHI nodes into the existing CFG, will preserve
12970b57cec5SDimitry Andric // CFG, will not remove or mutate any existing nodes
12980b57cec5SDimitry Andric //
12990b57cec5SDimitry Andric // post condition: PointerToBase contains one (derived, base) pair for every
13000b57cec5SDimitry Andric // pointer in live.  Note that derived can be equal to base if the original
13010b57cec5SDimitry Andric // pointer was a base pointer.
13021fd87a68SDimitry Andric static void findBasePointers(const StatepointLiveSetTy &live,
13031fd87a68SDimitry Andric                              PointerToBaseTy &PointerToBase, DominatorTree *DT,
130481ad6265SDimitry Andric                              DefiningValueMapTy &DVCache,
130581ad6265SDimitry Andric                              IsKnownBaseMapTy &KnownBases) {
13060b57cec5SDimitry Andric   for (Value *ptr : live) {
130781ad6265SDimitry Andric     Value *base = findBasePointer(ptr, DVCache, KnownBases);
13080b57cec5SDimitry Andric     assert(base && "failed to find base pointer");
13090b57cec5SDimitry Andric     PointerToBase[ptr] = base;
13100b57cec5SDimitry Andric     assert((!isa<Instruction>(base) || !isa<Instruction>(ptr) ||
13110b57cec5SDimitry Andric             DT->dominates(cast<Instruction>(base)->getParent(),
13120b57cec5SDimitry Andric                           cast<Instruction>(ptr)->getParent())) &&
13130b57cec5SDimitry Andric            "The base we found better dominate the derived pointer");
13140b57cec5SDimitry Andric   }
13150b57cec5SDimitry Andric }
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric /// Find the required based pointers (and adjust the live set) for the given
13180b57cec5SDimitry Andric /// parse point.
13190b57cec5SDimitry Andric static void findBasePointers(DominatorTree &DT, DefiningValueMapTy &DVCache,
13200b57cec5SDimitry Andric                              CallBase *Call,
13211fd87a68SDimitry Andric                              PartiallyConstructedSafepointRecord &result,
132281ad6265SDimitry Andric                              PointerToBaseTy &PointerToBase,
132381ad6265SDimitry Andric                              IsKnownBaseMapTy &KnownBases) {
1324fe6060f1SDimitry Andric   StatepointLiveSetTy PotentiallyDerivedPointers = result.LiveSet;
1325fe6060f1SDimitry Andric   // We assume that all pointers passed to deopt are base pointers; as an
1326*0fca6ea1SDimitry Andric   // optimization, we can use this to avoid separately materializing the base
1327fe6060f1SDimitry Andric   // pointer graph.  This is only relevant since we're very conservative about
1328fe6060f1SDimitry Andric   // generating new conflict nodes during base pointer insertion.  If we were
1329fe6060f1SDimitry Andric   // smarter there, this would be irrelevant.
1330fe6060f1SDimitry Andric   if (auto Opt = Call->getOperandBundle(LLVMContext::OB_deopt))
1331fe6060f1SDimitry Andric     for (Value *V : Opt->Inputs) {
1332fe6060f1SDimitry Andric       if (!PotentiallyDerivedPointers.count(V))
1333fe6060f1SDimitry Andric         continue;
1334fe6060f1SDimitry Andric       PotentiallyDerivedPointers.remove(V);
1335fe6060f1SDimitry Andric       PointerToBase[V] = V;
1336fe6060f1SDimitry Andric     }
133781ad6265SDimitry Andric   findBasePointers(PotentiallyDerivedPointers, PointerToBase, &DT, DVCache,
133881ad6265SDimitry Andric                    KnownBases);
13390b57cec5SDimitry Andric }
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric /// Given an updated version of the dataflow liveness results, update the
13420b57cec5SDimitry Andric /// liveset and base pointer maps for the call site CS.
13430b57cec5SDimitry Andric static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
13440b57cec5SDimitry Andric                                   CallBase *Call,
13451fd87a68SDimitry Andric                                   PartiallyConstructedSafepointRecord &result,
134606c3fb27SDimitry Andric                                   PointerToBaseTy &PointerToBase,
134706c3fb27SDimitry Andric                                   GCStrategy *GC);
13480b57cec5SDimitry Andric 
13490b57cec5SDimitry Andric static void recomputeLiveInValues(
13500b57cec5SDimitry Andric     Function &F, DominatorTree &DT, ArrayRef<CallBase *> toUpdate,
13511fd87a68SDimitry Andric     MutableArrayRef<struct PartiallyConstructedSafepointRecord> records,
135206c3fb27SDimitry Andric     PointerToBaseTy &PointerToBase, GCStrategy *GC) {
13530b57cec5SDimitry Andric   // TODO-PERF: reuse the original liveness, then simply run the dataflow
13540b57cec5SDimitry Andric   // again.  The old values are still live and will help it stabilize quickly.
13550b57cec5SDimitry Andric   GCPtrLivenessData RevisedLivenessData;
135606c3fb27SDimitry Andric   computeLiveInValues(DT, F, RevisedLivenessData, GC);
13570b57cec5SDimitry Andric   for (size_t i = 0; i < records.size(); i++) {
13580b57cec5SDimitry Andric     struct PartiallyConstructedSafepointRecord &info = records[i];
135906c3fb27SDimitry Andric     recomputeLiveInValues(RevisedLivenessData, toUpdate[i], info, PointerToBase,
136006c3fb27SDimitry Andric                           GC);
13610b57cec5SDimitry Andric   }
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric 
1364bdd1243dSDimitry Andric // Utility function which clones all instructions from "ChainToBase"
1365bdd1243dSDimitry Andric // and inserts them before "InsertBefore". Returns rematerialized value
1366bdd1243dSDimitry Andric // which should be used after statepoint.
1367bdd1243dSDimitry Andric static Instruction *rematerializeChain(ArrayRef<Instruction *> ChainToBase,
1368bdd1243dSDimitry Andric                                        Instruction *InsertBefore,
1369bdd1243dSDimitry Andric                                        Value *RootOfChain,
1370bdd1243dSDimitry Andric                                        Value *AlternateLiveBase) {
1371bdd1243dSDimitry Andric   Instruction *LastClonedValue = nullptr;
1372bdd1243dSDimitry Andric   Instruction *LastValue = nullptr;
1373bdd1243dSDimitry Andric   // Walk backwards to visit top-most instructions first.
1374bdd1243dSDimitry Andric   for (Instruction *Instr :
1375bdd1243dSDimitry Andric        make_range(ChainToBase.rbegin(), ChainToBase.rend())) {
1376bdd1243dSDimitry Andric     // Only GEP's and casts are supported as we need to be careful to not
1377bdd1243dSDimitry Andric     // introduce any new uses of pointers not in the liveset.
1378bdd1243dSDimitry Andric     // Note that it's fine to introduce new uses of pointers which were
1379bdd1243dSDimitry Andric     // otherwise not used after this statepoint.
1380bdd1243dSDimitry Andric     assert(isa<GetElementPtrInst>(Instr) || isa<CastInst>(Instr));
1381bdd1243dSDimitry Andric 
1382bdd1243dSDimitry Andric     Instruction *ClonedValue = Instr->clone();
1383bdd1243dSDimitry Andric     ClonedValue->insertBefore(InsertBefore);
1384bdd1243dSDimitry Andric     ClonedValue->setName(Instr->getName() + ".remat");
1385bdd1243dSDimitry Andric 
1386bdd1243dSDimitry Andric     // If it is not first instruction in the chain then it uses previously
1387bdd1243dSDimitry Andric     // cloned value. We should update it to use cloned value.
1388bdd1243dSDimitry Andric     if (LastClonedValue) {
1389bdd1243dSDimitry Andric       assert(LastValue);
1390bdd1243dSDimitry Andric       ClonedValue->replaceUsesOfWith(LastValue, LastClonedValue);
1391bdd1243dSDimitry Andric #ifndef NDEBUG
1392bdd1243dSDimitry Andric       for (auto *OpValue : ClonedValue->operand_values()) {
1393bdd1243dSDimitry Andric         // Assert that cloned instruction does not use any instructions from
1394bdd1243dSDimitry Andric         // this chain other than LastClonedValue
1395bdd1243dSDimitry Andric         assert(!is_contained(ChainToBase, OpValue) &&
1396bdd1243dSDimitry Andric                "incorrect use in rematerialization chain");
1397bdd1243dSDimitry Andric         // Assert that the cloned instruction does not use the RootOfChain
1398bdd1243dSDimitry Andric         // or the AlternateLiveBase.
1399bdd1243dSDimitry Andric         assert(OpValue != RootOfChain && OpValue != AlternateLiveBase);
1400bdd1243dSDimitry Andric       }
1401bdd1243dSDimitry Andric #endif
1402bdd1243dSDimitry Andric     } else {
1403bdd1243dSDimitry Andric       // For the first instruction, replace the use of unrelocated base i.e.
1404bdd1243dSDimitry Andric       // RootOfChain/OrigRootPhi, with the corresponding PHI present in the
1405bdd1243dSDimitry Andric       // live set. They have been proved to be the same PHI nodes.  Note
1406bdd1243dSDimitry Andric       // that the *only* use of the RootOfChain in the ChainToBase list is
1407bdd1243dSDimitry Andric       // the first Value in the list.
1408bdd1243dSDimitry Andric       if (RootOfChain != AlternateLiveBase)
1409bdd1243dSDimitry Andric         ClonedValue->replaceUsesOfWith(RootOfChain, AlternateLiveBase);
1410bdd1243dSDimitry Andric     }
1411bdd1243dSDimitry Andric 
1412bdd1243dSDimitry Andric     LastClonedValue = ClonedValue;
1413bdd1243dSDimitry Andric     LastValue = Instr;
1414bdd1243dSDimitry Andric   }
1415bdd1243dSDimitry Andric   assert(LastClonedValue);
1416bdd1243dSDimitry Andric   return LastClonedValue;
1417bdd1243dSDimitry Andric }
1418bdd1243dSDimitry Andric 
14190b57cec5SDimitry Andric // When inserting gc.relocate and gc.result calls, we need to ensure there are
14200b57cec5SDimitry Andric // no uses of the original value / return value between the gc.statepoint and
14210b57cec5SDimitry Andric // the gc.relocate / gc.result call.  One case which can arise is a phi node
14220b57cec5SDimitry Andric // starting one of the successor blocks.  We also need to be able to insert the
14230b57cec5SDimitry Andric // gc.relocates only on the path which goes through the statepoint.  We might
14240b57cec5SDimitry Andric // need to split an edge to make this possible.
14250b57cec5SDimitry Andric static BasicBlock *
14260b57cec5SDimitry Andric normalizeForInvokeSafepoint(BasicBlock *BB, BasicBlock *InvokeParent,
14270b57cec5SDimitry Andric                             DominatorTree &DT) {
14280b57cec5SDimitry Andric   BasicBlock *Ret = BB;
14290b57cec5SDimitry Andric   if (!BB->getUniquePredecessor())
14300b57cec5SDimitry Andric     Ret = SplitBlockPredecessors(BB, InvokeParent, "", &DT);
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric   // Now that 'Ret' has unique predecessor we can safely remove all phi nodes
14330b57cec5SDimitry Andric   // from it
14340b57cec5SDimitry Andric   FoldSingleEntryPHINodes(Ret);
14350b57cec5SDimitry Andric   assert(!isa<PHINode>(Ret->begin()) &&
14360b57cec5SDimitry Andric          "All PHI nodes should have been removed!");
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric   // At this point, we can safely insert a gc.relocate or gc.result as the first
14390b57cec5SDimitry Andric   // instruction in Ret if needed.
14400b57cec5SDimitry Andric   return Ret;
14410b57cec5SDimitry Andric }
14420b57cec5SDimitry Andric 
1443fe6060f1SDimitry Andric // List of all function attributes which must be stripped when lowering from
1444fe6060f1SDimitry Andric // abstract machine model to physical machine model.  Essentially, these are
1445fe6060f1SDimitry Andric // all the effects a safepoint might have which we ignored in the abstract
1446fe6060f1SDimitry Andric // machine model for purposes of optimization.  We have to strip these on
1447fe6060f1SDimitry Andric // both function declarations and call sites.
1448fe6060f1SDimitry Andric static constexpr Attribute::AttrKind FnAttrsToStrip[] =
1449bdd1243dSDimitry Andric   {Attribute::Memory, Attribute::NoSync, Attribute::NoFree};
1450fe6060f1SDimitry Andric 
14510b57cec5SDimitry Andric // Create new attribute set containing only attributes which can be transferred
14525f757f3fSDimitry Andric // from the original call to the safepoint.
14535f757f3fSDimitry Andric static AttributeList legalizeCallAttributes(CallBase *Call, bool IsMemIntrinsic,
145481ad6265SDimitry Andric                                             AttributeList StatepointAL) {
14555f757f3fSDimitry Andric   AttributeList OrigAL = Call->getAttributes();
145681ad6265SDimitry Andric   if (OrigAL.isEmpty())
145781ad6265SDimitry Andric     return StatepointAL;
14580b57cec5SDimitry Andric 
14590b57cec5SDimitry Andric   // Remove the readonly, readnone, and statepoint function attributes.
14605f757f3fSDimitry Andric   LLVMContext &Ctx = Call->getContext();
146181ad6265SDimitry Andric   AttrBuilder FnAttrs(Ctx, OrigAL.getFnAttrs());
1462fe6060f1SDimitry Andric   for (auto Attr : FnAttrsToStrip)
1463fe6060f1SDimitry Andric     FnAttrs.removeAttribute(Attr);
1464fe6060f1SDimitry Andric 
146581ad6265SDimitry Andric   for (Attribute A : OrigAL.getFnAttrs()) {
14660b57cec5SDimitry Andric     if (isStatepointDirectiveAttr(A))
146704eeddc0SDimitry Andric       FnAttrs.removeAttribute(A);
14680b57cec5SDimitry Andric   }
14690b57cec5SDimitry Andric 
14705f757f3fSDimitry Andric   StatepointAL = StatepointAL.addFnAttributes(Ctx, FnAttrs);
14715f757f3fSDimitry Andric 
14725f757f3fSDimitry Andric   // The memory intrinsics do not have a 1:1 correspondence of the original
14735f757f3fSDimitry Andric   // call arguments to the produced statepoint. Do not transfer the argument
14745f757f3fSDimitry Andric   // attributes to avoid putting them on incorrect arguments.
14755f757f3fSDimitry Andric   if (IsMemIntrinsic)
14765f757f3fSDimitry Andric     return StatepointAL;
14775f757f3fSDimitry Andric 
14785f757f3fSDimitry Andric   // Attach the argument attributes from the original call at the corresponding
14795f757f3fSDimitry Andric   // arguments in the statepoint. Note that any argument attributes that are
14805f757f3fSDimitry Andric   // invalid after lowering are stripped in stripNonValidDataFromBody.
14815f757f3fSDimitry Andric   for (unsigned I : llvm::seq(Call->arg_size()))
14825f757f3fSDimitry Andric     StatepointAL = StatepointAL.addParamAttributes(
14835f757f3fSDimitry Andric         Ctx, GCStatepointInst::CallArgsBeginPos + I,
14845f757f3fSDimitry Andric         AttrBuilder(Ctx, OrigAL.getParamAttrs(I)));
14855f757f3fSDimitry Andric 
14865f757f3fSDimitry Andric   // Return attributes are later attached to the gc.result intrinsic.
14875f757f3fSDimitry Andric   return StatepointAL;
14880b57cec5SDimitry Andric }
14890b57cec5SDimitry Andric 
14900b57cec5SDimitry Andric /// Helper function to place all gc relocates necessary for the given
14910b57cec5SDimitry Andric /// statepoint.
14920b57cec5SDimitry Andric /// Inputs:
14930b57cec5SDimitry Andric ///   liveVariables - list of variables to be relocated.
14940b57cec5SDimitry Andric ///   basePtrs - base pointers.
14950b57cec5SDimitry Andric ///   statepointToken - statepoint instruction to which relocates should be
14960b57cec5SDimitry Andric ///   bound.
14970b57cec5SDimitry Andric ///   Builder - Llvm IR builder to be used to construct new calls.
14980b57cec5SDimitry Andric static void CreateGCRelocates(ArrayRef<Value *> LiveVariables,
14990b57cec5SDimitry Andric                               ArrayRef<Value *> BasePtrs,
15000b57cec5SDimitry Andric                               Instruction *StatepointToken,
150106c3fb27SDimitry Andric                               IRBuilder<> &Builder, GCStrategy *GC) {
15020b57cec5SDimitry Andric   if (LiveVariables.empty())
15030b57cec5SDimitry Andric     return;
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   auto FindIndex = [](ArrayRef<Value *> LiveVec, Value *Val) {
15060b57cec5SDimitry Andric     auto ValIt = llvm::find(LiveVec, Val);
15070b57cec5SDimitry Andric     assert(ValIt != LiveVec.end() && "Val not found in LiveVec!");
15080b57cec5SDimitry Andric     size_t Index = std::distance(LiveVec.begin(), ValIt);
15090b57cec5SDimitry Andric     assert(Index < LiveVec.size() && "Bug in std::find?");
15100b57cec5SDimitry Andric     return Index;
15110b57cec5SDimitry Andric   };
15120b57cec5SDimitry Andric   Module *M = StatepointToken->getModule();
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric   // All gc_relocate are generated as i8 addrspace(1)* (or a vector type whose
15150b57cec5SDimitry Andric   // element type is i8 addrspace(1)*). We originally generated unique
15160b57cec5SDimitry Andric   // declarations for each pointer type, but this proved problematic because
15170b57cec5SDimitry Andric   // the intrinsic mangling code is incomplete and fragile.  Since we're moving
15180b57cec5SDimitry Andric   // towards a single unified pointer type anyways, we can just cast everything
15190b57cec5SDimitry Andric   // to an i8* of the right address space.  A bitcast is added later to convert
15200b57cec5SDimitry Andric   // gc_relocate to the actual value's type.
15210b57cec5SDimitry Andric   auto getGCRelocateDecl = [&](Type *Ty) {
152206c3fb27SDimitry Andric     assert(isHandledGCPointerType(Ty, GC));
15230b57cec5SDimitry Andric     auto AS = Ty->getScalarType()->getPointerAddressSpace();
15245f757f3fSDimitry Andric     Type *NewTy = PointerType::get(M->getContext(), AS);
15250b57cec5SDimitry Andric     if (auto *VT = dyn_cast<VectorType>(Ty))
15265ffd83dbSDimitry Andric       NewTy = FixedVectorType::get(NewTy,
15275ffd83dbSDimitry Andric                                    cast<FixedVectorType>(VT)->getNumElements());
15280b57cec5SDimitry Andric     return Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate,
15290b57cec5SDimitry Andric                                      {NewTy});
15300b57cec5SDimitry Andric   };
15310b57cec5SDimitry Andric 
15320b57cec5SDimitry Andric   // Lazily populated map from input types to the canonicalized form mentioned
15330b57cec5SDimitry Andric   // in the comment above.  This should probably be cached somewhere more
15340b57cec5SDimitry Andric   // broadly.
15350b57cec5SDimitry Andric   DenseMap<Type *, Function *> TypeToDeclMap;
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   for (unsigned i = 0; i < LiveVariables.size(); i++) {
15380b57cec5SDimitry Andric     // Generate the gc.relocate call and save the result
15395ffd83dbSDimitry Andric     Value *BaseIdx = Builder.getInt32(FindIndex(LiveVariables, BasePtrs[i]));
15405ffd83dbSDimitry Andric     Value *LiveIdx = Builder.getInt32(i);
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric     Type *Ty = LiveVariables[i]->getType();
15430b57cec5SDimitry Andric     if (!TypeToDeclMap.count(Ty))
15440b57cec5SDimitry Andric       TypeToDeclMap[Ty] = getGCRelocateDecl(Ty);
15450b57cec5SDimitry Andric     Function *GCRelocateDecl = TypeToDeclMap[Ty];
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric     // only specify a debug name if we can give a useful one
15480b57cec5SDimitry Andric     CallInst *Reloc = Builder.CreateCall(
15490b57cec5SDimitry Andric         GCRelocateDecl, {StatepointToken, BaseIdx, LiveIdx},
15500b57cec5SDimitry Andric         suffixed_name_or(LiveVariables[i], ".relocated", ""));
15510b57cec5SDimitry Andric     // Trick CodeGen into thinking there are lots of free registers at this
15520b57cec5SDimitry Andric     // fake call.
15530b57cec5SDimitry Andric     Reloc->setCallingConv(CallingConv::Cold);
15540b57cec5SDimitry Andric   }
15550b57cec5SDimitry Andric }
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric namespace {
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric /// This struct is used to defer RAUWs and `eraseFromParent` s.  Using this
15600b57cec5SDimitry Andric /// avoids having to worry about keeping around dangling pointers to Values.
15610b57cec5SDimitry Andric class DeferredReplacement {
15620b57cec5SDimitry Andric   AssertingVH<Instruction> Old;
15630b57cec5SDimitry Andric   AssertingVH<Instruction> New;
15640b57cec5SDimitry Andric   bool IsDeoptimize = false;
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric   DeferredReplacement() = default;
15670b57cec5SDimitry Andric 
15680b57cec5SDimitry Andric public:
15690b57cec5SDimitry Andric   static DeferredReplacement createRAUW(Instruction *Old, Instruction *New) {
15700b57cec5SDimitry Andric     assert(Old != New && Old && New &&
15710b57cec5SDimitry Andric            "Cannot RAUW equal values or to / from null!");
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric     DeferredReplacement D;
15740b57cec5SDimitry Andric     D.Old = Old;
15750b57cec5SDimitry Andric     D.New = New;
15760b57cec5SDimitry Andric     return D;
15770b57cec5SDimitry Andric   }
15780b57cec5SDimitry Andric 
15790b57cec5SDimitry Andric   static DeferredReplacement createDelete(Instruction *ToErase) {
15800b57cec5SDimitry Andric     DeferredReplacement D;
15810b57cec5SDimitry Andric     D.Old = ToErase;
15820b57cec5SDimitry Andric     return D;
15830b57cec5SDimitry Andric   }
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   static DeferredReplacement createDeoptimizeReplacement(Instruction *Old) {
15860b57cec5SDimitry Andric #ifndef NDEBUG
15870b57cec5SDimitry Andric     auto *F = cast<CallInst>(Old)->getCalledFunction();
15880b57cec5SDimitry Andric     assert(F && F->getIntrinsicID() == Intrinsic::experimental_deoptimize &&
15890b57cec5SDimitry Andric            "Only way to construct a deoptimize deferred replacement");
15900b57cec5SDimitry Andric #endif
15910b57cec5SDimitry Andric     DeferredReplacement D;
15920b57cec5SDimitry Andric     D.Old = Old;
15930b57cec5SDimitry Andric     D.IsDeoptimize = true;
15940b57cec5SDimitry Andric     return D;
15950b57cec5SDimitry Andric   }
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   /// Does the task represented by this instance.
15980b57cec5SDimitry Andric   void doReplacement() {
15990b57cec5SDimitry Andric     Instruction *OldI = Old;
16000b57cec5SDimitry Andric     Instruction *NewI = New;
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric     assert(OldI != NewI && "Disallowed at construction?!");
16030b57cec5SDimitry Andric     assert((!IsDeoptimize || !New) &&
16040b57cec5SDimitry Andric            "Deoptimize intrinsics are not replaced!");
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric     Old = nullptr;
16070b57cec5SDimitry Andric     New = nullptr;
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric     if (NewI)
16100b57cec5SDimitry Andric       OldI->replaceAllUsesWith(NewI);
16110b57cec5SDimitry Andric 
16120b57cec5SDimitry Andric     if (IsDeoptimize) {
16130b57cec5SDimitry Andric       // Note: we've inserted instructions, so the call to llvm.deoptimize may
16140b57cec5SDimitry Andric       // not necessarily be followed by the matching return.
16150b57cec5SDimitry Andric       auto *RI = cast<ReturnInst>(OldI->getParent()->getTerminator());
1616*0fca6ea1SDimitry Andric       new UnreachableInst(RI->getContext(), RI->getIterator());
16170b57cec5SDimitry Andric       RI->eraseFromParent();
16180b57cec5SDimitry Andric     }
16190b57cec5SDimitry Andric 
16200b57cec5SDimitry Andric     OldI->eraseFromParent();
16210b57cec5SDimitry Andric   }
16220b57cec5SDimitry Andric };
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric } // end anonymous namespace
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric static StringRef getDeoptLowering(CallBase *Call) {
16270b57cec5SDimitry Andric   const char *DeoptLowering = "deopt-lowering";
16280b57cec5SDimitry Andric   if (Call->hasFnAttr(DeoptLowering)) {
16290b57cec5SDimitry Andric     // FIXME: Calls have a *really* confusing interface around attributes
16300b57cec5SDimitry Andric     // with values.
16310b57cec5SDimitry Andric     const AttributeList &CSAS = Call->getAttributes();
1632349cc55cSDimitry Andric     if (CSAS.hasFnAttr(DeoptLowering))
1633349cc55cSDimitry Andric       return CSAS.getFnAttr(DeoptLowering).getValueAsString();
16340b57cec5SDimitry Andric     Function *F = Call->getCalledFunction();
16350b57cec5SDimitry Andric     assert(F && F->hasFnAttribute(DeoptLowering));
16360b57cec5SDimitry Andric     return F->getFnAttribute(DeoptLowering).getValueAsString();
16370b57cec5SDimitry Andric   }
16380b57cec5SDimitry Andric   return "live-through";
16390b57cec5SDimitry Andric }
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric static void
16420b57cec5SDimitry Andric makeStatepointExplicitImpl(CallBase *Call, /* to replace */
16430b57cec5SDimitry Andric                            const SmallVectorImpl<Value *> &BasePtrs,
16440b57cec5SDimitry Andric                            const SmallVectorImpl<Value *> &LiveVariables,
16450b57cec5SDimitry Andric                            PartiallyConstructedSafepointRecord &Result,
16461fd87a68SDimitry Andric                            std::vector<DeferredReplacement> &Replacements,
164706c3fb27SDimitry Andric                            const PointerToBaseTy &PointerToBase,
164806c3fb27SDimitry Andric                            GCStrategy *GC) {
16490b57cec5SDimitry Andric   assert(BasePtrs.size() == LiveVariables.size());
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric   // Then go ahead and use the builder do actually do the inserts.  We insert
16520b57cec5SDimitry Andric   // immediately before the previous instruction under the assumption that all
16530b57cec5SDimitry Andric   // arguments will be available here.  We can't insert afterwards since we may
16540b57cec5SDimitry Andric   // be replacing a terminator.
16550b57cec5SDimitry Andric   IRBuilder<> Builder(Call);
16560b57cec5SDimitry Andric 
16570b57cec5SDimitry Andric   ArrayRef<Value *> GCArgs(LiveVariables);
16580b57cec5SDimitry Andric   uint64_t StatepointID = StatepointDirectives::DefaultStatepointID;
16590b57cec5SDimitry Andric   uint32_t NumPatchBytes = 0;
16600b57cec5SDimitry Andric   uint32_t Flags = uint32_t(StatepointFlags::None);
16610b57cec5SDimitry Andric 
1662e8d8bef9SDimitry Andric   SmallVector<Value *, 8> CallArgs(Call->args());
1663bdd1243dSDimitry Andric   std::optional<ArrayRef<Use>> DeoptArgs;
16645ffd83dbSDimitry Andric   if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_deopt))
16655ffd83dbSDimitry Andric     DeoptArgs = Bundle->Inputs;
1666bdd1243dSDimitry Andric   std::optional<ArrayRef<Use>> TransitionArgs;
16675ffd83dbSDimitry Andric   if (auto Bundle = Call->getOperandBundle(LLVMContext::OB_gc_transition)) {
16685ffd83dbSDimitry Andric     TransitionArgs = Bundle->Inputs;
16695ffd83dbSDimitry Andric     // TODO: This flag no longer serves a purpose and can be removed later
16700b57cec5SDimitry Andric     Flags |= uint32_t(StatepointFlags::GCTransition);
16710b57cec5SDimitry Andric   }
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric   // Instead of lowering calls to @llvm.experimental.deoptimize as normal calls
16740b57cec5SDimitry Andric   // with a return value, we lower then as never returning calls to
16750b57cec5SDimitry Andric   // __llvm_deoptimize that are followed by unreachable to get better codegen.
16760b57cec5SDimitry Andric   bool IsDeoptimize = false;
16775f757f3fSDimitry Andric   bool IsMemIntrinsic = false;
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric   StatepointDirectives SD =
16800b57cec5SDimitry Andric       parseStatepointDirectivesFromAttrs(Call->getAttributes());
16810b57cec5SDimitry Andric   if (SD.NumPatchBytes)
16820b57cec5SDimitry Andric     NumPatchBytes = *SD.NumPatchBytes;
16830b57cec5SDimitry Andric   if (SD.StatepointID)
16840b57cec5SDimitry Andric     StatepointID = *SD.StatepointID;
16850b57cec5SDimitry Andric 
16860b57cec5SDimitry Andric   // Pass through the requested lowering if any.  The default is live-through.
16870b57cec5SDimitry Andric   StringRef DeoptLowering = getDeoptLowering(Call);
1688*0fca6ea1SDimitry Andric   if (DeoptLowering == "live-in")
16890b57cec5SDimitry Andric     Flags |= uint32_t(StatepointFlags::DeoptLiveIn);
16900b57cec5SDimitry Andric   else {
1691*0fca6ea1SDimitry Andric     assert(DeoptLowering == "live-through" && "Unsupported value!");
16920b57cec5SDimitry Andric   }
16930b57cec5SDimitry Andric 
169481ad6265SDimitry Andric   FunctionCallee CallTarget(Call->getFunctionType(), Call->getCalledOperand());
169581ad6265SDimitry Andric   if (Function *F = dyn_cast<Function>(CallTarget.getCallee())) {
1696e8d8bef9SDimitry Andric     auto IID = F->getIntrinsicID();
1697e8d8bef9SDimitry Andric     if (IID == Intrinsic::experimental_deoptimize) {
16980b57cec5SDimitry Andric       // Calls to llvm.experimental.deoptimize are lowered to calls to the
16990b57cec5SDimitry Andric       // __llvm_deoptimize symbol.  We want to resolve this now, since the
17000b57cec5SDimitry Andric       // verifier does not allow taking the address of an intrinsic function.
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric       SmallVector<Type *, 8> DomainTy;
17030b57cec5SDimitry Andric       for (Value *Arg : CallArgs)
17040b57cec5SDimitry Andric         DomainTy.push_back(Arg->getType());
17050b57cec5SDimitry Andric       auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
17060b57cec5SDimitry Andric                                     /* isVarArg = */ false);
17070b57cec5SDimitry Andric 
17080b57cec5SDimitry Andric       // Note: CallTarget can be a bitcast instruction of a symbol if there are
17090b57cec5SDimitry Andric       // calls to @llvm.experimental.deoptimize with different argument types in
17100b57cec5SDimitry Andric       // the same module.  This is fine -- we assume the frontend knew what it
17110b57cec5SDimitry Andric       // was doing when generating this kind of IR.
17120b57cec5SDimitry Andric       CallTarget = F->getParent()
171381ad6265SDimitry Andric                        ->getOrInsertFunction("__llvm_deoptimize", FTy);
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric       IsDeoptimize = true;
1716e8d8bef9SDimitry Andric     } else if (IID == Intrinsic::memcpy_element_unordered_atomic ||
1717e8d8bef9SDimitry Andric                IID == Intrinsic::memmove_element_unordered_atomic) {
17185f757f3fSDimitry Andric       IsMemIntrinsic = true;
17195f757f3fSDimitry Andric 
1720e8d8bef9SDimitry Andric       // Unordered atomic memcpy and memmove intrinsics which are not explicitly
1721e8d8bef9SDimitry Andric       // marked as "gc-leaf-function" should be lowered in a GC parseable way.
1722e8d8bef9SDimitry Andric       // Specifically, these calls should be lowered to the
1723e8d8bef9SDimitry Andric       // __llvm_{memcpy|memmove}_element_unordered_atomic_safepoint symbols.
1724e8d8bef9SDimitry Andric       // Similarly to __llvm_deoptimize we want to resolve this now, since the
1725e8d8bef9SDimitry Andric       // verifier does not allow taking the address of an intrinsic function.
1726e8d8bef9SDimitry Andric       //
1727e8d8bef9SDimitry Andric       // Moreover we need to shuffle the arguments for the call in order to
1728e8d8bef9SDimitry Andric       // accommodate GC. The underlying source and destination objects might be
1729e8d8bef9SDimitry Andric       // relocated during copy operation should the GC occur. To relocate the
1730e8d8bef9SDimitry Andric       // derived source and destination pointers the implementation of the
1731e8d8bef9SDimitry Andric       // intrinsic should know the corresponding base pointers.
1732e8d8bef9SDimitry Andric       //
1733e8d8bef9SDimitry Andric       // To make the base pointers available pass them explicitly as arguments:
1734e8d8bef9SDimitry Andric       //   memcpy(dest_derived, source_derived, ...) =>
1735e8d8bef9SDimitry Andric       //   memcpy(dest_base, dest_offset, source_base, source_offset, ...)
1736e8d8bef9SDimitry Andric       auto &Context = Call->getContext();
1737*0fca6ea1SDimitry Andric       auto &DL = Call->getDataLayout();
1738e8d8bef9SDimitry Andric       auto GetBaseAndOffset = [&](Value *Derived) {
1739fcaf7f86SDimitry Andric         Value *Base = nullptr;
1740fcaf7f86SDimitry Andric         // Optimizations in unreachable code might substitute the real pointer
1741fcaf7f86SDimitry Andric         // with undef, poison or null-derived constant. Return null base for
1742fcaf7f86SDimitry Andric         // them to be consistent with the handling in the main algorithm in
1743fcaf7f86SDimitry Andric         // findBaseDefiningValue.
1744fcaf7f86SDimitry Andric         if (isa<Constant>(Derived))
1745fcaf7f86SDimitry Andric           Base =
1746fcaf7f86SDimitry Andric               ConstantPointerNull::get(cast<PointerType>(Derived->getType()));
1747fcaf7f86SDimitry Andric         else {
17481fd87a68SDimitry Andric           assert(PointerToBase.count(Derived));
1749fcaf7f86SDimitry Andric           Base = PointerToBase.find(Derived)->second;
1750fcaf7f86SDimitry Andric         }
1751e8d8bef9SDimitry Andric         unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
1752e8d8bef9SDimitry Andric         unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
1753e8d8bef9SDimitry Andric         Value *Base_int = Builder.CreatePtrToInt(
1754e8d8bef9SDimitry Andric             Base, Type::getIntNTy(Context, IntPtrSize));
1755e8d8bef9SDimitry Andric         Value *Derived_int = Builder.CreatePtrToInt(
1756e8d8bef9SDimitry Andric             Derived, Type::getIntNTy(Context, IntPtrSize));
1757e8d8bef9SDimitry Andric         return std::make_pair(Base, Builder.CreateSub(Derived_int, Base_int));
1758e8d8bef9SDimitry Andric       };
1759e8d8bef9SDimitry Andric 
1760e8d8bef9SDimitry Andric       auto *Dest = CallArgs[0];
1761e8d8bef9SDimitry Andric       Value *DestBase, *DestOffset;
1762e8d8bef9SDimitry Andric       std::tie(DestBase, DestOffset) = GetBaseAndOffset(Dest);
1763e8d8bef9SDimitry Andric 
1764e8d8bef9SDimitry Andric       auto *Source = CallArgs[1];
1765e8d8bef9SDimitry Andric       Value *SourceBase, *SourceOffset;
1766e8d8bef9SDimitry Andric       std::tie(SourceBase, SourceOffset) = GetBaseAndOffset(Source);
1767e8d8bef9SDimitry Andric 
1768e8d8bef9SDimitry Andric       auto *LengthInBytes = CallArgs[2];
1769e8d8bef9SDimitry Andric       auto *ElementSizeCI = cast<ConstantInt>(CallArgs[3]);
1770e8d8bef9SDimitry Andric 
1771e8d8bef9SDimitry Andric       CallArgs.clear();
1772e8d8bef9SDimitry Andric       CallArgs.push_back(DestBase);
1773e8d8bef9SDimitry Andric       CallArgs.push_back(DestOffset);
1774e8d8bef9SDimitry Andric       CallArgs.push_back(SourceBase);
1775e8d8bef9SDimitry Andric       CallArgs.push_back(SourceOffset);
1776e8d8bef9SDimitry Andric       CallArgs.push_back(LengthInBytes);
1777e8d8bef9SDimitry Andric 
1778e8d8bef9SDimitry Andric       SmallVector<Type *, 8> DomainTy;
1779e8d8bef9SDimitry Andric       for (Value *Arg : CallArgs)
1780e8d8bef9SDimitry Andric         DomainTy.push_back(Arg->getType());
1781e8d8bef9SDimitry Andric       auto *FTy = FunctionType::get(Type::getVoidTy(F->getContext()), DomainTy,
1782e8d8bef9SDimitry Andric                                     /* isVarArg = */ false);
1783e8d8bef9SDimitry Andric 
1784e8d8bef9SDimitry Andric       auto GetFunctionName = [](Intrinsic::ID IID, ConstantInt *ElementSizeCI) {
1785e8d8bef9SDimitry Andric         uint64_t ElementSize = ElementSizeCI->getZExtValue();
1786e8d8bef9SDimitry Andric         if (IID == Intrinsic::memcpy_element_unordered_atomic) {
1787e8d8bef9SDimitry Andric           switch (ElementSize) {
1788e8d8bef9SDimitry Andric           case 1:
1789e8d8bef9SDimitry Andric             return "__llvm_memcpy_element_unordered_atomic_safepoint_1";
1790e8d8bef9SDimitry Andric           case 2:
1791e8d8bef9SDimitry Andric             return "__llvm_memcpy_element_unordered_atomic_safepoint_2";
1792e8d8bef9SDimitry Andric           case 4:
1793e8d8bef9SDimitry Andric             return "__llvm_memcpy_element_unordered_atomic_safepoint_4";
1794e8d8bef9SDimitry Andric           case 8:
1795e8d8bef9SDimitry Andric             return "__llvm_memcpy_element_unordered_atomic_safepoint_8";
1796e8d8bef9SDimitry Andric           case 16:
1797e8d8bef9SDimitry Andric             return "__llvm_memcpy_element_unordered_atomic_safepoint_16";
1798e8d8bef9SDimitry Andric           default:
1799e8d8bef9SDimitry Andric             llvm_unreachable("unexpected element size!");
1800e8d8bef9SDimitry Andric           }
1801e8d8bef9SDimitry Andric         }
1802e8d8bef9SDimitry Andric         assert(IID == Intrinsic::memmove_element_unordered_atomic);
1803e8d8bef9SDimitry Andric         switch (ElementSize) {
1804e8d8bef9SDimitry Andric         case 1:
1805e8d8bef9SDimitry Andric           return "__llvm_memmove_element_unordered_atomic_safepoint_1";
1806e8d8bef9SDimitry Andric         case 2:
1807e8d8bef9SDimitry Andric           return "__llvm_memmove_element_unordered_atomic_safepoint_2";
1808e8d8bef9SDimitry Andric         case 4:
1809e8d8bef9SDimitry Andric           return "__llvm_memmove_element_unordered_atomic_safepoint_4";
1810e8d8bef9SDimitry Andric         case 8:
1811e8d8bef9SDimitry Andric           return "__llvm_memmove_element_unordered_atomic_safepoint_8";
1812e8d8bef9SDimitry Andric         case 16:
1813e8d8bef9SDimitry Andric           return "__llvm_memmove_element_unordered_atomic_safepoint_16";
1814e8d8bef9SDimitry Andric         default:
1815e8d8bef9SDimitry Andric           llvm_unreachable("unexpected element size!");
1816e8d8bef9SDimitry Andric         }
1817e8d8bef9SDimitry Andric       };
1818e8d8bef9SDimitry Andric 
1819e8d8bef9SDimitry Andric       CallTarget =
1820e8d8bef9SDimitry Andric           F->getParent()
182181ad6265SDimitry Andric               ->getOrInsertFunction(GetFunctionName(IID, ElementSizeCI), FTy);
18220b57cec5SDimitry Andric     }
18230b57cec5SDimitry Andric   }
18240b57cec5SDimitry Andric 
18250b57cec5SDimitry Andric   // Create the statepoint given all the arguments
18265ffd83dbSDimitry Andric   GCStatepointInst *Token = nullptr;
18270b57cec5SDimitry Andric   if (auto *CI = dyn_cast<CallInst>(Call)) {
18280b57cec5SDimitry Andric     CallInst *SPCall = Builder.CreateGCStatepointCall(
18290b57cec5SDimitry Andric         StatepointID, NumPatchBytes, CallTarget, Flags, CallArgs,
18300b57cec5SDimitry Andric         TransitionArgs, DeoptArgs, GCArgs, "safepoint_token");
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric     SPCall->setTailCallKind(CI->getTailCallKind());
18330b57cec5SDimitry Andric     SPCall->setCallingConv(CI->getCallingConv());
18340b57cec5SDimitry Andric 
18355f757f3fSDimitry Andric     // Set up function attrs directly on statepoint and return attrs later for
18360b57cec5SDimitry Andric     // gc_result intrinsic.
18375f757f3fSDimitry Andric     SPCall->setAttributes(
18385f757f3fSDimitry Andric         legalizeCallAttributes(CI, IsMemIntrinsic, SPCall->getAttributes()));
18390b57cec5SDimitry Andric 
18405ffd83dbSDimitry Andric     Token = cast<GCStatepointInst>(SPCall);
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric     // Put the following gc_result and gc_relocate calls immediately after the
18430b57cec5SDimitry Andric     // the old call (which we're about to delete)
18440b57cec5SDimitry Andric     assert(CI->getNextNode() && "Not a terminator, must have next!");
18450b57cec5SDimitry Andric     Builder.SetInsertPoint(CI->getNextNode());
18460b57cec5SDimitry Andric     Builder.SetCurrentDebugLocation(CI->getNextNode()->getDebugLoc());
18470b57cec5SDimitry Andric   } else {
18480b57cec5SDimitry Andric     auto *II = cast<InvokeInst>(Call);
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric     // Insert the new invoke into the old block.  We'll remove the old one in a
18510b57cec5SDimitry Andric     // moment at which point this will become the new terminator for the
18520b57cec5SDimitry Andric     // original block.
18530b57cec5SDimitry Andric     InvokeInst *SPInvoke = Builder.CreateGCStatepointInvoke(
18540b57cec5SDimitry Andric         StatepointID, NumPatchBytes, CallTarget, II->getNormalDest(),
18550b57cec5SDimitry Andric         II->getUnwindDest(), Flags, CallArgs, TransitionArgs, DeoptArgs, GCArgs,
18560b57cec5SDimitry Andric         "statepoint_token");
18570b57cec5SDimitry Andric 
18580b57cec5SDimitry Andric     SPInvoke->setCallingConv(II->getCallingConv());
18590b57cec5SDimitry Andric 
18605f757f3fSDimitry Andric     // Set up function attrs directly on statepoint and return attrs later for
18610b57cec5SDimitry Andric     // gc_result intrinsic.
18625f757f3fSDimitry Andric     SPInvoke->setAttributes(
18635f757f3fSDimitry Andric         legalizeCallAttributes(II, IsMemIntrinsic, SPInvoke->getAttributes()));
18640b57cec5SDimitry Andric 
18655ffd83dbSDimitry Andric     Token = cast<GCStatepointInst>(SPInvoke);
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric     // Generate gc relocates in exceptional path
18680b57cec5SDimitry Andric     BasicBlock *UnwindBlock = II->getUnwindDest();
18690b57cec5SDimitry Andric     assert(!isa<PHINode>(UnwindBlock->begin()) &&
18700b57cec5SDimitry Andric            UnwindBlock->getUniquePredecessor() &&
18710b57cec5SDimitry Andric            "can't safely insert in this block!");
18720b57cec5SDimitry Andric 
18735f757f3fSDimitry Andric     Builder.SetInsertPoint(UnwindBlock, UnwindBlock->getFirstInsertionPt());
18740b57cec5SDimitry Andric     Builder.SetCurrentDebugLocation(II->getDebugLoc());
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric     // Attach exceptional gc relocates to the landingpad.
18770b57cec5SDimitry Andric     Instruction *ExceptionalToken = UnwindBlock->getLandingPadInst();
18780b57cec5SDimitry Andric     Result.UnwindToken = ExceptionalToken;
18790b57cec5SDimitry Andric 
188006c3fb27SDimitry Andric     CreateGCRelocates(LiveVariables, BasePtrs, ExceptionalToken, Builder, GC);
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric     // Generate gc relocates and returns for normal block
18830b57cec5SDimitry Andric     BasicBlock *NormalDest = II->getNormalDest();
18840b57cec5SDimitry Andric     assert(!isa<PHINode>(NormalDest->begin()) &&
18850b57cec5SDimitry Andric            NormalDest->getUniquePredecessor() &&
18860b57cec5SDimitry Andric            "can't safely insert in this block!");
18870b57cec5SDimitry Andric 
18885f757f3fSDimitry Andric     Builder.SetInsertPoint(NormalDest, NormalDest->getFirstInsertionPt());
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric     // gc relocates will be generated later as if it were regular call
18910b57cec5SDimitry Andric     // statepoint
18920b57cec5SDimitry Andric   }
18930b57cec5SDimitry Andric   assert(Token && "Should be set in one of the above branches!");
18940b57cec5SDimitry Andric 
18950b57cec5SDimitry Andric   if (IsDeoptimize) {
18960b57cec5SDimitry Andric     // If we're wrapping an @llvm.experimental.deoptimize in a statepoint, we
18970b57cec5SDimitry Andric     // transform the tail-call like structure to a call to a void function
18980b57cec5SDimitry Andric     // followed by unreachable to get better codegen.
18990b57cec5SDimitry Andric     Replacements.push_back(
19000b57cec5SDimitry Andric         DeferredReplacement::createDeoptimizeReplacement(Call));
19010b57cec5SDimitry Andric   } else {
19020b57cec5SDimitry Andric     Token->setName("statepoint_token");
19030b57cec5SDimitry Andric     if (!Call->getType()->isVoidTy() && !Call->use_empty()) {
19040b57cec5SDimitry Andric       StringRef Name = Call->hasName() ? Call->getName() : "";
19050b57cec5SDimitry Andric       CallInst *GCResult = Builder.CreateGCResult(Token, Call->getType(), Name);
19060b57cec5SDimitry Andric       GCResult->setAttributes(
19070b57cec5SDimitry Andric           AttributeList::get(GCResult->getContext(), AttributeList::ReturnIndex,
1908349cc55cSDimitry Andric                              Call->getAttributes().getRetAttrs()));
19090b57cec5SDimitry Andric 
19100b57cec5SDimitry Andric       // We cannot RAUW or delete CS.getInstruction() because it could be in the
19110b57cec5SDimitry Andric       // live set of some other safepoint, in which case that safepoint's
19120b57cec5SDimitry Andric       // PartiallyConstructedSafepointRecord will hold a raw pointer to this
19130b57cec5SDimitry Andric       // llvm::Instruction.  Instead, we defer the replacement and deletion to
19140b57cec5SDimitry Andric       // after the live sets have been made explicit in the IR, and we no longer
19150b57cec5SDimitry Andric       // have raw pointers to worry about.
19160b57cec5SDimitry Andric       Replacements.emplace_back(
19170b57cec5SDimitry Andric           DeferredReplacement::createRAUW(Call, GCResult));
19180b57cec5SDimitry Andric     } else {
19190b57cec5SDimitry Andric       Replacements.emplace_back(DeferredReplacement::createDelete(Call));
19200b57cec5SDimitry Andric     }
19210b57cec5SDimitry Andric   }
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric   Result.StatepointToken = Token;
19240b57cec5SDimitry Andric 
19250b57cec5SDimitry Andric   // Second, create a gc.relocate for every live variable
192606c3fb27SDimitry Andric   CreateGCRelocates(LiveVariables, BasePtrs, Token, Builder, GC);
19270b57cec5SDimitry Andric }
19280b57cec5SDimitry Andric 
19290b57cec5SDimitry Andric // Replace an existing gc.statepoint with a new one and a set of gc.relocates
19300b57cec5SDimitry Andric // which make the relocations happening at this safepoint explicit.
19310b57cec5SDimitry Andric //
19320b57cec5SDimitry Andric // WARNING: Does not do any fixup to adjust users of the original live
19330b57cec5SDimitry Andric // values.  That's the callers responsibility.
19340b57cec5SDimitry Andric static void
19350b57cec5SDimitry Andric makeStatepointExplicit(DominatorTree &DT, CallBase *Call,
19360b57cec5SDimitry Andric                        PartiallyConstructedSafepointRecord &Result,
19371fd87a68SDimitry Andric                        std::vector<DeferredReplacement> &Replacements,
193806c3fb27SDimitry Andric                        const PointerToBaseTy &PointerToBase, GCStrategy *GC) {
19390b57cec5SDimitry Andric   const auto &LiveSet = Result.LiveSet;
19400b57cec5SDimitry Andric 
19410b57cec5SDimitry Andric   // Convert to vector for efficient cross referencing.
19420b57cec5SDimitry Andric   SmallVector<Value *, 64> BaseVec, LiveVec;
19430b57cec5SDimitry Andric   LiveVec.reserve(LiveSet.size());
19440b57cec5SDimitry Andric   BaseVec.reserve(LiveSet.size());
19450b57cec5SDimitry Andric   for (Value *L : LiveSet) {
19460b57cec5SDimitry Andric     LiveVec.push_back(L);
19470b57cec5SDimitry Andric     assert(PointerToBase.count(L));
19480b57cec5SDimitry Andric     Value *Base = PointerToBase.find(L)->second;
19490b57cec5SDimitry Andric     BaseVec.push_back(Base);
19500b57cec5SDimitry Andric   }
19510b57cec5SDimitry Andric   assert(LiveVec.size() == BaseVec.size());
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric   // Do the actual rewriting and delete the old statepoint
19541fd87a68SDimitry Andric   makeStatepointExplicitImpl(Call, BaseVec, LiveVec, Result, Replacements,
195506c3fb27SDimitry Andric                              PointerToBase, GC);
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric 
19580b57cec5SDimitry Andric // Helper function for the relocationViaAlloca.
19590b57cec5SDimitry Andric //
19600b57cec5SDimitry Andric // It receives iterator to the statepoint gc relocates and emits a store to the
19610b57cec5SDimitry Andric // assigned location (via allocaMap) for the each one of them.  It adds the
19620b57cec5SDimitry Andric // visited values into the visitedLiveValues set, which we will later use them
1963349cc55cSDimitry Andric // for validation checking.
19640b57cec5SDimitry Andric static void
19650b57cec5SDimitry Andric insertRelocationStores(iterator_range<Value::user_iterator> GCRelocs,
19660b57cec5SDimitry Andric                        DenseMap<Value *, AllocaInst *> &AllocaMap,
19670b57cec5SDimitry Andric                        DenseSet<Value *> &VisitedLiveValues) {
19680b57cec5SDimitry Andric   for (User *U : GCRelocs) {
19690b57cec5SDimitry Andric     GCRelocateInst *Relocate = dyn_cast<GCRelocateInst>(U);
19700b57cec5SDimitry Andric     if (!Relocate)
19710b57cec5SDimitry Andric       continue;
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric     Value *OriginalValue = Relocate->getDerivedPtr();
19740b57cec5SDimitry Andric     assert(AllocaMap.count(OriginalValue));
19750b57cec5SDimitry Andric     Value *Alloca = AllocaMap[OriginalValue];
19760b57cec5SDimitry Andric 
1977297eecfbSDimitry Andric     // Emit store into the related alloca.
19780b57cec5SDimitry Andric     assert(Relocate->getNextNode() &&
19790b57cec5SDimitry Andric            "Should always have one since it's not a terminator");
1980*0fca6ea1SDimitry Andric     new StoreInst(Relocate, Alloca, std::next(Relocate->getIterator()));
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric #ifndef NDEBUG
19830b57cec5SDimitry Andric     VisitedLiveValues.insert(OriginalValue);
19840b57cec5SDimitry Andric #endif
19850b57cec5SDimitry Andric   }
19860b57cec5SDimitry Andric }
19870b57cec5SDimitry Andric 
19880b57cec5SDimitry Andric // Helper function for the "relocationViaAlloca". Similar to the
19890b57cec5SDimitry Andric // "insertRelocationStores" but works for rematerialized values.
19900b57cec5SDimitry Andric static void insertRematerializationStores(
19910b57cec5SDimitry Andric     const RematerializedValueMapTy &RematerializedValues,
19920b57cec5SDimitry Andric     DenseMap<Value *, AllocaInst *> &AllocaMap,
19930b57cec5SDimitry Andric     DenseSet<Value *> &VisitedLiveValues) {
19940b57cec5SDimitry Andric   for (auto RematerializedValuePair: RematerializedValues) {
19950b57cec5SDimitry Andric     Instruction *RematerializedValue = RematerializedValuePair.first;
19960b57cec5SDimitry Andric     Value *OriginalValue = RematerializedValuePair.second;
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric     assert(AllocaMap.count(OriginalValue) &&
19990b57cec5SDimitry Andric            "Can not find alloca for rematerialized value");
20000b57cec5SDimitry Andric     Value *Alloca = AllocaMap[OriginalValue];
20010b57cec5SDimitry Andric 
20025ffd83dbSDimitry Andric     new StoreInst(RematerializedValue, Alloca,
2003*0fca6ea1SDimitry Andric                   std::next(RematerializedValue->getIterator()));
20040b57cec5SDimitry Andric 
20050b57cec5SDimitry Andric #ifndef NDEBUG
20060b57cec5SDimitry Andric     VisitedLiveValues.insert(OriginalValue);
20070b57cec5SDimitry Andric #endif
20080b57cec5SDimitry Andric   }
20090b57cec5SDimitry Andric }
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric /// Do all the relocation update via allocas and mem2reg
20120b57cec5SDimitry Andric static void relocationViaAlloca(
20130b57cec5SDimitry Andric     Function &F, DominatorTree &DT, ArrayRef<Value *> Live,
20140b57cec5SDimitry Andric     ArrayRef<PartiallyConstructedSafepointRecord> Records) {
20150b57cec5SDimitry Andric #ifndef NDEBUG
20160b57cec5SDimitry Andric   // record initial number of (static) allocas; we'll check we have the same
20170b57cec5SDimitry Andric   // number when we get done.
20180b57cec5SDimitry Andric   int InitialAllocaNum = 0;
20190b57cec5SDimitry Andric   for (Instruction &I : F.getEntryBlock())
20200b57cec5SDimitry Andric     if (isa<AllocaInst>(I))
20210b57cec5SDimitry Andric       InitialAllocaNum++;
20220b57cec5SDimitry Andric #endif
20230b57cec5SDimitry Andric 
20240b57cec5SDimitry Andric   // TODO-PERF: change data structures, reserve
20250b57cec5SDimitry Andric   DenseMap<Value *, AllocaInst *> AllocaMap;
20260b57cec5SDimitry Andric   SmallVector<AllocaInst *, 200> PromotableAllocas;
20270b57cec5SDimitry Andric   // Used later to chack that we have enough allocas to store all values
20280b57cec5SDimitry Andric   std::size_t NumRematerializedValues = 0;
20290b57cec5SDimitry Andric   PromotableAllocas.reserve(Live.size());
20300b57cec5SDimitry Andric 
20310b57cec5SDimitry Andric   // Emit alloca for "LiveValue" and record it in "allocaMap" and
20320b57cec5SDimitry Andric   // "PromotableAllocas"
2033*0fca6ea1SDimitry Andric   const DataLayout &DL = F.getDataLayout();
20340b57cec5SDimitry Andric   auto emitAllocaFor = [&](Value *LiveValue) {
2035*0fca6ea1SDimitry Andric     AllocaInst *Alloca =
2036*0fca6ea1SDimitry Andric         new AllocaInst(LiveValue->getType(), DL.getAllocaAddrSpace(), "",
2037*0fca6ea1SDimitry Andric                        F.getEntryBlock().getFirstNonPHIIt());
20380b57cec5SDimitry Andric     AllocaMap[LiveValue] = Alloca;
20390b57cec5SDimitry Andric     PromotableAllocas.push_back(Alloca);
20400b57cec5SDimitry Andric   };
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric   // Emit alloca for each live gc pointer
20430b57cec5SDimitry Andric   for (Value *V : Live)
20440b57cec5SDimitry Andric     emitAllocaFor(V);
20450b57cec5SDimitry Andric 
20460b57cec5SDimitry Andric   // Emit allocas for rematerialized values
20470b57cec5SDimitry Andric   for (const auto &Info : Records)
20480b57cec5SDimitry Andric     for (auto RematerializedValuePair : Info.RematerializedValues) {
20490b57cec5SDimitry Andric       Value *OriginalValue = RematerializedValuePair.second;
2050cb14a3feSDimitry Andric       if (AllocaMap.contains(OriginalValue))
20510b57cec5SDimitry Andric         continue;
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric       emitAllocaFor(OriginalValue);
20540b57cec5SDimitry Andric       ++NumRematerializedValues;
20550b57cec5SDimitry Andric     }
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric   // The next two loops are part of the same conceptual operation.  We need to
20580b57cec5SDimitry Andric   // insert a store to the alloca after the original def and at each
20590b57cec5SDimitry Andric   // redefinition.  We need to insert a load before each use.  These are split
20600b57cec5SDimitry Andric   // into distinct loops for performance reasons.
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   // Update gc pointer after each statepoint: either store a relocated value or
20630b57cec5SDimitry Andric   // null (if no relocated value was found for this gc pointer and it is not a
20640b57cec5SDimitry Andric   // gc_result).  This must happen before we update the statepoint with load of
20650b57cec5SDimitry Andric   // alloca otherwise we lose the link between statepoint and old def.
20660b57cec5SDimitry Andric   for (const auto &Info : Records) {
20670b57cec5SDimitry Andric     Value *Statepoint = Info.StatepointToken;
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric     // This will be used for consistency check
20700b57cec5SDimitry Andric     DenseSet<Value *> VisitedLiveValues;
20710b57cec5SDimitry Andric 
20720b57cec5SDimitry Andric     // Insert stores for normal statepoint gc relocates
20730b57cec5SDimitry Andric     insertRelocationStores(Statepoint->users(), AllocaMap, VisitedLiveValues);
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric     // In case if it was invoke statepoint
20760b57cec5SDimitry Andric     // we will insert stores for exceptional path gc relocates.
20770b57cec5SDimitry Andric     if (isa<InvokeInst>(Statepoint)) {
20780b57cec5SDimitry Andric       insertRelocationStores(Info.UnwindToken->users(), AllocaMap,
20790b57cec5SDimitry Andric                              VisitedLiveValues);
20800b57cec5SDimitry Andric     }
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric     // Do similar thing with rematerialized values
20830b57cec5SDimitry Andric     insertRematerializationStores(Info.RematerializedValues, AllocaMap,
20840b57cec5SDimitry Andric                                   VisitedLiveValues);
20850b57cec5SDimitry Andric 
20860b57cec5SDimitry Andric     if (ClobberNonLive) {
20870b57cec5SDimitry Andric       // As a debugging aid, pretend that an unrelocated pointer becomes null at
20880b57cec5SDimitry Andric       // the gc.statepoint.  This will turn some subtle GC problems into
20890b57cec5SDimitry Andric       // slightly easier to debug SEGVs.  Note that on large IR files with
20900b57cec5SDimitry Andric       // lots of gc.statepoints this is extremely costly both memory and time
20910b57cec5SDimitry Andric       // wise.
20920b57cec5SDimitry Andric       SmallVector<AllocaInst *, 64> ToClobber;
20930b57cec5SDimitry Andric       for (auto Pair : AllocaMap) {
20940b57cec5SDimitry Andric         Value *Def = Pair.first;
20950b57cec5SDimitry Andric         AllocaInst *Alloca = Pair.second;
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric         // This value was relocated
20980b57cec5SDimitry Andric         if (VisitedLiveValues.count(Def)) {
20990b57cec5SDimitry Andric           continue;
21000b57cec5SDimitry Andric         }
21010b57cec5SDimitry Andric         ToClobber.push_back(Alloca);
21020b57cec5SDimitry Andric       }
21030b57cec5SDimitry Andric 
2104*0fca6ea1SDimitry Andric       auto InsertClobbersAt = [&](BasicBlock::iterator IP) {
21050b57cec5SDimitry Andric         for (auto *AI : ToClobber) {
2106bdd1243dSDimitry Andric           auto AT = AI->getAllocatedType();
2107bdd1243dSDimitry Andric           Constant *CPN;
2108bdd1243dSDimitry Andric           if (AT->isVectorTy())
2109bdd1243dSDimitry Andric             CPN = ConstantAggregateZero::get(AT);
2110bdd1243dSDimitry Andric           else
2111bdd1243dSDimitry Andric             CPN = ConstantPointerNull::get(cast<PointerType>(AT));
21125ffd83dbSDimitry Andric           new StoreInst(CPN, AI, IP);
21130b57cec5SDimitry Andric         }
21140b57cec5SDimitry Andric       };
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric       // Insert the clobbering stores.  These may get intermixed with the
21170b57cec5SDimitry Andric       // gc.results and gc.relocates, but that's fine.
21180b57cec5SDimitry Andric       if (auto II = dyn_cast<InvokeInst>(Statepoint)) {
2119*0fca6ea1SDimitry Andric         InsertClobbersAt(II->getNormalDest()->getFirstInsertionPt());
2120*0fca6ea1SDimitry Andric         InsertClobbersAt(II->getUnwindDest()->getFirstInsertionPt());
21210b57cec5SDimitry Andric       } else {
2122*0fca6ea1SDimitry Andric         InsertClobbersAt(
2123*0fca6ea1SDimitry Andric             std::next(cast<Instruction>(Statepoint)->getIterator()));
21240b57cec5SDimitry Andric       }
21250b57cec5SDimitry Andric     }
21260b57cec5SDimitry Andric   }
21270b57cec5SDimitry Andric 
21280b57cec5SDimitry Andric   // Update use with load allocas and add store for gc_relocated.
21290b57cec5SDimitry Andric   for (auto Pair : AllocaMap) {
21300b57cec5SDimitry Andric     Value *Def = Pair.first;
21310b57cec5SDimitry Andric     AllocaInst *Alloca = Pair.second;
21320b57cec5SDimitry Andric 
21330b57cec5SDimitry Andric     // We pre-record the uses of allocas so that we dont have to worry about
21340b57cec5SDimitry Andric     // later update that changes the user information..
21350b57cec5SDimitry Andric 
21360b57cec5SDimitry Andric     SmallVector<Instruction *, 20> Uses;
21370b57cec5SDimitry Andric     // PERF: trade a linear scan for repeated reallocation
21380b57cec5SDimitry Andric     Uses.reserve(Def->getNumUses());
21390b57cec5SDimitry Andric     for (User *U : Def->users()) {
21400b57cec5SDimitry Andric       if (!isa<ConstantExpr>(U)) {
21410b57cec5SDimitry Andric         // If the def has a ConstantExpr use, then the def is either a
21420b57cec5SDimitry Andric         // ConstantExpr use itself or null.  In either case
21430b57cec5SDimitry Andric         // (recursively in the first, directly in the second), the oop
21440b57cec5SDimitry Andric         // it is ultimately dependent on is null and this particular
21450b57cec5SDimitry Andric         // use does not need to be fixed up.
21460b57cec5SDimitry Andric         Uses.push_back(cast<Instruction>(U));
21470b57cec5SDimitry Andric       }
21480b57cec5SDimitry Andric     }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric     llvm::sort(Uses);
2151*0fca6ea1SDimitry Andric     auto Last = llvm::unique(Uses);
21520b57cec5SDimitry Andric     Uses.erase(Last, Uses.end());
21530b57cec5SDimitry Andric 
21540b57cec5SDimitry Andric     for (Instruction *Use : Uses) {
21550b57cec5SDimitry Andric       if (isa<PHINode>(Use)) {
21560b57cec5SDimitry Andric         PHINode *Phi = cast<PHINode>(Use);
21570b57cec5SDimitry Andric         for (unsigned i = 0; i < Phi->getNumIncomingValues(); i++) {
21580b57cec5SDimitry Andric           if (Def == Phi->getIncomingValue(i)) {
2159*0fca6ea1SDimitry Andric             LoadInst *Load = new LoadInst(
2160*0fca6ea1SDimitry Andric                 Alloca->getAllocatedType(), Alloca, "",
2161*0fca6ea1SDimitry Andric                 Phi->getIncomingBlock(i)->getTerminator()->getIterator());
21620b57cec5SDimitry Andric             Phi->setIncomingValue(i, Load);
21630b57cec5SDimitry Andric           }
21640b57cec5SDimitry Andric         }
21650b57cec5SDimitry Andric       } else {
2166*0fca6ea1SDimitry Andric         LoadInst *Load = new LoadInst(Alloca->getAllocatedType(), Alloca, "",
2167*0fca6ea1SDimitry Andric                                       Use->getIterator());
21680b57cec5SDimitry Andric         Use->replaceUsesOfWith(Def, Load);
21690b57cec5SDimitry Andric       }
21700b57cec5SDimitry Andric     }
21710b57cec5SDimitry Andric 
21720b57cec5SDimitry Andric     // Emit store for the initial gc value.  Store must be inserted after load,
21730b57cec5SDimitry Andric     // otherwise store will be in alloca's use list and an extra load will be
21740b57cec5SDimitry Andric     // inserted before it.
21755ffd83dbSDimitry Andric     StoreInst *Store = new StoreInst(Def, Alloca, /*volatile*/ false,
21765ffd83dbSDimitry Andric                                      DL.getABITypeAlign(Def->getType()));
21770b57cec5SDimitry Andric     if (Instruction *Inst = dyn_cast<Instruction>(Def)) {
21780b57cec5SDimitry Andric       if (InvokeInst *Invoke = dyn_cast<InvokeInst>(Inst)) {
21790b57cec5SDimitry Andric         // InvokeInst is a terminator so the store need to be inserted into its
21800b57cec5SDimitry Andric         // normal destination block.
21810b57cec5SDimitry Andric         BasicBlock *NormalDest = Invoke->getNormalDest();
21820b57cec5SDimitry Andric         Store->insertBefore(NormalDest->getFirstNonPHI());
21830b57cec5SDimitry Andric       } else {
21840b57cec5SDimitry Andric         assert(!Inst->isTerminator() &&
21850b57cec5SDimitry Andric                "The only terminator that can produce a value is "
21860b57cec5SDimitry Andric                "InvokeInst which is handled above.");
21870b57cec5SDimitry Andric         Store->insertAfter(Inst);
21880b57cec5SDimitry Andric       }
21890b57cec5SDimitry Andric     } else {
21900b57cec5SDimitry Andric       assert(isa<Argument>(Def));
21910b57cec5SDimitry Andric       Store->insertAfter(cast<Instruction>(Alloca));
21920b57cec5SDimitry Andric     }
21930b57cec5SDimitry Andric   }
21940b57cec5SDimitry Andric 
21950b57cec5SDimitry Andric   assert(PromotableAllocas.size() == Live.size() + NumRematerializedValues &&
21960b57cec5SDimitry Andric          "we must have the same allocas with lives");
219781ad6265SDimitry Andric   (void) NumRematerializedValues;
21980b57cec5SDimitry Andric   if (!PromotableAllocas.empty()) {
21990b57cec5SDimitry Andric     // Apply mem2reg to promote alloca to SSA
22000b57cec5SDimitry Andric     PromoteMemToReg(PromotableAllocas, DT);
22010b57cec5SDimitry Andric   }
22020b57cec5SDimitry Andric 
22030b57cec5SDimitry Andric #ifndef NDEBUG
22040b57cec5SDimitry Andric   for (auto &I : F.getEntryBlock())
22050b57cec5SDimitry Andric     if (isa<AllocaInst>(I))
22060b57cec5SDimitry Andric       InitialAllocaNum--;
22070b57cec5SDimitry Andric   assert(InitialAllocaNum == 0 && "We must not introduce any extra allocas");
22080b57cec5SDimitry Andric #endif
22090b57cec5SDimitry Andric }
22100b57cec5SDimitry Andric 
22110b57cec5SDimitry Andric /// Implement a unique function which doesn't require we sort the input
22120b57cec5SDimitry Andric /// vector.  Doing so has the effect of changing the output of a couple of
22130b57cec5SDimitry Andric /// tests in ways which make them less useful in testing fused safepoints.
22140b57cec5SDimitry Andric template <typename T> static void unique_unsorted(SmallVectorImpl<T> &Vec) {
22150b57cec5SDimitry Andric   SmallSet<T, 8> Seen;
2216e8d8bef9SDimitry Andric   erase_if(Vec, [&](const T &V) { return !Seen.insert(V).second; });
22170b57cec5SDimitry Andric }
22180b57cec5SDimitry Andric 
22190b57cec5SDimitry Andric /// Insert holders so that each Value is obviously live through the entire
22200b57cec5SDimitry Andric /// lifetime of the call.
22210b57cec5SDimitry Andric static void insertUseHolderAfter(CallBase *Call, const ArrayRef<Value *> Values,
22220b57cec5SDimitry Andric                                  SmallVectorImpl<CallInst *> &Holders) {
22230b57cec5SDimitry Andric   if (Values.empty())
22240b57cec5SDimitry Andric     // No values to hold live, might as well not insert the empty holder
22250b57cec5SDimitry Andric     return;
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric   Module *M = Call->getModule();
22280b57cec5SDimitry Andric   // Use a dummy vararg function to actually hold the values live
22290b57cec5SDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(
22300b57cec5SDimitry Andric       "__tmp_use", FunctionType::get(Type::getVoidTy(M->getContext()), true));
22310b57cec5SDimitry Andric   if (isa<CallInst>(Call)) {
22320b57cec5SDimitry Andric     // For call safepoints insert dummy calls right after safepoint
22330b57cec5SDimitry Andric     Holders.push_back(
2234*0fca6ea1SDimitry Andric         CallInst::Create(Func, Values, "", std::next(Call->getIterator())));
22350b57cec5SDimitry Andric     return;
22360b57cec5SDimitry Andric   }
22370b57cec5SDimitry Andric   // For invoke safepooints insert dummy calls both in normal and
22380b57cec5SDimitry Andric   // exceptional destination blocks
22390b57cec5SDimitry Andric   auto *II = cast<InvokeInst>(Call);
22400b57cec5SDimitry Andric   Holders.push_back(CallInst::Create(
2241*0fca6ea1SDimitry Andric       Func, Values, "", II->getNormalDest()->getFirstInsertionPt()));
22420b57cec5SDimitry Andric   Holders.push_back(CallInst::Create(
2243*0fca6ea1SDimitry Andric       Func, Values, "", II->getUnwindDest()->getFirstInsertionPt()));
22440b57cec5SDimitry Andric }
22450b57cec5SDimitry Andric 
22460b57cec5SDimitry Andric static void findLiveReferences(
22470b57cec5SDimitry Andric     Function &F, DominatorTree &DT, ArrayRef<CallBase *> toUpdate,
224806c3fb27SDimitry Andric     MutableArrayRef<struct PartiallyConstructedSafepointRecord> records,
224906c3fb27SDimitry Andric     GCStrategy *GC) {
22500b57cec5SDimitry Andric   GCPtrLivenessData OriginalLivenessData;
225106c3fb27SDimitry Andric   computeLiveInValues(DT, F, OriginalLivenessData, GC);
22520b57cec5SDimitry Andric   for (size_t i = 0; i < records.size(); i++) {
22530b57cec5SDimitry Andric     struct PartiallyConstructedSafepointRecord &info = records[i];
225406c3fb27SDimitry Andric     analyzeParsePointLiveness(DT, OriginalLivenessData, toUpdate[i], info, GC);
22550b57cec5SDimitry Andric   }
22560b57cec5SDimitry Andric }
22570b57cec5SDimitry Andric 
22580b57cec5SDimitry Andric // Helper function for the "rematerializeLiveValues". It walks use chain
22590b57cec5SDimitry Andric // starting from the "CurrentValue" until it reaches the root of the chain, i.e.
22600b57cec5SDimitry Andric // the base or a value it cannot process. Only "simple" values are processed
22610b57cec5SDimitry Andric // (currently it is GEP's and casts). The returned root is  examined by the
22620b57cec5SDimitry Andric // callers of findRematerializableChainToBasePointer.  Fills "ChainToBase" array
22630b57cec5SDimitry Andric // with all visited values.
22640b57cec5SDimitry Andric static Value* findRematerializableChainToBasePointer(
22650b57cec5SDimitry Andric   SmallVectorImpl<Instruction*> &ChainToBase,
22660b57cec5SDimitry Andric   Value *CurrentValue) {
22670b57cec5SDimitry Andric   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurrentValue)) {
22680b57cec5SDimitry Andric     ChainToBase.push_back(GEP);
22690b57cec5SDimitry Andric     return findRematerializableChainToBasePointer(ChainToBase,
22700b57cec5SDimitry Andric                                                   GEP->getPointerOperand());
22710b57cec5SDimitry Andric   }
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   if (CastInst *CI = dyn_cast<CastInst>(CurrentValue)) {
2274*0fca6ea1SDimitry Andric     if (!CI->isNoopCast(CI->getDataLayout()))
22750b57cec5SDimitry Andric       return CI;
22760b57cec5SDimitry Andric 
22770b57cec5SDimitry Andric     ChainToBase.push_back(CI);
22780b57cec5SDimitry Andric     return findRematerializableChainToBasePointer(ChainToBase,
22790b57cec5SDimitry Andric                                                   CI->getOperand(0));
22800b57cec5SDimitry Andric   }
22810b57cec5SDimitry Andric 
22820b57cec5SDimitry Andric   // We have reached the root of the chain, which is either equal to the base or
22830b57cec5SDimitry Andric   // is the first unsupported value along the use chain.
22840b57cec5SDimitry Andric   return CurrentValue;
22850b57cec5SDimitry Andric }
22860b57cec5SDimitry Andric 
22870b57cec5SDimitry Andric // Helper function for the "rematerializeLiveValues". Compute cost of the use
22880b57cec5SDimitry Andric // chain we are going to rematerialize.
2289e8d8bef9SDimitry Andric static InstructionCost
22900b57cec5SDimitry Andric chainToBasePointerCost(SmallVectorImpl<Instruction *> &Chain,
22910b57cec5SDimitry Andric                        TargetTransformInfo &TTI) {
2292e8d8bef9SDimitry Andric   InstructionCost Cost = 0;
22930b57cec5SDimitry Andric 
22940b57cec5SDimitry Andric   for (Instruction *Instr : Chain) {
22950b57cec5SDimitry Andric     if (CastInst *CI = dyn_cast<CastInst>(Instr)) {
2296*0fca6ea1SDimitry Andric       assert(CI->isNoopCast(CI->getDataLayout()) &&
22970b57cec5SDimitry Andric              "non noop cast is found during rematerialization");
22980b57cec5SDimitry Andric 
22990b57cec5SDimitry Andric       Type *SrcTy = CI->getOperand(0)->getType();
23005ffd83dbSDimitry Andric       Cost += TTI.getCastInstrCost(CI->getOpcode(), CI->getType(), SrcTy,
2301e8d8bef9SDimitry Andric                                    TTI::getCastContextHint(CI),
2302e8d8bef9SDimitry Andric                                    TargetTransformInfo::TCK_SizeAndLatency, CI);
23030b57cec5SDimitry Andric 
23040b57cec5SDimitry Andric     } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Instr)) {
23050b57cec5SDimitry Andric       // Cost of the address calculation
23060b57cec5SDimitry Andric       Type *ValTy = GEP->getSourceElementType();
23070b57cec5SDimitry Andric       Cost += TTI.getAddressComputationCost(ValTy);
23080b57cec5SDimitry Andric 
23090b57cec5SDimitry Andric       // And cost of the GEP itself
23100b57cec5SDimitry Andric       // TODO: Use TTI->getGEPCost here (it exists, but appears to be not
23110b57cec5SDimitry Andric       //       allowed for the external usage)
23120b57cec5SDimitry Andric       if (!GEP->hasAllConstantIndices())
23130b57cec5SDimitry Andric         Cost += 2;
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric     } else {
23160b57cec5SDimitry Andric       llvm_unreachable("unsupported instruction type during rematerialization");
23170b57cec5SDimitry Andric     }
23180b57cec5SDimitry Andric   }
23190b57cec5SDimitry Andric 
23200b57cec5SDimitry Andric   return Cost;
23210b57cec5SDimitry Andric }
23220b57cec5SDimitry Andric 
23230b57cec5SDimitry Andric static bool AreEquivalentPhiNodes(PHINode &OrigRootPhi, PHINode &AlternateRootPhi) {
23240b57cec5SDimitry Andric   unsigned PhiNum = OrigRootPhi.getNumIncomingValues();
23250b57cec5SDimitry Andric   if (PhiNum != AlternateRootPhi.getNumIncomingValues() ||
23260b57cec5SDimitry Andric       OrigRootPhi.getParent() != AlternateRootPhi.getParent())
23270b57cec5SDimitry Andric     return false;
23280b57cec5SDimitry Andric   // Map of incoming values and their corresponding basic blocks of
23290b57cec5SDimitry Andric   // OrigRootPhi.
23300b57cec5SDimitry Andric   SmallDenseMap<Value *, BasicBlock *, 8> CurrentIncomingValues;
23310b57cec5SDimitry Andric   for (unsigned i = 0; i < PhiNum; i++)
23320b57cec5SDimitry Andric     CurrentIncomingValues[OrigRootPhi.getIncomingValue(i)] =
23330b57cec5SDimitry Andric         OrigRootPhi.getIncomingBlock(i);
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric   // Both current and base PHIs should have same incoming values and
23360b57cec5SDimitry Andric   // the same basic blocks corresponding to the incoming values.
23370b57cec5SDimitry Andric   for (unsigned i = 0; i < PhiNum; i++) {
23380b57cec5SDimitry Andric     auto CIVI =
23390b57cec5SDimitry Andric         CurrentIncomingValues.find(AlternateRootPhi.getIncomingValue(i));
23400b57cec5SDimitry Andric     if (CIVI == CurrentIncomingValues.end())
23410b57cec5SDimitry Andric       return false;
23420b57cec5SDimitry Andric     BasicBlock *CurrentIncomingBB = CIVI->second;
23430b57cec5SDimitry Andric     if (CurrentIncomingBB != AlternateRootPhi.getIncomingBlock(i))
23440b57cec5SDimitry Andric       return false;
23450b57cec5SDimitry Andric   }
23460b57cec5SDimitry Andric   return true;
23470b57cec5SDimitry Andric }
23480b57cec5SDimitry Andric 
234981ad6265SDimitry Andric // Find derived pointers that can be recomputed cheap enough and fill
235081ad6265SDimitry Andric // RematerizationCandidates with such candidates.
235181ad6265SDimitry Andric static void
235281ad6265SDimitry Andric findRematerializationCandidates(PointerToBaseTy PointerToBase,
235381ad6265SDimitry Andric                                 RematCandTy &RematerizationCandidates,
23540b57cec5SDimitry Andric                                 TargetTransformInfo &TTI) {
23550b57cec5SDimitry Andric   const unsigned int ChainLengthThreshold = 10;
23560b57cec5SDimitry Andric 
235781ad6265SDimitry Andric   for (auto P2B : PointerToBase) {
235881ad6265SDimitry Andric     auto *Derived = P2B.first;
235981ad6265SDimitry Andric     auto *Base = P2B.second;
236081ad6265SDimitry Andric     // Consider only derived pointers.
236181ad6265SDimitry Andric     if (Derived == Base)
236281ad6265SDimitry Andric       continue;
23630b57cec5SDimitry Andric 
236481ad6265SDimitry Andric     // For each live pointer find its defining chain.
23650b57cec5SDimitry Andric     SmallVector<Instruction *, 3> ChainToBase;
23660b57cec5SDimitry Andric     Value *RootOfChain =
236781ad6265SDimitry Andric         findRematerializableChainToBasePointer(ChainToBase, Derived);
23680b57cec5SDimitry Andric 
23690b57cec5SDimitry Andric     // Nothing to do, or chain is too long
23700b57cec5SDimitry Andric     if ( ChainToBase.size() == 0 ||
23710b57cec5SDimitry Andric         ChainToBase.size() > ChainLengthThreshold)
23720b57cec5SDimitry Andric       continue;
23730b57cec5SDimitry Andric 
23740b57cec5SDimitry Andric     // Handle the scenario where the RootOfChain is not equal to the
23750b57cec5SDimitry Andric     // Base Value, but they are essentially the same phi values.
237681ad6265SDimitry Andric     if (RootOfChain != PointerToBase[Derived]) {
23770b57cec5SDimitry Andric       PHINode *OrigRootPhi = dyn_cast<PHINode>(RootOfChain);
237881ad6265SDimitry Andric       PHINode *AlternateRootPhi = dyn_cast<PHINode>(PointerToBase[Derived]);
23790b57cec5SDimitry Andric       if (!OrigRootPhi || !AlternateRootPhi)
23800b57cec5SDimitry Andric         continue;
23810b57cec5SDimitry Andric       // PHI nodes that have the same incoming values, and belonging to the same
23820b57cec5SDimitry Andric       // basic blocks are essentially the same SSA value.  When the original phi
23830b57cec5SDimitry Andric       // has incoming values with different base pointers, the original phi is
23840b57cec5SDimitry Andric       // marked as conflict, and an additional `AlternateRootPhi` with the same
23850b57cec5SDimitry Andric       // incoming values get generated by the findBasePointer function. We need
23860b57cec5SDimitry Andric       // to identify the newly generated AlternateRootPhi (.base version of phi)
23870b57cec5SDimitry Andric       // and RootOfChain (the original phi node itself) are the same, so that we
23880b57cec5SDimitry Andric       // can rematerialize the gep and casts. This is a workaround for the
23890b57cec5SDimitry Andric       // deficiency in the findBasePointer algorithm.
23900b57cec5SDimitry Andric       if (!AreEquivalentPhiNodes(*OrigRootPhi, *AlternateRootPhi))
23910b57cec5SDimitry Andric         continue;
23920b57cec5SDimitry Andric     }
239381ad6265SDimitry Andric     // Compute cost of this chain.
2394e8d8bef9SDimitry Andric     InstructionCost Cost = chainToBasePointerCost(ChainToBase, TTI);
23950b57cec5SDimitry Andric     // TODO: We can also account for cases when we will be able to remove some
23960b57cec5SDimitry Andric     //       of the rematerialized values by later optimization passes. I.e if
23970b57cec5SDimitry Andric     //       we rematerialized several intersecting chains. Or if original values
23980b57cec5SDimitry Andric     //       don't have any uses besides this statepoint.
23990b57cec5SDimitry Andric 
240081ad6265SDimitry Andric     // Ok, there is a candidate.
240181ad6265SDimitry Andric     RematerizlizationCandidateRecord Record;
240281ad6265SDimitry Andric     Record.ChainToBase = ChainToBase;
240381ad6265SDimitry Andric     Record.RootOfChain = RootOfChain;
240481ad6265SDimitry Andric     Record.Cost = Cost;
240581ad6265SDimitry Andric     RematerizationCandidates.insert({ Derived, Record });
240681ad6265SDimitry Andric   }
240781ad6265SDimitry Andric }
240881ad6265SDimitry Andric 
2409bdd1243dSDimitry Andric // Try to rematerialize derived pointers immediately before their uses
2410bdd1243dSDimitry Andric // (instead of rematerializing after every statepoint it is live through).
2411bdd1243dSDimitry Andric // This can be beneficial when derived pointer is live across many
2412bdd1243dSDimitry Andric // statepoints, but uses are rare.
2413bdd1243dSDimitry Andric static void rematerializeLiveValuesAtUses(
2414bdd1243dSDimitry Andric     RematCandTy &RematerizationCandidates,
2415bdd1243dSDimitry Andric     MutableArrayRef<PartiallyConstructedSafepointRecord> Records,
2416bdd1243dSDimitry Andric     PointerToBaseTy &PointerToBase) {
2417bdd1243dSDimitry Andric   if (!RematDerivedAtUses)
2418bdd1243dSDimitry Andric     return;
2419bdd1243dSDimitry Andric 
2420bdd1243dSDimitry Andric   SmallVector<Instruction *, 32> LiveValuesToBeDeleted;
2421bdd1243dSDimitry Andric 
2422bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Rematerialize derived pointers at uses, "
2423bdd1243dSDimitry Andric                     << "Num statepoints: " << Records.size() << '\n');
2424bdd1243dSDimitry Andric 
2425bdd1243dSDimitry Andric   for (auto &It : RematerizationCandidates) {
2426bdd1243dSDimitry Andric     Instruction *Cand = cast<Instruction>(It.first);
2427bdd1243dSDimitry Andric     auto &Record = It.second;
2428bdd1243dSDimitry Andric 
2429bdd1243dSDimitry Andric     if (Record.Cost >= RematerializationThreshold)
2430bdd1243dSDimitry Andric       continue;
2431bdd1243dSDimitry Andric 
2432bdd1243dSDimitry Andric     if (Cand->user_empty())
2433bdd1243dSDimitry Andric       continue;
2434bdd1243dSDimitry Andric 
2435bdd1243dSDimitry Andric     if (Cand->hasOneUse())
2436bdd1243dSDimitry Andric       if (auto *U = dyn_cast<Instruction>(Cand->getUniqueUndroppableUser()))
2437bdd1243dSDimitry Andric         if (U->getParent() == Cand->getParent())
2438bdd1243dSDimitry Andric           continue;
2439bdd1243dSDimitry Andric 
2440bdd1243dSDimitry Andric     // Rematerialization before PHI nodes is not implemented.
2441bdd1243dSDimitry Andric     if (llvm::any_of(Cand->users(),
2442bdd1243dSDimitry Andric                      [](const auto *U) { return isa<PHINode>(U); }))
2443bdd1243dSDimitry Andric       continue;
2444bdd1243dSDimitry Andric 
2445bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "Trying cand " << *Cand << " ... ");
2446bdd1243dSDimitry Andric 
2447bdd1243dSDimitry Andric     // Count of rematerialization instructions we introduce is equal to number
2448bdd1243dSDimitry Andric     // of candidate uses.
2449bdd1243dSDimitry Andric     // Count of rematerialization instructions we eliminate is equal to number
2450bdd1243dSDimitry Andric     // of statepoints it is live through.
2451bdd1243dSDimitry Andric     // Consider transformation profitable if latter is greater than former
2452bdd1243dSDimitry Andric     // (in other words, we create less than eliminate).
2453bdd1243dSDimitry Andric     unsigned NumLiveStatepoints = llvm::count_if(
2454bdd1243dSDimitry Andric         Records, [Cand](const auto &R) { return R.LiveSet.contains(Cand); });
2455bdd1243dSDimitry Andric     unsigned NumUses = Cand->getNumUses();
2456bdd1243dSDimitry Andric 
2457bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "Num uses: " << NumUses << " Num live statepoints: "
2458bdd1243dSDimitry Andric                       << NumLiveStatepoints << " ");
2459bdd1243dSDimitry Andric 
2460bdd1243dSDimitry Andric     if (NumLiveStatepoints < NumUses) {
2461bdd1243dSDimitry Andric       LLVM_DEBUG(dbgs() << "not profitable\n");
2462bdd1243dSDimitry Andric       continue;
2463bdd1243dSDimitry Andric     }
2464bdd1243dSDimitry Andric 
2465bdd1243dSDimitry Andric     // If rematerialization is 'free', then favor rematerialization at
2466bdd1243dSDimitry Andric     // uses as it generally shortens live ranges.
2467bdd1243dSDimitry Andric     // TODO: Short (size ==1) chains only?
2468bdd1243dSDimitry Andric     if (NumLiveStatepoints == NumUses && Record.Cost > 0) {
2469bdd1243dSDimitry Andric       LLVM_DEBUG(dbgs() << "not profitable\n");
2470bdd1243dSDimitry Andric       continue;
2471bdd1243dSDimitry Andric     }
2472bdd1243dSDimitry Andric 
2473bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "looks profitable\n");
2474bdd1243dSDimitry Andric 
2475bdd1243dSDimitry Andric     // ChainToBase may contain another remat candidate (as a sub chain) which
2476bdd1243dSDimitry Andric     // has been rewritten by now. Need to recollect chain to have up to date
2477bdd1243dSDimitry Andric     // value.
2478bdd1243dSDimitry Andric     // TODO: sort records in findRematerializationCandidates() in
2479bdd1243dSDimitry Andric     // decreasing chain size order?
2480bdd1243dSDimitry Andric     if (Record.ChainToBase.size() > 1) {
2481bdd1243dSDimitry Andric       Record.ChainToBase.clear();
2482bdd1243dSDimitry Andric       findRematerializableChainToBasePointer(Record.ChainToBase, Cand);
2483bdd1243dSDimitry Andric     }
2484bdd1243dSDimitry Andric 
2485bdd1243dSDimitry Andric     // Current rematerialization algorithm is very simple: we rematerialize
2486bdd1243dSDimitry Andric     // immediately before EVERY use, even if there are several uses in same
2487bdd1243dSDimitry Andric     // block or if use is local to Cand Def. The reason is that this allows
2488bdd1243dSDimitry Andric     // us to avoid recomputing liveness without complicated analysis:
2489bdd1243dSDimitry Andric     // - If we did not eliminate all uses of original Candidate, we do not
2490bdd1243dSDimitry Andric     //   know exaclty in what BBs it is still live.
2491bdd1243dSDimitry Andric     // - If we rematerialize once per BB, we need to find proper insertion
2492bdd1243dSDimitry Andric     //   place (first use in block, but after Def) and analyze if there is
2493bdd1243dSDimitry Andric     //   statepoint between uses in the block.
2494bdd1243dSDimitry Andric     while (!Cand->user_empty()) {
2495bdd1243dSDimitry Andric       Instruction *UserI = cast<Instruction>(*Cand->user_begin());
2496bdd1243dSDimitry Andric       Instruction *RematChain = rematerializeChain(
2497bdd1243dSDimitry Andric           Record.ChainToBase, UserI, Record.RootOfChain, PointerToBase[Cand]);
2498bdd1243dSDimitry Andric       UserI->replaceUsesOfWith(Cand, RematChain);
2499bdd1243dSDimitry Andric       PointerToBase[RematChain] = PointerToBase[Cand];
2500bdd1243dSDimitry Andric     }
2501bdd1243dSDimitry Andric     LiveValuesToBeDeleted.push_back(Cand);
2502bdd1243dSDimitry Andric   }
2503bdd1243dSDimitry Andric 
2504bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Rematerialized " << LiveValuesToBeDeleted.size()
2505bdd1243dSDimitry Andric                     << " derived pointers\n");
2506bdd1243dSDimitry Andric   for (auto *Cand : LiveValuesToBeDeleted) {
2507bdd1243dSDimitry Andric     assert(Cand->use_empty() && "Unexpected user remain");
2508bdd1243dSDimitry Andric     RematerizationCandidates.erase(Cand);
2509bdd1243dSDimitry Andric     for (auto &R : Records) {
2510bdd1243dSDimitry Andric       assert(!R.LiveSet.contains(Cand) ||
2511bdd1243dSDimitry Andric              R.LiveSet.contains(PointerToBase[Cand]));
2512bdd1243dSDimitry Andric       R.LiveSet.remove(Cand);
2513bdd1243dSDimitry Andric     }
2514bdd1243dSDimitry Andric   }
2515bdd1243dSDimitry Andric 
2516bdd1243dSDimitry Andric   // Recollect not rematerialized chains - we might have rewritten
2517bdd1243dSDimitry Andric   // their sub-chains.
2518bdd1243dSDimitry Andric   if (!LiveValuesToBeDeleted.empty()) {
2519bdd1243dSDimitry Andric     for (auto &P : RematerizationCandidates) {
2520bdd1243dSDimitry Andric       auto &R = P.second;
2521bdd1243dSDimitry Andric       if (R.ChainToBase.size() > 1) {
2522bdd1243dSDimitry Andric         R.ChainToBase.clear();
2523bdd1243dSDimitry Andric         findRematerializableChainToBasePointer(R.ChainToBase, P.first);
2524bdd1243dSDimitry Andric       }
2525bdd1243dSDimitry Andric     }
2526bdd1243dSDimitry Andric   }
2527bdd1243dSDimitry Andric }
2528bdd1243dSDimitry Andric 
252981ad6265SDimitry Andric // From the statepoint live set pick values that are cheaper to recompute then
253081ad6265SDimitry Andric // to relocate. Remove this values from the live set, rematerialize them after
253181ad6265SDimitry Andric // statepoint and record them in "Info" structure. Note that similar to
253281ad6265SDimitry Andric // relocated values we don't do any user adjustments here.
253381ad6265SDimitry Andric static void rematerializeLiveValues(CallBase *Call,
253481ad6265SDimitry Andric                                     PartiallyConstructedSafepointRecord &Info,
253581ad6265SDimitry Andric                                     PointerToBaseTy &PointerToBase,
253681ad6265SDimitry Andric                                     RematCandTy &RematerizationCandidates,
253781ad6265SDimitry Andric                                     TargetTransformInfo &TTI) {
253881ad6265SDimitry Andric   // Record values we are going to delete from this statepoint live set.
253981ad6265SDimitry Andric   // We can not di this in following loop due to iterator invalidation.
254081ad6265SDimitry Andric   SmallVector<Value *, 32> LiveValuesToBeDeleted;
254181ad6265SDimitry Andric 
254281ad6265SDimitry Andric   for (Value *LiveValue : Info.LiveSet) {
254381ad6265SDimitry Andric     auto It = RematerizationCandidates.find(LiveValue);
254481ad6265SDimitry Andric     if (It == RematerizationCandidates.end())
254581ad6265SDimitry Andric       continue;
254681ad6265SDimitry Andric 
254781ad6265SDimitry Andric     RematerizlizationCandidateRecord &Record = It->second;
254881ad6265SDimitry Andric 
254981ad6265SDimitry Andric     InstructionCost Cost = Record.Cost;
25500b57cec5SDimitry Andric     // For invokes we need to rematerialize each chain twice - for normal and
25510b57cec5SDimitry Andric     // for unwind basic blocks. Model this by multiplying cost by two.
255281ad6265SDimitry Andric     if (isa<InvokeInst>(Call))
25530b57cec5SDimitry Andric       Cost *= 2;
255481ad6265SDimitry Andric 
255581ad6265SDimitry Andric     // If it's too expensive - skip it.
25560b57cec5SDimitry Andric     if (Cost >= RematerializationThreshold)
25570b57cec5SDimitry Andric       continue;
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric     // Remove value from the live set
25600b57cec5SDimitry Andric     LiveValuesToBeDeleted.push_back(LiveValue);
25610b57cec5SDimitry Andric 
256281ad6265SDimitry Andric     // Clone instructions and record them inside "Info" structure.
25630b57cec5SDimitry Andric 
25640b57cec5SDimitry Andric     // Different cases for calls and invokes. For invokes we need to clone
25650b57cec5SDimitry Andric     // instructions both on normal and unwind path.
25660b57cec5SDimitry Andric     if (isa<CallInst>(Call)) {
25670b57cec5SDimitry Andric       Instruction *InsertBefore = Call->getNextNode();
25680b57cec5SDimitry Andric       assert(InsertBefore);
2569bdd1243dSDimitry Andric       Instruction *RematerializedValue =
2570bdd1243dSDimitry Andric           rematerializeChain(Record.ChainToBase, InsertBefore,
2571bdd1243dSDimitry Andric                              Record.RootOfChain, PointerToBase[LiveValue]);
25720b57cec5SDimitry Andric       Info.RematerializedValues[RematerializedValue] = LiveValue;
25730b57cec5SDimitry Andric     } else {
25740b57cec5SDimitry Andric       auto *Invoke = cast<InvokeInst>(Call);
25750b57cec5SDimitry Andric 
25760b57cec5SDimitry Andric       Instruction *NormalInsertBefore =
25770b57cec5SDimitry Andric           &*Invoke->getNormalDest()->getFirstInsertionPt();
25780b57cec5SDimitry Andric       Instruction *UnwindInsertBefore =
25790b57cec5SDimitry Andric           &*Invoke->getUnwindDest()->getFirstInsertionPt();
25800b57cec5SDimitry Andric 
2581bdd1243dSDimitry Andric       Instruction *NormalRematerializedValue =
2582bdd1243dSDimitry Andric           rematerializeChain(Record.ChainToBase, NormalInsertBefore,
2583bdd1243dSDimitry Andric                              Record.RootOfChain, PointerToBase[LiveValue]);
2584bdd1243dSDimitry Andric       Instruction *UnwindRematerializedValue =
2585bdd1243dSDimitry Andric           rematerializeChain(Record.ChainToBase, UnwindInsertBefore,
2586bdd1243dSDimitry Andric                              Record.RootOfChain, PointerToBase[LiveValue]);
25870b57cec5SDimitry Andric 
25880b57cec5SDimitry Andric       Info.RematerializedValues[NormalRematerializedValue] = LiveValue;
25890b57cec5SDimitry Andric       Info.RematerializedValues[UnwindRematerializedValue] = LiveValue;
25900b57cec5SDimitry Andric     }
25910b57cec5SDimitry Andric   }
25920b57cec5SDimitry Andric 
2593bdd1243dSDimitry Andric   // Remove rematerialized values from the live set.
2594bdd1243dSDimitry Andric   for (auto *LiveValue: LiveValuesToBeDeleted) {
25950b57cec5SDimitry Andric     Info.LiveSet.remove(LiveValue);
25960b57cec5SDimitry Andric   }
25970b57cec5SDimitry Andric }
25980b57cec5SDimitry Andric 
2599fe6060f1SDimitry Andric static bool inlineGetBaseAndOffset(Function &F,
2600fe6060f1SDimitry Andric                                    SmallVectorImpl<CallInst *> &Intrinsics,
260181ad6265SDimitry Andric                                    DefiningValueMapTy &DVCache,
260281ad6265SDimitry Andric                                    IsKnownBaseMapTy &KnownBases) {
2603fe6060f1SDimitry Andric   auto &Context = F.getContext();
2604*0fca6ea1SDimitry Andric   auto &DL = F.getDataLayout();
2605fe6060f1SDimitry Andric   bool Changed = false;
2606fe6060f1SDimitry Andric 
2607fe6060f1SDimitry Andric   for (auto *Callsite : Intrinsics)
2608fe6060f1SDimitry Andric     switch (Callsite->getIntrinsicID()) {
2609fe6060f1SDimitry Andric     case Intrinsic::experimental_gc_get_pointer_base: {
2610fe6060f1SDimitry Andric       Changed = true;
261181ad6265SDimitry Andric       Value *Base =
261281ad6265SDimitry Andric           findBasePointer(Callsite->getOperand(0), DVCache, KnownBases);
2613fe6060f1SDimitry Andric       assert(!DVCache.count(Callsite));
2614297eecfbSDimitry Andric       Callsite->replaceAllUsesWith(Base);
2615297eecfbSDimitry Andric       if (!Base->hasName())
2616297eecfbSDimitry Andric         Base->takeName(Callsite);
2617fe6060f1SDimitry Andric       Callsite->eraseFromParent();
2618fe6060f1SDimitry Andric       break;
2619fe6060f1SDimitry Andric     }
2620fe6060f1SDimitry Andric     case Intrinsic::experimental_gc_get_pointer_offset: {
2621fe6060f1SDimitry Andric       Changed = true;
2622fe6060f1SDimitry Andric       Value *Derived = Callsite->getOperand(0);
262381ad6265SDimitry Andric       Value *Base = findBasePointer(Derived, DVCache, KnownBases);
2624fe6060f1SDimitry Andric       assert(!DVCache.count(Callsite));
2625fe6060f1SDimitry Andric       unsigned AddressSpace = Derived->getType()->getPointerAddressSpace();
2626fe6060f1SDimitry Andric       unsigned IntPtrSize = DL.getPointerSizeInBits(AddressSpace);
2627fe6060f1SDimitry Andric       IRBuilder<> Builder(Callsite);
2628fe6060f1SDimitry Andric       Value *BaseInt =
2629fe6060f1SDimitry Andric           Builder.CreatePtrToInt(Base, Type::getIntNTy(Context, IntPtrSize),
2630fe6060f1SDimitry Andric                                  suffixed_name_or(Base, ".int", ""));
2631fe6060f1SDimitry Andric       Value *DerivedInt =
2632fe6060f1SDimitry Andric           Builder.CreatePtrToInt(Derived, Type::getIntNTy(Context, IntPtrSize),
2633fe6060f1SDimitry Andric                                  suffixed_name_or(Derived, ".int", ""));
2634fe6060f1SDimitry Andric       Value *Offset = Builder.CreateSub(DerivedInt, BaseInt);
2635fe6060f1SDimitry Andric       Callsite->replaceAllUsesWith(Offset);
2636fe6060f1SDimitry Andric       Offset->takeName(Callsite);
2637fe6060f1SDimitry Andric       Callsite->eraseFromParent();
2638fe6060f1SDimitry Andric       break;
2639fe6060f1SDimitry Andric     }
2640fe6060f1SDimitry Andric     default:
2641fe6060f1SDimitry Andric       llvm_unreachable("Unknown intrinsic");
2642fe6060f1SDimitry Andric     }
2643fe6060f1SDimitry Andric 
2644fe6060f1SDimitry Andric   return Changed;
2645fe6060f1SDimitry Andric }
2646fe6060f1SDimitry Andric 
26470b57cec5SDimitry Andric static bool insertParsePoints(Function &F, DominatorTree &DT,
26480b57cec5SDimitry Andric                               TargetTransformInfo &TTI,
2649fe6060f1SDimitry Andric                               SmallVectorImpl<CallBase *> &ToUpdate,
265081ad6265SDimitry Andric                               DefiningValueMapTy &DVCache,
265181ad6265SDimitry Andric                               IsKnownBaseMapTy &KnownBases) {
265206c3fb27SDimitry Andric   std::unique_ptr<GCStrategy> GC = findGCStrategy(F);
265306c3fb27SDimitry Andric 
26540b57cec5SDimitry Andric #ifndef NDEBUG
2655349cc55cSDimitry Andric   // Validate the input
26560b57cec5SDimitry Andric   std::set<CallBase *> Uniqued;
26570b57cec5SDimitry Andric   Uniqued.insert(ToUpdate.begin(), ToUpdate.end());
26580b57cec5SDimitry Andric   assert(Uniqued.size() == ToUpdate.size() && "no duplicates please!");
26590b57cec5SDimitry Andric 
26600b57cec5SDimitry Andric   for (CallBase *Call : ToUpdate)
26610b57cec5SDimitry Andric     assert(Call->getFunction() == &F);
26620b57cec5SDimitry Andric #endif
26630b57cec5SDimitry Andric 
26640b57cec5SDimitry Andric   // When inserting gc.relocates for invokes, we need to be able to insert at
26650b57cec5SDimitry Andric   // the top of the successor blocks.  See the comment on
26660b57cec5SDimitry Andric   // normalForInvokeSafepoint on exactly what is needed.  Note that this step
26670b57cec5SDimitry Andric   // may restructure the CFG.
26680b57cec5SDimitry Andric   for (CallBase *Call : ToUpdate) {
26690b57cec5SDimitry Andric     auto *II = dyn_cast<InvokeInst>(Call);
26700b57cec5SDimitry Andric     if (!II)
26710b57cec5SDimitry Andric       continue;
26720b57cec5SDimitry Andric     normalizeForInvokeSafepoint(II->getNormalDest(), II->getParent(), DT);
26730b57cec5SDimitry Andric     normalizeForInvokeSafepoint(II->getUnwindDest(), II->getParent(), DT);
26740b57cec5SDimitry Andric   }
26750b57cec5SDimitry Andric 
26760b57cec5SDimitry Andric   // A list of dummy calls added to the IR to keep various values obviously
26770b57cec5SDimitry Andric   // live in the IR.  We'll remove all of these when done.
26780b57cec5SDimitry Andric   SmallVector<CallInst *, 64> Holders;
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric   // Insert a dummy call with all of the deopt operands we'll need for the
26810b57cec5SDimitry Andric   // actual safepoint insertion as arguments.  This ensures reference operands
26820b57cec5SDimitry Andric   // in the deopt argument list are considered live through the safepoint (and
26830b57cec5SDimitry Andric   // thus makes sure they get relocated.)
26840b57cec5SDimitry Andric   for (CallBase *Call : ToUpdate) {
26850b57cec5SDimitry Andric     SmallVector<Value *, 64> DeoptValues;
26860b57cec5SDimitry Andric 
26870b57cec5SDimitry Andric     for (Value *Arg : GetDeoptBundleOperands(Call)) {
268806c3fb27SDimitry Andric       assert(!isUnhandledGCPointerType(Arg->getType(), GC.get()) &&
26890b57cec5SDimitry Andric              "support for FCA unimplemented");
269006c3fb27SDimitry Andric       if (isHandledGCPointerType(Arg->getType(), GC.get()))
26910b57cec5SDimitry Andric         DeoptValues.push_back(Arg);
26920b57cec5SDimitry Andric     }
26930b57cec5SDimitry Andric 
26940b57cec5SDimitry Andric     insertUseHolderAfter(Call, DeoptValues, Holders);
26950b57cec5SDimitry Andric   }
26960b57cec5SDimitry Andric 
26970b57cec5SDimitry Andric   SmallVector<PartiallyConstructedSafepointRecord, 64> Records(ToUpdate.size());
26980b57cec5SDimitry Andric 
26990b57cec5SDimitry Andric   // A) Identify all gc pointers which are statically live at the given call
27000b57cec5SDimitry Andric   // site.
270106c3fb27SDimitry Andric   findLiveReferences(F, DT, ToUpdate, Records, GC.get());
27020b57cec5SDimitry Andric 
27031fd87a68SDimitry Andric   /// Global mapping from live pointers to a base-defining-value.
27041fd87a68SDimitry Andric   PointerToBaseTy PointerToBase;
27051fd87a68SDimitry Andric 
27060b57cec5SDimitry Andric   // B) Find the base pointers for each live pointer
27070b57cec5SDimitry Andric   for (size_t i = 0; i < Records.size(); i++) {
27080b57cec5SDimitry Andric     PartiallyConstructedSafepointRecord &info = Records[i];
270981ad6265SDimitry Andric     findBasePointers(DT, DVCache, ToUpdate[i], info, PointerToBase, KnownBases);
27101fd87a68SDimitry Andric   }
27111fd87a68SDimitry Andric   if (PrintBasePointers) {
27121fd87a68SDimitry Andric     errs() << "Base Pairs (w/o Relocation):\n";
27131fd87a68SDimitry Andric     for (auto &Pair : PointerToBase) {
27141fd87a68SDimitry Andric       errs() << " derived ";
27151fd87a68SDimitry Andric       Pair.first->printAsOperand(errs(), false);
27161fd87a68SDimitry Andric       errs() << " base ";
27171fd87a68SDimitry Andric       Pair.second->printAsOperand(errs(), false);
27181fd87a68SDimitry Andric       errs() << "\n";
27191fd87a68SDimitry Andric       ;
27201fd87a68SDimitry Andric     }
27210b57cec5SDimitry Andric   }
27220b57cec5SDimitry Andric 
27230b57cec5SDimitry Andric   // The base phi insertion logic (for any safepoint) may have inserted new
27240b57cec5SDimitry Andric   // instructions which are now live at some safepoint.  The simplest such
27250b57cec5SDimitry Andric   // example is:
27260b57cec5SDimitry Andric   // loop:
27270b57cec5SDimitry Andric   //   phi a  <-- will be a new base_phi here
27280b57cec5SDimitry Andric   //   safepoint 1 <-- that needs to be live here
27290b57cec5SDimitry Andric   //   gep a + 1
27300b57cec5SDimitry Andric   //   safepoint 2
27310b57cec5SDimitry Andric   //   br loop
27320b57cec5SDimitry Andric   // We insert some dummy calls after each safepoint to definitely hold live
27330b57cec5SDimitry Andric   // the base pointers which were identified for that safepoint.  We'll then
27340b57cec5SDimitry Andric   // ask liveness for _every_ base inserted to see what is now live.  Then we
27350b57cec5SDimitry Andric   // remove the dummy calls.
27360b57cec5SDimitry Andric   Holders.reserve(Holders.size() + Records.size());
27370b57cec5SDimitry Andric   for (size_t i = 0; i < Records.size(); i++) {
27380b57cec5SDimitry Andric     PartiallyConstructedSafepointRecord &Info = Records[i];
27390b57cec5SDimitry Andric 
27400b57cec5SDimitry Andric     SmallVector<Value *, 128> Bases;
27411fd87a68SDimitry Andric     for (auto *Derived : Info.LiveSet) {
27421fd87a68SDimitry Andric       assert(PointerToBase.count(Derived) && "Missed base for derived pointer");
27431fd87a68SDimitry Andric       Bases.push_back(PointerToBase[Derived]);
27441fd87a68SDimitry Andric     }
27450b57cec5SDimitry Andric 
27460b57cec5SDimitry Andric     insertUseHolderAfter(ToUpdate[i], Bases, Holders);
27470b57cec5SDimitry Andric   }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric   // By selecting base pointers, we've effectively inserted new uses. Thus, we
27500b57cec5SDimitry Andric   // need to rerun liveness.  We may *also* have inserted new defs, but that's
27510b57cec5SDimitry Andric   // not the key issue.
275206c3fb27SDimitry Andric   recomputeLiveInValues(F, DT, ToUpdate, Records, PointerToBase, GC.get());
27530b57cec5SDimitry Andric 
27540b57cec5SDimitry Andric   if (PrintBasePointers) {
27550b57cec5SDimitry Andric     errs() << "Base Pairs: (w/Relocation)\n";
27561fd87a68SDimitry Andric     for (auto Pair : PointerToBase) {
27570b57cec5SDimitry Andric       errs() << " derived ";
27580b57cec5SDimitry Andric       Pair.first->printAsOperand(errs(), false);
27590b57cec5SDimitry Andric       errs() << " base ";
27600b57cec5SDimitry Andric       Pair.second->printAsOperand(errs(), false);
27610b57cec5SDimitry Andric       errs() << "\n";
27620b57cec5SDimitry Andric     }
27630b57cec5SDimitry Andric   }
27640b57cec5SDimitry Andric 
27650b57cec5SDimitry Andric   // It is possible that non-constant live variables have a constant base.  For
27660b57cec5SDimitry Andric   // example, a GEP with a variable offset from a global.  In this case we can
27670b57cec5SDimitry Andric   // remove it from the liveset.  We already don't add constants to the liveset
27680b57cec5SDimitry Andric   // because we assume they won't move at runtime and the GC doesn't need to be
27690b57cec5SDimitry Andric   // informed about them.  The same reasoning applies if the base is constant.
27700b57cec5SDimitry Andric   // Note that the relocation placement code relies on this filtering for
27710b57cec5SDimitry Andric   // correctness as it expects the base to be in the liveset, which isn't true
27720b57cec5SDimitry Andric   // if the base is constant.
27731fd87a68SDimitry Andric   for (auto &Info : Records) {
27741fd87a68SDimitry Andric     Info.LiveSet.remove_if([&](Value *LiveV) {
27751fd87a68SDimitry Andric       assert(PointerToBase.count(LiveV) && "Missed base for derived pointer");
27761fd87a68SDimitry Andric       return isa<Constant>(PointerToBase[LiveV]);
27771fd87a68SDimitry Andric     });
27781fd87a68SDimitry Andric   }
27790b57cec5SDimitry Andric 
27800b57cec5SDimitry Andric   for (CallInst *CI : Holders)
27810b57cec5SDimitry Andric     CI->eraseFromParent();
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric   Holders.clear();
27840b57cec5SDimitry Andric 
278581ad6265SDimitry Andric   // Compute the cost of possible re-materialization of derived pointers.
278681ad6265SDimitry Andric   RematCandTy RematerizationCandidates;
278781ad6265SDimitry Andric   findRematerializationCandidates(PointerToBase, RematerizationCandidates, TTI);
278881ad6265SDimitry Andric 
27890b57cec5SDimitry Andric   // In order to reduce live set of statepoint we might choose to rematerialize
27900b57cec5SDimitry Andric   // some values instead of relocating them. This is purely an optimization and
27910b57cec5SDimitry Andric   // does not influence correctness.
2792bdd1243dSDimitry Andric   // First try rematerialization at uses, then after statepoints.
2793bdd1243dSDimitry Andric   rematerializeLiveValuesAtUses(RematerizationCandidates, Records,
2794bdd1243dSDimitry Andric                                 PointerToBase);
27950b57cec5SDimitry Andric   for (size_t i = 0; i < Records.size(); i++)
279681ad6265SDimitry Andric     rematerializeLiveValues(ToUpdate[i], Records[i], PointerToBase,
279781ad6265SDimitry Andric                             RematerizationCandidates, TTI);
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric   // We need this to safely RAUW and delete call or invoke return values that
28000b57cec5SDimitry Andric   // may themselves be live over a statepoint.  For details, please see usage in
28010b57cec5SDimitry Andric   // makeStatepointExplicitImpl.
28020b57cec5SDimitry Andric   std::vector<DeferredReplacement> Replacements;
28030b57cec5SDimitry Andric 
28040b57cec5SDimitry Andric   // Now run through and replace the existing statepoints with new ones with
28050b57cec5SDimitry Andric   // the live variables listed.  We do not yet update uses of the values being
28060b57cec5SDimitry Andric   // relocated. We have references to live variables that need to
28070b57cec5SDimitry Andric   // survive to the last iteration of this loop.  (By construction, the
28080b57cec5SDimitry Andric   // previous statepoint can not be a live variable, thus we can and remove
28090b57cec5SDimitry Andric   // the old statepoint calls as we go.)
28100b57cec5SDimitry Andric   for (size_t i = 0; i < Records.size(); i++)
28111fd87a68SDimitry Andric     makeStatepointExplicit(DT, ToUpdate[i], Records[i], Replacements,
281206c3fb27SDimitry Andric                            PointerToBase, GC.get());
28130b57cec5SDimitry Andric 
28140b57cec5SDimitry Andric   ToUpdate.clear(); // prevent accident use of invalid calls.
28150b57cec5SDimitry Andric 
28160b57cec5SDimitry Andric   for (auto &PR : Replacements)
28170b57cec5SDimitry Andric     PR.doReplacement();
28180b57cec5SDimitry Andric 
28190b57cec5SDimitry Andric   Replacements.clear();
28200b57cec5SDimitry Andric 
28210b57cec5SDimitry Andric   for (auto &Info : Records) {
28220b57cec5SDimitry Andric     // These live sets may contain state Value pointers, since we replaced calls
28230b57cec5SDimitry Andric     // with operand bundles with calls wrapped in gc.statepoint, and some of
28240b57cec5SDimitry Andric     // those calls may have been def'ing live gc pointers.  Clear these out to
28250b57cec5SDimitry Andric     // avoid accidentally using them.
28260b57cec5SDimitry Andric     //
28270b57cec5SDimitry Andric     // TODO: We should create a separate data structure that does not contain
28280b57cec5SDimitry Andric     // these live sets, and migrate to using that data structure from this point
28290b57cec5SDimitry Andric     // onward.
28300b57cec5SDimitry Andric     Info.LiveSet.clear();
28310b57cec5SDimitry Andric   }
28321fd87a68SDimitry Andric   PointerToBase.clear();
28330b57cec5SDimitry Andric 
28340b57cec5SDimitry Andric   // Do all the fixups of the original live variables to their relocated selves
28350b57cec5SDimitry Andric   SmallVector<Value *, 128> Live;
283606c3fb27SDimitry Andric   for (const PartiallyConstructedSafepointRecord &Info : Records) {
28370b57cec5SDimitry Andric     // We can't simply save the live set from the original insertion.  One of
28380b57cec5SDimitry Andric     // the live values might be the result of a call which needs a safepoint.
28390b57cec5SDimitry Andric     // That Value* no longer exists and we need to use the new gc_result.
28400b57cec5SDimitry Andric     // Thankfully, the live set is embedded in the statepoint (and updated), so
28410b57cec5SDimitry Andric     // we just grab that.
2842e8d8bef9SDimitry Andric     llvm::append_range(Live, Info.StatepointToken->gc_args());
28430b57cec5SDimitry Andric #ifndef NDEBUG
2844349cc55cSDimitry Andric     // Do some basic validation checking on our liveness results before
2845349cc55cSDimitry Andric     // performing relocation.  Relocation can and will turn mistakes in liveness
2846349cc55cSDimitry Andric     // results into non-sensical code which is must harder to debug.
28470b57cec5SDimitry Andric     // TODO: It would be nice to test consistency as well
28480b57cec5SDimitry Andric     assert(DT.isReachableFromEntry(Info.StatepointToken->getParent()) &&
28490b57cec5SDimitry Andric            "statepoint must be reachable or liveness is meaningless");
28505ffd83dbSDimitry Andric     for (Value *V : Info.StatepointToken->gc_args()) {
28510b57cec5SDimitry Andric       if (!isa<Instruction>(V))
28520b57cec5SDimitry Andric         // Non-instruction values trivial dominate all possible uses
28530b57cec5SDimitry Andric         continue;
28540b57cec5SDimitry Andric       auto *LiveInst = cast<Instruction>(V);
28550b57cec5SDimitry Andric       assert(DT.isReachableFromEntry(LiveInst->getParent()) &&
28560b57cec5SDimitry Andric              "unreachable values should never be live");
28570b57cec5SDimitry Andric       assert(DT.dominates(LiveInst, Info.StatepointToken) &&
28580b57cec5SDimitry Andric              "basic SSA liveness expectation violated by liveness analysis");
28590b57cec5SDimitry Andric     }
28600b57cec5SDimitry Andric #endif
28610b57cec5SDimitry Andric   }
28620b57cec5SDimitry Andric   unique_unsorted(Live);
28630b57cec5SDimitry Andric 
28640b57cec5SDimitry Andric #ifndef NDEBUG
2865349cc55cSDimitry Andric   // Validation check
28660b57cec5SDimitry Andric   for (auto *Ptr : Live)
286706c3fb27SDimitry Andric     assert(isHandledGCPointerType(Ptr->getType(), GC.get()) &&
28680b57cec5SDimitry Andric            "must be a gc pointer type");
28690b57cec5SDimitry Andric #endif
28700b57cec5SDimitry Andric 
28710b57cec5SDimitry Andric   relocationViaAlloca(F, DT, Live, Records);
28720b57cec5SDimitry Andric   return !Records.empty();
28730b57cec5SDimitry Andric }
28740b57cec5SDimitry Andric 
28750eae32dcSDimitry Andric // List of all parameter and return attributes which must be stripped when
28760eae32dcSDimitry Andric // lowering from the abstract machine model.  Note that we list attributes
28770eae32dcSDimitry Andric // here which aren't valid as return attributes, that is okay.
287804eeddc0SDimitry Andric static AttributeMask getParamAndReturnAttributesToRemove() {
287904eeddc0SDimitry Andric   AttributeMask R;
288004eeddc0SDimitry Andric   R.addAttribute(Attribute::Dereferenceable);
288104eeddc0SDimitry Andric   R.addAttribute(Attribute::DereferenceableOrNull);
28820eae32dcSDimitry Andric   R.addAttribute(Attribute::ReadNone);
28830eae32dcSDimitry Andric   R.addAttribute(Attribute::ReadOnly);
28840eae32dcSDimitry Andric   R.addAttribute(Attribute::WriteOnly);
28850eae32dcSDimitry Andric   R.addAttribute(Attribute::NoAlias);
28860eae32dcSDimitry Andric   R.addAttribute(Attribute::NoFree);
28870eae32dcSDimitry Andric   return R;
28880b57cec5SDimitry Andric }
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric static void stripNonValidAttributesFromPrototype(Function &F) {
28910b57cec5SDimitry Andric   LLVMContext &Ctx = F.getContext();
28920b57cec5SDimitry Andric 
2893fe6060f1SDimitry Andric   // Intrinsics are very delicate.  Lowering sometimes depends the presence
2894fe6060f1SDimitry Andric   // of certain attributes for correctness, but we may have also inferred
2895fe6060f1SDimitry Andric   // additional ones in the abstract machine model which need stripped.  This
2896fe6060f1SDimitry Andric   // assumes that the attributes defined in Intrinsic.td are conservatively
2897fe6060f1SDimitry Andric   // correct for both physical and abstract model.
2898fe6060f1SDimitry Andric   if (Intrinsic::ID id = F.getIntrinsicID()) {
2899fe6060f1SDimitry Andric     F.setAttributes(Intrinsic::getAttributes(Ctx, id));
2900fe6060f1SDimitry Andric     return;
2901fe6060f1SDimitry Andric   }
2902fe6060f1SDimitry Andric 
290304eeddc0SDimitry Andric   AttributeMask R = getParamAndReturnAttributesToRemove();
29040b57cec5SDimitry Andric   for (Argument &A : F.args())
29050b57cec5SDimitry Andric     if (isa<PointerType>(A.getType()))
29060eae32dcSDimitry Andric       F.removeParamAttrs(A.getArgNo(), R);
29070b57cec5SDimitry Andric 
29080b57cec5SDimitry Andric   if (isa<PointerType>(F.getReturnType()))
29090eae32dcSDimitry Andric     F.removeRetAttrs(R);
2910fe6060f1SDimitry Andric 
2911fe6060f1SDimitry Andric   for (auto Attr : FnAttrsToStrip)
2912fe6060f1SDimitry Andric     F.removeFnAttr(Attr);
29130b57cec5SDimitry Andric }
29140b57cec5SDimitry Andric 
29150b57cec5SDimitry Andric /// Certain metadata on instructions are invalid after running RS4GC.
29160b57cec5SDimitry Andric /// Optimizations that run after RS4GC can incorrectly use this metadata to
29170b57cec5SDimitry Andric /// optimize functions. We drop such metadata on the instruction.
29180b57cec5SDimitry Andric static void stripInvalidMetadataFromInstruction(Instruction &I) {
29190b57cec5SDimitry Andric   if (!isa<LoadInst>(I) && !isa<StoreInst>(I))
29200b57cec5SDimitry Andric     return;
29210b57cec5SDimitry Andric   // These are the attributes that are still valid on loads and stores after
29220b57cec5SDimitry Andric   // RS4GC.
29230b57cec5SDimitry Andric   // The metadata implying dereferenceability and noalias are (conservatively)
29240b57cec5SDimitry Andric   // dropped.  This is because semantically, after RewriteStatepointsForGC runs,
29250b57cec5SDimitry Andric   // all calls to gc.statepoint "free" the entire heap. Also, gc.statepoint can
29260b57cec5SDimitry Andric   // touch the entire heap including noalias objects. Note: The reasoning is
29270b57cec5SDimitry Andric   // same as stripping the dereferenceability and noalias attributes that are
29280b57cec5SDimitry Andric   // analogous to the metadata counterparts.
29290b57cec5SDimitry Andric   // We also drop the invariant.load metadata on the load because that metadata
29300b57cec5SDimitry Andric   // implies the address operand to the load points to memory that is never
29310b57cec5SDimitry Andric   // changed once it became dereferenceable. This is no longer true after RS4GC.
29320b57cec5SDimitry Andric   // Similar reasoning applies to invariant.group metadata, which applies to
29330b57cec5SDimitry Andric   // loads within a group.
29340b57cec5SDimitry Andric   unsigned ValidMetadataAfterRS4GC[] = {LLVMContext::MD_tbaa,
29350b57cec5SDimitry Andric                          LLVMContext::MD_range,
29360b57cec5SDimitry Andric                          LLVMContext::MD_alias_scope,
29370b57cec5SDimitry Andric                          LLVMContext::MD_nontemporal,
29380b57cec5SDimitry Andric                          LLVMContext::MD_nonnull,
29390b57cec5SDimitry Andric                          LLVMContext::MD_align,
29400b57cec5SDimitry Andric                          LLVMContext::MD_type};
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric   // Drops all metadata on the instruction other than ValidMetadataAfterRS4GC.
29430b57cec5SDimitry Andric   I.dropUnknownNonDebugMetadata(ValidMetadataAfterRS4GC);
29440b57cec5SDimitry Andric }
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric static void stripNonValidDataFromBody(Function &F) {
29470b57cec5SDimitry Andric   if (F.empty())
29480b57cec5SDimitry Andric     return;
29490b57cec5SDimitry Andric 
29500b57cec5SDimitry Andric   LLVMContext &Ctx = F.getContext();
29510b57cec5SDimitry Andric   MDBuilder Builder(Ctx);
29520b57cec5SDimitry Andric 
29530b57cec5SDimitry Andric   // Set of invariantstart instructions that we need to remove.
29540b57cec5SDimitry Andric   // Use this to avoid invalidating the instruction iterator.
29550b57cec5SDimitry Andric   SmallVector<IntrinsicInst*, 12> InvariantStartInstructions;
29560b57cec5SDimitry Andric 
29570b57cec5SDimitry Andric   for (Instruction &I : instructions(F)) {
29580b57cec5SDimitry Andric     // invariant.start on memory location implies that the referenced memory
29590b57cec5SDimitry Andric     // location is constant and unchanging. This is no longer true after
29600b57cec5SDimitry Andric     // RewriteStatepointsForGC runs because there can be calls to gc.statepoint
29610b57cec5SDimitry Andric     // which frees the entire heap and the presence of invariant.start allows
29620b57cec5SDimitry Andric     // the optimizer to sink the load of a memory location past a statepoint,
29630b57cec5SDimitry Andric     // which is incorrect.
29640b57cec5SDimitry Andric     if (auto *II = dyn_cast<IntrinsicInst>(&I))
29650b57cec5SDimitry Andric       if (II->getIntrinsicID() == Intrinsic::invariant_start) {
29660b57cec5SDimitry Andric         InvariantStartInstructions.push_back(II);
29670b57cec5SDimitry Andric         continue;
29680b57cec5SDimitry Andric       }
29690b57cec5SDimitry Andric 
29700b57cec5SDimitry Andric     if (MDNode *Tag = I.getMetadata(LLVMContext::MD_tbaa)) {
29710b57cec5SDimitry Andric       MDNode *MutableTBAA = Builder.createMutableTBAAAccessTag(Tag);
29720b57cec5SDimitry Andric       I.setMetadata(LLVMContext::MD_tbaa, MutableTBAA);
29730b57cec5SDimitry Andric     }
29740b57cec5SDimitry Andric 
29750b57cec5SDimitry Andric     stripInvalidMetadataFromInstruction(I);
29760b57cec5SDimitry Andric 
297704eeddc0SDimitry Andric     AttributeMask R = getParamAndReturnAttributesToRemove();
29780b57cec5SDimitry Andric     if (auto *Call = dyn_cast<CallBase>(&I)) {
29790b57cec5SDimitry Andric       for (int i = 0, e = Call->arg_size(); i != e; i++)
29800b57cec5SDimitry Andric         if (isa<PointerType>(Call->getArgOperand(i)->getType()))
29810eae32dcSDimitry Andric           Call->removeParamAttrs(i, R);
29820b57cec5SDimitry Andric       if (isa<PointerType>(Call->getType()))
29830eae32dcSDimitry Andric         Call->removeRetAttrs(R);
29840b57cec5SDimitry Andric     }
29850b57cec5SDimitry Andric   }
29860b57cec5SDimitry Andric 
298706c3fb27SDimitry Andric   // Delete the invariant.start instructions and RAUW poison.
29880b57cec5SDimitry Andric   for (auto *II : InvariantStartInstructions) {
298906c3fb27SDimitry Andric     II->replaceAllUsesWith(PoisonValue::get(II->getType()));
29900b57cec5SDimitry Andric     II->eraseFromParent();
29910b57cec5SDimitry Andric   }
29920b57cec5SDimitry Andric }
29930b57cec5SDimitry Andric 
299406c3fb27SDimitry Andric /// Looks up the GC strategy for a given function, returning null if the
299506c3fb27SDimitry Andric /// function doesn't have a GC tag. The strategy is stored in the cache.
299606c3fb27SDimitry Andric static std::unique_ptr<GCStrategy> findGCStrategy(Function &F) {
299706c3fb27SDimitry Andric   if (!F.hasGC())
299806c3fb27SDimitry Andric     return nullptr;
299906c3fb27SDimitry Andric 
300006c3fb27SDimitry Andric   return getGCStrategy(F.getGC());
300106c3fb27SDimitry Andric }
300206c3fb27SDimitry Andric 
30030b57cec5SDimitry Andric /// Returns true if this function should be rewritten by this pass.  The main
30040b57cec5SDimitry Andric /// point of this function is as an extension point for custom logic.
30050b57cec5SDimitry Andric static bool shouldRewriteStatepointsIn(Function &F) {
300606c3fb27SDimitry Andric   if (!F.hasGC())
30070b57cec5SDimitry Andric     return false;
300806c3fb27SDimitry Andric 
300906c3fb27SDimitry Andric   std::unique_ptr<GCStrategy> Strategy = findGCStrategy(F);
301006c3fb27SDimitry Andric 
301106c3fb27SDimitry Andric   assert(Strategy && "GC strategy is required by function, but was not found");
301206c3fb27SDimitry Andric 
301306c3fb27SDimitry Andric   return Strategy->useRS4GC();
30140b57cec5SDimitry Andric }
30150b57cec5SDimitry Andric 
30160b57cec5SDimitry Andric static void stripNonValidData(Module &M) {
30170b57cec5SDimitry Andric #ifndef NDEBUG
30180b57cec5SDimitry Andric   assert(llvm::any_of(M, shouldRewriteStatepointsIn) && "precondition!");
30190b57cec5SDimitry Andric #endif
30200b57cec5SDimitry Andric 
30210b57cec5SDimitry Andric   for (Function &F : M)
30220b57cec5SDimitry Andric     stripNonValidAttributesFromPrototype(F);
30230b57cec5SDimitry Andric 
30240b57cec5SDimitry Andric   for (Function &F : M)
30250b57cec5SDimitry Andric     stripNonValidDataFromBody(F);
30260b57cec5SDimitry Andric }
30270b57cec5SDimitry Andric 
30280b57cec5SDimitry Andric bool RewriteStatepointsForGC::runOnFunction(Function &F, DominatorTree &DT,
30290b57cec5SDimitry Andric                                             TargetTransformInfo &TTI,
30300b57cec5SDimitry Andric                                             const TargetLibraryInfo &TLI) {
30310b57cec5SDimitry Andric   assert(!F.isDeclaration() && !F.empty() &&
30320b57cec5SDimitry Andric          "need function body to rewrite statepoints in");
30330b57cec5SDimitry Andric   assert(shouldRewriteStatepointsIn(F) && "mismatch in rewrite decision");
30340b57cec5SDimitry Andric 
30350b57cec5SDimitry Andric   auto NeedsRewrite = [&TLI](Instruction &I) {
3036e8d8bef9SDimitry Andric     if (const auto *Call = dyn_cast<CallBase>(&I)) {
3037e8d8bef9SDimitry Andric       if (isa<GCStatepointInst>(Call))
3038e8d8bef9SDimitry Andric         return false;
3039e8d8bef9SDimitry Andric       if (callsGCLeafFunction(Call, TLI))
3040e8d8bef9SDimitry Andric         return false;
3041e8d8bef9SDimitry Andric 
3042e8d8bef9SDimitry Andric       // Normally it's up to the frontend to make sure that non-leaf calls also
3043e8d8bef9SDimitry Andric       // have proper deopt state if it is required. We make an exception for
3044e8d8bef9SDimitry Andric       // element atomic memcpy/memmove intrinsics here. Unlike other intrinsics
3045e8d8bef9SDimitry Andric       // these are non-leaf by default. They might be generated by the optimizer
3046e8d8bef9SDimitry Andric       // which doesn't know how to produce a proper deopt state. So if we see a
3047e8d8bef9SDimitry Andric       // non-leaf memcpy/memmove without deopt state just treat it as a leaf
3048e8d8bef9SDimitry Andric       // copy and don't produce a statepoint.
3049*0fca6ea1SDimitry Andric       if (!AllowStatepointWithNoDeoptInfo && !Call->hasDeoptState()) {
3050e8d8bef9SDimitry Andric         assert((isa<AtomicMemCpyInst>(Call) || isa<AtomicMemMoveInst>(Call)) &&
3051e8d8bef9SDimitry Andric                "Don't expect any other calls here!");
3052e8d8bef9SDimitry Andric         return false;
3053e8d8bef9SDimitry Andric       }
3054e8d8bef9SDimitry Andric       return true;
3055e8d8bef9SDimitry Andric     }
30560b57cec5SDimitry Andric     return false;
30570b57cec5SDimitry Andric   };
30580b57cec5SDimitry Andric 
30590b57cec5SDimitry Andric   // Delete any unreachable statepoints so that we don't have unrewritten
30600b57cec5SDimitry Andric   // statepoints surviving this pass.  This makes testing easier and the
30610b57cec5SDimitry Andric   // resulting IR less confusing to human readers.
30620b57cec5SDimitry Andric   DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
30638bcb0991SDimitry Andric   bool MadeChange = removeUnreachableBlocks(F, &DTU);
30640b57cec5SDimitry Andric   // Flush the Dominator Tree.
30650b57cec5SDimitry Andric   DTU.getDomTree();
30660b57cec5SDimitry Andric 
30670b57cec5SDimitry Andric   // Gather all the statepoints which need rewritten.  Be careful to only
30680b57cec5SDimitry Andric   // consider those in reachable code since we need to ask dominance queries
30690b57cec5SDimitry Andric   // when rewriting.  We'll delete the unreachable ones in a moment.
30700b57cec5SDimitry Andric   SmallVector<CallBase *, 64> ParsePointNeeded;
3071fe6060f1SDimitry Andric   SmallVector<CallInst *, 64> Intrinsics;
30720b57cec5SDimitry Andric   for (Instruction &I : instructions(F)) {
30730b57cec5SDimitry Andric     // TODO: only the ones with the flag set!
30740b57cec5SDimitry Andric     if (NeedsRewrite(I)) {
30750b57cec5SDimitry Andric       // NOTE removeUnreachableBlocks() is stronger than
30760b57cec5SDimitry Andric       // DominatorTree::isReachableFromEntry(). In other words
30770b57cec5SDimitry Andric       // removeUnreachableBlocks can remove some blocks for which
30780b57cec5SDimitry Andric       // isReachableFromEntry() returns true.
30790b57cec5SDimitry Andric       assert(DT.isReachableFromEntry(I.getParent()) &&
30800b57cec5SDimitry Andric             "no unreachable blocks expected");
30810b57cec5SDimitry Andric       ParsePointNeeded.push_back(cast<CallBase>(&I));
30820b57cec5SDimitry Andric     }
3083fe6060f1SDimitry Andric     if (auto *CI = dyn_cast<CallInst>(&I))
3084fe6060f1SDimitry Andric       if (CI->getIntrinsicID() == Intrinsic::experimental_gc_get_pointer_base ||
3085fe6060f1SDimitry Andric           CI->getIntrinsicID() == Intrinsic::experimental_gc_get_pointer_offset)
3086fe6060f1SDimitry Andric         Intrinsics.emplace_back(CI);
30870b57cec5SDimitry Andric   }
30880b57cec5SDimitry Andric 
30890b57cec5SDimitry Andric   // Return early if no work to do.
3090fe6060f1SDimitry Andric   if (ParsePointNeeded.empty() && Intrinsics.empty())
30910b57cec5SDimitry Andric     return MadeChange;
30920b57cec5SDimitry Andric 
30930b57cec5SDimitry Andric   // As a prepass, go ahead and aggressively destroy single entry phi nodes.
30940b57cec5SDimitry Andric   // These are created by LCSSA.  They have the effect of increasing the size
30950b57cec5SDimitry Andric   // of liveness sets for no good reason.  It may be harder to do this post
30960b57cec5SDimitry Andric   // insertion since relocations and base phis can confuse things.
30970b57cec5SDimitry Andric   for (BasicBlock &BB : F)
3098e8d8bef9SDimitry Andric     if (BB.getUniquePredecessor())
3099e8d8bef9SDimitry Andric       MadeChange |= FoldSingleEntryPHINodes(&BB);
31000b57cec5SDimitry Andric 
31010b57cec5SDimitry Andric   // Before we start introducing relocations, we want to tweak the IR a bit to
31020b57cec5SDimitry Andric   // avoid unfortunate code generation effects.  The main example is that we
31030b57cec5SDimitry Andric   // want to try to make sure the comparison feeding a branch is after any
31040b57cec5SDimitry Andric   // safepoints.  Otherwise, we end up with a comparison of pre-relocation
31050b57cec5SDimitry Andric   // values feeding a branch after relocation.  This is semantically correct,
31060b57cec5SDimitry Andric   // but results in extra register pressure since both the pre-relocation and
31070b57cec5SDimitry Andric   // post-relocation copies must be available in registers.  For code without
31080b57cec5SDimitry Andric   // relocations this is handled elsewhere, but teaching the scheduler to
31090b57cec5SDimitry Andric   // reverse the transform we're about to do would be slightly complex.
31100b57cec5SDimitry Andric   // Note: This may extend the live range of the inputs to the icmp and thus
31110b57cec5SDimitry Andric   // increase the liveset of any statepoint we move over.  This is profitable
31120b57cec5SDimitry Andric   // as long as all statepoints are in rare blocks.  If we had in-register
31130b57cec5SDimitry Andric   // lowering for live values this would be a much safer transform.
31140b57cec5SDimitry Andric   auto getConditionInst = [](Instruction *TI) -> Instruction * {
31150b57cec5SDimitry Andric     if (auto *BI = dyn_cast<BranchInst>(TI))
31160b57cec5SDimitry Andric       if (BI->isConditional())
31170b57cec5SDimitry Andric         return dyn_cast<Instruction>(BI->getCondition());
31180b57cec5SDimitry Andric     // TODO: Extend this to handle switches
31190b57cec5SDimitry Andric     return nullptr;
31200b57cec5SDimitry Andric   };
31210b57cec5SDimitry Andric   for (BasicBlock &BB : F) {
31220b57cec5SDimitry Andric     Instruction *TI = BB.getTerminator();
31230b57cec5SDimitry Andric     if (auto *Cond = getConditionInst(TI))
31240b57cec5SDimitry Andric       // TODO: Handle more than just ICmps here.  We should be able to move
31250b57cec5SDimitry Andric       // most instructions without side effects or memory access.
31260b57cec5SDimitry Andric       if (isa<ICmpInst>(Cond) && Cond->hasOneUse()) {
31270b57cec5SDimitry Andric         MadeChange = true;
31280b57cec5SDimitry Andric         Cond->moveBefore(TI);
31290b57cec5SDimitry Andric       }
31300b57cec5SDimitry Andric   }
31310b57cec5SDimitry Andric 
31320b57cec5SDimitry Andric   // Nasty workaround - The base computation code in the main algorithm doesn't
31330b57cec5SDimitry Andric   // consider the fact that a GEP can be used to convert a scalar to a vector.
31340b57cec5SDimitry Andric   // The right fix for this is to integrate GEPs into the base rewriting
31350b57cec5SDimitry Andric   // algorithm properly, this is just a short term workaround to prevent
31360b57cec5SDimitry Andric   // crashes by canonicalizing such GEPs into fully vector GEPs.
31370b57cec5SDimitry Andric   for (Instruction &I : instructions(F)) {
31380b57cec5SDimitry Andric     if (!isa<GetElementPtrInst>(I))
31390b57cec5SDimitry Andric       continue;
31400b57cec5SDimitry Andric 
31410b57cec5SDimitry Andric     unsigned VF = 0;
31420b57cec5SDimitry Andric     for (unsigned i = 0; i < I.getNumOperands(); i++)
31435ffd83dbSDimitry Andric       if (auto *OpndVTy = dyn_cast<VectorType>(I.getOperand(i)->getType())) {
31440b57cec5SDimitry Andric         assert(VF == 0 ||
31455ffd83dbSDimitry Andric                VF == cast<FixedVectorType>(OpndVTy)->getNumElements());
31465ffd83dbSDimitry Andric         VF = cast<FixedVectorType>(OpndVTy)->getNumElements();
31470b57cec5SDimitry Andric       }
31480b57cec5SDimitry Andric 
31490b57cec5SDimitry Andric     // It's the vector to scalar traversal through the pointer operand which
31500b57cec5SDimitry Andric     // confuses base pointer rewriting, so limit ourselves to that case.
31510b57cec5SDimitry Andric     if (!I.getOperand(0)->getType()->isVectorTy() && VF != 0) {
31520b57cec5SDimitry Andric       IRBuilder<> B(&I);
31530b57cec5SDimitry Andric       auto *Splat = B.CreateVectorSplat(VF, I.getOperand(0));
31540b57cec5SDimitry Andric       I.setOperand(0, Splat);
31550b57cec5SDimitry Andric       MadeChange = true;
31560b57cec5SDimitry Andric     }
31570b57cec5SDimitry Andric   }
31580b57cec5SDimitry Andric 
3159fe6060f1SDimitry Andric   // Cache the 'defining value' relation used in the computation and
3160fe6060f1SDimitry Andric   // insertion of base phis and selects.  This ensures that we don't insert
3161fe6060f1SDimitry Andric   // large numbers of duplicate base_phis. Use one cache for both
3162fe6060f1SDimitry Andric   // inlineGetBaseAndOffset() and insertParsePoints().
3163fe6060f1SDimitry Andric   DefiningValueMapTy DVCache;
3164fe6060f1SDimitry Andric 
316581ad6265SDimitry Andric   // Mapping between a base values and a flag indicating whether it's a known
316681ad6265SDimitry Andric   // base or not.
316781ad6265SDimitry Andric   IsKnownBaseMapTy KnownBases;
316881ad6265SDimitry Andric 
3169fe6060f1SDimitry Andric   if (!Intrinsics.empty())
3170fe6060f1SDimitry Andric     // Inline @gc.get.pointer.base() and @gc.get.pointer.offset() before finding
3171fe6060f1SDimitry Andric     // live references.
317281ad6265SDimitry Andric     MadeChange |= inlineGetBaseAndOffset(F, Intrinsics, DVCache, KnownBases);
3173fe6060f1SDimitry Andric 
3174fe6060f1SDimitry Andric   if (!ParsePointNeeded.empty())
317581ad6265SDimitry Andric     MadeChange |=
317681ad6265SDimitry Andric         insertParsePoints(F, DT, TTI, ParsePointNeeded, DVCache, KnownBases);
3177fe6060f1SDimitry Andric 
31780b57cec5SDimitry Andric   return MadeChange;
31790b57cec5SDimitry Andric }
31800b57cec5SDimitry Andric 
31810b57cec5SDimitry Andric // liveness computation via standard dataflow
31820b57cec5SDimitry Andric // -------------------------------------------------------------------
31830b57cec5SDimitry Andric 
31840b57cec5SDimitry Andric // TODO: Consider using bitvectors for liveness, the set of potentially
31850b57cec5SDimitry Andric // interesting values should be small and easy to pre-compute.
31860b57cec5SDimitry Andric 
31870b57cec5SDimitry Andric /// Compute the live-in set for the location rbegin starting from
31880b57cec5SDimitry Andric /// the live-out set of the basic block
31890b57cec5SDimitry Andric static void computeLiveInValues(BasicBlock::reverse_iterator Begin,
31900b57cec5SDimitry Andric                                 BasicBlock::reverse_iterator End,
319106c3fb27SDimitry Andric                                 SetVector<Value *> &LiveTmp, GCStrategy *GC) {
31920b57cec5SDimitry Andric   for (auto &I : make_range(Begin, End)) {
31930b57cec5SDimitry Andric     // KILL/Def - Remove this definition from LiveIn
31940b57cec5SDimitry Andric     LiveTmp.remove(&I);
31950b57cec5SDimitry Andric 
31960b57cec5SDimitry Andric     // Don't consider *uses* in PHI nodes, we handle their contribution to
31970b57cec5SDimitry Andric     // predecessor blocks when we seed the LiveOut sets
31980b57cec5SDimitry Andric     if (isa<PHINode>(I))
31990b57cec5SDimitry Andric       continue;
32000b57cec5SDimitry Andric 
32010b57cec5SDimitry Andric     // USE - Add to the LiveIn set for this instruction
32020b57cec5SDimitry Andric     for (Value *V : I.operands()) {
320306c3fb27SDimitry Andric       assert(!isUnhandledGCPointerType(V->getType(), GC) &&
32040b57cec5SDimitry Andric              "support for FCA unimplemented");
320506c3fb27SDimitry Andric       if (isHandledGCPointerType(V->getType(), GC) && !isa<Constant>(V)) {
32060b57cec5SDimitry Andric         // The choice to exclude all things constant here is slightly subtle.
32070b57cec5SDimitry Andric         // There are two independent reasons:
32080b57cec5SDimitry Andric         // - We assume that things which are constant (from LLVM's definition)
32090b57cec5SDimitry Andric         // do not move at runtime.  For example, the address of a global
32100b57cec5SDimitry Andric         // variable is fixed, even though it's contents may not be.
32110b57cec5SDimitry Andric         // - Second, we can't disallow arbitrary inttoptr constants even
32120b57cec5SDimitry Andric         // if the language frontend does.  Optimization passes are free to
32130b57cec5SDimitry Andric         // locally exploit facts without respect to global reachability.  This
32140b57cec5SDimitry Andric         // can create sections of code which are dynamically unreachable and
32150b57cec5SDimitry Andric         // contain just about anything.  (see constants.ll in tests)
32160b57cec5SDimitry Andric         LiveTmp.insert(V);
32170b57cec5SDimitry Andric       }
32180b57cec5SDimitry Andric     }
32190b57cec5SDimitry Andric   }
32200b57cec5SDimitry Andric }
32210b57cec5SDimitry Andric 
322206c3fb27SDimitry Andric static void computeLiveOutSeed(BasicBlock *BB, SetVector<Value *> &LiveTmp,
322306c3fb27SDimitry Andric                                GCStrategy *GC) {
32240b57cec5SDimitry Andric   for (BasicBlock *Succ : successors(BB)) {
32250b57cec5SDimitry Andric     for (auto &I : *Succ) {
32260b57cec5SDimitry Andric       PHINode *PN = dyn_cast<PHINode>(&I);
32270b57cec5SDimitry Andric       if (!PN)
32280b57cec5SDimitry Andric         break;
32290b57cec5SDimitry Andric 
32300b57cec5SDimitry Andric       Value *V = PN->getIncomingValueForBlock(BB);
323106c3fb27SDimitry Andric       assert(!isUnhandledGCPointerType(V->getType(), GC) &&
32320b57cec5SDimitry Andric              "support for FCA unimplemented");
323306c3fb27SDimitry Andric       if (isHandledGCPointerType(V->getType(), GC) && !isa<Constant>(V))
32340b57cec5SDimitry Andric         LiveTmp.insert(V);
32350b57cec5SDimitry Andric     }
32360b57cec5SDimitry Andric   }
32370b57cec5SDimitry Andric }
32380b57cec5SDimitry Andric 
323906c3fb27SDimitry Andric static SetVector<Value *> computeKillSet(BasicBlock *BB, GCStrategy *GC) {
32400b57cec5SDimitry Andric   SetVector<Value *> KillSet;
32410b57cec5SDimitry Andric   for (Instruction &I : *BB)
324206c3fb27SDimitry Andric     if (isHandledGCPointerType(I.getType(), GC))
32430b57cec5SDimitry Andric       KillSet.insert(&I);
32440b57cec5SDimitry Andric   return KillSet;
32450b57cec5SDimitry Andric }
32460b57cec5SDimitry Andric 
32470b57cec5SDimitry Andric #ifndef NDEBUG
32480b57cec5SDimitry Andric /// Check that the items in 'Live' dominate 'TI'.  This is used as a basic
3249349cc55cSDimitry Andric /// validation check for the liveness computation.
32500b57cec5SDimitry Andric static void checkBasicSSA(DominatorTree &DT, SetVector<Value *> &Live,
32510b57cec5SDimitry Andric                           Instruction *TI, bool TermOkay = false) {
32520b57cec5SDimitry Andric   for (Value *V : Live) {
32530b57cec5SDimitry Andric     if (auto *I = dyn_cast<Instruction>(V)) {
32540b57cec5SDimitry Andric       // The terminator can be a member of the LiveOut set.  LLVM's definition
32550b57cec5SDimitry Andric       // of instruction dominance states that V does not dominate itself.  As
32560b57cec5SDimitry Andric       // such, we need to special case this to allow it.
32570b57cec5SDimitry Andric       if (TermOkay && TI == I)
32580b57cec5SDimitry Andric         continue;
32590b57cec5SDimitry Andric       assert(DT.dominates(I, TI) &&
32600b57cec5SDimitry Andric              "basic SSA liveness expectation violated by liveness analysis");
32610b57cec5SDimitry Andric     }
32620b57cec5SDimitry Andric   }
32630b57cec5SDimitry Andric }
32640b57cec5SDimitry Andric 
32650b57cec5SDimitry Andric /// Check that all the liveness sets used during the computation of liveness
32660b57cec5SDimitry Andric /// obey basic SSA properties.  This is useful for finding cases where we miss
32670b57cec5SDimitry Andric /// a def.
32680b57cec5SDimitry Andric static void checkBasicSSA(DominatorTree &DT, GCPtrLivenessData &Data,
32690b57cec5SDimitry Andric                           BasicBlock &BB) {
32700b57cec5SDimitry Andric   checkBasicSSA(DT, Data.LiveSet[&BB], BB.getTerminator());
32710b57cec5SDimitry Andric   checkBasicSSA(DT, Data.LiveOut[&BB], BB.getTerminator(), true);
32720b57cec5SDimitry Andric   checkBasicSSA(DT, Data.LiveIn[&BB], BB.getTerminator());
32730b57cec5SDimitry Andric }
32740b57cec5SDimitry Andric #endif
32750b57cec5SDimitry Andric 
32760b57cec5SDimitry Andric static void computeLiveInValues(DominatorTree &DT, Function &F,
327706c3fb27SDimitry Andric                                 GCPtrLivenessData &Data, GCStrategy *GC) {
32780b57cec5SDimitry Andric   SmallSetVector<BasicBlock *, 32> Worklist;
32790b57cec5SDimitry Andric 
32800b57cec5SDimitry Andric   // Seed the liveness for each individual block
32810b57cec5SDimitry Andric   for (BasicBlock &BB : F) {
328206c3fb27SDimitry Andric     Data.KillSet[&BB] = computeKillSet(&BB, GC);
32830b57cec5SDimitry Andric     Data.LiveSet[&BB].clear();
328406c3fb27SDimitry Andric     computeLiveInValues(BB.rbegin(), BB.rend(), Data.LiveSet[&BB], GC);
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric #ifndef NDEBUG
32870b57cec5SDimitry Andric     for (Value *Kill : Data.KillSet[&BB])
32880b57cec5SDimitry Andric       assert(!Data.LiveSet[&BB].count(Kill) && "live set contains kill");
32890b57cec5SDimitry Andric #endif
32900b57cec5SDimitry Andric 
32910b57cec5SDimitry Andric     Data.LiveOut[&BB] = SetVector<Value *>();
329206c3fb27SDimitry Andric     computeLiveOutSeed(&BB, Data.LiveOut[&BB], GC);
32930b57cec5SDimitry Andric     Data.LiveIn[&BB] = Data.LiveSet[&BB];
32940b57cec5SDimitry Andric     Data.LiveIn[&BB].set_union(Data.LiveOut[&BB]);
32950b57cec5SDimitry Andric     Data.LiveIn[&BB].set_subtract(Data.KillSet[&BB]);
32960b57cec5SDimitry Andric     if (!Data.LiveIn[&BB].empty())
32970b57cec5SDimitry Andric       Worklist.insert(pred_begin(&BB), pred_end(&BB));
32980b57cec5SDimitry Andric   }
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric   // Propagate that liveness until stable
33010b57cec5SDimitry Andric   while (!Worklist.empty()) {
33020b57cec5SDimitry Andric     BasicBlock *BB = Worklist.pop_back_val();
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric     // Compute our new liveout set, then exit early if it hasn't changed despite
33050b57cec5SDimitry Andric     // the contribution of our successor.
33060b57cec5SDimitry Andric     SetVector<Value *> LiveOut = Data.LiveOut[BB];
33070b57cec5SDimitry Andric     const auto OldLiveOutSize = LiveOut.size();
33080b57cec5SDimitry Andric     for (BasicBlock *Succ : successors(BB)) {
33090b57cec5SDimitry Andric       assert(Data.LiveIn.count(Succ));
33100b57cec5SDimitry Andric       LiveOut.set_union(Data.LiveIn[Succ]);
33110b57cec5SDimitry Andric     }
33120b57cec5SDimitry Andric     // assert OutLiveOut is a subset of LiveOut
33130b57cec5SDimitry Andric     if (OldLiveOutSize == LiveOut.size()) {
33140b57cec5SDimitry Andric       // If the sets are the same size, then we didn't actually add anything
33150b57cec5SDimitry Andric       // when unioning our successors LiveIn.  Thus, the LiveIn of this block
33160b57cec5SDimitry Andric       // hasn't changed.
33170b57cec5SDimitry Andric       continue;
33180b57cec5SDimitry Andric     }
33190b57cec5SDimitry Andric     Data.LiveOut[BB] = LiveOut;
33200b57cec5SDimitry Andric 
33210b57cec5SDimitry Andric     // Apply the effects of this basic block
33220b57cec5SDimitry Andric     SetVector<Value *> LiveTmp = LiveOut;
33230b57cec5SDimitry Andric     LiveTmp.set_union(Data.LiveSet[BB]);
33240b57cec5SDimitry Andric     LiveTmp.set_subtract(Data.KillSet[BB]);
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric     assert(Data.LiveIn.count(BB));
33270b57cec5SDimitry Andric     const SetVector<Value *> &OldLiveIn = Data.LiveIn[BB];
33280b57cec5SDimitry Andric     // assert: OldLiveIn is a subset of LiveTmp
33290b57cec5SDimitry Andric     if (OldLiveIn.size() != LiveTmp.size()) {
33300b57cec5SDimitry Andric       Data.LiveIn[BB] = LiveTmp;
33310b57cec5SDimitry Andric       Worklist.insert(pred_begin(BB), pred_end(BB));
33320b57cec5SDimitry Andric     }
33330b57cec5SDimitry Andric   } // while (!Worklist.empty())
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric #ifndef NDEBUG
3336349cc55cSDimitry Andric   // Verify our output against SSA properties.  This helps catch any
33370b57cec5SDimitry Andric   // missing kills during the above iteration.
33380b57cec5SDimitry Andric   for (BasicBlock &BB : F)
33390b57cec5SDimitry Andric     checkBasicSSA(DT, Data, BB);
33400b57cec5SDimitry Andric #endif
33410b57cec5SDimitry Andric }
33420b57cec5SDimitry Andric 
33430b57cec5SDimitry Andric static void findLiveSetAtInst(Instruction *Inst, GCPtrLivenessData &Data,
334406c3fb27SDimitry Andric                               StatepointLiveSetTy &Out, GCStrategy *GC) {
33450b57cec5SDimitry Andric   BasicBlock *BB = Inst->getParent();
33460b57cec5SDimitry Andric 
33470b57cec5SDimitry Andric   // Note: The copy is intentional and required
33480b57cec5SDimitry Andric   assert(Data.LiveOut.count(BB));
33490b57cec5SDimitry Andric   SetVector<Value *> LiveOut = Data.LiveOut[BB];
33500b57cec5SDimitry Andric 
33510b57cec5SDimitry Andric   // We want to handle the statepoint itself oddly.  It's
33520b57cec5SDimitry Andric   // call result is not live (normal), nor are it's arguments
33530b57cec5SDimitry Andric   // (unless they're used again later).  This adjustment is
33540b57cec5SDimitry Andric   // specifically what we need to relocate
335506c3fb27SDimitry Andric   computeLiveInValues(BB->rbegin(), ++Inst->getIterator().getReverse(), LiveOut,
335606c3fb27SDimitry Andric                       GC);
33570b57cec5SDimitry Andric   LiveOut.remove(Inst);
33580b57cec5SDimitry Andric   Out.insert(LiveOut.begin(), LiveOut.end());
33590b57cec5SDimitry Andric }
33600b57cec5SDimitry Andric 
33610b57cec5SDimitry Andric static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
33620b57cec5SDimitry Andric                                   CallBase *Call,
33631fd87a68SDimitry Andric                                   PartiallyConstructedSafepointRecord &Info,
336406c3fb27SDimitry Andric                                   PointerToBaseTy &PointerToBase,
336506c3fb27SDimitry Andric                                   GCStrategy *GC) {
33660b57cec5SDimitry Andric   StatepointLiveSetTy Updated;
336706c3fb27SDimitry Andric   findLiveSetAtInst(Call, RevisedLivenessData, Updated, GC);
33680b57cec5SDimitry Andric 
33690b57cec5SDimitry Andric   // We may have base pointers which are now live that weren't before.  We need
33700b57cec5SDimitry Andric   // to update the PointerToBase structure to reflect this.
3371bdd1243dSDimitry Andric   for (auto *V : Updated)
33721fd87a68SDimitry Andric     PointerToBase.insert({ V, V });
33730b57cec5SDimitry Andric 
33740b57cec5SDimitry Andric   Info.LiveSet = Updated;
33750b57cec5SDimitry Andric }
3376