1 //===-- ErlangGC.cpp - Erlang/OTP GC strategy -------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Erlang/OTP runtime-compatible garbage collector 11 // (e.g. defines safe points, root initialization etc.) 12 // 13 // The frametable emitter is in ErlangGCPrinter.cpp. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/CodeGen/GCs.h" 18 #include "llvm/CodeGen/GCStrategy.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCSymbol.h" 22 #include "llvm/Target/TargetInstrInfo.h" 23 #include "llvm/Target/TargetMachine.h" 24 25 using namespace llvm; 26 27 namespace { 28 29 class ErlangGC : public GCStrategy { 30 MCSymbol *InsertLabel(MachineBasicBlock &MBB, 31 MachineBasicBlock::iterator MI, 32 DebugLoc DL) const; 33 public: 34 ErlangGC(); 35 bool findCustomSafePoints(GCFunctionInfo &FI, MachineFunction &MF); 36 }; 37 38 } 39 40 static GCRegistry::Add<ErlangGC> 41 X("erlang", "erlang-compatible garbage collector"); 42 43 void llvm::linkErlangGC() { } 44 45 ErlangGC::ErlangGC() { 46 InitRoots = false; 47 NeededSafePoints = 1 << GC::PostCall; 48 UsesMetadata = true; 49 CustomRoots = false; 50 CustomSafePoints = true; 51 } 52 53 MCSymbol *ErlangGC::InsertLabel(MachineBasicBlock &MBB, 54 MachineBasicBlock::iterator MI, 55 DebugLoc DL) const { 56 const TargetInstrInfo* TII = MBB.getParent()->getTarget().getInstrInfo(); 57 MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol(); 58 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label); 59 return Label; 60 } 61 62 bool ErlangGC::findCustomSafePoints(GCFunctionInfo &FI, MachineFunction &MF) { 63 for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE; 64 ++BBI) 65 for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end(); 66 MI != ME; ++MI) 67 68 if (MI->getDesc().isCall()) { 69 70 // Do not treat tail call sites as safe points. 71 if (MI->getDesc().isTerminator()) 72 continue; 73 74 /* Code copied from VisitCallPoint(...) */ 75 MachineBasicBlock::iterator RAI = MI; ++RAI; 76 MCSymbol* Label = InsertLabel(*MI->getParent(), RAI, MI->getDebugLoc()); 77 FI.addSafePoint(GC::PostCall, Label, MI->getDebugLoc()); 78 } 79 80 return false; 81 } 82