Skip to content

Commit

Permalink
GCStrategy should not own GCFunctionInfo
Browse files Browse the repository at this point in the history
This change moves the ownership and access of GCFunctionInfo (the object which describes the safepoints associated with a safepoint under GCRoot) to GCModuleInfo. Previously, this was owned by GCStrategy which was in turned owned by GCModuleInfo. This made GCStrategy module specific which is 'surprising' given it's name and other purposes.

There's a few more changes needed, but we're getting towards the point we can reuse GCStrategy for gc.statepoint as well.

p.s. The style of this code ends up being a mess. I was trying to move code around without otherwise changing much. Once I get the ownership structure rearranged, I will go through and fixup spacing, naming, comments etc.

Differential Revision: http://reviews.llvm.org/D6587



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223994 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
preames committed Dec 11, 2014
1 parent a40cc0b commit 5e62b84
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 64 deletions.
26 changes: 21 additions & 5 deletions include/llvm/CodeGen/GCMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,37 @@ namespace llvm {
size_t live_size(const iterator &p) const { return roots_size(); }
};


/// An analysis pass which caches information about the entire Module.
/// Records both the function level information used by GCRoots and a
/// cache of the 'active' gc strategy objects for the current Module.
class GCModuleInfo : public ImmutablePass {
typedef StringMap<GCStrategy*> strategy_map_type;
typedef std::vector<std::unique_ptr<GCStrategy>> list_type;
typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;

strategy_map_type StrategyMap;
list_type StrategyList;
finfo_map_type FInfoMap;

GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);

public:
/// List of per function info objects. In theory, Each of these
/// may be associated with a different GC.
typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec;

FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
FuncInfoVec::iterator funcinfo_end() { return Functions.end(); }


private:
/// Owning list of all GCFunctionInfos associated with this Module
FuncInfoVec Functions;

/// Non-owning map to bypass linear search when finding the GCFunctionInfo
/// associated with a particular Function.
typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
finfo_map_type FInfoMap;
public:

typedef list_type::const_iterator iterator;

static char ID;
Expand All @@ -192,8 +207,9 @@ namespace llvm {
iterator begin() const { return StrategyList.begin(); }
iterator end() const { return StrategyList.end(); }

/// get - Look up function metadata.
///
/// get - Look up function metadata. This is currently assumed
/// have the side effect of initializing the associated GCStrategy. That
/// will soon change.
GCFunctionInfo &getFunctionInfo(const Function &F);
};

Expand Down
24 changes: 10 additions & 14 deletions include/llvm/CodeGen/GCMetadataPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,11 @@ namespace llvm {
/// defaults from Registry.
typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;

/// GCMetadataPrinter - Emits GC metadata as assembly code.
///
/// GCMetadataPrinter - Emits GC metadata as assembly code. Instances are
/// created, managed, and owned by the AsmPrinter.
class GCMetadataPrinter {
public:
typedef GCStrategy::list_type list_type;
typedef GCStrategy::iterator iterator;

private:
GCStrategy *S;

friend class AsmPrinter;

protected:
Expand All @@ -56,13 +51,14 @@ namespace llvm {
public:
GCStrategy &getStrategy() { return *S; }

/// begin/end - Iterate over the collected function metadata.
iterator begin() { return S->begin(); }
iterator end() { return S->end(); }

/// beginAssembly/finishAssembly - Emit module metadata as assembly code.
virtual void beginAssembly(Module &M, AsmPrinter &AP);
virtual void finishAssembly(Module &M, AsmPrinter &AP);
/// Called before the assembly for the module is generated by
/// the AsmPrinter (but after target specific hooks.)
virtual void beginAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) {}
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) {}

virtual ~GCMetadataPrinter();
};
Expand Down
15 changes: 0 additions & 15 deletions include/llvm/CodeGen/GCStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,10 @@ namespace llvm {
/// through the GCModuleInfo analysis pass. They are owned by the analysis
/// pass and recreated every time that pass is invalidated.
class GCStrategy {
public:
typedef std::vector<std::unique_ptr<GCFunctionInfo>> list_type;
typedef list_type::iterator iterator;

private:
friend class GCModuleInfo;
std::string Name;

list_type Functions;

protected:
unsigned NeededSafePoints; ///< Bitmask of required safe points.
bool CustomReadBarriers; ///< Default is to insert loads.
Expand Down Expand Up @@ -126,15 +120,6 @@ namespace llvm {
/// the back-end (assembler, JIT, or otherwise).
bool usesMetadata() const { return UsesMetadata; }

/// begin/end - Iterators for function metadata.
///
iterator begin() { return Functions.begin(); }
iterator end() { return Functions.end(); }

/// insertFunctionMetadata - Creates metadata for a function.
///
GCFunctionInfo *insertFunctionInfo(const Function &F);

/// initializeCustomLowering/performCustomLowering - If any of the actions
/// are set to custom, performCustomLowering must be overriden to transform
/// the corresponding actions to LLVM IR. initializeCustomLowering is
Expand Down
4 changes: 2 additions & 2 deletions lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ bool AsmPrinter::doInitialization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (auto &I : *MI)
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
MP->beginAssembly(M, *this);
MP->beginAssembly(M, *MI, *this);

// Emit module-level inline asm if it exists.
if (!M.getModuleInlineAsm().empty()) {
Expand Down Expand Up @@ -985,7 +985,7 @@ bool AsmPrinter::doFinalization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(**--I))
MP->finishAssembly(M, *this);
MP->finishAssembly(M, *MI, *this);

// Emit llvm.ident metadata in an '.ident' directive.
EmitModuleIdents(M);
Expand Down
17 changes: 10 additions & 7 deletions lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ namespace {

class ErlangGCPrinter : public GCMetadataPrinter {
public:
void beginAssembly(Module &M, AsmPrinter &AP) override;
void finishAssembly(Module &M, AsmPrinter &AP) override;
void finishAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) override;
};

}
Expand All @@ -47,9 +47,8 @@ X("erlang", "erlang-compatible garbage collector");

void llvm::linkErlangGCPrinter() { }

void ErlangGCPrinter::beginAssembly(Module &M, AsmPrinter &AP) { }

void ErlangGCPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) {
MCStreamer &OS = AP.OutStreamer;
unsigned IntPtrSize =
AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize();
Expand All @@ -60,9 +59,13 @@ void ErlangGCPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
SectionKind::getDataRel()));

// For each function...
for (iterator FI = begin(), FE = end(); FI != FE; ++FI) {
for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(),
IE = Info.funcinfo_end();
FI != IE; ++FI) {
GCFunctionInfo &MD = **FI;

if (MD.getStrategy().getName() != getStrategy().getName())
// this function is managed by some other GC
continue;
/** A compact GC layout. Emit this data structure:
*
* struct {
Expand Down
24 changes: 18 additions & 6 deletions lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ namespace {

class OcamlGCMetadataPrinter : public GCMetadataPrinter {
public:
void beginAssembly(Module &M, AsmPrinter &AP) override;
void finishAssembly(Module &M, AsmPrinter &AP) override;
void beginAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) override;
void finishAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) override;
};

}
Expand Down Expand Up @@ -67,7 +69,8 @@ static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
AP.OutStreamer.EmitLabel(Sym);
}

void OcamlGCMetadataPrinter::beginAssembly(Module &M, AsmPrinter &AP) {
void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) {
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
EmitCamlGlobal(M, AP, "code_begin");

Expand All @@ -91,7 +94,8 @@ void OcamlGCMetadataPrinter::beginAssembly(Module &M, AsmPrinter &AP) {
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
void OcamlGCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
AsmPrinter &AP) {
unsigned IntPtrSize =
AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize();

Expand All @@ -108,8 +112,12 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
EmitCamlGlobal(M, AP, "frametable");

int NumDescriptors = 0;
for (iterator I = begin(), IE = end(); I != IE; ++I) {
for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
IE = Info.funcinfo_end(); I != IE; ++I) {
GCFunctionInfo &FI = **I;
if (FI.getStrategy().getName() != getStrategy().getName())
// this function is managed by some other GC
continue;
for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
NumDescriptors++;
}
Expand All @@ -122,8 +130,12 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
AP.EmitInt16(NumDescriptors);
AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);

for (iterator I = begin(), IE = end(); I != IE; ++I) {
for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
IE = Info.funcinfo_end(); I != IE; ++I) {
GCFunctionInfo &FI = **I;
if (FI.getStrategy().getName() != getStrategy().getName())
// this function is managed by some other GC
continue;

uint64_t FrameSize = FI.getFrameSize();
if (FrameSize >= 1<<16) {
Expand Down
4 changes: 3 additions & 1 deletion lib/CodeGen/GCMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,14 @@ GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
return *I->second;

GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC());
GCFunctionInfo *GFI = S->insertFunctionInfo(F);
Functions.push_back(make_unique<GCFunctionInfo>(F, *S));
GCFunctionInfo *GFI = Functions.back().get();
FInfoMap[&F] = GFI;
return *GFI;
}

void GCModuleInfo::clear() {
Functions.clear();
FInfoMap.clear();
StrategyMap.clear();
StrategyList.clear();
Expand Down
8 changes: 0 additions & 8 deletions lib/CodeGen/GCMetadataPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,3 @@ using namespace llvm;
GCMetadataPrinter::GCMetadataPrinter() { }

GCMetadataPrinter::~GCMetadataPrinter() { }

void GCMetadataPrinter::beginAssembly(Module &M, AsmPrinter &AP) {
// Default is no action.
}

void GCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) {
// Default is no action.
}
6 changes: 0 additions & 6 deletions lib/CodeGen/GCStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ bool GCStrategy::findCustomSafePoints(GCFunctionInfo& FI, MachineFunction &F) {
llvm_unreachable(nullptr);
}


GCFunctionInfo *GCStrategy::insertFunctionInfo(const Function &F) {
Functions.push_back(make_unique<GCFunctionInfo>(F, *this));
return Functions.back().get();
}

// -----------------------------------------------------------------------------

INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering",
Expand Down

0 comments on commit 5e62b84

Please sign in to comment.