LLVM API Documentation

GCStrategy.cpp
Go to the documentation of this file.
00001 //===-- GCStrategy.cpp - Garbage collection infrastructure -----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements target- and collector-independent garbage collection
00011 // infrastructure.
00012 //
00013 // GCMachineCodeAnalysis identifies the GC safe points in the machine code.
00014 // Roots are identified in SelectionDAGISel.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #include "llvm/CodeGen/GCStrategy.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineFunctionPass.h"
00021 #include "llvm/CodeGen/MachineInstrBuilder.h"
00022 #include "llvm/CodeGen/MachineModuleInfo.h"
00023 #include "llvm/CodeGen/Passes.h"
00024 #include "llvm/IR/Dominators.h"
00025 #include "llvm/IR/IntrinsicInst.h"
00026 #include "llvm/IR/Module.h"
00027 #include "llvm/Support/Debug.h"
00028 #include "llvm/Support/ErrorHandling.h"
00029 #include "llvm/Support/raw_ostream.h"
00030 #include "llvm/Target/TargetFrameLowering.h"
00031 #include "llvm/Target/TargetInstrInfo.h"
00032 #include "llvm/Target/TargetMachine.h"
00033 #include "llvm/Target/TargetRegisterInfo.h"
00034 #include "llvm/Target/TargetSubtargetInfo.h"
00035 
00036 using namespace llvm;
00037 
00038 namespace {
00039 
00040   /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
00041   /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
00042   /// directed by the GCStrategy. It also performs automatic root initialization
00043   /// and custom intrinsic lowering.
00044   class LowerIntrinsics : public FunctionPass {
00045     static bool NeedsDefaultLoweringPass(const GCStrategy &C);
00046     static bool NeedsCustomLoweringPass(const GCStrategy &C);
00047     static bool CouldBecomeSafePoint(Instruction *I);
00048     bool PerformDefaultLowering(Function &F, GCStrategy &Coll);
00049     static bool InsertRootInitializers(Function &F,
00050                                        AllocaInst **Roots, unsigned Count);
00051 
00052   public:
00053     static char ID;
00054 
00055     LowerIntrinsics();
00056     const char *getPassName() const override;
00057     void getAnalysisUsage(AnalysisUsage &AU) const override;
00058 
00059     bool doInitialization(Module &M) override;
00060     bool runOnFunction(Function &F) override;
00061   };
00062 
00063 
00064   /// GCMachineCodeAnalysis - This is a target-independent pass over the machine
00065   /// function representation to identify safe points for the garbage collector
00066   /// in the machine code. It inserts labels at safe points and populates a
00067   /// GCMetadata record for each function.
00068   class GCMachineCodeAnalysis : public MachineFunctionPass {
00069     const TargetMachine *TM;
00070     GCFunctionInfo *FI;
00071     MachineModuleInfo *MMI;
00072     const TargetInstrInfo *TII;
00073 
00074     void FindSafePoints(MachineFunction &MF);
00075     void VisitCallPoint(MachineBasicBlock::iterator MI);
00076     MCSymbol *InsertLabel(MachineBasicBlock &MBB,
00077                           MachineBasicBlock::iterator MI,
00078                           DebugLoc DL) const;
00079 
00080     void FindStackOffsets(MachineFunction &MF);
00081 
00082   public:
00083     static char ID;
00084 
00085     GCMachineCodeAnalysis();
00086     void getAnalysisUsage(AnalysisUsage &AU) const override;
00087 
00088     bool runOnMachineFunction(MachineFunction &MF) override;
00089   };
00090 
00091 }
00092 
00093 // -----------------------------------------------------------------------------
00094 
00095 GCStrategy::GCStrategy() :
00096   NeededSafePoints(0),
00097   CustomReadBarriers(false),
00098   CustomWriteBarriers(false),
00099   CustomRoots(false),
00100   CustomSafePoints(false),
00101   InitRoots(true),
00102   UsesMetadata(false)
00103 {}
00104 
00105 bool GCStrategy::initializeCustomLowering(Module &M) { return false; }
00106 
00107 bool GCStrategy::performCustomLowering(Function &F) {
00108   dbgs() << "gc " << getName() << " must override performCustomLowering.\n";
00109   llvm_unreachable("must override performCustomLowering");
00110 }
00111 
00112 
00113 bool GCStrategy::findCustomSafePoints(GCFunctionInfo& FI, MachineFunction &F) {
00114   dbgs() << "gc " << getName() << " must override findCustomSafePoints.\n";
00115   llvm_unreachable(nullptr);
00116 }
00117 
00118 
00119 GCFunctionInfo *GCStrategy::insertFunctionInfo(const Function &F) {
00120   Functions.push_back(make_unique<GCFunctionInfo>(F, *this));
00121   return Functions.back().get();
00122 }
00123 
00124 // -----------------------------------------------------------------------------
00125 
00126 INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering",
00127                       false, false)
00128 INITIALIZE_PASS_DEPENDENCY(GCModuleInfo)
00129 INITIALIZE_PASS_END(LowerIntrinsics, "gc-lowering", "GC Lowering", false, false)
00130 
00131 FunctionPass *llvm::createGCLoweringPass() {
00132   return new LowerIntrinsics();
00133 }
00134 
00135 char LowerIntrinsics::ID = 0;
00136 
00137 LowerIntrinsics::LowerIntrinsics()
00138   : FunctionPass(ID) {
00139     initializeLowerIntrinsicsPass(*PassRegistry::getPassRegistry());
00140   }
00141 
00142 const char *LowerIntrinsics::getPassName() const {
00143   return "Lower Garbage Collection Instructions";
00144 }
00145 
00146 void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
00147   FunctionPass::getAnalysisUsage(AU);
00148   AU.addRequired<GCModuleInfo>();
00149   AU.addPreserved<DominatorTreeWrapperPass>();
00150 }
00151 
00152 /// doInitialization - If this module uses the GC intrinsics, find them now.
00153 bool LowerIntrinsics::doInitialization(Module &M) {
00154   // FIXME: This is rather antisocial in the context of a JIT since it performs
00155   //        work against the entire module. But this cannot be done at
00156   //        runFunction time (initializeCustomLowering likely needs to change
00157   //        the module).
00158   GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
00159   assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
00160   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
00161     if (!I->isDeclaration() && I->hasGC())
00162       MI->getFunctionInfo(*I); // Instantiate the GC strategy.
00163 
00164   bool MadeChange = false;
00165   for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
00166     if (NeedsCustomLoweringPass(**I))
00167       if ((*I)->initializeCustomLowering(M))
00168         MadeChange = true;
00169 
00170   return MadeChange;
00171 }
00172 
00173 bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots,
00174                                                           unsigned Count) {
00175   // Scroll past alloca instructions.
00176   BasicBlock::iterator IP = F.getEntryBlock().begin();
00177   while (isa<AllocaInst>(IP)) ++IP;
00178 
00179   // Search for initializers in the initial BB.
00180   SmallPtrSet<AllocaInst*,16> InitedRoots;
00181   for (; !CouldBecomeSafePoint(IP); ++IP)
00182     if (StoreInst *SI = dyn_cast<StoreInst>(IP))
00183       if (AllocaInst *AI =
00184           dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
00185         InitedRoots.insert(AI);
00186 
00187   // Add root initializers.
00188   bool MadeChange = false;
00189 
00190   for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I)
00191     if (!InitedRoots.count(*I)) {
00192       StoreInst* SI = new StoreInst(ConstantPointerNull::get(cast<PointerType>(
00193                         cast<PointerType>((*I)->getType())->getElementType())),
00194                         *I);
00195       SI->insertAfter(*I);
00196       MadeChange = true;
00197     }
00198 
00199   return MadeChange;
00200 }
00201 
00202 bool LowerIntrinsics::NeedsDefaultLoweringPass(const GCStrategy &C) {
00203   // Default lowering is necessary only if read or write barriers have a default
00204   // action. The default for roots is no action.
00205   return !C.customWriteBarrier()
00206       || !C.customReadBarrier()
00207       || C.initializeRoots();
00208 }
00209 
00210 bool LowerIntrinsics::NeedsCustomLoweringPass(const GCStrategy &C) {
00211   // Custom lowering is only necessary if enabled for some action.
00212   return C.customWriteBarrier()
00213       || C.customReadBarrier()
00214       || C.customRoots();
00215 }
00216 
00217 /// CouldBecomeSafePoint - Predicate to conservatively determine whether the
00218 /// instruction could introduce a safe point.
00219 bool LowerIntrinsics::CouldBecomeSafePoint(Instruction *I) {
00220   // The natural definition of instructions which could introduce safe points
00221   // are:
00222   //
00223   //   - call, invoke (AfterCall, BeforeCall)
00224   //   - phis (Loops)
00225   //   - invoke, ret, unwind (Exit)
00226   //
00227   // However, instructions as seemingly inoccuous as arithmetic can become
00228   // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead
00229   // it is necessary to take a conservative approach.
00230 
00231   if (isa<AllocaInst>(I) || isa<GetElementPtrInst>(I) ||
00232       isa<StoreInst>(I) || isa<LoadInst>(I))
00233     return false;
00234 
00235   // llvm.gcroot is safe because it doesn't do anything at runtime.
00236   if (CallInst *CI = dyn_cast<CallInst>(I))
00237     if (Function *F = CI->getCalledFunction())
00238       if (unsigned IID = F->getIntrinsicID())
00239         if (IID == Intrinsic::gcroot)
00240           return false;
00241 
00242   return true;
00243 }
00244 
00245 /// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
00246 /// Leave gcroot intrinsics; the code generator needs to see those.
00247 bool LowerIntrinsics::runOnFunction(Function &F) {
00248   // Quick exit for functions that do not use GC.
00249   if (!F.hasGC())
00250     return false;
00251 
00252   GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
00253   GCStrategy &S = FI.getStrategy();
00254 
00255   bool MadeChange = false;
00256 
00257   if (NeedsDefaultLoweringPass(S))
00258     MadeChange |= PerformDefaultLowering(F, S);
00259 
00260   bool UseCustomLoweringPass = NeedsCustomLoweringPass(S);
00261   if (UseCustomLoweringPass)
00262     MadeChange |= S.performCustomLowering(F);
00263 
00264   // Custom lowering may modify the CFG, so dominators must be recomputed.
00265   if (UseCustomLoweringPass) {
00266     if (DominatorTreeWrapperPass *DTWP =
00267             getAnalysisIfAvailable<DominatorTreeWrapperPass>())
00268       DTWP->getDomTree().recalculate(F);
00269   }
00270 
00271   return MadeChange;
00272 }
00273 
00274 bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) {
00275   bool LowerWr = !S.customWriteBarrier();
00276   bool LowerRd = !S.customReadBarrier();
00277   bool InitRoots = S.initializeRoots();
00278 
00279   SmallVector<AllocaInst*, 32> Roots;
00280 
00281   bool MadeChange = false;
00282   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
00283     for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
00284       if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) {
00285         Function *F = CI->getCalledFunction();
00286         switch (F->getIntrinsicID()) {
00287         case Intrinsic::gcwrite:
00288           if (LowerWr) {
00289             // Replace a write barrier with a simple store.
00290             Value *St = new StoreInst(CI->getArgOperand(0),
00291                                       CI->getArgOperand(2), CI);
00292             CI->replaceAllUsesWith(St);
00293             CI->eraseFromParent();
00294           }
00295           break;
00296         case Intrinsic::gcread:
00297           if (LowerRd) {
00298             // Replace a read barrier with a simple load.
00299             Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI);
00300             Ld->takeName(CI);
00301             CI->replaceAllUsesWith(Ld);
00302             CI->eraseFromParent();
00303           }
00304           break;
00305         case Intrinsic::gcroot:
00306           if (InitRoots) {
00307             // Initialize the GC root, but do not delete the intrinsic. The
00308             // backend needs the intrinsic to flag the stack slot.
00309             Roots.push_back(cast<AllocaInst>(
00310                               CI->getArgOperand(0)->stripPointerCasts()));
00311           }
00312           break;
00313         default:
00314           continue;
00315         }
00316 
00317         MadeChange = true;
00318       }
00319     }
00320   }
00321 
00322   if (Roots.size())
00323     MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size());
00324 
00325   return MadeChange;
00326 }
00327 
00328 // -----------------------------------------------------------------------------
00329 
00330 char GCMachineCodeAnalysis::ID = 0;
00331 char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID;
00332 
00333 INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis",
00334                 "Analyze Machine Code For Garbage Collection", false, false)
00335 
00336 GCMachineCodeAnalysis::GCMachineCodeAnalysis()
00337   : MachineFunctionPass(ID) {}
00338 
00339 void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
00340   MachineFunctionPass::getAnalysisUsage(AU);
00341   AU.setPreservesAll();
00342   AU.addRequired<MachineModuleInfo>();
00343   AU.addRequired<GCModuleInfo>();
00344 }
00345 
00346 MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
00347                                              MachineBasicBlock::iterator MI,
00348                                              DebugLoc DL) const {
00349   MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol();
00350   BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
00351   return Label;
00352 }
00353 
00354 void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) {
00355   // Find the return address (next instruction), too, so as to bracket the call
00356   // instruction.
00357   MachineBasicBlock::iterator RAI = CI;
00358   ++RAI;
00359 
00360   if (FI->getStrategy().needsSafePoint(GC::PreCall)) {
00361     MCSymbol* Label = InsertLabel(*CI->getParent(), CI, CI->getDebugLoc());
00362     FI->addSafePoint(GC::PreCall, Label, CI->getDebugLoc());
00363   }
00364 
00365   if (FI->getStrategy().needsSafePoint(GC::PostCall)) {
00366     MCSymbol* Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc());
00367     FI->addSafePoint(GC::PostCall, Label, CI->getDebugLoc());
00368   }
00369 }
00370 
00371 void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
00372   for (MachineFunction::iterator BBI = MF.begin(),
00373                                  BBE = MF.end(); BBI != BBE; ++BBI)
00374     for (MachineBasicBlock::iterator MI = BBI->begin(),
00375                                      ME = BBI->end(); MI != ME; ++MI)
00376       if (MI->isCall())
00377         VisitCallPoint(MI);
00378 }
00379 
00380 void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
00381   const TargetFrameLowering *TFI = TM->getSubtargetImpl()->getFrameLowering();
00382   assert(TFI && "TargetRegisterInfo not available!");
00383 
00384   for (GCFunctionInfo::roots_iterator RI = FI->roots_begin();
00385        RI != FI->roots_end();) {
00386     // If the root references a dead object, no need to keep it.
00387     if (MF.getFrameInfo()->isDeadObjectIndex(RI->Num)) {
00388       RI = FI->removeStackRoot(RI);
00389     } else {
00390       RI->StackOffset = TFI->getFrameIndexOffset(MF, RI->Num);
00391       ++RI;
00392     }
00393   }
00394 }
00395 
00396 bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
00397   // Quick exit for functions that do not use GC.
00398   if (!MF.getFunction()->hasGC())
00399     return false;
00400 
00401   FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
00402   if (!FI->getStrategy().needsSafePoints())
00403     return false;
00404 
00405   TM = &MF.getTarget();
00406   MMI = &getAnalysis<MachineModuleInfo>();
00407   TII = TM->getSubtargetImpl()->getInstrInfo();
00408 
00409   // Find the size of the stack frame.
00410   FI->setFrameSize(MF.getFrameInfo()->getStackSize());
00411 
00412   // Find all safe points.
00413   if (FI->getStrategy().customSafePoints()) {
00414     FI->getStrategy().findCustomSafePoints(*FI, MF);
00415   } else {
00416     FindSafePoints(MF);
00417   }
00418 
00419   // Find the stack offsets for all roots.
00420   FindStackOffsets(MF);
00421 
00422   return false;
00423 }