15eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===// 2fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// 3fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// The LLVM Compiler Infrastructure 4fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// 8fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//===----------------------------------------------------------------------===// 9fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// 105eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen// This file implements the GCFunctionInfo class and GCModuleInfo pass. 11fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// 12fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen//===----------------------------------------------------------------------===// 13fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 145a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCMetadata.h" 155a29c9eed157af51a8d338b5a225b146881819e8Gordon Henriksen#include "llvm/CodeGen/GCStrategy.h" 16fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen#include "llvm/CodeGen/MachineFrameInfo.h" 17ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen#include "llvm/CodeGen/Passes.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 19aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner#include "llvm/MC/MCSymbol.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h" 21aba28d1273f7332a6a8c335e99dd5a68af748d4fDavid Greene#include "llvm/Support/Debug.h" 227d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h" 23cf143a4d917699f8f4202f331fa9e184070471fbChris Lattner#include "llvm/Support/raw_ostream.h" 24fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenusing namespace llvm; 25fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 26fc3282221f90c626d80292327213e2badc3de86bGordon Henriksennamespace { 27fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 286726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class Printer : public FunctionPass { 29fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen static char ID; 30cf143a4d917699f8f4202f331fa9e184070471fbChris Lattner raw_ostream &OS; 31fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 32fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen public: 3390c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {} 34cf143a4d917699f8f4202f331fa9e184070471fbChris Lattner 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *getPassName() const override; 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override; 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doFinalization(Module &M) override; 41fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen }; 42063337309e71683fc57c049c10d03d4f8a2ce356Benjamin Kramer 43fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 44fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 45d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen AndersonINITIALIZE_PASS(GCModuleInfo, "collector-metadata", 46ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson "Create Garbage Collector Module Metadata", false, false) 47844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 48fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// ----------------------------------------------------------------------------- 49fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 505eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S) 515eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen : F(F), S(S), FrameSize(~0LL) {} 52fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 535eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCFunctionInfo::~GCFunctionInfo() {} 54fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 55fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// ----------------------------------------------------------------------------- 56fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 575eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksenchar GCModuleInfo::ID = 0; 58fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 595eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCModuleInfo::GCModuleInfo() 60081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson : ImmutablePass(ID) { 61081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); 62081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson} 63fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 645eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M, 655eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen const std::string &Name) { 666316fbcb04af00fe76b6526fab09f51484014b3eDaniel Dunbar strategy_map_type::iterator NMI = StrategyMap.find(Name); 675eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (NMI != StrategyMap.end()) 68ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen return NMI->getValue(); 69ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen 705eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen for (GCRegistry::iterator I = GCRegistry::begin(), 715eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen E = GCRegistry::end(); I != E; ++I) { 726316fbcb04af00fe76b6526fab09f51484014b3eDaniel Dunbar if (Name == I->getName()) { 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<GCStrategy> S = I->instantiate(); 745eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen S->M = M; 755eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen S->Name = Name; 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StrategyMap.GetOrCreateValue(Name).setValue(S.get()); 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StrategyList.push_back(std::move(S)); 78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return StrategyList.back().get(); 79ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen } 80ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen } 817d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin 82aba28d1273f7332a6a8c335e99dd5a68af748d4fDavid Greene dbgs() << "unsupported GC: " << Name << "\n"; 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable(nullptr); 84fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 85fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 865eca075b74d62c621b160aa216b4cd50829a2cc7Gordon HenriksenGCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) { 87418b6e875f844261064c5dd43e76cb401117ac74Gordon Henriksen assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!"); 885eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen assert(F.hasGC()); 89418b6e875f844261064c5dd43e76cb401117ac74Gordon Henriksen 905eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen finfo_map_type::iterator I = FInfoMap.find(&F); 915eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen if (I != FInfoMap.end()) 92ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen return *I->second; 935eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen 945eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC()); 955eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GCFunctionInfo *GFI = S->insertFunctionInfo(F); 965eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen FInfoMap[&F] = GFI; 975eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen return *GFI; 98fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 99fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 1005eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksenvoid GCModuleInfo::clear() { 1015eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen FInfoMap.clear(); 1025eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen StrategyMap.clear(); 1035eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen StrategyList.clear(); 104fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 105fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 106fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen// ----------------------------------------------------------------------------- 107fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 108fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenchar Printer::ID = 0; 109fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 110cf143a4d917699f8f4202f331fa9e184070471fbChris LattnerFunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) { 111fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen return new Printer(OS); 112fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 113fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 114fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 115fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenconst char *Printer::getPassName() const { 116fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen return "Print Garbage Collector Information"; 117fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 118fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 119fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenvoid Printer::getAnalysisUsage(AnalysisUsage &AU) const { 120ad93c4f936d220570535711262e0fff8857f798aGordon Henriksen FunctionPass::getAnalysisUsage(AU); 121fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen AU.setPreservesAll(); 1225eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen AU.addRequired<GCModuleInfo>(); 123fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 124fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 125fc3282221f90c626d80292327213e2badc3de86bGordon Henriksenstatic const char *DescKind(GC::PointKind Kind) { 126fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen switch (Kind) { 127fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen case GC::Loop: return "loop"; 128fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen case GC::Return: return "return"; 129fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen case GC::PreCall: return "pre-call"; 130fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen case GC::PostCall: return "post-call"; 131fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen } 132732f05c41f177a0bc4d47e93a5d02120f146cb4cChandler Carruth llvm_unreachable("Invalid point kind"); 133fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 134fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 135ad93c4f936d220570535711262e0fff8857f798aGordon Henriksenbool Printer::runOnFunction(Function &F) { 136aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner if (F.hasGC()) return false; 137aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner 138aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F); 139aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner 140a7b0cb759433c715065440ee2a963a04db7f2b0bBenjamin Kramer OS << "GC roots for " << FD->getFunction().getName() << ":\n"; 141aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(), 142aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner RE = FD->roots_end(); RI != RE; ++RI) 143aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; 144aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner 145a7b0cb759433c715065440ee2a963a04db7f2b0bBenjamin Kramer OS << "GC safe points for " << FD->getFunction().getName() << ":\n"; 146aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner for (GCFunctionInfo::iterator PI = FD->begin(), 147aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner PE = FD->end(); PI != PE; ++PI) { 148fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 149aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner OS << "\t" << PI->Label->getName() << ": " 150aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner << DescKind(PI->Kind) << ", live = {"; 151fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 152aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI), 153aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner RE = FD->live_end(PI);;) { 154aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner OS << " " << RI->Num; 155aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner if (++RI == RE) 156aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner break; 157aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner OS << ","; 158fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen } 159aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner 160aba9bcb9b60edbad3646b2f3088c120d06549cc7Chris Lattner OS << " }\n"; 161fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen } 162fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 163fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen return false; 164fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 165fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen 166063337309e71683fc57c049c10d03d4f8a2ce356Benjamin Kramerbool Printer::doFinalization(Module &M) { 1671465d61bdd36cfd6021036a527895f0dd358e97dDuncan Sands GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>(); 168063337309e71683fc57c049c10d03d4f8a2ce356Benjamin Kramer assert(GMI && "Printer didn't require GCModuleInfo?!"); 1695eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen GMI->clear(); 170fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen return false; 171fc3282221f90c626d80292327213e2badc3de86bGordon Henriksen} 172