GCRootLowering.cpp 11 KB

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