mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
Sooooo many of these had incorrect or strange main module includes. I have manually inspected all of these, and fixed the main module include to be the nearest plausible thing I could find. If you own or care about any of these source files, I encourage you to take some time and check that these edits were sensible. I can't have broken anything (I strictly added headers, and reordered them, never removed), but they may not be the headers you'd really like to identify as containing the API being implemented. Many forward declarations and missing includes were added to a header files to allow them to parse cleanly when included first. The main module rule does in fact have its merits. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169131 91177308-0d34-0410-b5e6-96231b3b80d8
214 lines
5.6 KiB
C++
214 lines
5.6 KiB
C++
//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the GCFunctionInfo class and GCModuleInfo pass.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/CodeGen/GCMetadata.h"
|
|
#include "llvm/CodeGen/GCStrategy.h"
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/Function.h"
|
|
#include "llvm/MC/MCSymbol.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
class Printer : public FunctionPass {
|
|
static char ID;
|
|
raw_ostream &OS;
|
|
|
|
public:
|
|
explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {}
|
|
|
|
|
|
const char *getPassName() const;
|
|
void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
|
|
bool runOnFunction(Function &F);
|
|
};
|
|
|
|
class Deleter : public FunctionPass {
|
|
static char ID;
|
|
|
|
public:
|
|
Deleter();
|
|
|
|
const char *getPassName() const;
|
|
void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
|
|
bool runOnFunction(Function &F);
|
|
bool doFinalization(Module &M);
|
|
};
|
|
|
|
}
|
|
|
|
INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
|
|
"Create Garbage Collector Module Metadata", false, false)
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
|
|
: F(F), S(S), FrameSize(~0LL) {}
|
|
|
|
GCFunctionInfo::~GCFunctionInfo() {}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
char GCModuleInfo::ID = 0;
|
|
|
|
GCModuleInfo::GCModuleInfo()
|
|
: ImmutablePass(ID) {
|
|
initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
GCModuleInfo::~GCModuleInfo() {
|
|
clear();
|
|
}
|
|
|
|
GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M,
|
|
const std::string &Name) {
|
|
strategy_map_type::iterator NMI = StrategyMap.find(Name);
|
|
if (NMI != StrategyMap.end())
|
|
return NMI->getValue();
|
|
|
|
for (GCRegistry::iterator I = GCRegistry::begin(),
|
|
E = GCRegistry::end(); I != E; ++I) {
|
|
if (Name == I->getName()) {
|
|
GCStrategy *S = I->instantiate();
|
|
S->M = M;
|
|
S->Name = Name;
|
|
StrategyMap.GetOrCreateValue(Name).setValue(S);
|
|
StrategyList.push_back(S);
|
|
return S;
|
|
}
|
|
}
|
|
|
|
dbgs() << "unsupported GC: " << Name << "\n";
|
|
llvm_unreachable(0);
|
|
}
|
|
|
|
GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
|
|
assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
|
|
assert(F.hasGC());
|
|
|
|
finfo_map_type::iterator I = FInfoMap.find(&F);
|
|
if (I != FInfoMap.end())
|
|
return *I->second;
|
|
|
|
GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
|
|
GCFunctionInfo *GFI = S->insertFunctionInfo(F);
|
|
FInfoMap[&F] = GFI;
|
|
return *GFI;
|
|
}
|
|
|
|
void GCModuleInfo::clear() {
|
|
FInfoMap.clear();
|
|
StrategyMap.clear();
|
|
|
|
for (iterator I = begin(), E = end(); I != E; ++I)
|
|
delete *I;
|
|
StrategyList.clear();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
char Printer::ID = 0;
|
|
|
|
FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) {
|
|
return new Printer(OS);
|
|
}
|
|
|
|
|
|
const char *Printer::getPassName() const {
|
|
return "Print Garbage Collector Information";
|
|
}
|
|
|
|
void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
FunctionPass::getAnalysisUsage(AU);
|
|
AU.setPreservesAll();
|
|
AU.addRequired<GCModuleInfo>();
|
|
}
|
|
|
|
static const char *DescKind(GC::PointKind Kind) {
|
|
switch (Kind) {
|
|
case GC::Loop: return "loop";
|
|
case GC::Return: return "return";
|
|
case GC::PreCall: return "pre-call";
|
|
case GC::PostCall: return "post-call";
|
|
}
|
|
llvm_unreachable("Invalid point kind");
|
|
}
|
|
|
|
bool Printer::runOnFunction(Function &F) {
|
|
if (F.hasGC()) return false;
|
|
|
|
GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
|
|
|
|
OS << "GC roots for " << FD->getFunction().getName() << ":\n";
|
|
for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
|
|
RE = FD->roots_end(); RI != RE; ++RI)
|
|
OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
|
|
|
|
OS << "GC safe points for " << FD->getFunction().getName() << ":\n";
|
|
for (GCFunctionInfo::iterator PI = FD->begin(),
|
|
PE = FD->end(); PI != PE; ++PI) {
|
|
|
|
OS << "\t" << PI->Label->getName() << ": "
|
|
<< DescKind(PI->Kind) << ", live = {";
|
|
|
|
for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI),
|
|
RE = FD->live_end(PI);;) {
|
|
OS << " " << RI->Num;
|
|
if (++RI == RE)
|
|
break;
|
|
OS << ",";
|
|
}
|
|
|
|
OS << " }\n";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
char Deleter::ID = 0;
|
|
|
|
FunctionPass *llvm::createGCInfoDeleter() {
|
|
return new Deleter();
|
|
}
|
|
|
|
Deleter::Deleter() : FunctionPass(ID) {}
|
|
|
|
const char *Deleter::getPassName() const {
|
|
return "Delete Garbage Collector Information";
|
|
}
|
|
|
|
void Deleter::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesAll();
|
|
AU.addRequired<GCModuleInfo>();
|
|
}
|
|
|
|
bool Deleter::runOnFunction(Function &MF) {
|
|
return false;
|
|
}
|
|
|
|
bool Deleter::doFinalization(Module &M) {
|
|
GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
|
|
assert(GMI && "Deleter didn't require GCModuleInfo?!");
|
|
GMI->clear();
|
|
return false;
|
|
}
|