llvm: Update llvm to use new gcnoteroot infrastructure
This commit is contained in:
parent
92470336dd
commit
59abf93b79
4 changed files with 2 additions and 236 deletions
|
@ -12,8 +12,7 @@ LLVM_EXTRA_INCDIRS_$(1)= -iquote $(S)src/llvm/include \
|
||||||
-iquote llvm/$(1)/include
|
-iquote llvm/$(1)/include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustGCMetadataPrinter.cpp \
|
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustWrapper.cpp)
|
||||||
RustGCStrategy.cpp RustWrapper.cpp)
|
|
||||||
|
|
||||||
# Behind an ifdef for now since this requires a patched LLVM.
|
# Behind an ifdef for now since this requires a patched LLVM.
|
||||||
ifdef CFG_STACK_GROWTH
|
ifdef CFG_STACK_GROWTH
|
||||||
|
|
2
src/llvm
2
src/llvm
|
@ -1 +1 @@
|
||||||
Subproject commit 4119fda4c6c4df372bd6edbbb08d48c7941577b5
|
Subproject commit 8b035b5fe83ca15df171e581681bbc9cbd7e2ae0
|
|
@ -1,202 +0,0 @@
|
||||||
//===-- RustGCPrinter.cpp - Rust garbage collection map printer -----------===
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===
|
|
||||||
//
|
|
||||||
// This file defines the emitter for the Rust garbage collection stack maps.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===
|
|
||||||
|
|
||||||
#include "llvm/Constants.h"
|
|
||||||
#include "llvm/DerivedTypes.h"
|
|
||||||
#include "llvm/Module.h"
|
|
||||||
#include "llvm/CodeGen/GCs.h"
|
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
|
||||||
#include "llvm/CodeGen/GCMetadataPrinter.h"
|
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
|
||||||
#include "llvm/MC/MCContext.h"
|
|
||||||
#include "llvm/MC/MCSymbol.h"
|
|
||||||
#include "llvm/MC/MCStreamer.h"
|
|
||||||
#include "llvm/Target/Mangler.h"
|
|
||||||
#include "llvm/Target/TargetData.h"
|
|
||||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
|
||||||
#include "llvm/Target/TargetMachine.h"
|
|
||||||
#include "llvm/ADT/SmallString.h"
|
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
|
||||||
#include "llvm/Support/FormattedStream.h"
|
|
||||||
#include <cctype>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
enum RustGCMetaType {
|
|
||||||
RGCMT_DestIndex, // Type descriptor index -> type descriptor.
|
|
||||||
RGCMT_SrcIndex, // Value -> type descriptor index.
|
|
||||||
RGCMT_Static // Value with static type descriptor.
|
|
||||||
};
|
|
||||||
|
|
||||||
class RustGCMetadataPrinter : public GCMetadataPrinter {
|
|
||||||
private:
|
|
||||||
std::pair<RustGCMetaType,const Constant *>
|
|
||||||
GetGCMetadataForRoot(const GCRoot &Root);
|
|
||||||
void EmitGCMetadata(AsmPrinter &AP, MCStreamer &Out, GCRoot &Root);
|
|
||||||
bool HandleDestIndex(const GCRoot &Root);
|
|
||||||
public:
|
|
||||||
void beginAssembly(AsmPrinter &AP) {};
|
|
||||||
void finishAssembly(AsmPrinter &AP);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrderedSymbol {
|
|
||||||
unsigned Index;
|
|
||||||
MCSymbol *Sym;
|
|
||||||
|
|
||||||
OrderedSymbol(unsigned I, MCSymbol *S) : Index(I), Sym(S) {}
|
|
||||||
|
|
||||||
static OrderedSymbol make(unsigned I, MCSymbol *S) {
|
|
||||||
OrderedSymbol OS(I, S);
|
|
||||||
return OS;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static GCMetadataPrinterRegistry::Add<RustGCMetadataPrinter>
|
|
||||||
X("rust", "Rust GC metadata printer");
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector< std::pair< MCSymbol *,std::vector<GCRoot> > > RootMap;
|
|
||||||
|
|
||||||
std::pair<RustGCMetaType,const Constant *>
|
|
||||||
RustGCMetadataPrinter::GetGCMetadataForRoot(const GCRoot &Root) {
|
|
||||||
const GlobalVariable *GCMetaVar =
|
|
||||||
cast<const GlobalVariable>(Root.Metadata->stripPointerCasts());
|
|
||||||
|
|
||||||
const Constant *GCMetaInit = GCMetaVar->getInitializer();
|
|
||||||
if (isa<ConstantAggregateZero>(GCMetaInit)) {
|
|
||||||
// "zeroinitializer": expand to (0, 0).
|
|
||||||
IntegerType *I32 = IntegerType::get(GCMetaInit->getContext(), 32);
|
|
||||||
ConstantInt *Zero = ConstantInt::get(I32, 0);
|
|
||||||
return std::make_pair(RGCMT_DestIndex, Zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstantStruct *GCMeta =
|
|
||||||
cast<const ConstantStruct>(GCMetaVar->getInitializer());
|
|
||||||
|
|
||||||
RustGCMetaType GCMetaType = (RustGCMetaType)
|
|
||||||
(cast<const ConstantInt>(GCMeta->getOperand(0))->getZExtValue());
|
|
||||||
const Constant *Payload = cast<const Constant>(GCMeta->getOperand(1));
|
|
||||||
return std::make_pair(GCMetaType, Payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RustGCMetadataPrinter::EmitGCMetadata(AsmPrinter &AP, MCStreamer &Out,
|
|
||||||
GCRoot &Root) {
|
|
||||||
int WordSize = AP.TM.getTargetData()->getPointerSize();
|
|
||||||
|
|
||||||
std::pair<RustGCMetaType,const Constant *> Pair =
|
|
||||||
GetGCMetadataForRoot(Root);
|
|
||||||
const GlobalValue *Tydesc = 0;
|
|
||||||
|
|
||||||
switch (Pair.first) {
|
|
||||||
case RGCMT_DestIndex: // Dest index.
|
|
||||||
assert(0 && "Dest index should not be here!");
|
|
||||||
case RGCMT_SrcIndex:
|
|
||||||
// TODO: Use the mapping to find the tydesc frame offset.
|
|
||||||
Out.EmitIntValue(1, WordSize, 0);
|
|
||||||
Out.EmitIntValue(0, WordSize, 0);
|
|
||||||
return;
|
|
||||||
case 2: // Static type descriptor.
|
|
||||||
Out.EmitIntValue(0, WordSize, 0);
|
|
||||||
Tydesc = cast<const GlobalValue>(Pair.second);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MCSymbol *TydescSym = AP.Mang->getSymbol(Tydesc);
|
|
||||||
Out.EmitSymbolValue(TydescSym, WordSize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Records the destination index of a type descriptor in the type descriptor
|
|
||||||
// map, if this GC root is a destination index. Returns true if the GC root is
|
|
||||||
// a destination index and false otherwise.
|
|
||||||
bool RustGCMetadataPrinter::HandleDestIndex(const GCRoot &Root) {
|
|
||||||
std::pair<RustGCMetaType,const Constant *> Pair =
|
|
||||||
GetGCMetadataForRoot(Root);
|
|
||||||
return Pair.first == RGCMT_DestIndex; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void RustGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
|
|
||||||
MCStreamer &Out = AP.OutStreamer;
|
|
||||||
|
|
||||||
// Use the data section.
|
|
||||||
Out.SwitchSection(AP.getObjFileLowering().getDataSection());
|
|
||||||
|
|
||||||
// Iterate over each function.
|
|
||||||
RootMap Map;
|
|
||||||
|
|
||||||
iterator FI = begin(), FE = end();
|
|
||||||
while (FI != FE) {
|
|
||||||
GCFunctionInfo &GCFI = **FI;
|
|
||||||
|
|
||||||
// Iterate over each safe point.
|
|
||||||
GCFunctionInfo::iterator SPI = GCFI.begin(), SPE = GCFI.end();
|
|
||||||
while (SPI != SPE) {
|
|
||||||
std::vector<GCRoot> Roots;
|
|
||||||
|
|
||||||
// Iterate over each live root.
|
|
||||||
GCFunctionInfo::live_iterator LI = GCFI.live_begin(SPI);
|
|
||||||
GCFunctionInfo::live_iterator LE = GCFI.live_end(SPI);
|
|
||||||
while (LI != LE) {
|
|
||||||
if (!HandleDestIndex(*LI))
|
|
||||||
Roots.push_back(*LI);
|
|
||||||
++LI;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.push_back(std::make_pair(SPI->Label, Roots));
|
|
||||||
++SPI;
|
|
||||||
}
|
|
||||||
++FI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out the map.
|
|
||||||
Out.AddBlankLine();
|
|
||||||
|
|
||||||
int WordSize = AP.TM.getTargetData()->getPointerSize();
|
|
||||||
|
|
||||||
MCSymbol *SafePointSym = AP.GetExternalSymbolSymbol("rust_gc_safe_points");
|
|
||||||
Out.EmitSymbolAttribute(SafePointSym, MCSA_Global);
|
|
||||||
Out.EmitLabel(SafePointSym);
|
|
||||||
Out.EmitIntValue(Map.size(), WordSize, 0);
|
|
||||||
|
|
||||||
std::vector<MCSymbol *> FrameMapLabels;
|
|
||||||
|
|
||||||
RootMap::iterator MI = Map.begin(), ME = Map.end();
|
|
||||||
unsigned i = 0;
|
|
||||||
while (MI != ME) {
|
|
||||||
Out.EmitSymbolValue(MI->first, WordSize, 0);
|
|
||||||
MCSymbol *FrameMapLabel = AP.GetTempSymbol("rust_frame_map_label", i);
|
|
||||||
Out.EmitSymbolValue(FrameMapLabel, WordSize, 0);
|
|
||||||
FrameMapLabels.push_back(FrameMapLabel);
|
|
||||||
++MI, ++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
MI = Map.begin(), i = 0;
|
|
||||||
while (MI != ME) {
|
|
||||||
Out.EmitLabel(FrameMapLabels[i]);
|
|
||||||
|
|
||||||
std::vector<GCRoot> &Roots = MI->second;
|
|
||||||
Out.EmitIntValue(Roots.size(), WordSize, 0);
|
|
||||||
|
|
||||||
std::vector<GCRoot>::iterator RI = Roots.begin(), RE = Roots.end();
|
|
||||||
while (RI != RE) {
|
|
||||||
Out.EmitIntValue(RI->StackOffset, WordSize, 0);
|
|
||||||
EmitGCMetadata(AP, Out, *RI);
|
|
||||||
++RI;
|
|
||||||
}
|
|
||||||
|
|
||||||
++MI, ++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
//===- RustGCStrategy.cpp - Rust garbage collection strategy ----*- C++ -*-===
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===
|
|
||||||
//
|
|
||||||
// This file defines the garbage collection strategy for Rust.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===
|
|
||||||
|
|
||||||
#include "llvm/CodeGen/GCs.h"
|
|
||||||
#include "llvm/CodeGen/GCStrategy.h"
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
class RustGCStrategy : public GCStrategy {
|
|
||||||
public:
|
|
||||||
RustGCStrategy() {
|
|
||||||
NeededSafePoints = 1 << GC::PostCall;
|
|
||||||
UsesMetadata = true;
|
|
||||||
InitRoots = false; // LLVM crashes with this on due to bitcasts.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static GCRegistry::Add<RustGCStrategy>
|
|
||||||
RustGCStrategyRegistration("rust", "Rust GC");
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue