ErlangGC.cpp revision 280031
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#include "llvm/Target/TargetSubtargetInfo.h" 25 26using namespace llvm; 27 28namespace { 29 30 class ErlangGC : public GCStrategy { 31 MCSymbol *InsertLabel(MachineBasicBlock &MBB, 32 MachineBasicBlock::iterator MI, 33 DebugLoc DL) const; 34 public: 35 ErlangGC(); 36 bool findCustomSafePoints(GCFunctionInfo &FI, MachineFunction &MF) override; 37 }; 38 39} 40 41static GCRegistry::Add<ErlangGC> 42X("erlang", "erlang-compatible garbage collector"); 43 44void llvm::linkErlangGC() { } 45 46ErlangGC::ErlangGC() { 47 InitRoots = false; 48 NeededSafePoints = 1 << GC::PostCall; 49 UsesMetadata = true; 50 CustomRoots = false; 51 CustomSafePoints = true; 52} 53 54MCSymbol *ErlangGC::InsertLabel(MachineBasicBlock &MBB, 55 MachineBasicBlock::iterator MI, 56 DebugLoc DL) const { 57 const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); 58 MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol(); 59 BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label); 60 return Label; 61} 62 63bool ErlangGC::findCustomSafePoints(GCFunctionInfo &FI, MachineFunction &MF) { 64 for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE; 65 ++BBI) 66 for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end(); 67 MI != ME; ++MI) 68 69 if (MI->getDesc().isCall()) { 70 71 // Do not treat tail call sites as safe points. 72 if (MI->getDesc().isTerminator()) 73 continue; 74 75 /* Code copied from VisitCallPoint(...) */ 76 MachineBasicBlock::iterator RAI = MI; ++RAI; 77 MCSymbol* Label = InsertLabel(*MI->getParent(), RAI, MI->getDebugLoc()); 78 FI.addSafePoint(GC::PostCall, Label, MI->getDebugLoc()); 79 } 80 81 return false; 82} 83