[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though

This commit is contained in:
Tomas Lindquist Olsen
2008-01-17 03:15:12 +01:00
parent 4f977e3cec
commit 5652546986
40 changed files with 900 additions and 548 deletions

View File

@@ -45,7 +45,7 @@ namespace llvm
class ConstantStruct;
class GlobalVariable;
}
struct IRStruct;
struct IrStruct;
struct DUnion;
struct AggregateDeclaration : ScopeDsymbol
@@ -110,7 +110,7 @@ struct AggregateDeclaration : ScopeDsymbol
llvm::Constant* llvmConstClass;
bool llvmHasUnions;
DUnion* llvmUnion;
IRStruct* llvmIRStruct;
IrStruct* llvmIrStruct;
bool llvmClassDeclared;
bool llvmClassDefined;

View File

@@ -549,12 +549,10 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
onstack = 0;
canassign = 0;
value = NULL;
llvmNestedIndex = -1;
llvmFieldIndex = -1;
llvmFieldIndexOffset = 0;
llvmNeedsStorage = false;
llvmConstInit = NULL;
llvmIRGlobal = NULL;
irGlobal = NULL;
irLocal = NULL;
irField = NULL;
needsStorage = false;
}
Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
@@ -1060,7 +1058,7 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
fdthis->getLevel(loc, fdv);
nestedref = 1;
fdv->nestedFrameRef = 1;
fdv->llvmNestedVars.insert(this);
fdv->nestedVars.insert(this);
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
}
}

View File

@@ -24,8 +24,11 @@
namespace llvm {
class Value;
}
struct IRFunction;
struct IRGlobal;
struct IrFunction;
struct IrVar;
struct IrGlobal;
struct IrLocal;
struct IrField;
struct Expression;
struct Statement;
@@ -261,12 +264,13 @@ struct VarDeclaration : Declaration
VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
// LLVMDC
int llvmNestedIndex;
int llvmFieldIndex;
size_t llvmFieldIndexOffset;
bool llvmNeedsStorage;
llvm::Constant* llvmConstInit;
IRGlobal* llvmIRGlobal;
IrGlobal* irGlobal;
IrLocal* irLocal;
IrField* irField;
bool needsStorage;
IrVar* getIrVar();
llvm::Value*& getIrValue();
};
/**************************************************************/
@@ -609,16 +613,9 @@ struct FuncDeclaration : Declaration
FuncDeclaration *isFuncDeclaration() { return this; }
// llvmdc stuff
bool llvmQueued;
llvm::Value* llvmThisVar;
std::set<VarDeclaration*> llvmNestedVars;
llvm::Value* llvmNested;
llvm::Value* llvmArguments;
llvm::Value* llvmArgPtr;
llvm::Constant* llvmDwarfSubProgram;
bool llvmRunTimeHack;
IRFunction* llvmIRFunc;
llvm::Value* llvmRetArg;
bool runTimeHack;
IrFunction* irFunc;
std::set<VarDeclaration*> nestedVars;
};
struct FuncAliasDeclaration : FuncDeclaration

View File

@@ -43,10 +43,12 @@ Dsymbol::Dsymbol()
this->isym = NULL;
this->loc = 0;
this->comment = NULL;
this->llvmInternal = LLVMnone;
this->llvmInternal1 = NULL;
this->llvmInternal2 = NULL;
this->llvmValue = NULL;
//this->llvmValue = NULL;
this->llvmDModule = NULL;
this->llvmResolved = false;
@@ -65,10 +67,12 @@ Dsymbol::Dsymbol(Identifier *ident)
this->isym = NULL;
this->loc = 0;
this->comment = NULL;
this->llvmInternal = LLVMnone;
this->llvmInternal1 = NULL;
this->llvmInternal2 = NULL;
this->llvmValue = NULL;
//this->llvmValue = NULL;
this->llvmDModule = NULL;
this->llvmResolved = false;

View File

@@ -220,7 +220,7 @@ struct Dsymbol : Object
char* llvmInternal1;
char* llvmInternal2;
llvm::Value* llvmValue;
//llvm::Value* llvmValue;
Module* llvmDModule;
bool llvmResolved;

View File

@@ -3456,7 +3456,7 @@ Expression *SymOffExp::semantic(Scope *sc)
if (v)
{
v->checkNestedReference(sc, loc);
v->llvmNeedsStorage = true;
v->needsStorage = true;
}
return this;
}
@@ -3601,7 +3601,7 @@ Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
if (v && v->canassign == 0 &&
(var->isConst() || (global.params.Dversion > 1 && var->isFinal())))
error("cannot modify final variable '%s'", var->toChars());
v->llvmNeedsStorage = true;
v->needsStorage = true;
if (var->isCtorinit())
{ // It's only modifiable if inside the right constructor
@@ -5887,7 +5887,7 @@ Expression *AddrExp::semantic(Scope *sc)
}
else if (v)
{
v->llvmNeedsStorage = true;
v->needsStorage = true;
}
}
else if (e1->op == TOKarray)

View File

@@ -73,15 +73,9 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
nrvo_can = 1;
nrvo_var = NULL;
shidden = NULL;
llvmQueued = false;
llvmThisVar = NULL;
llvmNested = NULL;
llvmArguments = NULL;
llvmArgPtr = NULL;
llvmDwarfSubProgram = NULL;
llvmRunTimeHack = false;
llvmIRFunc = NULL;
llvmRetArg = NULL;
// llvmdc
runTimeHack = false;
irFunc = NULL;
}
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)

View File

@@ -1514,7 +1514,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
nm = name[n->ty == Twchar];
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1532,7 +1532,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
nm = name[n->ty == Twchar];
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1551,7 +1551,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
assert(size);
dup = (ident == Id::dup);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -1571,7 +1571,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(),
(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
arguments = new Expressions();
@@ -2273,7 +2273,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
@@ -2289,7 +2289,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
assert(size);
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
@@ -2304,7 +2304,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e);
@@ -2322,7 +2322,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
Expressions *arguments;
fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash);
fd->llvmRunTimeHack = true;
fd->runTimeHack = true;
ec = new VarExp(0, fd);
arguments = new Expressions();
arguments->push(e->addressOf(sc));

View File

@@ -1431,7 +1431,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
else
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
fdapply->llvmRunTimeHack = true;
fdapply->runTimeHack = true;
ec = new VarExp(0, fdapply);
Expressions *exps = new Expressions();
exps->push(aggr);
@@ -1473,7 +1473,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim);
assert(j < sizeof(fdname));
fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname);
fdapply->llvmRunTimeHack = true;
fdapply->runTimeHack = true;
ec = new VarExp(0, fdapply);
Expressions *exps = new Expressions();

View File

@@ -54,7 +54,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
llvmInProgress = false;
llvmHasUnions = false;
llvmUnion = NULL;
llvmIRStruct = NULL;
llvmIrStruct = NULL;
llvmClassDeclared = false;
llvmClassDefined = false;
}

View File

@@ -58,8 +58,8 @@ static llvm::Value* to_keyti(DValue* key)
assert(tid);
DtoResolveDsymbol(Type::typeinfo);
DtoForceDeclareDsymbol(tid);
assert(tid->llvmValue);
return tid->llvmValue;
assert(tid->irGlobal->value);
return tid->irGlobal->value;
}
/////////////////////////////////////////////////////////////////////////////////////

View File

@@ -671,13 +671,11 @@ static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, b
// pass element typeinfo ?
if (useti) {
TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration();
if (!ti->llvmValue) {
DtoForceConstInitDsymbol(ti);
}
Logger::cout() << "typeinfo decl: " << *ti->llvmValue << '\n';
DtoForceConstInitDsymbol(ti);
Logger::cout() << "typeinfo decl: " << *ti->getIrValue() << '\n';
pt = fn->getFunctionType()->getParamType(2);
args.push_back(DtoBitCast(ti->llvmValue, pt));
args.push_back(DtoBitCast(ti->getIrValue(), pt));
}
return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp");

View File

@@ -16,6 +16,8 @@
#include "gen/runtime.h"
#include "gen/dvalue.h"
#include "ir/irstruct.h"
//////////////////////////////////////////////////////////////////////////////////////////
static void LLVM_AddBaseClassData(BaseClasses* bcs)
@@ -24,9 +26,8 @@ static void LLVM_AddBaseClassData(BaseClasses* bcs)
for (int j=0; j<bcs->dim; j++)
{
BaseClass* bc = (BaseClass*)(bcs->data[j]);
assert(bc);
if (bc->base->isInterfaceDeclaration())
continue; // interfaces only has methods
continue; // interfaces only have methods
LLVM_AddBaseClassData(&bc->base->baseclasses);
@@ -38,14 +39,6 @@ static void LLVM_AddBaseClassData(BaseClasses* bcs)
VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
v->toObjFile();
}
/*for (int k=0; k < bc->base->members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
if (dsym->isVarDeclaration())
{
dsym->toObjFile();
}
}*/
}
}
@@ -63,11 +56,11 @@ void DtoResolveClass(ClassDeclaration* cd)
assert(cd->type->ty == Tclass);
TypeClass* ts = (TypeClass*)cd->type;
// make sure the IRStruct is created
IRStruct* irstruct = cd->llvmIRStruct;
// make sure the IrStruct is created
IrStruct* irstruct = cd->llvmIrStruct;
if (!irstruct) {
irstruct = new IRStruct(ts);
cd->llvmIRStruct = irstruct;
irstruct = new IrStruct(ts);
cd->llvmIrStruct = irstruct;
}
// resolve the base class
@@ -75,7 +68,7 @@ void DtoResolveClass(ClassDeclaration* cd)
DtoResolveClass(cd->baseClass);
}
// resolve interfaces
// resolve interface vtables
if (cd->vtblInterfaces) {
for (int i=0; i < cd->vtblInterfaces->dim; i++) {
BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
@@ -111,7 +104,7 @@ void DtoResolveClass(ClassDeclaration* cd)
fieldtypes.push_back(ivtblTy);
// add this interface to the map
IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get()));
IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get()));
irstruct->interfaces.insert(std::make_pair(id, iri));
}
@@ -140,14 +133,14 @@ void DtoResolveClass(ClassDeclaration* cd)
VarDeclaration* fieldinit = NULL;
size_t fieldpad = 0;
int idx = 0;
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
// first iteration
if (lastoffset == (unsigned)-1) {
lastoffset = i->first;
fieldtype = i->second.type;
fieldinit = i->second.var;
prevsize = getABITypeSize(fieldtype);
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
}
// colliding offset?
else if (lastoffset == i->first) {
@@ -157,15 +150,15 @@ void DtoResolveClass(ClassDeclaration* cd)
prevsize = s;
}
cd->llvmHasUnions = true;
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
}
// intersecting offset?
else if (i->first < (lastoffset + prevsize)) {
size_t s = getABITypeSize(i->second.type);
assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
cd->llvmHasUnions = true;
i->second.var->llvmFieldIndex = idx;
i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
i->second.var->irField->index = idx;
i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
}
// fresh offset
else {
@@ -185,7 +178,7 @@ void DtoResolveClass(ClassDeclaration* cd)
fieldtype = i->second.type;
fieldinit = i->second.var;
prevsize = getABITypeSize(fieldtype);
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
fieldpad = 0;
}
}
@@ -199,7 +192,7 @@ void DtoResolveClass(ClassDeclaration* cd)
/*
// add field types
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
fieldtypes.push_back(i->second.type);
}
*/
@@ -307,8 +300,8 @@ void DtoDeclareClass(ClassDeclaration* cd)
assert(cd->type->ty == Tclass);
TypeClass* ts = (TypeClass*)cd->type;
assert(cd->llvmIRStruct);
IRStruct* irstruct = cd->llvmIRStruct;
assert(cd->llvmIrStruct);
IrStruct* irstruct = cd->llvmIrStruct;
gIR->structs.push_back(irstruct);
gIR->classes.push_back(cd);
@@ -318,56 +311,45 @@ void DtoDeclareClass(ClassDeclaration* cd)
needs_definition = true;
}
// interface vtables are emitted by the class implementing them
// also, interfaces have no static initializer
// also, abstract classes have no vtable
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
// interfaces have no static initializer
// same goes for abstract classes
if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
// vtable
std::string varname("_D");
varname.append(cd->mangle());
varname.append("6__vtblZ");
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
}
// build interface info type
std::vector<const llvm::Type*> types;
// ClassInfo classinfo
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
DtoResolveClass(cd2);
types.push_back(getPtrToType(cd2->type->llvmType->get()));
// void*[] vtbl
std::vector<const llvm::Type*> vtbltypes;
vtbltypes.push_back(DtoSize_t());
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
vtbltypes.push_back(byteptrptrty);
types.push_back(llvm::StructType::get(vtbltypes));
// int offset
types.push_back(llvm::Type::Int32Ty);
// create type
const llvm::StructType* infoTy = llvm::StructType::get(types);
// get interface info type
const llvm::StructType* infoTy = DtoInterfaceInfoType();
// interface info array
if (cd->vtblInterfaces->dim > 0) {
// symbol name
std::string nam = "_D";
nam.append(cd->mangle());
nam.append("16__interfaceInfosZ");
// resolve array type
const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
// declare global
irstruct->interfaceInfosTy = arrTy;
irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
}
// interface info array
if (cd->vtblInterfaces->dim > 0) {
// symbol name
std::string nam = "_D";
nam.append(cd->mangle());
nam.append("16__interfaceInfosZ");
// resolve array type
const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
// declare global
irstruct->interfaceInfosTy = arrTy;
irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
}
// interfaces have no static initializer
// same goes for abstract classes
if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
// interface vtables
unsigned idx = 0;
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
{
ClassDeclaration* id = i->first;
IRInterface* iri = i->second;
IrInterface* iri = i->second;
std::string nam("_D");
nam.append(cd->mangle());
@@ -377,7 +359,6 @@ void DtoDeclareClass(ClassDeclaration* cd)
assert(iri->vtblTy);
iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module);
iri->infoTy = infoTy;
llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
idx++;
@@ -420,7 +401,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
LOG_SCOPE;
IRStruct* irstruct = cd->llvmIRStruct;
IrStruct* irstruct = cd->llvmIrStruct;
gIR->structs.push_back(irstruct);
gIR->classes.push_back(cd);
@@ -431,12 +412,12 @@ void DtoConstInitClass(ClassDeclaration* cd)
const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
// make sure each offset knows its default initializer
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
{
IRStruct::Offset* so = &i->second;
IrStruct::Offset* so = &i->second;
llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
so->init = finit;
so->var->llvmConstInit = finit;
so->var->irField->constInit = finit;
}
// fill out fieldtypes/inits
@@ -465,9 +446,11 @@ void DtoConstInitClass(ClassDeclaration* cd)
size_t dataoffset = 2;
// next comes interface vtables
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
const llvm::StructType* infoTy = DtoInterfaceInfoType();
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
{
IRInterface* iri = i->second;
IrInterface* iri = i->second;
iri->infoTy = infoTy;
if (cd->isAbstract())
{
fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
@@ -482,7 +465,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
/*
// rest
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
Logger::println("adding fieldinit for: %s", i->second.var->toChars());
fieldinits.push_back(i->second.init);
}
@@ -493,7 +476,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
for (size_t i=0; i<nfi; ++i) {
llvm::Constant* c;
if (irstruct->defaultFields[i] != NULL) {
c = irstruct->defaultFields[i]->llvmConstInit;
c = irstruct->defaultFields[i]->irField->constInit;
assert(c);
}
else {
@@ -535,8 +518,8 @@ void DtoConstInitClass(ClassDeclaration* cd)
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
DtoForceDeclareDsymbol(fd);
assert(fd->llvmValue);
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
assert(fd->irFunc->func);
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
// cast if necessary (overridden method)
if (c->getType() != vtbltype->getElementType(k))
c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
@@ -568,30 +551,34 @@ void DtoConstInitClass(ClassDeclaration* cd)
// create interface vtable const initalizers
int idx = 2;
int idxScale = PTRSIZE;
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
{
ClassDeclaration* id = i->first;
assert(id->type->ty == Tclass);
TypeClass* its = (TypeClass*)id->type;
IRInterface* iri = i->second;
IrInterface* iri = i->second;
BaseClass* b = iri->base;
const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
// generate interface info initializer
std::vector<llvm::Constant*> infoInits;
// classinfo
assert(id->llvmClass);
llvm::Constant* c = id->llvmClass;
infoInits.push_back(c);
// vtbl
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
infoInits.push_back(c);
// offset
infoInits.push_back(DtoConstInt(idx*idxScale));
// create interface info initializer constant
iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
@@ -608,8 +595,9 @@ void DtoConstInitClass(ClassDeclaration* cd)
FuncDeclaration* fd = dsym->isFuncDeclaration();
assert(fd);
DtoForceDeclareDsymbol(fd);
assert(fd->llvmValue);
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
assert(fd->irFunc->func);
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
// we have to bitcast, as the type created in ResolveClass expects a different this type
c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
iinits.push_back(c);
@@ -629,7 +617,39 @@ void DtoConstInitClass(ClassDeclaration* cd)
idx++;
}
} // !abstract
}
// we always generate interfaceinfos as best we can
else
{
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
{
ClassDeclaration* id = i->first;
assert(id->type->ty == Tclass);
TypeClass* its = (TypeClass*)id->type;
IrInterface* iri = i->second;
BaseClass* b = iri->base;
// generate interface info initializer
std::vector<llvm::Constant*> infoInits;
// classinfo
assert(id->llvmClass);
llvm::Constant* c = id->llvmClass;
infoInits.push_back(c);
// vtbl
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
infoInits.push_back(c);
// offset
infoInits.push_back(DtoConstInt(0));
// create interface info initializer constant
iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
}
}
gIR->classes.pop_back();
gIR->structs.pop_back();
@@ -658,11 +678,11 @@ void DtoDefineClass(ClassDeclaration* cd)
cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
// initialize interface vtables
IRStruct* irstruct = cd->llvmIRStruct;
IrStruct* irstruct = cd->llvmIrStruct;
std::vector<llvm::Constant*> infoInits;
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
{
IRInterface* iri = i->second;
IrInterface* iri = i->second;
iri->vtbl->setInitializer(iri->vtblInit);
infoInits.push_back(iri->infoInit);
}
@@ -711,7 +731,7 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
LOG_SCOPE;
DValue* thisval = newexp->thisexp->toElem(gIR);
size_t idx = 2;
idx += tc->sym->llvmIRStruct->interfaces.size();
idx += tc->sym->llvmIrStruct->interfaces.size();
llvm::Value* dst = thisval->getRVal();
llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
@@ -723,10 +743,10 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
Logger::println("Resolving nested context");
LOG_SCOPE;
size_t idx = 2;
idx += tc->sym->llvmIRStruct->interfaces.size();
llvm::Value* nest = gIR->func()->decl->llvmNested;
idx += tc->sym->llvmIrStruct->interfaces.size();
llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar;
if (!nest)
nest = gIR->func()->decl->llvmThisVar;
nest = gIR->func()->decl->irFunc->thisVar;
assert(nest);
llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
@@ -792,7 +812,7 @@ DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* argument
assert(ctor);
DtoForceDeclareDsymbol(ctor);
llvm::Function* fn = llvm::cast<llvm::Function>(ctor->llvmValue);
llvm::Function* fn = ctor->irFunc->func;
TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
std::vector<llvm::Value*> ctorargs;
@@ -822,8 +842,8 @@ void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
for (size_t i=0; i<arr->dim; i++)
{
FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
assert(fd->llvmValue);
new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
assert(fd->irFunc->func);
new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb());
}
}
@@ -1031,37 +1051,37 @@ llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsi
unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
IRStruct* irstruct = cd->llvmIRStruct;
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
IrStruct* irstruct = cd->llvmIrStruct;
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
//for (unsigned i=0; i<cd->fields.dim; ++i) {
//VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
VarDeclaration* vd = i->second.var;
assert(vd);
Type* vdtype = DtoDType(vd->type);
Logger::println("found %u type %s", vd->offset, vdtype->toChars());
assert(vd->llvmFieldIndex >= 0);
assert(vd->irField->index >= 0);
if (os == vd->offset && vdtype == t) {
idxs.push_back(vd->llvmFieldIndex + dataoffset);
idxs.push_back(vd->irField->index + dataoffset);
Logger::cout() << "indexing: " << *ptr << '\n';
ptr = DtoGEP(ptr, idxs, "tmp");
if (ptr->getType() != llt)
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
Logger::cout() << "indexing: " << *ptr << '\n';
if (vd->llvmFieldIndexOffset)
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
if (vd->irField->indexOffset)
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
Logger::cout() << "indexing: " << *ptr << '\n';
return ptr;
}
else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
TypeStruct* ts = (TypeStruct*)vdtype;
StructDeclaration* ssd = ts->sym;
idxs.push_back(vd->llvmFieldIndex + dataoffset);
if (vd->llvmFieldIndexOffset) {
idxs.push_back(vd->irField->index + dataoffset);
if (vd->irField->indexOffset) {
Logger::println("has union field offset");
ptr = DtoGEP(ptr, idxs, "tmp");
if (ptr->getType() != llt)
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
std::vector<unsigned> tmp;
return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
}
@@ -1153,7 +1173,7 @@ static llvm::Constant* build_offti_entry(VarDeclaration* vd)
vd->type->getTypeInfo(NULL);
assert(vd->type->vtinfo);
DtoForceDeclareDsymbol(vd->type->vtinfo);
llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue());
const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
//Logger::cout() << "tiTy = " << *tiTy << '\n';
@@ -1230,8 +1250,8 @@ static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
else if (cd->dtors.dim == 1) {
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
DtoForceDeclareDsymbol(d);
assert(d->llvmValue);
return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty));
assert(d->irFunc->func);
return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty));
}
std::string gname("_D");
@@ -1249,8 +1269,8 @@ static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
{
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
DtoForceDeclareDsymbol(d);
assert(d->llvmValue);
builder.CreateCall(d->llvmValue, thisptr);
assert(d->irFunc->func);
builder.CreateCall(d->irFunc->func, thisptr);
}
builder.CreateRetVoid();
@@ -1380,7 +1400,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
inits.push_back(c);
// interfaces array
IRStruct* irstruct = cd->llvmIRStruct;
IrStruct* irstruct = cd->llvmIrStruct;
if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
c = cinfo->llvmConstInit->getOperand(5);
}
@@ -1446,7 +1466,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
// default constructor
if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
DtoForceDeclareDsymbol(cd->defaultCtor);
c = isaConstant(cd->defaultCtor->llvmValue);
c = isaConstant(cd->defaultCtor->irFunc->func);
const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
c = llvm::ConstantExpr::getBitCast(c, toTy);
}

View File

@@ -232,7 +232,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn);
assert(func);
assert(func->isIntrinsic());
fdecl->llvmValue = func;
fdecl->irFunc->func = func;
return func;
}
@@ -257,7 +257,7 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
LOG_SCOPE;
if (fdecl->llvmRunTimeHack) {
if (fdecl->runTimeHack) {
gIR->declareList.push_back(fdecl);
TypeFunction* tf = (TypeFunction*)fdecl->type;
tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
@@ -309,10 +309,12 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
fatal();
}
if (fdecl->llvmRunTimeHack) {
if (fdecl->runTimeHack) {
Logger::println("runtime hack func chars: %s", fdecl->toChars());
if (!fdecl->llvmValue)
fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
if (!fdecl->irFunc) {
fdecl->irFunc = new IrFunction(fdecl);
fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
}
return;
}
@@ -323,8 +325,8 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
else if (fdecl->llvmInternal == LLVMva_start)
declareOnly = true;
if (!fdecl->llvmIRFunc) {
fdecl->llvmIRFunc = new IRFunction(fdecl);
if (!fdecl->irFunc) {
fdecl->irFunc = new IrFunction(fdecl);
}
// mangled name
@@ -351,7 +353,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
assert(func->getFunctionType() == functype);
// add func to IRFunc
fdecl->llvmIRFunc->func = func;
fdecl->irFunc->func = func;
// calling convention
if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
@@ -372,7 +374,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
func->setCallingConv(llvm::CallingConv::C);
}
fdecl->llvmValue = func;
fdecl->irFunc->func = func;
assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
// main
@@ -394,22 +396,22 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
int k = 0;
if (f->llvmRetInPtr) {
iarg->setName("retval");
fdecl->llvmRetArg = iarg;
fdecl->irFunc->retArg = iarg;
++iarg;
}
if (f->llvmUsesThis) {
iarg->setName("this");
fdecl->llvmThisVar = iarg;
assert(fdecl->llvmThisVar);
fdecl->irFunc->thisVar = iarg;
assert(fdecl->irFunc->thisVar);
++iarg;
}
if (f->linkage == LINKd && f->varargs == 1) {
iarg->setName("_arguments");
fdecl->llvmArguments = iarg;
fdecl->irFunc->_arguments = iarg;
++iarg;
iarg->setName("_argptr");
fdecl->llvmArgPtr = iarg;
fdecl->irFunc->_argptr = iarg;
++iarg;
}
@@ -420,7 +422,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
//Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
if (arg && arg->ident != 0) {
if (arg->vardecl) {
arg->vardecl->llvmValue = iarg;
assert(!arg->vardecl->irLocal);
arg->vardecl->irLocal = new IrLocal(arg->vardecl);
arg->vardecl->irLocal->value = iarg;
}
iarg->setName(arg->ident->toChars());
}
@@ -458,14 +462,14 @@ void DtoDefineFunc(FuncDeclaration* fd)
if (!mo->llvmCompileUnit) {
mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
}
fd->llvmDwarfSubProgram = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
}
Type* t = DtoDType(fd->type);
TypeFunction* f = (TypeFunction*)t;
assert(f->llvmType);
llvm::Function* func = fd->llvmIRFunc->func;
llvm::Function* func = fd->irFunc->func;
const llvm::FunctionType* functype = func->getFunctionType();
// only members of the current module or template instances maybe be defined
@@ -477,8 +481,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
if (fd->fbody != 0)
{
Logger::println("Doing function body for: %s", fd->toChars());
assert(fd->llvmIRFunc);
gIR->functions.push_back(fd->llvmIRFunc);
assert(fd->irFunc);
gIR->functions.push_back(fd->irFunc);
if (fd->isMain())
gIR->emitMain = true;
@@ -496,7 +500,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
// need result variable? (not nested)
if (fd->vresult && !fd->vresult->nestedref) {
Logger::println("non-nested vresult value");
fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
fd->vresult->irLocal = new IrLocal(fd->vresult);
fd->vresult->irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
}
// give arguments storage
@@ -505,16 +510,16 @@ void DtoDefineFunc(FuncDeclaration* fd)
Argument* arg = Argument::getNth(f->parameters, i);
if (arg && arg->vardecl) {
VarDeclaration* vd = arg->vardecl;
if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
continue;
llvm::Value* a = vd->llvmValue;
llvm::Value* a = vd->irLocal->value;
assert(a);
std::string s(a->getName());
Logger::println("giving argument '%s' storage", s.c_str());
s.append("_storage");
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
gIR->ir->CreateStore(a,v);
vd->llvmValue = v;
vd->irLocal->value = v;
}
else {
Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
@@ -527,29 +532,32 @@ void DtoDefineFunc(FuncDeclaration* fd)
llvm::Value* parentNested = NULL;
if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
if (!fd->isStatic()) // huh?
parentNested = fd2->llvmNested;
parentNested = fd2->irFunc->nestedVar;
}
// need result variable? (nested)
if (fd->vresult && fd->vresult->nestedref) {
Logger::println("nested vresult value: %s", fd->vresult->toChars());
fd->llvmNestedVars.insert(fd->vresult);
fd->nestedVars.insert(fd->vresult);
}
// construct nested variables struct
if (!fd->llvmNestedVars.empty() || parentNested) {
if (!fd->nestedVars.empty() || parentNested) {
std::vector<const llvm::Type*> nestTypes;
int j = 0;
if (parentNested) {
nestTypes.push_back(parentNested->getType());
j++;
}
for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
VarDeclaration* vd = *i;
vd->llvmNestedIndex = j++;
if (!vd->irLocal)
vd->irLocal = new IrLocal(vd);
vd->irLocal->nestedIndex = j++;
if (vd->isParameter()) {
assert(vd->llvmValue);
nestTypes.push_back(vd->llvmValue->getType());
assert(vd->irLocal->value);
nestTypes.push_back(vd->irLocal->value->getType());
}
else {
nestTypes.push_back(DtoType(vd->type));
@@ -557,17 +565,18 @@ void DtoDefineFunc(FuncDeclaration* fd)
}
const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
if (parentNested) {
assert(fd->llvmThisVar);
llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp");
gIR->ir->CreateStore(ptr, DtoGEPi(fd->llvmNested, 0,0, "tmp"));
assert(fd->irFunc->thisVar);
llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp");
gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp"));
}
for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
VarDeclaration* vd = *i;
if (vd->isParameter()) {
gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(fd->llvmNested, 0, vd->llvmNestedIndex, "tmp"));
vd->llvmValue = fd->llvmNested;
assert(vd->irLocal);
gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp"));
vd->irLocal->value = fd->irFunc->nestedVar;
}
}
}
@@ -575,9 +584,9 @@ void DtoDefineFunc(FuncDeclaration* fd)
// copy _argptr to a memory location
if (f->linkage == LINKd && f->varargs == 1)
{
llvm::Value* argptrmem = new llvm::AllocaInst(fd->llvmArgPtr->getType(), "_argptrmem", gIR->topallocapoint());
new llvm::StoreInst(fd->llvmArgPtr, argptrmem, gIR->scopebb());
fd->llvmArgPtr = argptrmem;
llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb());
fd->irFunc->_argptr = argptrmem;
}
// output function body

View File

@@ -40,7 +40,7 @@ IRState::IRState()
ir.state = this;
}
IRFunction* IRState::func()
IrFunction* IRState::func()
{
assert(!functions.empty() && "Function stack is empty!");
return functions.back();
@@ -64,7 +64,7 @@ llvm::Instruction* IRState::topallocapoint()
return functions.back()->allocapoint;
}
IRStruct* IRState::topstruct()
IrStruct* IRState::topstruct()
{
assert(!structs.empty() && "Struct vector is empty!");
return structs.back();
@@ -101,32 +101,6 @@ bool IRState::scopereturned()
//////////////////////////////////////////////////////////////////////////////////////////
IRStruct::IRStruct(Type* t)
: recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
{
type = t;
defined = false;
constinited = false;
interfaceInfosTy = NULL;
interfaceInfos = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////
IRFinally::IRFinally()
{
bb = 0;
retbb = 0;
}
IRFinally::IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
{
bb = b;
retbb = rb;
}
//////////////////////////////////////////////////////////////////////////////////////////
LLVMBuilder* IRBuilderHelper::operator->()
{
LLVMBuilder& b = state->scope().builder;
@@ -136,20 +110,6 @@ LLVMBuilder* IRBuilderHelper::operator->()
//////////////////////////////////////////////////////////////////////////////////////////
IRFunction::IRFunction(FuncDeclaration* fd)
{
decl = fd;
Type* t = DtoDType(fd->type);
assert(t->ty == Tfunction);
type = (TypeFunction*)t;
func = NULL;
allocapoint = NULL;
finallyretval = NULL;
defined = false;
}
//////////////////////////////////////////////////////////////////////////////////////////
IRExp::IRExp()
{
e1 = e2 = NULL;
@@ -162,11 +122,3 @@ IRExp::IRExp(Expression* l, Expression* r, DValue* val)
e2 = r;
v = val;
}
//////////////////////////////////////////////////////////////////////////////////////////
IRGlobal::IRGlobal(VarDeclaration* v) :
type(llvm::OpaqueType::get())
{
var = v;
}

View File

@@ -1,15 +1,16 @@
#ifndef LLVMDC_GEN_IRSTATE_H
#define LLVMDC_GEN_IRSTATE_H
#include <stack>
#include <vector>
#include <deque>
#include <map>
#include <list>
#include "root.h"
#include "aggregate.h"
#include "ir/irfunction.h"
#include "ir/irstruct.h"
#include "ir/irvar.h"
// global ir state for current module
struct IRState;
extern IRState* gIR;
@@ -23,13 +24,6 @@ struct Module;
struct TypeStruct;
struct BaseClass;
/*
struct LLVMValue
{
std::vector<llvm::Value*> vals;
};
*/
// represents a scope
struct IRScope
{
@@ -41,94 +35,6 @@ struct IRScope
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
};
struct IRInterface : Object
{
BaseClass* base;
ClassDeclaration* decl;
const llvm::StructType* vtblTy;
llvm::ConstantStruct* vtblInit;
llvm::GlobalVariable* vtbl;
const llvm::StructType* infoTy;
llvm::ConstantStruct* infoInit;
llvm::Constant* info;
IRInterface(BaseClass* b, const llvm::StructType* vt)
{
base = b;
decl = b->base;
vtblTy = vt;
vtblInit = NULL;
vtbl = NULL;
infoTy = NULL;
infoInit = NULL;
info = NULL;
}
};
// represents a struct or class
struct IRStruct : Object
{
struct Offset
{
VarDeclaration* var;
const llvm::Type* type;
llvm::Constant* init;
Offset(VarDeclaration* v, const llvm::Type* ty)
: var(v), type(ty), init(NULL) {}
};
typedef std::multimap<unsigned, Offset> OffsetMap;
typedef std::vector<VarDeclaration*> VarDeclVector;
typedef std::map<ClassDeclaration*, IRInterface*> InterfaceMap;
typedef InterfaceMap::iterator InterfaceIter;
public:
IRStruct(Type*);
Type* type;
llvm::PATypeHolder recty;
OffsetMap offsets;
VarDeclVector defaultFields;
InterfaceMap interfaces;
const llvm::ArrayType* interfaceInfosTy;
llvm::GlobalVariable* interfaceInfos;
bool defined;
bool constinited;
};
// represents a finally block
struct IRFinally
{
llvm::BasicBlock* bb;
llvm::BasicBlock* retbb;
IRFinally();
IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
};
// represents a function
struct IRFunction : Object
{
llvm::Function* func;
llvm::Instruction* allocapoint;
FuncDeclaration* decl;
TypeFunction* type;
// finally blocks
typedef std::vector<IRFinally> FinallyVec;
FinallyVec finallys;
llvm::Value* finallyretval;
bool defined;
IRFunction(FuncDeclaration*);
};
struct IRBuilderHelper
{
IRState* state;
@@ -144,15 +50,6 @@ struct IRExp
IRExp(Expression* l, Expression* r, DValue* val);
};
// represents a global variable
struct IRGlobal : Object
{
VarDeclaration* var;
llvm::PATypeHolder type;
IRGlobal(VarDeclaration* v);
};
// represents the module
struct IRState
{
@@ -163,18 +60,18 @@ struct IRState
llvm::Module* module;
// functions
typedef std::vector<IRFunction*> FunctionVector;
typedef std::vector<IrFunction*> FunctionVector;
FunctionVector functions;
IRFunction* func();
IrFunction* func();
llvm::Function* topfunc();
TypeFunction* topfunctype();
llvm::Instruction* topallocapoint();
// structs
typedef std::vector<IRStruct*> StructVector;
typedef std::vector<IrStruct*> StructVector;
StructVector structs;
IRStruct* topstruct();
IrStruct* topstruct();
// classes TODO move into IRClass
typedef std::vector<ClassDeclaration*> ClassDeclVec;

View File

@@ -25,6 +25,8 @@
#include "gen/todebug.h"
#include "gen/dvalue.h"
#include "ir/irfunction.h"
//////////////////////////////////////////////////////////////////////////////
void CompoundStatement::toIR(IRState* p)
@@ -57,13 +59,13 @@ void ReturnStatement::toIR(IRState* p)
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
assert(DtoIsPassedByRef(exptype));
IRFunction* f = p->func();
IrFunction* f = p->func();
assert(f->type->llvmRetInPtr);
assert(f->decl->llvmRetArg);
assert(f->decl->irFunc->retArg);
if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
DValue* rvar = new DVarValue(f->type->next, f->decl->llvmRetArg, true);
DValue* rvar = new DVarValue(f->type->next, f->decl->irFunc->retArg, true);
p->exps.push_back(IRExp(NULL,exp,rvar));
DValue* e = exp->toElem(p);
@@ -72,7 +74,7 @@ void ReturnStatement::toIR(IRState* p)
if (!e->inPlace())
DtoAssign(rvar, e);
IRFunction::FinallyVec& fin = f->finallys;
IrFunction::FinallyVec& fin = f->finallys;
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
new llvm::ReturnInst(p->scopebb());
@@ -88,7 +90,7 @@ void ReturnStatement::toIR(IRState* p)
delete e;
Logger::cout() << "return value is '" <<*v << "'\n";
IRFunction::FinallyVec& fin = p->func()->finallys;
IrFunction::FinallyVec& fin = p->func()->finallys;
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
new llvm::ReturnInst(v, p->scopebb());
@@ -105,7 +107,7 @@ void ReturnStatement::toIR(IRState* p)
else
{
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
IRFunction::FinallyVec& fin = p->func()->finallys;
IrFunction::FinallyVec& fin = p->func()->finallys;
if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
new llvm::ReturnInst(p->scopebb());
@@ -425,8 +427,8 @@ void TryFinallyStatement::toIR(IRState* p)
// do the try block
p->scope() = IRScope(trybb,finallybb);
gIR->func()->finallys.push_back(IRFinally(finallybb,finallyretbb));
IRFinally& fin = p->func()->finallys.back();
gIR->func()->finallys.push_back(IrFinally(finallybb,finallyretbb));
IrFinally& fin = p->func()->finallys.back();
assert(body);
body->toIR(p);
@@ -453,7 +455,7 @@ void TryFinallyStatement::toIR(IRState* p)
// terminate finally (return path)
size_t nfin = p->func()->finallys.size();
if (nfin > 1) {
IRFinally& ofin = p->func()->finallys[nfin-2];
IrFinally& ofin = p->func()->finallys[nfin-2];
p->ir->CreateBr(ofin.retbb);
}
// no outer
@@ -793,7 +795,13 @@ void ForeachStatement::toIR(IRState* p)
// key
const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t();
llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
if (key) key->llvmValue = keyvar;
if (key)
{
//key->llvmValue = keyvar;
assert(!key->irLocal);
key->irLocal = new IrLocal(key);
key->irLocal->value = keyvar;
}
llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false);
// value
@@ -801,6 +809,8 @@ void ForeachStatement::toIR(IRState* p)
llvm::Value* valvar = NULL;
if (!value->isRef() && !value->isOut())
valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
assert(!value->irLocal);
value->irLocal = new IrLocal(value);
// what to iterate
DValue* aggrval = aggr->toElem(p);
@@ -896,15 +906,15 @@ void ForeachStatement::toIR(IRState* p)
llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false);
llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
if (aggrtype->ty == Tsarray)
value->llvmValue = DtoGEP(val,zero,loadedKey,"tmp");
value->irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
else if (aggrtype->ty == Tarray)
value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
value->irLocal->value = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
if (!value->isRef() && !value->isOut()) {
DValue* dst = new DVarValue(value->type, valvar, true);
DValue* src = new DVarValue(value->type, value->llvmValue, true);
DValue* src = new DVarValue(value->type, value->irLocal->value, true);
DtoAssign(dst, src);
value->llvmValue = valvar;
value->irLocal->value = valvar;
}
// emit body
@@ -982,7 +992,7 @@ void WithStatement::toIR(IRState* p)
assert(body);
DValue* e = exp->toElem(p);
wthis->llvmValue = e->getRVal();
wthis->irLocal->value = e->getRVal();
delete e;
body->toIR(p);

View File

@@ -13,6 +13,8 @@
#include "gen/logger.h"
#include "gen/structs.h"
#include "ir/irstruct.h"
//////////////////////////////////////////////////////////////////////////////////////////
const llvm::Type* DtoStructType(Type* t)
@@ -93,7 +95,7 @@ llvm::Constant* DtoConstStructInitializer(StructInitializer* si)
VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
assert(vd);
llvm::Constant* v = DtoConstInitializer(vd->type, ini);
inits.push_back(DUnionIdx(vd->llvmFieldIndex, vd->llvmFieldIndexOffset, v));
inits.push_back(DUnionIdx(vd->irField->index, vd->irField->indexOffset, v));
}
DtoConstInitStruct((StructDeclaration*)si->ad);
@@ -121,26 +123,26 @@ llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, un
VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
Type* vdtype = DtoDType(vd->type);
Logger::println("found %u type %s", vd->offset, vdtype->toChars());
assert(vd->llvmFieldIndex >= 0);
assert(vd->irField->index >= 0);
if (os == vd->offset && vdtype == t) {
idxs.push_back(vd->llvmFieldIndex);
idxs.push_back(vd->irField->index);
ptr = DtoGEP(ptr, idxs, "tmp");
if (ptr->getType() != llt)
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
if (vd->llvmFieldIndexOffset)
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
if (vd->irField->indexOffset)
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
return ptr;
}
else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
TypeStruct* ts = (TypeStruct*)vdtype;
StructDeclaration* ssd = ts->sym;
idxs.push_back(vd->llvmFieldIndex);
if (vd->llvmFieldIndexOffset) {
idxs.push_back(vd->irField->index);
if (vd->irField->indexOffset) {
Logger::println("has union field offset");
ptr = DtoGEP(ptr, idxs, "tmp");
if (ptr->getType() != llt)
ptr = DtoBitCast(ptr, llt);
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
std::vector<unsigned> tmp;
return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
}
@@ -176,8 +178,8 @@ void DtoResolveStruct(StructDeclaration* sd)
TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
IRStruct* irstruct = new IRStruct(ts);
sd->llvmIRStruct = irstruct;
IrStruct* irstruct = new IrStruct(ts);
sd->llvmIrStruct = irstruct;
gIR->structs.push_back(irstruct);
// fields
@@ -233,7 +235,7 @@ void DtoResolveStruct(StructDeclaration* sd)
VarDeclaration* fieldinit = NULL;
size_t fieldpad = 0;
int idx = 0;
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
// first iteration
if (lastoffset == (unsigned)-1) {
lastoffset = i->first;
@@ -241,7 +243,7 @@ void DtoResolveStruct(StructDeclaration* sd)
fieldtype = i->second.type;
fieldinit = i->second.var;
prevsize = getABITypeSize(fieldtype);
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
}
// colliding offset?
else if (lastoffset == i->first) {
@@ -251,15 +253,15 @@ void DtoResolveStruct(StructDeclaration* sd)
prevsize = s;
}
sd->llvmHasUnions = true;
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
}
// intersecting offset?
else if (i->first < (lastoffset + prevsize)) {
size_t s = getABITypeSize(i->second.type);
assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
sd->llvmHasUnions = true;
i->second.var->llvmFieldIndex = idx;
i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
i->second.var->irField->index = idx;
i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
}
// fresh offset
else {
@@ -279,7 +281,7 @@ void DtoResolveStruct(StructDeclaration* sd)
fieldtype = i->second.type;
fieldinit = i->second.var;
prevsize = getABITypeSize(fieldtype);
i->second.var->llvmFieldIndex = idx;
i->second.var->irField->index = idx;
fieldpad = 0;
}
}
@@ -349,16 +351,16 @@ void DtoConstInitStruct(StructDeclaration* sd)
Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
LOG_SCOPE;
IRStruct* irstruct = sd->llvmIRStruct;
IrStruct* irstruct = sd->llvmIrStruct;
gIR->structs.push_back(irstruct);
// make sure each offset knows its default initializer
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
{
IRStruct::Offset* so = &i->second;
IrStruct::Offset* so = &i->second;
llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
so->init = finit;
so->var->llvmConstInit = finit;
so->var->irField->constInit = finit;
}
const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get());
@@ -369,7 +371,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
for (size_t i=0; i<nfi; ++i) {
llvm::Constant* c;
if (irstruct->defaultFields[i] != NULL) {
c = irstruct->defaultFields[i]->llvmConstInit;
c = irstruct->defaultFields[i]->irField->constInit;
assert(c);
}
else {
@@ -435,12 +437,12 @@ void DtoDefineStruct(StructDeclaration* sd)
DUnion::DUnion()
{
DUnionField* f = NULL;
IRStruct* topstruct = gIR->topstruct();
IrStruct* topstruct = gIR->topstruct();
bool unions = false;
for (IRStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
{
unsigned o = i->first;
IRStruct::Offset* so = &i->second;
IrStruct::Offset* so = &i->second;
const llvm::Type* ft = so->init->getType();
size_t sz = getABITypeSize(ft);
if (f == NULL) { // new field

View File

@@ -164,14 +164,14 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariab
void DtoDwarfFuncStart(FuncDeclaration* fd)
{
assert(fd->llvmDwarfSubProgram);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram));
assert(fd->irFunc->dwarfSubProg);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->irFunc->dwarfSubProg));
}
void DtoDwarfFuncEnd(FuncDeclaration* fd)
{
assert(fd->llvmDwarfSubProgram);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram));
assert(fd->irFunc->dwarfSubProg);
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->irFunc->dwarfSubProg));
}
//////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -57,12 +57,14 @@ DValue* DeclarationExp::toElem(IRState* p)
DtoAnnotation(toChars());
Logger::println("vdtype = %s", vd->type->toChars());
// referenced by nested delegate?
if (vd->nestedref) {
Logger::println("has nestedref set");
vd->llvmValue = p->func()->decl->llvmNested;
assert(vd->llvmValue);
assert(vd->llvmNestedIndex >= 0);
assert(vd->irLocal);
vd->irLocal->value = p->func()->decl->irFunc->nestedVar;
assert(vd->irLocal->value);
assert(vd->irLocal->nestedIndex >= 0);
}
// normal stack variable
else {
@@ -70,14 +72,16 @@ DValue* DeclarationExp::toElem(IRState* p)
const llvm::Type* lltype = DtoType(vd->type);
llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
//allocainst->setAlignment(vd->type->alignsize()); // TODO
vd->llvmValue = allocainst;
assert(!vd->irLocal);
vd->irLocal = new IrLocal(vd);
vd->irLocal->value = allocainst;
}
Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n';
Logger::cout() << "llvm value for decl: " << *vd->irLocal->value << '\n';
DValue* ie = DtoInitializer(vd->init);
}
return new DVarValue(vd, vd->llvmValue, true);
return new DVarValue(vd, vd->getIrValue(), true);
}
// struct declaration
else if (StructDeclaration* s = declaration->isStructDeclaration())
@@ -149,19 +153,19 @@ DValue* VarExp::toElem(IRState* p)
if (vd->ident == Id::_arguments)
{
Logger::println("Id::_arguments");
if (!vd->llvmValue)
vd->llvmValue = p->func()->decl->llvmArguments;
assert(vd->llvmValue);
return new DVarValue(vd, vd->llvmValue, true);
if (!vd->getIrValue())
vd->getIrValue() = p->func()->decl->irFunc->_arguments;
assert(vd->getIrValue());
return new DVarValue(vd, vd->getIrValue(), true);
}
// _argptr
else if (vd->ident == Id::_argptr)
{
Logger::println("Id::_argptr");
if (!vd->llvmValue)
vd->llvmValue = p->func()->decl->llvmArgPtr;
assert(vd->llvmValue);
return new DVarValue(vd, vd->llvmValue, true);
if (!vd->getIrValue())
vd->getIrValue() = p->func()->decl->irFunc->_argptr;
assert(vd->getIrValue());
return new DVarValue(vd, vd->getIrValue(), true);
}
// _dollar
else if (vd->ident == Id::dollar)
@@ -176,13 +180,13 @@ DValue* VarExp::toElem(IRState* p)
{
Logger::println("TypeInfoDeclaration");
DtoForceDeclareDsymbol(tid);
assert(tid->llvmValue);
assert(tid->getIrValue());
const llvm::Type* vartype = DtoType(type);
llvm::Value* m;
if (tid->llvmValue->getType() != getPtrToType(vartype))
m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp");
if (tid->getIrValue()->getType() != getPtrToType(vartype))
m = p->ir->CreateBitCast(tid->getIrValue(), vartype, "tmp");
else
m = tid->llvmValue;
m = tid->getIrValue();
return new DVarValue(vd, m, true);
}
// classinfo
@@ -201,16 +205,16 @@ DValue* VarExp::toElem(IRState* p)
// function parameter
else if (vd->isParameter()) {
Logger::println("function param");
if (!vd->llvmValue) {
if (!vd->getIrValue()) {
// TODO: determine this properly
// this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
vd->llvmValue = &p->func()->func->getArgumentList().back();
vd->getIrValue() = &p->func()->func->getArgumentList().back();
}
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) {
return new DVarValue(vd, vd->llvmValue, true);
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->getIrValue())) {
return new DVarValue(vd, vd->getIrValue(), true);
}
else if (llvm::isa<llvm::Argument>(vd->llvmValue)) {
return new DImValue(type, vd->llvmValue);
else if (llvm::isa<llvm::Argument>(vd->getIrValue())) {
return new DImValue(type, vd->getIrValue());
}
else assert(0);
}
@@ -220,11 +224,11 @@ DValue* VarExp::toElem(IRState* p)
vd->toObjFile();
DtoConstInitGlobal(vd);
}
if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) {
if (!vd->getIrValue() || vd->getIrValue()->getType()->isAbstract()) {
Logger::println("global variable not resolved :/ %s", vd->toChars());
assert(0);
}
return new DVarValue(vd, vd->llvmValue, true);
return new DVarValue(vd, vd->getIrValue(), true);
}
}
else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
@@ -233,7 +237,7 @@ DValue* VarExp::toElem(IRState* p)
if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0)
DtoForceDeclareDsymbol(fdecl);
}
return new DFuncValue(fdecl, fdecl->llvmValue);
return new DFuncValue(fdecl, fdecl->irFunc->func);
}
else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
{
@@ -274,11 +278,11 @@ llvm::Constant* VarExp::toConstElem(IRState* p)
else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
{
DtoForceDeclareDsymbol(ti);
assert(ti->llvmValue);
assert(ti->getIrValue());
const llvm::Type* vartype = DtoType(type);
llvm::Constant* m = isaConstant(ti->llvmValue);
llvm::Constant* m = isaConstant(ti->getIrValue());
assert(m);
if (ti->llvmValue->getType() != getPtrToType(vartype))
if (ti->getIrValue()->getType() != getPtrToType(vartype))
m = llvm::ConstantExpr::getBitCast(m, vartype);
return m;
}
@@ -974,7 +978,7 @@ DValue* CallExp::toElem(IRState* p)
llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
}
if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
if (dfn && dfn->func && dfn->func->runTimeHack) {
const llvm::Type* rettype = getPtrToType(DtoType(type));
if (llargs[j]->getType() != llfnty->getParamType(j)) {
Logger::println("llvmRunTimeHack==true - force casting return value param");
@@ -1075,8 +1079,8 @@ DValue* CallExp::toElem(IRState* p)
Expression* argexp = (Expression*)arguments->data[i];
TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
DtoForceDeclareDsymbol(tidecl);
assert(tidecl->llvmValue);
vtypeinfos.push_back(tidecl->llvmValue);
assert(tidecl->getIrValue());
vtypeinfos.push_back(tidecl->getIrValue());
llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
}
@@ -1108,7 +1112,7 @@ DValue* CallExp::toElem(IRState* p)
}
// this hack is necessary :/
if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
if (dfn && dfn->func && dfn->func->runTimeHack) {
if (llfnty->getParamType(j) != NULL) {
if (llargs[j]->getType() != llfnty->getParamType(j)) {
Logger::println("llvmRunTimeHack==true - force casting argument");
@@ -1137,7 +1141,7 @@ DValue* CallExp::toElem(IRState* p)
llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
llvm::Value* retllval = (retinptr) ? llargs[0] : call;
if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) {
if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
const llvm::Type* rettype = getPtrToType(DtoType(type));
if (retllval->getType() != rettype) {
Logger::println("llvmRunTimeHack==true - force casting return value");
@@ -1208,12 +1212,12 @@ DValue* SymOffExp::toElem(IRState* p)
vd->toObjFile(); // TODO
}
assert(vd->llvmValue);
assert(vd->getIrValue());
Type* t = DtoDType(type);
Type* tnext = DtoDType(t->next);
Type* vdtype = DtoDType(vd->type);
llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->llvmValue;
llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->getIrValue();
llvm::Value* varmem = 0;
if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) {
@@ -1287,9 +1291,8 @@ DValue* AddrExp::toElem(IRState* p)
//Logger::println("FuncDeclaration");
FuncDeclaration* fd = fv->func;
assert(fd);
if (fd->llvmValue == 0)
DtoForceDeclareDsymbol(fd);
return new DFuncValue(fd, fd->llvmValue);
DtoForceDeclareDsymbol(fd);
return new DFuncValue(fd, fd->irFunc->func);
}
else if (DImValue* im = v->isIm()) {
Logger::println("is immediate");
@@ -1394,7 +1397,7 @@ DValue* DotVarExp::toElem(IRState* p)
// super call
if (e1->op == TOKsuper) {
DtoForceDeclareDsymbol(fdecl);
funcval = fdecl->llvmValue;
funcval = fdecl->irFunc->func;
assert(funcval);
}
// normal virtual call
@@ -1415,7 +1418,7 @@ DValue* DotVarExp::toElem(IRState* p)
// static call
else {
DtoForceDeclareDsymbol(fdecl);
funcval = fdecl->llvmValue;
funcval = fdecl->irFunc->func;
assert(funcval);
//assert(funcval->getType() == DtoType(fdecl->type));
}
@@ -1438,7 +1441,7 @@ DValue* ThisExp::toElem(IRState* p)
if (VarDeclaration* vd = var->isVarDeclaration()) {
llvm::Value* v;
v = p->func()->decl->llvmThisVar;
v = p->func()->decl->irFunc->thisVar;
if (llvm::isa<llvm::AllocaInst>(v))
v = new llvm::LoadInst(v, "tmp", p->scopebb());
return new DThisValue(vd, v);
@@ -2187,7 +2190,7 @@ DValue* DelegateExp::toElem(IRState* p)
if (DFuncValue* f = u->isFunc()) {
//assert(f->vthis);
//uval = f->vthis;
llvm::Value* nestvar = p->func()->decl->llvmNested;
llvm::Value* nestvar = p->func()->decl->irFunc->nestedVar;
if (nestvar)
uval = nestvar;
else
@@ -2213,7 +2216,7 @@ DValue* DelegateExp::toElem(IRState* p)
else if (func->toParent()->isInterfaceDeclaration())
assert(0 && "TODO delegate to interface method");
else
castfptr = func->llvmValue;
castfptr = func->irFunc->func;
castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
DtoStore(castfptr, fptr);
@@ -2440,7 +2443,7 @@ DValue* FuncExp::toElem(IRState* p)
llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
llvm::Value* llvmNested = p->func()->decl->llvmNested;
llvm::Value* llvmNested = p->func()->decl->irFunc->nestedVar;
if (llvmNested == NULL) {
llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty);
p->ir->CreateStore(nullcontext, context);
@@ -2452,8 +2455,8 @@ DValue* FuncExp::toElem(IRState* p)
llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
assert(fd->llvmValue);
llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
assert(fd->irFunc->func);
llvm::Value* castfptr = new llvm::BitCastInst(fd->irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
new llvm::StoreInst(castfptr, fptr, p->scopebb());
if (temp)

View File

@@ -2,7 +2,6 @@
#include "gen/llvm.h"
#include "mtype.h"
#include "dsymbol.h"
#include "aggregate.h"
#include "declaration.h"
@@ -103,7 +102,7 @@ const llvm::Type* DtoType(Type* t)
// recursive or cyclic declaration
if (!gIR->structs.empty())
{
IRStruct* found = 0;
IrStruct* found = 0;
for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
{
if (t == (*i)->type)
@@ -117,7 +116,7 @@ const llvm::Type* DtoType(Type* t)
TypeStruct* ts = (TypeStruct*)t;
assert(ts->sym);
DtoResolveDsymbol(ts->sym);
return ts->sym->llvmIRStruct->recty.get();//t->llvmType->get();
return ts->sym->llvmIrStruct->recty.get();//t->llvmType->get();
}
case Tclass: {
@@ -125,7 +124,7 @@ const llvm::Type* DtoType(Type* t)
// recursive or cyclic declaration
if (!gIR->structs.empty())
{
IRStruct* found = 0;
IrStruct* found = 0;
for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
{
if (t == (*i)->type)
@@ -140,7 +139,7 @@ const llvm::Type* DtoType(Type* t)
TypeClass* tc = (TypeClass*)t;
assert(tc->sym);
DtoResolveDsymbol(tc->sym);
return getPtrToType(tc->sym->llvmIRStruct->recty.get());//t->llvmType->get());
return getPtrToType(tc->sym->llvmIrStruct->recty.get());//t->llvmType->get());
}
// functions
@@ -687,7 +686,7 @@ static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc)
assert(p->isFuncDeclaration() || p->isClassDeclaration());
if (FuncDeclaration* fd = p->isFuncDeclaration())
{
llvm::Value* v = fd->llvmNested;
llvm::Value* v = fd->irFunc->nestedVar;
assert(v);
return v->getType();
}
@@ -717,9 +716,9 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
if (fd->toParent2() == func)
{
if (!func->llvmNested)
if (!func->irFunc->nestedVar)
return NULL;
return DtoBitCast(v, func->llvmNested->getType());
return DtoBitCast(v, func->irFunc->nestedVar->getType());
}
v = DtoBitCast(v, get_next_frame_ptr_type(fd));
@@ -733,7 +732,7 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
{
size_t idx = 2;
idx += cd->llvmIRStruct->interfaces.size();
idx += cd->llvmIrStruct->interfaces.size();
v = DtoGEPi(v,0,idx,"tmp");
v = DtoLoad(v);
}
@@ -747,7 +746,7 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
{
Logger::println("scope is class: %s", cd->toChars());
/*size_t idx = 2;
idx += cd->llvmIRStruct->interfaces.size();
idx += cd->llvmIrStruct->interfaces.size();
v = DtoGEPi(v,0,idx,"tmp");
Logger::cout() << "gep = " << *v << '\n';
v = DtoLoad(v);*/
@@ -766,14 +765,14 @@ static llvm::Value* get_frame_ptr(FuncDeclaration* func)
{
Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
LOG_SCOPE;
IRFunction* irfunc = gIR->func();
IrFunction* irfunc = gIR->func();
// in the right scope already
if (func == irfunc->decl)
return irfunc->decl->llvmNested;
return irfunc->decl->irFunc->nestedVar;
// use the 'this' pointer
llvm::Value* ptr = irfunc->decl->llvmThisVar;
llvm::Value* ptr = irfunc->decl->irFunc->thisVar;
assert(ptr);
// return the fully resolved frame pointer
@@ -830,7 +829,7 @@ static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par)
llvm::Value* DtoNestedVariable(VarDeclaration* vd)
{
// log the frame list
IRFunction* irfunc = gIR->func();
IrFunction* irfunc = gIR->func();
if (Logger::enabled())
print_nested_frame_list(vd, irfunc->decl);
@@ -841,10 +840,10 @@ llvm::Value* DtoNestedVariable(VarDeclaration* vd)
assert(ptr && "nested var, but no context");
// we must cast here to be sure. nested classes just have a void*
ptr = DtoBitCast(ptr, func->llvmNested->getType());
ptr = DtoBitCast(ptr, func->irFunc->nestedVar->getType());
// index nested var and load (if necessary)
llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp");
llvm::Value* v = DtoGEPi(ptr, 0, vd->irLocal->nestedIndex, "tmp");
// references must be loaded, for normal variables this IS already the variable storage!!!
if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
v = DtoLoad(v);
@@ -922,9 +921,9 @@ void DtoAssign(DValue* lhs, DValue* rhs)
llvm::Value* tmp = rhs->getRVal();
FuncDeclaration* fdecl = gIR->func()->decl;
// respecify the this param
if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
DtoStore(tmp, fdecl->llvmThisVar);
if (!llvm::isa<llvm::AllocaInst>(fdecl->irFunc->thisVar))
fdecl->irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
DtoStore(tmp, fdecl->irFunc->thisVar);
}
// regular class ref -> class ref assignment
else {
@@ -1584,11 +1583,11 @@ void DtoConstInitGlobal(VarDeclaration* vd)
if (_init && _init->getType() != _type)
_type = _init->getType();
llvm::cast<llvm::OpaqueType>(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type);
_type = vd->llvmIRGlobal->type.get();
llvm::cast<llvm::OpaqueType>(vd->irGlobal->type.get())->refineAbstractTypeTo(_type);
_type = vd->irGlobal->type.get();
assert(!_type->isAbstract());
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->llvmValue);
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->irGlobal->value);
if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
{
gvar->setInitializer(_init);
@@ -1743,3 +1742,29 @@ void DtoAnnotation(const char* str)
// create a noop with the code as the result name!
gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
}
const llvm::StructType* DtoInterfaceInfoType()
{
static const llvm::StructType* t = NULL;
if (t)
return t;
// build interface info type
std::vector<const llvm::Type*> types;
// ClassInfo classinfo
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
DtoResolveClass(cd2);
types.push_back(getPtrToType(cd2->type->llvmType->get()));
// void*[] vtbl
std::vector<const llvm::Type*> vtbltypes;
vtbltypes.push_back(DtoSize_t());
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
vtbltypes.push_back(byteptrptrty);
types.push_back(llvm::StructType::get(vtbltypes));
// int offset
types.push_back(llvm::Type::Int32Ty);
// create type
t = llvm::StructType::get(types);
return t;
}

View File

@@ -1,51 +1,74 @@
#ifndef LLVMDC_GEN_TOLLVM_H
#define LLVMDC_GEN_TOLLVM_H
// D -> LLVM helpers
struct DValue;
#include "gen/llvm.h"
#include "lexer.h"
#include "mtype.h"
#include "attrib.h"
#include "declaration.h"
// D->LLVM type handling stuff
const llvm::Type* DtoType(Type* t);
bool DtoIsPassedByRef(Type* type);
// resolve typedefs to their real type.
// TODO should probably be removed in favor of DMD's Type::toBasetype
Type* DtoDType(Type* t);
// delegate helpers
const llvm::StructType* DtoDelegateType(Type* t);
llvm::Value* DtoNullDelegate(llvm::Value* v);
llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs);
// return linkage types for general cases
llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc);
// convert DMD calling conv to LLVM
unsigned DtoCallingConv(LINK l);
// TODO: this one should be removed!!!
llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val);
// casts any value to a boolean
llvm::Value* DtoBoolean(llvm::Value* val);
// some types
const llvm::Type* DtoSize_t();
const llvm::StructType* DtoInterfaceInfoType();
// initializer helpers
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
llvm::Constant* DtoConstFieldInitializer(Type* type, Initializer* init);
DValue* DtoInitializer(Initializer* init);
// declaration of memset/cpy intrinsics
llvm::Function* LLVM_DeclareMemSet32();
llvm::Function* LLVM_DeclareMemSet64();
llvm::Function* LLVM_DeclareMemCpy32();
llvm::Function* LLVM_DeclareMemCpy64();
// getelementptr helpers
llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb=NULL);
llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb=NULL);
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb=NULL);
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL);
// dynamic memory helpers
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
// assertion generator
void DtoAssert(Loc* loc, DValue* msg);
// nested variable/class helpers
llvm::Value* DtoNestedContext(FuncDeclaration* func);
llvm::Value* DtoNestedVariable(VarDeclaration* vd);
// annotation generator
void DtoAnnotation(const char* str);
// to constant helpers
llvm::ConstantInt* DtoConstSize_t(size_t);
llvm::ConstantInt* DtoConstUint(unsigned i);
llvm::ConstantInt* DtoConstInt(int i);
@@ -56,17 +79,18 @@ llvm::Constant* DtoConstStringPtr(const char* str, const char* section = 0);
llvm::Constant* DtoConstBool(bool);
llvm::Constant* DtoConstNullPtr(const llvm::Type* t);
// is template instance check
bool DtoIsTemplateInstance(Dsymbol* s);
// generates lazy static initialization code for a global variable
void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t);
// these are all basically drivers for the codegeneration called by the main loop
void DtoResolveDsymbol(Dsymbol* dsym);
void DtoDeclareDsymbol(Dsymbol* dsym);
void DtoDefineDsymbol(Dsymbol* dsym);
void DtoConstInitDsymbol(Dsymbol* dsym);
void DtoConstInitGlobal(VarDeclaration* vd);
void DtoEmptyResolveList();
void DtoEmptyDeclareList();
void DtoEmptyConstInitList();

View File

@@ -41,6 +41,8 @@
#include "gen/todebug.h"
#include "gen/runtime.h"
#include "ir/irvar.h"
//////////////////////////////////////////////////////////////////////////////////////////
// in gen/optimize.cpp
@@ -169,7 +171,7 @@ static llvm::Function* build_module_ctor()
size_t n = gIR->ctors.size();
if (n == 1)
return llvm::cast<llvm::Function>(gIR->ctors[0]->llvmValue);
return gIR->ctors[0]->irFunc->func;
std::string name("_D");
name.append(gIR->dmodule->mangle());
@@ -184,7 +186,7 @@ static llvm::Function* build_module_ctor()
LLVMBuilder builder(bb);
for (size_t i=0; i<n; i++) {
llvm::Function* f = llvm::cast<llvm::Function>(gIR->ctors[i]->llvmValue);
llvm::Function* f = gIR->ctors[i]->irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(llvm::CallingConv::Fast);
}
@@ -202,7 +204,7 @@ static llvm::Function* build_module_dtor()
size_t n = gIR->dtors.size();
if (n == 1)
return llvm::cast<llvm::Function>(gIR->dtors[0]->llvmValue);
return gIR->dtors[0]->irFunc->func;
std::string name("_D");
name.append(gIR->dmodule->mangle());
@@ -217,7 +219,7 @@ static llvm::Function* build_module_dtor()
LLVMBuilder builder(bb);
for (size_t i=0; i<n; i++) {
llvm::Function* f = llvm::cast<llvm::Function>(gIR->dtors[i]->llvmValue);
llvm::Function* f = gIR->dtors[i]->irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(llvm::CallingConv::Fast);
}
@@ -235,7 +237,7 @@ static llvm::Function* build_module_unittest()
size_t n = gIR->unitTests.size();
if (n == 1)
return llvm::cast<llvm::Function>(gIR->unitTests[0]->llvmValue);
return gIR->unitTests[0]->irFunc->func;
std::string name("_D");
name.append(gIR->dmodule->mangle());
@@ -250,7 +252,7 @@ static llvm::Function* build_module_unittest()
LLVMBuilder builder(bb);
for (size_t i=0; i<n; i++) {
llvm::Function* f = llvm::cast<llvm::Function>(gIR->unitTests[i]->llvmValue);
llvm::Function* f = gIR->unitTests[i]->irFunc->func;
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(llvm::CallingConv::Fast);
}
@@ -354,7 +356,7 @@ void Module::genmoduleinfo()
ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
if (cd->isInterfaceDeclaration())
{
Logger::println("skipping interface '%s'", cd->toPrettyChars());
Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
continue;
}
Logger::println("class: %s", cd->toPrettyChars());
@@ -507,7 +509,7 @@ void VarDeclaration::toObjFile()
llvmResolved = true;
llvmDeclared = true;
llvmIRGlobal = new IRGlobal(this);
irGlobal = new IrGlobal(this);
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
@@ -529,13 +531,13 @@ void VarDeclaration::toObjFile()
else
_linkage = DtoLinkage(protection, storage_class);
const llvm::Type* _type = llvmIRGlobal->type.get();
const llvm::Type* _type = irGlobal->type.get();
Logger::println("Creating global variable");
std::string _name(mangle());
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
llvmValue = gvar;
irGlobal->value = gvar;
if (static_local)
DtoConstInitGlobal(this);
@@ -549,9 +551,10 @@ void VarDeclaration::toObjFile()
Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset);
const llvm::Type* _type = DtoType(type);
irField = new IrField(this);
// add the field in the IRStruct
gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type)));
gIR->topstruct()->offsets.insert(std::make_pair(offset, IrStruct::Offset(this, _type)));
}
Logger::println("VarDeclaration::toObjFile is done");

View File

@@ -39,6 +39,8 @@
#include "gen/structs.h"
#include "gen/classes.h"
#include "ir/irvar.h"
/*******************************************
* Get a canonicalized form of the TypeInfo for use with the internal
* runtime library routines. Canonicalized in that static arrays are
@@ -254,7 +256,7 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
LOG_SCOPE;
tid->llvmIRGlobal = new IRGlobal(tid);
tid->irGlobal = new IrGlobal(tid);
gIR->declareList.push_back(tid);
}
@@ -280,15 +282,17 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
const llvm::Type* t = llvm::OpaqueType::get();
llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
assert(g);
tid->llvmValue = g;
/*if (!tid->irGlobal)
tid->irGlobal = new IrGlobal(tid);*/
tid->irGlobal->value = g;
mangled.append("__TYPE");
gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0));
Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str());
gIR->module->addTypeName(mangled, tid->irGlobal->value->getType()->getContainedType(0));
Logger::println("Got typeinfo var: %s", tid->irGlobal->value->getName().c_str());
tid->llvmInitialized = true;
tid->llvmDefined = true;
}
else if (!tid->llvmValue) {
tid->llvmValue = found;
else if (!tid->irGlobal->value) {
tid->irGlobal->value = found;
tid->llvmInitialized = true;
tid->llvmDefined = true;
}
@@ -352,7 +356,7 @@ void TypeInfoTypedefDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoTypedefDeclaration::llvmDefine()
@@ -385,12 +389,11 @@ void TypeInfoTypedefDeclaration::llvmDefine()
sd->basetype->getTypeInfo(NULL); // generate vtinfo
assert(sd->basetype->vtinfo);
if (!sd->basetype->vtinfo->llvmValue)
DtoForceDeclareDsymbol(sd->basetype->vtinfo);
DtoForceDeclareDsymbol(sd->basetype->vtinfo);
assert(sd->basetype->vtinfo->llvmValue);
assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue);
assert(sd->basetype->vtinfo->irGlobal->value);
assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
sinits.push_back(castbase);
@@ -418,7 +421,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
@@ -439,7 +442,7 @@ void TypeInfoEnumDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoEnumDeclaration::llvmDefine()
@@ -471,11 +474,10 @@ void TypeInfoEnumDeclaration::llvmDefine()
sd->memtype->getTypeInfo(NULL); // generate vtinfo
assert(sd->memtype->vtinfo);
if (!sd->memtype->vtinfo->llvmValue)
DtoForceDeclareDsymbol(sd->memtype->vtinfo);
DtoForceDeclareDsymbol(sd->memtype->vtinfo);
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
sinits.push_back(castbase);
@@ -504,7 +506,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
@@ -522,7 +524,7 @@ static llvm::Constant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, Cla
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
tid->llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
tid->irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
}
static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
@@ -543,16 +545,15 @@ static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclar
Logger::println("generating base typeinfo");
basetype->getTypeInfo(NULL);
assert(basetype->vtinfo);
if (!basetype->vtinfo->llvmValue)
DtoForceDeclareDsymbol(basetype->vtinfo);
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
DtoForceDeclareDsymbol(basetype->vtinfo);
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->irGlobal->value));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
sinits.push_back(castbase);
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(tid->llvmValue)->setInitializer(tiInit);
isaGlobalVar(tid->irGlobal->value)->setInitializer(tiInit);
}
/* ========================================================================= */
@@ -628,7 +629,7 @@ void TypeInfoStaticArrayDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoStaticArrayDeclaration::llvmDefine()
@@ -659,7 +660,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
// get symbol
assert(tc->next->vtinfo);
DtoForceDeclareDsymbol(tc->next->vtinfo);
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
sinits.push_back(castbase);
@@ -668,7 +669,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
@@ -691,7 +692,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoAssociativeArrayDeclaration::llvmDefine()
@@ -724,7 +725,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
// get symbol
assert(tc->next->vtinfo);
DtoForceDeclareDsymbol(tc->next->vtinfo);
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
sinits.push_back(castbase);
@@ -734,13 +735,13 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
// get symbol
assert(tc->index->vtinfo);
DtoForceDeclareDsymbol(tc->index->vtinfo);
castbase = isaConstant(tc->index->vtinfo->llvmValue);
castbase = isaConstant(tc->index->vtinfo->irGlobal->value);
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(3));
sinits.push_back(castbase);
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
@@ -824,7 +825,7 @@ void TypeInfoStructDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoStructDeclaration::llvmDefine()
@@ -924,8 +925,8 @@ void TypeInfoStructDeclaration::llvmDefine()
fd = fdx->overloadExactMatch(tftohash);
if (fd) {
DtoForceDeclareDsymbol(fd);
assert(fd->llvmValue != 0);
llvm::Constant* c = isaConstant(fd->llvmValue);
assert(fd->irFunc->func != 0);
llvm::Constant* c = isaConstant(fd->irFunc->func);
assert(c);
c = llvm::ConstantExpr::getBitCast(c, ptty);
sinits.push_back(c);
@@ -950,8 +951,8 @@ void TypeInfoStructDeclaration::llvmDefine()
fd = fdx->overloadExactMatch(tfeqptr);
if (fd) {
DtoForceDeclareDsymbol(fd);
assert(fd->llvmValue != 0);
llvm::Constant* c = isaConstant(fd->llvmValue);
assert(fd->irFunc->func != 0);
llvm::Constant* c = isaConstant(fd->irFunc->func);
assert(c);
c = llvm::ConstantExpr::getBitCast(c, ptty);
sinits.push_back(c);
@@ -978,8 +979,8 @@ void TypeInfoStructDeclaration::llvmDefine()
fd = fdx->overloadExactMatch(tftostring);
if (fd) {
DtoForceDeclareDsymbol(fd);
assert(fd->llvmValue != 0);
llvm::Constant* c = isaConstant(fd->llvmValue);
assert(fd->irFunc->func != 0);
llvm::Constant* c = isaConstant(fd->irFunc->func);
assert(c);
c = llvm::ConstantExpr::getBitCast(c, ptty);
sinits.push_back(c);
@@ -1000,7 +1001,7 @@ void TypeInfoStructDeclaration::llvmDefine()
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
@@ -1024,7 +1025,7 @@ void TypeInfoClassDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoClassDeclaration::llvmDefine()
@@ -1056,7 +1057,7 @@ void TypeInfoClassDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
@@ -1080,7 +1081,7 @@ void TypeInfoInterfaceDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoInterfaceDeclaration::llvmDefine()
@@ -1112,7 +1113,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
@@ -1136,7 +1137,7 @@ void TypeInfoTupleDeclaration::llvmDeclare()
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
// create the symbol
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
}
void TypeInfoTupleDeclaration::llvmDefine()
@@ -1175,8 +1176,8 @@ void TypeInfoTupleDeclaration::llvmDefine()
Argument *arg = (Argument *)tu->arguments->data[i];
arg->type->getTypeInfo(NULL);
DtoForceDeclareDsymbol(arg->type->vtinfo);
assert(arg->type->vtinfo->llvmValue);
llvm::Constant* c = isaConstant(arg->type->vtinfo->llvmValue);
assert(arg->type->vtinfo->irGlobal->value);
llvm::Constant* c = isaConstant(arg->type->vtinfo->irGlobal->value);
c = llvm::ConstantExpr::getBitCast(c, tiTy);
arrInits.push_back(c);
}
@@ -1191,7 +1192,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
isaGlobalVar(llvmValue)->setInitializer(tiInit);
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
}
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)

14
ir/ir.h Normal file
View File

@@ -0,0 +1,14 @@
// this head contains stuff used by all the IR
#ifndef LLVMDC_IR_IR_H
#define LLVMDC_IR_IR_H
#include "ir/irforw.h"
#include "root.h"
struct IrBase : Object
{
virtual ~IrBase() {}
};
#endif

45
ir/irforw.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef LLVMDC_IR_IRFORW_H
#define LLVMDC_IR_IRFORW_H
// dmd forward declarations
struct Module;
struct Dsymbol;
struct Declaration;
struct VarDeclaration;
struct FuncDeclaration;
struct AggregateDeclaration;
struct StructDeclaration;
struct ClassDeclaration;
struct InterfaceDeclaration;
struct Expression;
struct BaseClass;
struct Array;
struct Argument;
struct Type;
struct TypeStruct;
struct TypeClass;
struct TypeEnum;
struct TypeArray;
struct TypeFunction;
// llvm forward declarations
namespace llvm
{
class Value;
class GlobalValue;
class GlobalVariable;
class Function;
class Constant;
class ConstantStruct;
class ConstantArray;
class TargetData;
class Type;
class StructType;
class ArrayType;
class PointerType;
class BasicBlock;
class Instruction;
}
#endif

44
ir/irfunction.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include "gen/tollvm.h"
#include "ir/irfunction.h"
IrFinally::IrFinally()
{
bb = 0;
retbb = 0;
}
IrFinally::IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
{
bb = b;
retbb = rb;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrFunction::IrFunction(FuncDeclaration* fd)
{
decl = fd;
Type* t = DtoDType(fd->type);
assert(t->ty == Tfunction);
type = (TypeFunction*)t;
func = NULL;
allocapoint = NULL;
finallyretval = NULL;
queued = false;
defined = false;
retArg = NULL;
thisVar = NULL;
nestedVar = NULL;
_arguments = NULL;
_argptr = NULL;
dwarfSubProg = NULL;
}
IrFunction::~IrFunction()
{
}

44
ir/irfunction.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef LLVMDC_IR_IRFUNCTION_H
#define LLVMDC_IR_IRFUNCTION_H
#include "ir/ir.h"
#include <vector>
// represents a finally block
struct IrFinally
{
llvm::BasicBlock* bb;
llvm::BasicBlock* retbb;
IrFinally();
IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
};
// represents a function
struct IrFunction : IrBase
{
llvm::Function* func;
llvm::Instruction* allocapoint;
FuncDeclaration* decl;
TypeFunction* type;
// finally blocks
typedef std::vector<IrFinally> FinallyVec;
FinallyVec finallys;
llvm::Value* finallyretval;
bool queued;
bool defined;
llvm::Value* retArg;
llvm::Value* thisVar;
llvm::Value* nestedVar;
llvm::Value* _arguments;
llvm::Value* _argptr;
llvm::Constant* dwarfSubProg;
IrFunction(FuncDeclaration* fd);
virtual ~IrFunction();
};
#endif

10
ir/irmodule.cpp Normal file
View File

@@ -0,0 +1,10 @@
#include "ir/irmodule.h"
IrModule::IrModule(Module* module)
{
M = module;
}
IrModule::~IrModule()
{
}

16
ir/irmodule.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef LLVMDC_IR_IRMODULE_H
#define LLVMDC_IR_IRMODULE_H
#include "ir/ir.h"
struct Module;
struct IrModule : IrBase
{
IrModule(Module* module);
virtual ~IrModule();
Module* M;
};
#endif

38
ir/irstruct.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include "gen/llvm.h"
#include "mtype.h"
#include "aggregate.h"
#include "ir/irstruct.h"
IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt)
{
base = b;
decl = b->base;
vtblTy = vt;
vtblInit = NULL;
vtbl = NULL;
infoTy = NULL;
infoInit = NULL;
info = NULL;
}
IrInterface::~IrInterface()
{
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrStruct::IrStruct(Type* t)
: recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
{
type = t;
defined = false;
constinited = false;
interfaceInfosTy = NULL;
interfaceInfos = NULL;
}
IrStruct::~IrStruct()
{
}

65
ir/irstruct.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef LLVMDC_IR_IRSTRUCT_H
#define LLVMDC_IR_IRSTRUCT_H
#include "ir/ir.h"
#include <vector>
#include <map>
struct IrInterface : IrBase
{
BaseClass* base;
ClassDeclaration* decl;
const llvm::StructType* vtblTy;
llvm::ConstantStruct* vtblInit;
llvm::GlobalVariable* vtbl;
const llvm::StructType* infoTy;
llvm::ConstantStruct* infoInit;
llvm::Constant* info;
IrInterface(BaseClass* b, const llvm::StructType* vt);
~IrInterface();
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// represents a struct or class
struct IrStruct : IrBase
{
struct Offset
{
VarDeclaration* var;
const llvm::Type* type;
llvm::Constant* init;
Offset(VarDeclaration* v, const llvm::Type* ty)
: var(v), type(ty), init(NULL) {}
};
typedef std::multimap<unsigned, Offset> OffsetMap;
typedef std::vector<VarDeclaration*> VarDeclVector;
typedef std::map<ClassDeclaration*, IrInterface*> InterfaceMap;
typedef InterfaceMap::iterator InterfaceIter;
public:
IrStruct(Type*);
virtual ~IrStruct();
Type* type;
llvm::PATypeHolder recty;
OffsetMap offsets;
VarDeclVector defaultFields;
InterfaceMap interfaces;
const llvm::ArrayType* interfaceInfosTy;
llvm::GlobalVariable* interfaceInfos;
bool defined;
bool constinited;
};
#endif

63
ir/irvar.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "llvm/DerivedTypes.h"
#include "declaration.h"
#include "ir/irvar.h"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrVar* VarDeclaration::getIrVar()
{
assert(irGlobal || irLocal || irField);
return irGlobal ? (IrVar*)irGlobal : irLocal ? (IrVar*)irLocal : (IrVar*)irField;
}
llvm::Value*& VarDeclaration::getIrValue()
{
return getIrVar()->value;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrVar::IrVar(VarDeclaration* var)
{
V = var;
value = NULL;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v),
type(llvm::OpaqueType::get())
{
constInit = NULL;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrLocal::IrLocal(VarDeclaration* v) : IrVar(v)
{
nestedIndex = -1;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrField::IrField(VarDeclaration* v) : IrVar(v)
{
index = -1;
indexOffset = 0;
constInit = NULL;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

42
ir/irvar.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef LLVMDC_IR_IRVAR_H
#define LLVMDC_IR_IRVAR_H
#include "ir/ir.h"
#include "llvm/Type.h"
struct IrVar : IrBase
{
IrVar(VarDeclaration* var);
VarDeclaration* V;
llvm::Value* value;
};
// represents a global variable
struct IrGlobal : IrVar
{
IrGlobal(VarDeclaration* v);
llvm::PATypeHolder type;
llvm::Constant* constInit;
};
// represents a local variable variable
struct IrLocal : IrVar
{
IrLocal(VarDeclaration* v);
int nestedIndex;
};
// represents an aggregate field variable
struct IrField : IrVar
{
IrField(VarDeclaration* v);
int index;
size_t indexOffset;
llvm::Constant* constInit;
};
#endif

View File

@@ -120,7 +120,6 @@ gen/functions.h
gen/irstate.cpp
gen/irstate.h
gen/llvm.h
gen/llvmd.h
gen/logger.cpp
gen/logger.h
gen/optimizer.cpp
@@ -139,6 +138,19 @@ gen/tollvm.h
gen/toobj.cpp
gen/typeinf.h
gen/typinf.cpp
ir
ir/forw.h
ir/ir.h
ir/irfunction.cpp
ir/irfunction.h
ir/irglobal.cpp
ir/irglobal.h
ir/irmodule.cpp
ir/irmodule.h
ir/irstruct.cpp
ir/irstruct.h
ir/irvar.cpp
ir/irvar.h
lphobos
lphobos/build.sh
lphobos/crc32.d
@@ -263,7 +275,6 @@ tango/lib/compiler/llvmdc/aaA.d
tango/lib/compiler/llvmdc/adi.d
tango/lib/compiler/llvmdc/arrays.d
tango/lib/compiler/llvmdc/cast.d
tango/lib/compiler/llvmdc/contract.d
tango/lib/compiler/llvmdc/critical.c
tango/lib/compiler/llvmdc/dmain2.d
tango/lib/compiler/llvmdc/eh.d
@@ -749,6 +760,8 @@ tangotests/o.d
tangotests/p.d
tangotests/q.d
tangotests/r.d
tangotests/s.d
tangotests/t.d
test
test/a.d
test/aa1.d

View File

@@ -21,7 +21,7 @@ package.bindir = "bin"
package.name = "llvmdc"
package.kind = "exe"
package.language = "c++"
package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp") }
package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp"), matchfiles("ir/*.cpp") }
package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c" }
package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
package.linkoptions = {

View File

@@ -27,6 +27,9 @@
extern (C):
debug = PRINTF;
debug(PRINTF) int printf(char*, ...);
/******************************************
* Given a pointer:
* If it is an Object, return that Object.
@@ -54,6 +57,7 @@ Object _d_toObject(void* p)
o = cast(Object)(p - pi.offset);
}
}
debug(PRINTF) printf("toObject = %p\n", o);
return o;
}
@@ -75,6 +79,7 @@ Object _d_interface_cast(void* p, ClassInfo c)
o = cast(Object)(p - pi.offset);
return _d_dynamic_cast(o, c);
}
debug(PRINTF) printf("_d_interface_cast = %p\n", o);
return o;
}
@@ -82,7 +87,7 @@ Object _d_dynamic_cast(Object o, ClassInfo c)
{ ClassInfo oc;
size_t offset = 0;
//printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
if (o)
{
@@ -96,16 +101,20 @@ Object _d_dynamic_cast(Object o, ClassInfo c)
o = null;
}
//printf("\tresult = %p\n", o);
debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
return o;
}
int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
{ int i;
debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
if (oc is c)
return 1;
do
{
debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
if (oc.base is c)
return 1;
for (i = 0; i < oc.interfaces.length; i++)
@@ -113,6 +122,7 @@ int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
ClassInfo ic;
ic = oc.interfaces[i].classinfo;
debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
if (ic is c)
{ offset = cast(size_t)oc.interfaces[i].offset;
return 1;

View File

@@ -25,6 +25,7 @@ public import tango.io.model.IBuffer,
extern (C)
{
protected void * memcpy (void *dst, void *src, uint);
private int printf(char*, ...);
}
/*******************************************************************************
@@ -163,10 +164,14 @@ class Buffer : IBuffer
this (IConduit conduit)
{
printf("Buffer.this(%p)\n", conduit);
assert (conduit !is null);
assert (conduit);
this (conduit.bufferSize);
setConduit (conduit);
assert(this !is null);
}
/***********************************************************************
@@ -221,7 +226,8 @@ class Buffer : IBuffer
this (uint capacity = 0)
{
setContent (new ubyte[capacity], 0);
setContent (new ubyte[capacity], 0);
assert(this !is null);
}
/***********************************************************************

View File

@@ -23,6 +23,7 @@ private import tango.io.Buffer,
version (Posix)
private import tango.stdc.posix.unistd; // needed for isatty()
private extern(C) int printf(char*, ...);
/*******************************************************************************
@@ -69,6 +70,8 @@ struct Console
private this (Conduit conduit, bool redirected)
{
printf("Console.Input.this(%p, %d)\n", conduit, redirected);
assert (conduit);
redirect = redirected;
buffer = new Buffer (conduit);
}
@@ -596,6 +599,7 @@ struct Console
private this (Handle handle)
{
printf("Console.Conduit.this(%d)\n", handle);
reopen (handle);
redirected = (isatty(handle) is 0);
}
@@ -621,14 +625,13 @@ static Console.Output Cout, /// the standard output stream
******************************************************************************/
extern(C) int printf(char*, ...);
static this ()
{
printf("STATIC INIT FOR CONSOLE\n");
printf("Cin\n");
printf("Cin conduit\n");
auto conduit = new Console.Conduit (0);
assert(conduit);
printf("Cin input\n");
Cin = new Console.Input (conduit, conduit.redirected);
printf("Cout\n");

View File

@@ -18,6 +18,8 @@ public import tango.io.Conduit;
private import tango.core.Exception;
private extern(C) int printf(char*, ...);
/*******************************************************************************
Implements a means of reading and writing a file device. Conduits