mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Factor GC metadata table assembly generation out of Collector in preparation for splitting AsmPrinter into its own library.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54880 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b68dc369e0
commit
c317a60c27
@ -18,11 +18,14 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
class Collector;
|
||||||
class Constant;
|
class Constant;
|
||||||
class ConstantArray;
|
class ConstantArray;
|
||||||
|
class GCMetadataPrinter;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
class GlobalAlias;
|
class GlobalAlias;
|
||||||
class MachineConstantPoolEntry;
|
class MachineConstantPoolEntry;
|
||||||
@ -48,7 +51,12 @@ namespace llvm {
|
|||||||
/// DebugVariable entries into the dwarf table. This is a short term hack
|
/// DebugVariable entries into the dwarf table. This is a short term hack
|
||||||
/// that ought be fixed soon.
|
/// that ought be fixed soon.
|
||||||
MachineModuleInfo *MMI;
|
MachineModuleInfo *MMI;
|
||||||
|
|
||||||
|
// GCMetadataPrinters - The garbage collection metadata printer table.
|
||||||
|
typedef DenseMap<Collector*,GCMetadataPrinter*> gcp_map_type;
|
||||||
|
typedef gcp_map_type::iterator gcp_iterator;
|
||||||
|
gcp_map_type GCMetadataPrinters;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Necessary for external weak linkage support
|
// Necessary for external weak linkage support
|
||||||
std::set<const GlobalValue*> ExtWeakSymbols;
|
std::set<const GlobalValue*> ExtWeakSymbols;
|
||||||
@ -91,6 +99,8 @@ namespace llvm {
|
|||||||
AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T);
|
AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~AsmPrinter();
|
||||||
|
|
||||||
/// SwitchToTextSection - Switch to the specified section of the executable
|
/// SwitchToTextSection - Switch to the specified section of the executable
|
||||||
/// if we are not already in it! If GV is non-null and if the global has an
|
/// if we are not already in it! If GV is non-null and if the global has an
|
||||||
/// explicitly requested section, we switch to the section indicated for the
|
/// explicitly requested section, we switch to the section indicated for the
|
||||||
@ -356,7 +366,7 @@ namespace llvm {
|
|||||||
void EmitXXStructorList(Constant *List);
|
void EmitXXStructorList(Constant *List);
|
||||||
void EmitConstantPool(unsigned Alignment, const char *Section,
|
void EmitConstantPool(unsigned Alignment, const char *Section,
|
||||||
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
|
std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
|
||||||
|
GCMetadataPrinter *GetOrCreateGCPrinter(Collector *C);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ namespace llvm {
|
|||||||
bool CustomWriteBarriers; //< Default is to insert stores.
|
bool CustomWriteBarriers; //< Default is to insert stores.
|
||||||
bool CustomRoots; //< Default is to pass through to backend.
|
bool CustomRoots; //< Default is to pass through to backend.
|
||||||
bool InitRoots; //< If set, roots are nulled during lowering.
|
bool InitRoots; //< If set, roots are nulled during lowering.
|
||||||
|
bool UsesMetadata; //< If set, backend must emit metadata tables.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Collector();
|
Collector();
|
||||||
@ -103,12 +104,9 @@ namespace llvm {
|
|||||||
/// is necessary for most collectors.
|
/// is necessary for most collectors.
|
||||||
bool initializeRoots() const { return InitRoots; }
|
bool initializeRoots() const { return InitRoots; }
|
||||||
|
|
||||||
|
/// If set, appropriate metadata tables must be emitted by the back-end
|
||||||
/// beginAssembly/finishAssembly - Emit module metadata as assembly code.
|
/// (assembler, JIT, or otherwise).
|
||||||
virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
bool usesMetadata() const { return UsesMetadata; }
|
||||||
const TargetAsmInfo &TAI);
|
|
||||||
virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
|
||||||
const TargetAsmInfo &TAI);
|
|
||||||
|
|
||||||
/// begin/end - Iterators for function metadata.
|
/// begin/end - Iterators for function metadata.
|
||||||
///
|
///
|
||||||
@ -128,6 +126,42 @@ namespace llvm {
|
|||||||
virtual bool performCustomLowering(Function &F);
|
virtual bool performCustomLowering(Function &F);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// GCMetadataPrinter - Emits GC metadata as assembly code.
|
||||||
|
class GCMetadataPrinter {
|
||||||
|
public:
|
||||||
|
typedef Collector::list_type list_type;
|
||||||
|
typedef Collector::iterator iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Collector *Coll;
|
||||||
|
|
||||||
|
friend class AsmPrinter;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// May only be subclassed.
|
||||||
|
GCMetadataPrinter();
|
||||||
|
|
||||||
|
// Do not implement.
|
||||||
|
GCMetadataPrinter(const GCMetadataPrinter &);
|
||||||
|
GCMetadataPrinter &operator=(const GCMetadataPrinter &);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Collector &getCollector() { return *Coll; }
|
||||||
|
const Module &getModule() const { return Coll->getModule(); }
|
||||||
|
|
||||||
|
iterator begin() { return Coll->begin(); }
|
||||||
|
iterator end() { return Coll->end(); }
|
||||||
|
|
||||||
|
/// beginAssembly/finishAssembly - Emit module metadata as assembly code.
|
||||||
|
virtual void beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
|
const TargetAsmInfo &TAI);
|
||||||
|
|
||||||
|
virtual void finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
|
const TargetAsmInfo &TAI);
|
||||||
|
|
||||||
|
virtual ~GCMetadataPrinter();
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,11 +20,16 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class Collector;
|
class Collector;
|
||||||
|
class GCMetadataPrinter;
|
||||||
|
|
||||||
/// The collector registry uses all the defaults from Registry.
|
/// The collector registry uses all the defaults from Registry.
|
||||||
///
|
///
|
||||||
typedef Registry<Collector> CollectorRegistry;
|
typedef Registry<Collector> CollectorRegistry;
|
||||||
|
|
||||||
|
/// The GC assembly printer registry uses all the defaults from Registry.
|
||||||
|
///
|
||||||
|
typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
|
||||||
|
|
||||||
/// FIXME: Collector instances are not useful on their own. These no longer
|
/// FIXME: Collector instances are not useful on their own. These no longer
|
||||||
/// serve any purpose except to link in the plugins.
|
/// serve any purpose except to link in the plugins.
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/CodeGen/Collector.h"
|
#include "llvm/CodeGen/Collector.h"
|
||||||
#include "llvm/CodeGen/CollectorMetadata.h"
|
#include "llvm/CodeGen/CollectorMetadata.h"
|
||||||
|
#include "llvm/CodeGen/Collectors.h"
|
||||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
@ -43,6 +44,12 @@ AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
|
|||||||
IsInTextSection(false)
|
IsInTextSection(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
AsmPrinter::~AsmPrinter() {
|
||||||
|
for (gcp_iterator I = GCMetadataPrinters.begin(),
|
||||||
|
E = GCMetadataPrinters.end(); I != E; ++I)
|
||||||
|
delete I->second;
|
||||||
|
}
|
||||||
|
|
||||||
std::string AsmPrinter::getSectionForFunction(const Function &F) const {
|
std::string AsmPrinter::getSectionForFunction(const Function &F) const {
|
||||||
return TAI->getTextSection();
|
return TAI->getTextSection();
|
||||||
}
|
}
|
||||||
@ -113,7 +120,8 @@ bool AsmPrinter::doInitialization(Module &M) {
|
|||||||
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
|
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
|
||||||
for (CollectorModuleMetadata::iterator I = CMM->begin(),
|
for (CollectorModuleMetadata::iterator I = CMM->begin(),
|
||||||
E = CMM->end(); I != E; ++I)
|
E = CMM->end(); I != E; ++I)
|
||||||
(*I)->beginAssembly(O, *this, *TAI);
|
if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*I))
|
||||||
|
GCP->beginAssembly(O, *this, *TAI);
|
||||||
|
|
||||||
if (!M.getModuleInlineAsm().empty())
|
if (!M.getModuleInlineAsm().empty())
|
||||||
O << TAI->getCommentString() << " Start of file scope inline assembly\n"
|
O << TAI->getCommentString() << " Start of file scope inline assembly\n"
|
||||||
@ -188,7 +196,8 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||||||
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
|
assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
|
||||||
for (CollectorModuleMetadata::iterator I = CMM->end(),
|
for (CollectorModuleMetadata::iterator I = CMM->end(),
|
||||||
E = CMM->begin(); I != E; )
|
E = CMM->begin(); I != E; )
|
||||||
(*--I)->finishAssembly(O, *this, *TAI);
|
if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*--I))
|
||||||
|
GCP->finishAssembly(O, *this, *TAI);
|
||||||
|
|
||||||
// If we don't have any trampolines, then we don't require stack memory
|
// If we don't have any trampolines, then we don't require stack memory
|
||||||
// to be executable. Some targets have a directive to declare this.
|
// to be executable. Some targets have a directive to declare this.
|
||||||
@ -1456,3 +1465,27 @@ void AsmPrinter::printVisibility(const std::string& Name,
|
|||||||
O << Directive << Name << '\n';
|
O << Directive << Name << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(Collector *C) {
|
||||||
|
if (!C->usesMetadata())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
gcp_iterator GCPI = GCMetadataPrinters.find(C);
|
||||||
|
if (GCPI != GCMetadataPrinters.end())
|
||||||
|
return GCPI->second;
|
||||||
|
|
||||||
|
const char *Name = C->getName().c_str();
|
||||||
|
|
||||||
|
for (GCMetadataPrinterRegistry::iterator
|
||||||
|
I = GCMetadataPrinterRegistry::begin(),
|
||||||
|
E = GCMetadataPrinterRegistry::end(); I != E; ++I)
|
||||||
|
if (strcmp(Name, I->getName()) == 0) {
|
||||||
|
GCMetadataPrinter *GCP = I->instantiate();
|
||||||
|
GCP->Coll = C;
|
||||||
|
GCMetadataPrinters.insert(std::make_pair(C, GCP));
|
||||||
|
return GCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "no GCMetadataPrinter registered for collector: " << Name << "\n";
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
@ -92,7 +92,8 @@ Collector::Collector() :
|
|||||||
CustomReadBarriers(false),
|
CustomReadBarriers(false),
|
||||||
CustomWriteBarriers(false),
|
CustomWriteBarriers(false),
|
||||||
CustomRoots(false),
|
CustomRoots(false),
|
||||||
InitRoots(true)
|
InitRoots(true),
|
||||||
|
UsesMetadata(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Collector::~Collector() {
|
Collector::~Collector() {
|
||||||
@ -110,16 +111,6 @@ bool Collector::performCustomLowering(Function &F) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collector::beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
|
||||||
const TargetAsmInfo &TAI) {
|
|
||||||
// Default is no action.
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collector::finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
|
||||||
const TargetAsmInfo &TAI) {
|
|
||||||
// Default is no action.
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) {
|
CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) {
|
||||||
CollectorMetadata *CM = new CollectorMetadata(F, *this);
|
CollectorMetadata *CM = new CollectorMetadata(F, *this);
|
||||||
Functions.push_back(CM);
|
Functions.push_back(CM);
|
||||||
@ -128,6 +119,22 @@ CollectorMetadata *Collector::insertFunctionMetadata(const Function &F) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
GCMetadataPrinter::GCMetadataPrinter() { }
|
||||||
|
|
||||||
|
GCMetadataPrinter::~GCMetadataPrinter() { }
|
||||||
|
|
||||||
|
void GCMetadataPrinter::beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
|
const TargetAsmInfo &TAI) {
|
||||||
|
// Default is no action.
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCMetadataPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
|
const TargetAsmInfo &TAI) {
|
||||||
|
// Default is no action.
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
FunctionPass *llvm::createGCLoweringPass() {
|
FunctionPass *llvm::createGCLoweringPass() {
|
||||||
return new LowerIntrinsics();
|
return new LowerIntrinsics();
|
||||||
}
|
}
|
||||||
|
@ -19,3 +19,10 @@ template<> CollectorRegistry::node *CollectorRegistry::Head = 0;
|
|||||||
template<> CollectorRegistry::node *CollectorRegistry::Tail = 0;
|
template<> CollectorRegistry::node *CollectorRegistry::Tail = 0;
|
||||||
template<> CollectorRegistry::listener *CollectorRegistry::ListenerHead = 0;
|
template<> CollectorRegistry::listener *CollectorRegistry::ListenerHead = 0;
|
||||||
template<> CollectorRegistry::listener *CollectorRegistry::ListenerTail = 0;
|
template<> CollectorRegistry::listener *CollectorRegistry::ListenerTail = 0;
|
||||||
|
|
||||||
|
template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Head = 0;
|
||||||
|
template<> GCMetadataPrinterRegistry::node *GCMetadataPrinterRegistry::Tail = 0;
|
||||||
|
template<> GCMetadataPrinterRegistry::listener *
|
||||||
|
GCMetadataPrinterRegistry::ListenerHead = 0;
|
||||||
|
template<> GCMetadataPrinterRegistry::listener *
|
||||||
|
GCMetadataPrinterRegistry::ListenerTail = 0;
|
||||||
|
@ -27,7 +27,10 @@ namespace {
|
|||||||
class VISIBILITY_HIDDEN OcamlCollector : public Collector {
|
class VISIBILITY_HIDDEN OcamlCollector : public Collector {
|
||||||
public:
|
public:
|
||||||
OcamlCollector();
|
OcamlCollector();
|
||||||
|
};
|
||||||
|
|
||||||
|
class VISIBILITY_HIDDEN OcamlGCMetadataPrinter : public GCMetadataPrinter {
|
||||||
|
public:
|
||||||
void beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
void beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
const TargetAsmInfo &TAI);
|
const TargetAsmInfo &TAI);
|
||||||
|
|
||||||
@ -40,6 +43,9 @@ namespace {
|
|||||||
static CollectorRegistry::Add<OcamlCollector>
|
static CollectorRegistry::Add<OcamlCollector>
|
||||||
X("ocaml", "ocaml 3.10-compatible collector");
|
X("ocaml", "ocaml 3.10-compatible collector");
|
||||||
|
|
||||||
|
static GCMetadataPrinterRegistry::Add<OcamlGCMetadataPrinter>
|
||||||
|
Y("ocaml", "ocaml 3.10-compatible collector");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void EmitCamlGlobal(const Module &M, std::ostream &OS, AsmPrinter &AP,
|
static void EmitCamlGlobal(const Module &M, std::ostream &OS, AsmPrinter &AP,
|
||||||
@ -68,10 +74,11 @@ Collector *llvm::createOcamlCollector() {
|
|||||||
|
|
||||||
OcamlCollector::OcamlCollector() {
|
OcamlCollector::OcamlCollector() {
|
||||||
NeededSafePoints = 1 << GC::PostCall;
|
NeededSafePoints = 1 << GC::PostCall;
|
||||||
|
UsesMetadata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OcamlCollector::beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
void OcamlGCMetadataPrinter::beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
const TargetAsmInfo &TAI) {
|
const TargetAsmInfo &TAI) {
|
||||||
AP.SwitchToTextSection(TAI.getTextSection());
|
AP.SwitchToTextSection(TAI.getTextSection());
|
||||||
EmitCamlGlobal(getModule(), OS, AP, TAI, "code_begin");
|
EmitCamlGlobal(getModule(), OS, AP, TAI, "code_begin");
|
||||||
|
|
||||||
@ -95,8 +102,8 @@ void OcamlCollector::beginAssembly(std::ostream &OS, AsmPrinter &AP,
|
|||||||
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
|
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
|
||||||
/// either condition is detected in a function which uses the collector.
|
/// either condition is detected in a function which uses the collector.
|
||||||
///
|
///
|
||||||
void OcamlCollector::finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
void OcamlGCMetadataPrinter::finishAssembly(std::ostream &OS, AsmPrinter &AP,
|
||||||
const TargetAsmInfo &TAI) {
|
const TargetAsmInfo &TAI) {
|
||||||
const char *AddressDirective;
|
const char *AddressDirective;
|
||||||
int AddressAlignLog;
|
int AddressAlignLog;
|
||||||
if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) {
|
if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user