CollectorMetadata and Collector are rejiggered to get along with
per-function collector model. Collector is now the factory for
CollectorMetadata, so the latter may be subclassed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44827 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/Collector.cpp b/lib/CodeGen/Collector.cpp
index 29dc504..67b3928 100644
--- a/lib/CodeGen/Collector.cpp
+++ b/lib/CodeGen/Collector.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/Collector.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -29,38 +30,40 @@
namespace {
- /// This pass rewrites calls to the llvm.gcread or llvm.gcwrite intrinsics,
- /// replacing them with simple loads and stores as directed by the Collector.
- /// This is useful for most garbage collectors.
+ /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or
+ /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as
+ /// directed by the Collector. It also performs automatic root initialization
+ /// and custom intrinsic lowering.
class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
- const Collector &Coll;
-
/// GCRootInt, GCReadInt, GCWriteInt - The function prototypes for the
/// llvm.gc* intrinsics.
Function *GCRootInt, *GCReadInt, *GCWriteInt;
+ static bool NeedsDefaultLoweringPass(const Collector &C);
+ static bool NeedsCustomLoweringPass(const Collector &C);
static bool CouldBecomeSafePoint(Instruction *I);
- static void InsertRootInitializers(Function &F,
+ bool PerformDefaultLowering(Function &F, Collector &Coll);
+ static bool InsertRootInitializers(Function &F,
AllocaInst **Roots, unsigned Count);
public:
static char ID;
- LowerIntrinsics(const Collector &GC);
+ LowerIntrinsics();
const char *getPassName() const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
bool doInitialization(Module &M);
bool runOnFunction(Function &F);
};
- /// This is a target-independent pass over the machine function representation
- /// to identify safe points for the garbage collector in the machine code. It
- /// inserts labels at safe points and populates the GCInfo class.
+ /// MachineCodeAnalysis - This is a target-independent pass over the machine
+ /// function representation to identify safe points for the garbage collector
+ /// in the machine code. It inserts labels at safe points and populates a
+ /// CollectorMetadata record for each function.
class VISIBILITY_HIDDEN MachineCodeAnalysis : public MachineFunctionPass {
- const Collector &Coll;
- const TargetMachine &Targ;
-
+ const TargetMachine *TM;
CollectorMetadata *MD;
MachineModuleInfo *MMI;
const TargetInstrInfo *TII;
@@ -76,7 +79,7 @@
public:
static char ID;
- MachineCodeAnalysis(const Collector &C, const TargetMachine &T);
+ MachineCodeAnalysis();
const char *getPassName() const;
void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -87,8 +90,6 @@
// -----------------------------------------------------------------------------
-const Collector *llvm::TheCollector = 0;
-
Collector::Collector() :
NeededSafePoints(0),
CustomReadBarriers(false),
@@ -97,85 +98,85 @@
InitRoots(true)
{}
-Collector::~Collector() {}
-
-void Collector::addLoweringPasses(FunctionPassManager &PM) const {
- if (NeedsDefaultLoweringPass())
- PM.add(new LowerIntrinsics(*this));
-
- if (NeedsCustomLoweringPass())
- PM.add(createCustomLoweringPass());
+Collector::~Collector() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ delete *I;
+
+ Functions.clear();
}
-
-void Collector::addLoweringPasses(PassManager &PM) const {
- if (NeedsDefaultLoweringPass())
- PM.add(new LowerIntrinsics(*this));
-
- if (NeedsCustomLoweringPass())
- PM.add(createCustomLoweringPass());
-}
-
-void Collector::addGenericMachineCodePass(FunctionPassManager &PM,
- const TargetMachine &TM,
- bool Fast) const {
- if (needsSafePoints())
- PM.add(new MachineCodeAnalysis(*this, TM));
-}
-
-bool Collector::NeedsDefaultLoweringPass() const {
- // Default lowering is necessary only if read or write barriers have a default
- // action. The default for roots is no action.
- return !customWriteBarrier()
- || !customReadBarrier()
- || initializeRoots();
-}
-
-bool Collector::NeedsCustomLoweringPass() const {
- // Custom lowering is only necessary if enabled for some action.
- return customWriteBarrier()
- || customReadBarrier()
- || customRoots();
-}
-
-Pass *Collector::createCustomLoweringPass() const {
- cerr << "Collector must override createCustomLoweringPass.\n";
+
+bool Collector::initializeCustomLowering(Module &M) { return false; }
+
+bool Collector::performCustomLowering(Function &F) {
+ cerr << "gc " << getName() << " must override performCustomLowering.\n";
abort();
return 0;
}
-void Collector::beginAssembly(Module &M, std::ostream &OS, AsmPrinter &AP,
- const TargetAsmInfo &TAI) const {
+void Collector::beginAssembly(std::ostream &OS, AsmPrinter &AP,
+ const TargetAsmInfo &TAI) {
// Default is no action.
}
-void Collector::finishAssembly(Module &M, CollectorModuleMetadata &CMM,
- std::ostream &OS, AsmPrinter &AP,
- const TargetAsmInfo &TAI) const {
+void Collector::finishAssembly(std::ostream &OS, AsmPrinter &AP,
+ const TargetAsmInfo &TAI) {
// Default is no action.
}
+
+CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) {
+ CollectorMetadata *CM = new CollectorMetadata(F, *this);
+ Functions.push_back(CM);
+ return CM;
+}
// -----------------------------------------------------------------------------
+FunctionPass *llvm::createGCLoweringPass() {
+ return new LowerIntrinsics();
+}
+
char LowerIntrinsics::ID = 0;
-LowerIntrinsics::LowerIntrinsics(const Collector &C)
- : FunctionPass((intptr_t)&ID), Coll(C),
+LowerIntrinsics::LowerIntrinsics()
+ : FunctionPass((intptr_t)&ID),
GCRootInt(0), GCReadInt(0), GCWriteInt(0) {}
const char *LowerIntrinsics::getPassName() const {
return "Lower Garbage Collection Instructions";
}
-/// doInitialization - If this module uses the GC intrinsics, find them now. If
-/// not, this pass does not do anything.
+void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
+ FunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<CollectorModuleMetadata>();
+}
+
+/// doInitialization - If this module uses the GC intrinsics, find them now.
bool LowerIntrinsics::doInitialization(Module &M) {
GCReadInt = M.getFunction("llvm.gcread");
GCWriteInt = M.getFunction("llvm.gcwrite");
GCRootInt = M.getFunction("llvm.gcroot");
- return false;
+
+ // FIXME: This is rather antisocial in the context of a JIT since it performs
+ // work against the entire module. But this cannot be done at
+ // runFunction time (initializeCustomLowering likely needs to change
+ // the module).
+ CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
+ assert(CMM && "LowerIntrinsics didn't require CollectorModuleMetadata!?");
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (I->hasCollector())
+ CMM->get(*I); // Instantiate the Collector.
+
+ bool MadeChange = false;
+ for (CollectorModuleMetadata::iterator I = CMM->begin(),
+ E = CMM->end(); I != E; ++I)
+ if (NeedsCustomLoweringPass(**I))
+ if ((*I)->initializeCustomLowering(M))
+ MadeChange = true;
+
+ return MadeChange;
}
-void LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots,
+bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots,
unsigned Count) {
// Scroll past alloca instructions.
BasicBlock::iterator IP = F.getEntryBlock().begin();
@@ -190,11 +191,32 @@
InitedRoots.insert(AI);
// Add root initializers.
+ bool MadeChange = false;
+
for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I)
- if (!InitedRoots.count(*I))
+ if (!InitedRoots.count(*I)) {
new StoreInst(ConstantPointerNull::get(cast<PointerType>(
cast<PointerType>((*I)->getType())->getElementType())),
*I, IP);
+ MadeChange = true;
+ }
+
+ return MadeChange;
+}
+
+bool LowerIntrinsics::NeedsDefaultLoweringPass(const Collector &C) {
+ // Default lowering is necessary only if read or write barriers have a default
+ // action. The default for roots is no action.
+ return !C.customWriteBarrier()
+ || !C.customReadBarrier()
+ || C.initializeRoots();
+}
+
+bool LowerIntrinsics::NeedsCustomLoweringPass(const Collector &C) {
+ // Custom lowering is only necessary if enabled for some action.
+ return C.customWriteBarrier()
+ || C.customReadBarrier()
+ || C.customRoots();
}
/// CouldBecomeSafePoint - Predicate to conservatively determine whether the
@@ -228,9 +250,24 @@
/// runOnFunction - Replace gcread/gcwrite intrinsics with loads and stores.
/// Leave gcroot intrinsics; the code generator needs to see those.
bool LowerIntrinsics::runOnFunction(Function &F) {
- // Quick exit for programs that do not declare the intrinsics.
- if (!GCReadInt && !GCWriteInt && !GCRootInt) return false;
+ // Quick exit for functions that do not use GC.
+ if (!F.hasCollector()) return false;
+ CollectorMetadata &MD = getAnalysis<CollectorModuleMetadata>().get(F);
+ Collector &Coll = MD.getCollector();
+
+ bool MadeChange = false;
+
+ if (NeedsDefaultLoweringPass(Coll))
+ MadeChange |= PerformDefaultLowering(F, Coll);
+
+ if (NeedsCustomLoweringPass(Coll))
+ MadeChange |= Coll.performCustomLowering(F);
+
+ return MadeChange;
+}
+
+bool LowerIntrinsics::PerformDefaultLowering(Function &F, Collector &Coll) {
bool LowerWr = !Coll.customWriteBarrier();
bool LowerRd = !Coll.customReadBarrier();
bool InitRoots = Coll.initializeRoots();
@@ -268,17 +305,21 @@
}
if (Roots.size())
- InsertRootInitializers(F, Roots.begin(), Roots.size());
+ MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size());
return MadeChange;
}
// -----------------------------------------------------------------------------
+FunctionPass *llvm::createGCMachineCodeAnalysisPass() {
+ return new MachineCodeAnalysis();
+}
+
char MachineCodeAnalysis::ID = 0;
-MachineCodeAnalysis::MachineCodeAnalysis(const Collector &C, const TargetMachine &T)
- : MachineFunctionPass(intptr_t(&ID)), Coll(C), Targ(T) {}
+MachineCodeAnalysis::MachineCodeAnalysis()
+ : MachineFunctionPass(intptr_t(&ID)) {}
const char *MachineCodeAnalysis::getPassName() const {
return "Analyze Machine Code For Garbage Collection";
@@ -304,10 +345,10 @@
MachineBasicBlock::iterator RAI = CI;
++RAI;
- if (Coll.needsSafePoint(GC::PreCall))
+ if (MD->getCollector().needsSafePoint(GC::PreCall))
MD->addSafePoint(GC::PreCall, InsertLabel(*CI->getParent(), CI));
- if (Coll.needsSafePoint(GC::PostCall))
+ if (MD->getCollector().needsSafePoint(GC::PostCall))
MD->addSafePoint(GC::PostCall, InsertLabel(*CI->getParent(), RAI));
}
@@ -323,7 +364,7 @@
void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) {
uint64_t StackSize = MFI->getStackSize();
uint64_t OffsetAdjustment = MFI->getOffsetAdjustment();
- uint64_t OffsetOfLocalArea = Targ.getFrameInfo()->getOffsetOfLocalArea();
+ uint64_t OffsetOfLocalArea = TM->getFrameInfo()->getOffsetOfLocalArea();
for (CollectorMetadata::roots_iterator RI = MD->roots_begin(),
RE = MD->roots_end(); RI != RE; ++RI)
@@ -332,12 +373,16 @@
}
bool MachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
- if (!Coll.needsSafePoints())
+ // Quick exit for functions that do not use GC.
+ if (!MF.getFunction()->hasCollector()) return false;
+
+ MD = &getAnalysis<CollectorModuleMetadata>().get(*MF.getFunction());
+ if (!MD->getCollector().needsSafePoints())
return false;
- MD = getAnalysis<CollectorModuleMetadata>().get(MF.getFunction());
+ TM = &MF.getTarget();
MMI = &getAnalysis<MachineModuleInfo>();
- TII = MF.getTarget().getInstrInfo();
+ TII = TM->getInstrInfo();
MFI = MF.getFrameInfo();
// Find the size of the stack frame.
diff --git a/lib/CodeGen/CollectorMetadata.cpp b/lib/CodeGen/CollectorMetadata.cpp
index f86ee04..5734939 100644
--- a/lib/CodeGen/CollectorMetadata.cpp
+++ b/lib/CodeGen/CollectorMetadata.cpp
@@ -13,8 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/CollectorMetadata.h"
+#include "llvm/CodeGen/Collector.h"
+#include "llvm/CodeGen/Collectors.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
@@ -22,7 +25,7 @@
namespace {
- class VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
+ class VISIBILITY_HIDDEN Printer : public FunctionPass {
static char ID;
std::ostream &OS;
@@ -32,10 +35,10 @@
const char *getPassName() const;
void getAnalysisUsage(AnalysisUsage &AU) const;
- bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnFunction(Function &F);
};
- class VISIBILITY_HIDDEN Deleter : public MachineFunctionPass {
+ class VISIBILITY_HIDDEN Deleter : public FunctionPass {
static char ID;
public:
@@ -44,7 +47,7 @@
const char *getPassName() const;
void getAnalysisUsage(AnalysisUsage &AU) const;
- bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnFunction(Function &F);
bool doFinalization(Module &M);
};
@@ -55,8 +58,8 @@
// -----------------------------------------------------------------------------
-CollectorMetadata::CollectorMetadata(const Function &F)
- : F(F), FrameSize(~0LL) {}
+CollectorMetadata::CollectorMetadata(const Function &F, Collector &C)
+ : F(F), C(C), FrameSize(~0LL) {}
CollectorMetadata::~CollectorMetadata() {}
@@ -71,46 +74,71 @@
clear();
}
-CollectorMetadata& CollectorModuleMetadata::insert(const Function *F) {
- assert(Map.find(F) == Map.end() && "Function GC metadata already exists!");
- CollectorMetadata *FMD = new CollectorMetadata(*F);
- Functions.push_back(FMD);
- Map[F] = FMD;
- return *FMD;
+Collector *CollectorModuleMetadata::
+getOrCreateCollector(const Module *M, const std::string &Name) {
+ const char *Start = Name.c_str();
+
+ collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size());
+ if (NMI != NameMap.end())
+ return NMI->getValue();
+
+ for (CollectorRegistry::iterator I = CollectorRegistry::begin(),
+ E = CollectorRegistry::end(); I != E; ++I) {
+ if (strcmp(Start, I->getName()) == 0) {
+ Collector *C = I->instantiate();
+ C->M = M;
+ C->Name = Name;
+ NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C);
+ Collectors.push_back(C);
+ return C;
+ }
+ }
+
+ cerr << "unsupported collector: " << Name << "\n";
+ abort();
}
-CollectorMetadata* CollectorModuleMetadata::get(const Function *F) const {
- map_type::iterator I = Map.find(F);
- if (I == Map.end())
- return 0;
- return I->second;
+CollectorMetadata &CollectorModuleMetadata::get(const Function &F) {
+ assert(F.hasCollector());
+ function_map_type::iterator I = Map.find(&F);
+ if (I != Map.end())
+ return *I->second;
+
+ Collector *C = getOrCreateCollector(F.getParent(), F.getCollector());
+ CollectorMetadata *MD = C->insertFunctionMetadata(F);
+ Map[&F] = MD;
+ return *MD;
}
void CollectorModuleMetadata::clear() {
+ Map.clear();
+
+ // TODO: StringMap should provide a clear method.
+ while (!NameMap.empty())
+ NameMap.erase(NameMap.begin());
+
for (iterator I = begin(), E = end(); I != E; ++I)
delete *I;
-
- Functions.clear();
- Map.clear();
+ Collectors.clear();
}
// -----------------------------------------------------------------------------
char Printer::ID = 0;
-Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
+FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) {
return new Printer(OS);
}
Printer::Printer(std::ostream &OS)
- : MachineFunctionPass(intptr_t(&ID)), OS(OS) {}
+ : FunctionPass(intptr_t(&ID)), OS(OS) {}
const char *Printer::getPassName() const {
return "Print Garbage Collector Information";
}
void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
- MachineFunctionPass::getAnalysisUsage(AU);
+ FunctionPass::getAnalysisUsage(AU);
AU.setPreservesAll();
AU.addRequired<CollectorModuleMetadata>();
}
@@ -125,9 +153,9 @@
}
}
-bool Printer::runOnMachineFunction(MachineFunction &MF) {
- if (CollectorMetadata *FD =
- getAnalysis<CollectorModuleMetadata>().get(MF.getFunction())) {
+bool Printer::runOnFunction(Function &F) {
+ if (F.hasCollector()) {
+ CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F);
OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n";
for (CollectorMetadata::roots_iterator RI = FD->roots_begin(),
@@ -160,11 +188,11 @@
char Deleter::ID = 0;
-Pass *llvm::createCollectorMetadataDeleter() {
+FunctionPass *llvm::createCollectorMetadataDeleter() {
return new Deleter();
}
-Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {}
+Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {}
const char *Deleter::getPassName() const {
return "Delete Garbage Collector Information";
@@ -175,11 +203,13 @@
AU.addRequired<CollectorModuleMetadata>();
}
-bool Deleter::runOnMachineFunction(MachineFunction &MF) {
+bool Deleter::runOnFunction(Function &MF) {
return false;
}
bool Deleter::doFinalization(Module &M) {
- getAnalysis<CollectorModuleMetadata>().clear();
+ CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
+ assert(CMM && "Deleter didn't require CollectorModuleMetadata?!");
+ CMM->clear();
return false;
}