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 25using namespace llvm; 26 27namespace { 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) override; 36 }; 37 38} 39 40static GCRegistry::Add<ErlangGC> 41X("erlang", "erlang-compatible garbage collector"); 42 43void llvm::linkErlangGC() { } 44 45ErlangGC::ErlangGC() { 46 InitRoots = false; 47 NeededSafePoints = 1 << GC::PostCall; 48 UsesMetadata = true; 49 CustomRoots = false; 50 CustomSafePoints = true; 51} 52 53MCSymbol *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 62bool 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