Changed use of toObjFile to a new codegen method.

More versioning of DMD specific codegen code.
This commit is contained in:
Tomas Lindquist Olsen
2009-03-27 17:54:27 +01:00
parent c42c90ea80
commit daef67acc3
23 changed files with 446 additions and 351 deletions

View File

@@ -105,7 +105,7 @@ static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
Array* arr = cd->members;
for (int k=0; k < arr->dim; k++) {
Dsymbol* s = (Dsymbol*)arr->data[k];
s->toObjFile(0);
s->codegen(Type::sir);
}
// add interfaces
@@ -177,7 +177,7 @@ static void DtoResolveInterface(InterfaceDeclaration* cd)
Array* arr = cd->members;
for (int k=0; k < arr->dim; k++) {
Dsymbol* s = (Dsymbol*)arr->data[k];
s->toObjFile(0);
s->codegen(Type::sir);
}
}

268
gen/declarations.cpp Normal file
View File

@@ -0,0 +1,268 @@
#include "gen/llvm.h"
#include "aggregate.h"
#include "declaration.h"
#include "enum.h"
#include "id.h"
#include "mem.h"
#include "template.h"
#include "gen/irstate.h"
#include "gen/tollvm.h"
#include "gen/llvmhelpers.h"
#include "gen/logger.h"
#include "ir/ir.h"
#include "ir/irvar.h"
/* ================================================================== */
void Dsymbol::codegen(Ir*)
{
Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
}
/* ================================================================== */
void Declaration::codegen(Ir*)
{
Logger::println("Ignoring Declaration::toObjFile for %s", toChars());
}
/* ================================================================== */
void InterfaceDeclaration::codegen(Ir*)
{
//Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
DtoResolveDsymbol(this);
}
/* ================================================================== */
void StructDeclaration::codegen(Ir*)
{
DtoResolveDsymbol(this);
}
/* ================================================================== */
void ClassDeclaration::codegen(Ir*)
{
DtoResolveDsymbol(this);
}
/* ================================================================== */
void TupleDeclaration::codegen(Ir* p)
{
Logger::println("TupleDeclaration::toObjFile(): %s", toChars());
assert(isexp);
assert(objects);
int n = objects->dim;
for (int i=0; i < n; ++i)
{
DsymbolExp* exp = (DsymbolExp*)objects->data[i];
assert(exp->op == TOKdsymbol);
exp->s->codegen(p);
}
}
/* ================================================================== */
void VarDeclaration::codegen(Ir* p)
{
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
if (aliassym)
{
Logger::println("alias sym");
toAlias()->codegen(p);
return;
}
// global variable or magic
#if DMDV2
// taken from dmd2/structs
if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
#else
if (isDataseg())
#endif
{
Logger::println("data segment");
#if DMDV2
if (storage_class & STCmanifest)
{
assert(0 && "manifest constant being codegened!!!");
}
#endif
// don't duplicate work
if (this->ir.resolved) return;
this->ir.resolved = true;
this->ir.declared = true;
this->ir.irGlobal = new IrGlobal(this);
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
#if DMDV2
// not sure why this is only needed for d2
bool _isconst = isConst() && init;
#else
bool _isconst = isConst();
#endif
Logger::println("Creating global variable");
const LLType* _type = this->ir.irGlobal->type.get();
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
std::string _name(mangle());
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
this->ir.irGlobal->value = gvar;
if (Logger::enabled())
Logger::cout() << *gvar << '\n';
// if this global is used from a nested function, this is necessary or
// optimization could potentially remove the global (if it's the only use)
if (nakedUse)
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
gIR->constInitList.push_back(this);
}
else
{
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
if (!ir.irField)
{
assert(!ir.isSet());
ir.irField = new IrField(this);
}
IrStruct* irstruct = gIR->topstruct();
irstruct->addVar(this);
Logger::println("added offset %u", offset);
}
}
/* ================================================================== */
void TypedefDeclaration::codegen(Ir*)
{
static int tdi = 0;
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
LOG_SCOPE;
// generate typeinfo
DtoTypeInfoOf(type, false);
}
/* ================================================================== */
void EnumDeclaration::codegen(Ir*)
{
Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
}
/* ================================================================== */
void FuncDeclaration::codegen(Ir*)
{
DtoResolveDsymbol(this);
}
/* ================================================================== */
void AnonDeclaration::codegen(Ir* p)
{
Array *d = include(NULL, NULL);
if (d)
{
// get real aggregate parent
IrStruct* irstruct = gIR->topstruct();
// push a block on the stack
irstruct->pushAnon(isunion);
// go over children
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->codegen(p);
}
// finish
irstruct->popAnon();
}
}
/* ================================================================== */
void TemplateInstance::codegen(Ir* p)
{
#if LOG
printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this);
#endif
if (!errors && members)
{
for (int i = 0; i < members->dim; i++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->codegen(p);
}
}
}
/* ================================================================== */
void TemplateMixin::codegen(Ir* p)
{
TemplateInstance::codegen(p);
}
/* ================================================================== */
void AttribDeclaration::codegen(Ir* p)
{
Array *d = include(NULL, NULL);
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->codegen(p);
}
}
}
/* ================================================================== */
void obj_includelib(const char* lib);
void PragmaDeclaration::codegen(Ir* p)
{
if (ident == Id::lib)
{
assert(args && args->dim == 1);
Expression *e = (Expression *)args->data[0];
assert(e->op == TOKstring);
StringExp *se = (StringExp *)e;
char *name = (char *)mem.malloc(se->len + 1);
memcpy(name, se->string, se->len);
name[se->len] = 0;
obj_includelib(name);
}
AttribDeclaration::codegen(p);
}
/* ================================================================== */

View File

@@ -979,99 +979,12 @@ void DtoConstInitGlobal(VarDeclaration* vd)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoEmptyResolveList()
{
//Logger::println("DtoEmptyResolveList()");
Dsymbol* dsym;
while (!gIR->resolveList.empty()) {
dsym = gIR->resolveList.front();
gIR->resolveList.pop_front();
DtoResolveDsymbol(dsym);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoEmptyDeclareList()
{
//Logger::println("DtoEmptyDeclareList()");
Dsymbol* dsym;
while (!gIR->declareList.empty()) {
dsym = gIR->declareList.front();
gIR->declareList.pop_front();
DtoDeclareDsymbol(dsym);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoEmptyConstInitList()
{
//Logger::println("DtoEmptyConstInitList()");
Dsymbol* dsym;
while (!gIR->constInitList.empty()) {
dsym = gIR->constInitList.front();
gIR->constInitList.pop_front();
DtoConstInitDsymbol(dsym);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoEmptyDefineList()
{
//Logger::println("DtoEmptyDefineList()");
Dsymbol* dsym;
while (!gIR->defineList.empty()) {
dsym = gIR->defineList.front();
gIR->defineList.pop_front();
DtoDefineDsymbol(dsym);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoEmptyAllLists()
{
for(;;)
{
Dsymbol* dsym;
if (!gIR->resolveList.empty()) {
dsym = gIR->resolveList.front();
gIR->resolveList.pop_front();
DtoResolveDsymbol(dsym);
}
else if (!gIR->declareList.empty()) {
dsym = gIR->declareList.front();
gIR->declareList.pop_front();
DtoDeclareDsymbol(dsym);
}
else if (!gIR->constInitList.empty()) {
dsym = gIR->constInitList.front();
gIR->constInitList.pop_front();
DtoConstInitDsymbol(dsym);
}
else if (!gIR->defineList.empty()) {
dsym = gIR->defineList.front();
gIR->defineList.pop_front();
DtoDefineDsymbol(dsym);
}
else {
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void DtoForceDeclareDsymbol(Dsymbol* dsym)
{
if (dsym->ir.declared) return;
Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars());
LOG_SCOPE;
DtoResolveDsymbol(dsym);
DtoEmptyResolveList();
DtoDeclareDsymbol(dsym);
}
@@ -1083,10 +996,7 @@ void DtoForceConstInitDsymbol(Dsymbol* dsym)
Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars());
LOG_SCOPE;
DtoResolveDsymbol(dsym);
DtoEmptyResolveList();
DtoEmptyDeclareList();
DtoDeclareDsymbol(dsym);
DtoConstInitDsymbol(dsym);
}
@@ -1098,11 +1008,8 @@ void DtoForceDefineDsymbol(Dsymbol* dsym)
Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars());
LOG_SCOPE;
DtoResolveDsymbol(dsym);
DtoEmptyResolveList();
DtoEmptyDeclareList();
DtoEmptyConstInitList();
DtoDeclareDsymbol(dsym);
DtoConstInitDsymbol(dsym);
DtoDefineDsymbol(dsym);
}
@@ -1129,7 +1036,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
// static
if (vd->isDataseg())
{
vd->toObjFile(0); // TODO: multiobj
vd->codegen(Type::sir);
}
else
{

View File

@@ -94,10 +94,6 @@ void DtoDeclareDsymbol(Dsymbol* dsym);
void DtoDefineDsymbol(Dsymbol* dsym);
void DtoConstInitDsymbol(Dsymbol* dsym);
void DtoConstInitGlobal(VarDeclaration* vd);
void DtoEmptyResolveList();
void DtoEmptyDeclareList();
void DtoEmptyConstInitList();
void DtoEmptyAllLists();
void DtoForceDeclareDsymbol(Dsymbol* dsym);
void DtoForceConstInitDsymbol(Dsymbol* dsym);
void DtoForceDefineDsymbol(Dsymbol* dsym);

View File

@@ -362,6 +362,7 @@ int main(int argc, char** argv)
}
// create a proper target
Ir ir;
// check -m32/64 sanity
if (m32bits && m64bits)
@@ -562,7 +563,7 @@ int main(int argc, char** argv)
#endif
// Initialization
Type::init();
Type::init(&ir);
Id::initialize();
Module::init();
initPrecedence();
@@ -832,7 +833,7 @@ int main(int argc, char** argv)
printf("code %s\n", m->toChars());
if (global.params.obj)
{
llvm::Module* lm = m->genLLVMModule(0);
llvm::Module* lm = m->genLLVMModule(&ir);
if (!singleObj)
{
m->deleteObjFile();

View File

@@ -72,7 +72,7 @@ void ExpStatement::toNakedIR(IRState *p)
// enum decls should always be safe
// make sure the symbols gets processed
d->declaration->toObjFile(0);
d->declaration->codegen(Type::sir);
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -538,7 +538,7 @@ void DtoResolveStruct(StructDeclaration* sd)
Array* arr = sd->members;
for (int k=0; k < arr->dim; k++) {
Dsymbol* s = (Dsymbol*)arr->data[k];
s->toObjFile(0);
s->codegen(Type::sir);
}
const LLType* ST = irstruct->build();

View File

@@ -147,7 +147,7 @@ DValue* VarExp::toElem(IRState* p)
// take care of forward references of global variables
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
vd->toObjFile(0); // TODO: multiobj
vd->codegen(Type::sir);
}
LLValue* val;

View File

@@ -70,7 +70,7 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath);
//////////////////////////////////////////////////////////////////////////////////////////
llvm::Module* Module::genLLVMModule(int multiobj)
llvm::Module* Module::genLLVMModule(Ir* sir)
{
bool logenabled = Logger::enabled();
if (llvmForceLogging && !logenabled)
@@ -100,6 +100,8 @@ llvm::Module* Module::genLLVMModule(int multiobj)
IrDsymbol::resetAll();
IrType::resetAll();
sir->setState(&ir);
// module ir state
// might already exist via import, just overwrite since
// the global created for the filename must belong to the right llvm module
@@ -137,15 +139,11 @@ llvm::Module* Module::genLLVMModule(int multiobj)
for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
assert(dsym);
dsym->toObjFile(multiobj);
dsym->codegen(sir);
}
// main driver loop
DtoEmptyAllLists();
// generate ModuleInfo
genmoduleinfo();
// do this again as moduleinfo might have pulled something in!
DtoEmptyAllLists();
// emit usedArray
if (!ir.usedArray.empty())
@@ -172,12 +170,14 @@ llvm::Module* Module::genLLVMModule(int multiobj)
}
gIR = NULL;
if (llvmForceLogging && !logenabled)
{
Logger::disable();
}
sir->setState(NULL);
return ir.module;
}
@@ -680,6 +680,8 @@ void Module::genmoduleinfo()
for (size_t i = 0; i < aclasses.dim; i++)
{
ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
cd->codegen(Type::sir);
if (cd->isInterfaceDeclaration())
{
Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
@@ -790,191 +792,3 @@ void Module::genmoduleinfo()
std::string appendName("llvm.global_ctors");
llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
}
/* ================================================================== */
void Dsymbol::toObjFile(int multiobj)
{
Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
}
/* ================================================================== */
void Declaration::toObjFile(int unused)
{
Logger::println("Ignoring Declaration::toObjFile for %s", toChars());
}
/* ================================================================== */
void InterfaceDeclaration::toObjFile(int multiobj)
{
//Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
gIR->resolveList.push_back(this);
}
/* ================================================================== */
void StructDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
/* ================================================================== */
void ClassDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
/* ================================================================== */
void TupleDeclaration::toObjFile(int multiobj)
{
Logger::println("TupleDeclaration::toObjFile(): %s", toChars());
assert(isexp);
assert(objects);
int n = objects->dim;
for (int i=0; i < n; ++i)
{
DsymbolExp* exp = (DsymbolExp*)objects->data[i];
assert(exp->op == TOKdsymbol);
exp->s->toObjFile(multiobj);
}
}
/* ================================================================== */
void VarDeclaration::toObjFile(int multiobj)
{
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
if (aliassym)
{
Logger::println("alias sym");
toAlias()->toObjFile(multiobj);
return;
}
// global variable or magic
#if DMDV2
// taken from dmd2/structs
if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
#else
if (isDataseg())
#endif
{
Logger::println("data segment");
#if DMDV2
if (storage_class & STCmanifest)
{
assert(0 && "manifest constant being codegened!!!");
}
#endif
// don't duplicate work
if (this->ir.resolved) return;
this->ir.resolved = true;
this->ir.declared = true;
this->ir.irGlobal = new IrGlobal(this);
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
#if DMDV2
// not sure why this is only needed for d2
bool _isconst = isConst() && init;
#else
bool _isconst = isConst();
#endif
Logger::println("Creating global variable");
const LLType* _type = this->ir.irGlobal->type.get();
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
std::string _name(mangle());
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
this->ir.irGlobal->value = gvar;
if (Logger::enabled())
Logger::cout() << *gvar << '\n';
// if this global is used from a nested function, this is necessary or
// optimization could potentially remove the global (if it's the only use)
if (nakedUse)
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
gIR->constInitList.push_back(this);
}
else
{
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
if (!ir.irField)
{
assert(!ir.isSet());
ir.irField = new IrField(this);
}
IrStruct* irstruct = gIR->topstruct();
irstruct->addVar(this);
Logger::println("added offset %u", offset);
}
}
/* ================================================================== */
void TypedefDeclaration::toObjFile(int multiobj)
{
static int tdi = 0;
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
LOG_SCOPE;
// generate typeinfo
DtoTypeInfoOf(type, false);
}
/* ================================================================== */
void EnumDeclaration::toObjFile(int multiobj)
{
Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
}
/* ================================================================== */
void FuncDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
/* ================================================================== */
void AnonDeclaration::toObjFile(int multiobj)
{
Array *d = include(NULL, NULL);
if (d)
{
// get real aggregate parent
IrStruct* irstruct = gIR->topstruct();
// push a block on the stack
irstruct->pushAnon(isunion);
// go over children
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->toObjFile(multiobj);
}
// finish
irstruct->popAnon();
}
}

View File

@@ -138,13 +138,17 @@ Expression *Type::getTypeInfo(Scope *sc)
}
else // if in obj generation pass
{
#if IN_DMD
t->vtinfo->toObjFile(0); // TODO: multiobj
#else
t->vtinfo->codegen(sir);
#endif
}
}
}
e = new VarExp(0, t->vtinfo);
//e = e->addressOf(sc);
//e->type = t->vtinfo->type; // do this so we don't get redundant dereference
e = e->addressOf(sc);
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
return e;
}
@@ -267,11 +271,6 @@ Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
// MAGIC PLACE
//////////////////////////////////////////////////////////////////////////////
void TypeInfoDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
{
if (tid->ir.resolved) return;
@@ -285,6 +284,11 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
gIR->declareList.push_back(tid);
}
void TypeInfoDeclaration::codegen(Ir*)
{
DtoResolveTypeInfo(this);
}
void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
{
if (tid->ir.declared) return;