GCRootLowering.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. //===-- GCRootLowering.cpp - Garbage collection infrastructure ------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the lowering for the gc.root mechanism.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/CodeGen/GCMetadata.h"
  13. #include "llvm/CodeGen/MachineFrameInfo.h"
  14. #include "llvm/CodeGen/MachineFunctionPass.h"
  15. #include "llvm/CodeGen/MachineInstrBuilder.h"
  16. #include "llvm/CodeGen/MachineModuleInfo.h"
  17. #include "llvm/CodeGen/Passes.h"
  18. #include "llvm/CodeGen/TargetFrameLowering.h"
  19. #include "llvm/CodeGen/TargetInstrInfo.h"
  20. #include "llvm/CodeGen/TargetRegisterInfo.h"
  21. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  22. #include "llvm/IR/Dominators.h"
  23. #include "llvm/IR/IntrinsicInst.h"
  24. #include "llvm/IR/Module.h"
  25. #include "llvm/InitializePasses.h"
  26. #include "llvm/Support/Debug.h"
  27. #include "llvm/Support/ErrorHandling.h"
  28. #include "llvm/Support/raw_ostream.h"
  29. using namespace llvm;
  30. namespace {
  31. /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
  32. /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
  33. /// directed by the GCStrategy. It also performs automatic root initialization
  34. /// and custom intrinsic lowering.
  35. class LowerIntrinsics : public FunctionPass {
  36. bool DoLowering(Function &F, GCStrategy &S);
  37. public:
  38. static char ID;
  39. LowerIntrinsics();
  40. StringRef getPassName() const override;
  41. void getAnalysisUsage(AnalysisUsage &AU) const override;
  42. bool doInitialization(Module &M) override;
  43. bool runOnFunction(Function &F) override;
  44. };
  45. /// GCMachineCodeAnalysis - This is a target-independent pass over the machine
  46. /// function representation to identify safe points for the garbage collector
  47. /// in the machine code. It inserts labels at safe points and populates a
  48. /// GCMetadata record for each function.
  49. class GCMachineCodeAnalysis : public MachineFunctionPass {
  50. GCFunctionInfo *FI;
  51. const TargetInstrInfo *TII;
  52. void FindSafePoints(MachineFunction &MF);
  53. void VisitCallPoint(MachineBasicBlock::iterator CI);
  54. MCSymbol *InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
  55. const DebugLoc &DL) const;
  56. void FindStackOffsets(MachineFunction &MF);
  57. public:
  58. static char ID;
  59. GCMachineCodeAnalysis();
  60. void getAnalysisUsage(AnalysisUsage &AU) const override;
  61. bool runOnMachineFunction(MachineFunction &MF) override;
  62. };
  63. }
  64. // -----------------------------------------------------------------------------
  65. INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering", false,
  66. false)
  67. INITIALIZE_PASS_DEPENDENCY(GCModuleInfo)
  68. INITIALIZE_PASS_END(LowerIntrinsics, "gc-lowering", "GC Lowering", false, false)
  69. FunctionPass *llvm::createGCLoweringPass() { return new LowerIntrinsics(); }
  70. char LowerIntrinsics::ID = 0;
  71. char &llvm::GCLoweringID = LowerIntrinsics::ID;
  72. LowerIntrinsics::LowerIntrinsics() : FunctionPass(ID) {
  73. initializeLowerIntrinsicsPass(*PassRegistry::getPassRegistry());
  74. }
  75. StringRef LowerIntrinsics::getPassName() const {
  76. return "Lower Garbage Collection Instructions";
  77. }
  78. void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
  79. FunctionPass::getAnalysisUsage(AU);
  80. AU.addRequired<GCModuleInfo>();
  81. AU.addPreserved<DominatorTreeWrapperPass>();
  82. }
  83. /// doInitialization - If this module uses the GC intrinsics, find them now.
  84. bool LowerIntrinsics::doInitialization(Module &M) {
  85. GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
  86. assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
  87. for (Function &F : M)
  88. if (!F.isDeclaration() && F.hasGC())
  89. MI->getFunctionInfo(F); // Instantiate the GC strategy.
  90. return false;
  91. }
  92. /// CouldBecomeSafePoint - Predicate to conservatively determine whether the
  93. /// instruction could introduce a safe point.
  94. static bool CouldBecomeSafePoint(Instruction *I) {
  95. // The natural definition of instructions which could introduce safe points
  96. // are:
  97. //
  98. // - call, invoke (AfterCall, BeforeCall)
  99. // - phis (Loops)
  100. // - invoke, ret, unwind (Exit)
  101. //
  102. // However, instructions as seemingly inoccuous as arithmetic can become
  103. // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead
  104. // it is necessary to take a conservative approach.
  105. if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I) || isa<StoreInst>(I) ||
  106. isa<LoadInst>(I))
  107. return false;
  108. // llvm.gcroot is safe because it doesn't do anything at runtime.
  109. if (CallInst *CI = dyn_cast<CallInst>(I))
  110. if (Function *F = CI->getCalledFunction())
  111. if (Intrinsic::ID IID = F->getIntrinsicID())
  112. if (IID == Intrinsic::gcroot)
  113. return false;
  114. return true;
  115. }
  116. static bool InsertRootInitializers(Function &F, ArrayRef<AllocaInst *> Roots) {
  117. // Scroll past alloca instructions.
  118. BasicBlock::iterator IP = F.getEntryBlock().begin();
  119. while (isa<AllocaInst>(IP))
  120. ++IP;
  121. // Search for initializers in the initial BB.
  122. SmallPtrSet<AllocaInst *, 16> InitedRoots;
  123. for (; !CouldBecomeSafePoint(&*IP); ++IP)
  124. if (StoreInst *SI = dyn_cast<StoreInst>(IP))
  125. if (AllocaInst *AI =
  126. dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
  127. InitedRoots.insert(AI);
  128. // Add root initializers.
  129. bool MadeChange = false;
  130. for (AllocaInst *Root : Roots)
  131. if (!InitedRoots.count(Root)) {
  132. new StoreInst(
  133. ConstantPointerNull::get(cast<PointerType>(Root->getAllocatedType())),
  134. Root, Root->getNextNode());
  135. MadeChange = true;
  136. }
  137. return MadeChange;
  138. }
  139. /// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
  140. /// Leave gcroot intrinsics; the code generator needs to see those.
  141. bool LowerIntrinsics::runOnFunction(Function &F) {
  142. // Quick exit for functions that do not use GC.
  143. if (!F.hasGC())
  144. return false;
  145. GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
  146. GCStrategy &S = FI.getStrategy();
  147. return DoLowering(F, S);
  148. }
  149. /// Lower barriers out of existance (if the associated GCStrategy hasn't
  150. /// already done so...), and insert initializing stores to roots as a defensive
  151. /// measure. Given we're going to report all roots live at all safepoints, we
  152. /// need to be able to ensure each root has been initialized by the point the
  153. /// first safepoint is reached. This really should have been done by the
  154. /// frontend, but the old API made this non-obvious, so we do a potentially
  155. /// redundant store just in case.
  156. bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) {
  157. SmallVector<AllocaInst *, 32> Roots;
  158. bool MadeChange = false;
  159. for (BasicBlock &BB : F)
  160. for (Instruction &I : llvm::make_early_inc_range(BB)) {
  161. IntrinsicInst *CI = dyn_cast<IntrinsicInst>(&I);
  162. if (!CI)
  163. continue;
  164. Function *F = CI->getCalledFunction();
  165. switch (F->getIntrinsicID()) {
  166. default: break;
  167. case Intrinsic::gcwrite: {
  168. // Replace a write barrier with a simple store.
  169. Value *St = new StoreInst(CI->getArgOperand(0),
  170. CI->getArgOperand(2), CI);
  171. CI->replaceAllUsesWith(St);
  172. CI->eraseFromParent();
  173. MadeChange = true;
  174. break;
  175. }
  176. case Intrinsic::gcread: {
  177. // Replace a read barrier with a simple load.
  178. Value *Ld = new LoadInst(CI->getType(), CI->getArgOperand(1), "", CI);
  179. Ld->takeName(CI);
  180. CI->replaceAllUsesWith(Ld);
  181. CI->eraseFromParent();
  182. MadeChange = true;
  183. break;
  184. }
  185. case Intrinsic::gcroot: {
  186. // Initialize the GC root, but do not delete the intrinsic. The
  187. // backend needs the intrinsic to flag the stack slot.
  188. Roots.push_back(
  189. cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
  190. break;
  191. }
  192. }
  193. }
  194. if (Roots.size())
  195. MadeChange |= InsertRootInitializers(F, Roots);
  196. return MadeChange;
  197. }
  198. // -----------------------------------------------------------------------------
  199. char GCMachineCodeAnalysis::ID = 0;
  200. char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID;
  201. INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis",
  202. "Analyze Machine Code For Garbage Collection", false, false)
  203. GCMachineCodeAnalysis::GCMachineCodeAnalysis() : MachineFunctionPass(ID) {}
  204. void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  205. MachineFunctionPass::getAnalysisUsage(AU);
  206. AU.setPreservesAll();
  207. AU.addRequired<GCModuleInfo>();
  208. }
  209. MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
  210. MachineBasicBlock::iterator MI,
  211. const DebugLoc &DL) const {
  212. MCSymbol *Label = MBB.getParent()->getContext().createTempSymbol();
  213. BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
  214. return Label;
  215. }
  216. void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
  217. // Find the return address (next instruction), since that's what will be on
  218. // the stack when the call is suspended and we need to inspect the stack.
  219. MachineBasicBlock::iterator RAI = CI;
  220. ++RAI;
  221. MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc());
  222. FI->addSafePoint(Label, CI->getDebugLoc());
  223. }
  224. void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
  225. for (MachineBasicBlock &MBB : MF)
  226. for (MachineInstr &MI : MBB)
  227. if (MI.isCall()) {
  228. // Do not treat tail or sibling call sites as safe points. This is
  229. // legal since any arguments passed to the callee which live in the
  230. // remnants of the callers frame will be owned and updated by the
  231. // callee if required.
  232. if (MI.isTerminator())
  233. continue;
  234. VisitCallPoint(&MI);
  235. }
  236. }
  237. void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
  238. const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
  239. assert(TFI && "TargetRegisterInfo not available!");
  240. for (GCFunctionInfo::roots_iterator RI = FI->roots_begin();
  241. RI != FI->roots_end();) {
  242. // If the root references a dead object, no need to keep it.
  243. if (MF.getFrameInfo().isDeadObjectIndex(RI->Num)) {
  244. RI = FI->removeStackRoot(RI);
  245. } else {
  246. Register FrameReg; // FIXME: surely GCRoot ought to store the
  247. // register that the offset is from?
  248. auto FrameOffset = TFI->getFrameIndexReference(MF, RI->Num, FrameReg);
  249. assert(!FrameOffset.getScalable() &&
  250. "Frame offsets with a scalable component are not supported");
  251. RI->StackOffset = FrameOffset.getFixed();
  252. ++RI;
  253. }
  254. }
  255. }
  256. bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
  257. // Quick exit for functions that do not use GC.
  258. if (!MF.getFunction().hasGC())
  259. return false;
  260. FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(MF.getFunction());
  261. TII = MF.getSubtarget().getInstrInfo();
  262. // Find the size of the stack frame. There may be no correct static frame
  263. // size, we use UINT64_MAX to represent this.
  264. const MachineFrameInfo &MFI = MF.getFrameInfo();
  265. const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  266. const bool DynamicFrameSize =
  267. MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF);
  268. FI->setFrameSize(DynamicFrameSize ? UINT64_MAX : MFI.getStackSize());
  269. // Find all safe points.
  270. if (FI->getStrategy().needsSafePoints())
  271. FindSafePoints(MF);
  272. // Find the concrete stack offsets for all roots (stack slots)
  273. FindStackOffsets(MF);
  274. return false;
  275. }