[svn r10] Updated for LLVM rev. 20070913

Applied fixes from wilsonk on the forum
Some tweaks to work with gc 7.0
Fixed aggregate members of aggregates
Fixed cyclic/recursive class declarations
Other minor tweaks
This commit is contained in:
Tomas Lindquist Olsen
2007-09-26 19:05:18 +02:00
parent 5d2e8f1009
commit 329ad7747c
10 changed files with 118 additions and 54 deletions

View File

@@ -6,7 +6,8 @@
#include <stdlib.h>
#include <string.h>
#include "gc.h"
// I needed to perfix the dir after upgrading to gc 7.0
#include "gc/gc.h"
#include "mem.h"
@@ -14,10 +15,12 @@
*/
Mem mem;
static bool gc_was_init = false;
void Mem::init()
{
GC_init();
gc_was_init = true;
}
char *Mem::strdup(const char *s)
@@ -127,7 +130,11 @@ void Mem::mark(void *pointer)
/* =================================================== */
void * operator new(size_t m_size)
{
{
// without this we segfault with gc 7.0
if (!gc_was_init) {
mem.init();
}
void *p = GC_malloc(m_size);
if (p)
return p;

View File

@@ -133,11 +133,11 @@ llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
llvm::Value* dstlen = new llvm::GetElementPtrInst(dst,zero,zero,"tmp",gIR->scopebb());
llvm::Value* dstlen = LLVM_DtoGEP(dst,zero,zero,"tmp",gIR->scopebb());
llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
llvm::Value* dstptr = new llvm::GetElementPtrInst(dst,zero,one,"tmp",gIR->scopebb());
llvm::Value* dstptr = LLVM_DtoGEP(dst,zero,one,"tmp",gIR->scopebb());
llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb());
new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
}
@@ -155,7 +155,7 @@ void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
std::vector<llvm::Value*> args;
args.resize(3);
args[0] = new llvm::GetElementPtrInst(l,zero,zero,"tmp",gIR->scopebb());
args[0] = LLVM_DtoGEP(l,zero,zero,"tmp",gIR->scopebb());
args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
args[2] = r;
@@ -225,10 +225,10 @@ void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
llvm::Value* arrdim = new llvm::GetElementPtrInst(arr,zero,zero,"tmp",gIR->scopebb());
llvm::Value* arrdim = LLVM_DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
new llvm::StoreInst(dim, arrdim, gIR->scopebb());
llvm::Value* arrptr = new llvm::GetElementPtrInst(arr,zero,one,"tmp",gIR->scopebb());
llvm::Value* arrptr = LLVM_DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
}

View File

@@ -99,7 +99,7 @@ IRStruct::IRStruct()
type = 0;
}
IRStruct::IRStruct(TypeStruct* t)
IRStruct::IRStruct(Type* t)
: recty(llvm::OpaqueType::get())
{
type = t;

View File

@@ -36,7 +36,7 @@ struct IRScope
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
};
// represents a struct
// represents a struct or class
struct IRStruct : Object
{
typedef std::vector<const llvm::Type*> TypeVector;
@@ -45,21 +45,15 @@ struct IRStruct : Object
public:
IRStruct();
IRStruct(TypeStruct*);
IRStruct(Type*);
virtual ~IRStruct();
TypeStruct* type;
Type* type;
TypeVector fields;
ConstantVector inits;
llvm::PATypeHolder recty;
};
// represents a clas
struct IRClass : Object
{
// TODO
};
// represents the module
struct IRState : Object
{

View File

@@ -101,7 +101,8 @@ elem* VarExp::toElem(IRState* p)
if (!p->arrays.empty())
{
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb());
//llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb());
llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb());
e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb());
e->type = elem::VAL;
}
@@ -205,7 +206,13 @@ elem* RealExp::toElem(IRState* p)
Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
elem* e = new elem;
e->val = llvm::ConstantFP::get(LLVM_DtoType(type),value);
const llvm::Type* fty = LLVM_DtoType(type);
if (type->ty == Tfloat32)
e->val = llvm::ConstantFP::get(fty,float(value));
else if (type->ty == Tfloat64 || type->ty == Tfloat80)
e->val = llvm::ConstantFP::get(fty,double(value));
else
assert(0);
e->type = elem::CONST;
return e;
}
@@ -251,7 +258,7 @@ elem* StringExp::toElem(IRState* p)
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* arrptr = new llvm::GetElementPtrInst(gvar,zero,zero,"tmp",p->scopebb());
llvm::Value* arrptr = LLVM_DtoGEP(gvar,zero,zero,"tmp",p->scopebb());
elem* e = new elem;
@@ -435,7 +442,7 @@ elem* AddExp::toElem(IRState* p)
TypeStruct* ts = (TypeStruct*)e1->type->next;
llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, ts->sym->offsetToIndex(cofs->getZExtValue()), false);
e->mem = new llvm::GetElementPtrInst(l->getValue(), zero, offset, "tmp", p->scopebb());
e->mem = LLVM_DtoGEP(l->getValue(), zero, offset, "tmp", p->scopebb());
e->type = elem::VAR;
e->field = true;
}
@@ -806,7 +813,7 @@ elem* CallExp::toElem(IRState* p)
}
// struct pointer - delegate
else if (llvm::isa<llvm::StructType>(funcval->getType()->getContainedType(0))) {
funcval = new llvm::GetElementPtrInst(funcval,zero,one,"tmp",p->scopebb());
funcval = LLVM_DtoGEP(funcval,zero,one,"tmp",p->scopebb());
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
const llvm::Type* ty = funcval->getType()->getContainedType(0);
llfnty = llvm::cast<llvm::FunctionType>(ty);
@@ -865,7 +872,7 @@ elem* CallExp::toElem(IRState* p)
// delegate context parameter
else if (delegateCall) {
Logger::println("Delegate Call");
llvm::Value* contextptr = new llvm::GetElementPtrInst(fn->mem,zero,zero,"tmp",p->scopebb());
llvm::Value* contextptr = LLVM_DtoGEP(fn->mem,zero,zero,"tmp",p->scopebb());
llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb());
++j;
++argiter;
@@ -1039,7 +1046,7 @@ elem* CastExp::toElem(IRState* p)
assert(from->next == to->next);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
llvm::Value* ptr = new llvm::GetElementPtrInst(u->getValue(),zero,one,"tmp",p->scopebb());
llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb());
e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
e->type = elem::VAL;
}
@@ -1067,10 +1074,10 @@ elem* CastExp::toElem(IRState* p)
else {
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
e->arg = new llvm::GetElementPtrInst(uval,zero,zero,"tmp",p->scopebb());
e->arg = LLVM_DtoGEP(uval,zero,zero,"tmp",p->scopebb());
e->arg = new llvm::LoadInst(e->arg, "tmp", p->scopebb());
e->mem = new llvm::GetElementPtrInst(uval,zero,one,"tmp",p->scopebb());
e->mem = LLVM_DtoGEP(uval,zero,one,"tmp",p->scopebb());
e->mem = new llvm::LoadInst(e->mem, "tmp", p->scopebb());
//Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
e->mem = new llvm::BitCastInst(e->mem, ptrty, "tmp", p->scopebb());
@@ -1124,7 +1131,7 @@ elem* SymOffExp::toElem(IRState* p)
//const llvm::Type* _typ = llvm::GetElementPtrInst::getIndexedType(LLVM_DtoType(type), idx1);
llvm::Value* ptr = vd->llvmValue;
assert(ptr);
e->mem = new llvm::GetElementPtrInst(ptr,idx0,idx1,"tmp",p->scopebb());
e->mem = LLVM_DtoGEP(ptr,idx0,idx1,"tmp",p->scopebb());
e->type = elem::VAL;
e->field = true;
}
@@ -1135,7 +1142,7 @@ elem* SymOffExp::toElem(IRState* p)
e = new elem;
llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
//llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
e->mem = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());
e->mem = LLVM_DtoGEP(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());
e->type = elem::VAL;
}
else if (offset == 0) {
@@ -1222,7 +1229,7 @@ elem* DotVarExp::toElem(IRState* p)
assert(src != 0);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, vdoffset, false);
llvm::Value* arrptr = new llvm::GetElementPtrInst(src,zero,offset,"tmp",p->scopebb());
llvm::Value* arrptr = LLVM_DtoGEP(src,zero,offset,"tmp",p->scopebb());
e->mem = arrptr;
Logger::cout() << "mem: " << *e->mem << '\n';
e->type = elem::VAR;
@@ -1246,10 +1253,10 @@ elem* DotVarExp::toElem(IRState* p)
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false);
funcval = new llvm::GetElementPtrInst(e->arg, zero, zero, "tmp", p->scopebb());
funcval = LLVM_DtoGEP(e->arg, zero, zero, "tmp", p->scopebb());
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
funcval = new llvm::BitCastInst(funcval, vtbltype, "tmp", p->scopebb());
funcval = new llvm::GetElementPtrInst(funcval, zero, vtblidx, "tmp", p->scopebb());
funcval = LLVM_DtoGEP(funcval, zero, vtblidx, "tmp", p->scopebb());
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
funcval = new llvm::BitCastInst(funcval, fdecl->llvmValue->getType(), "tmp", p->scopebb());
}
@@ -1337,7 +1344,7 @@ elem* StructLiteralExp::toElem(IRState* p)
for (unsigned i=0; i<n; ++i)
{
llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false);
llvm::Value* arrptr = new llvm::GetElementPtrInst(sptr,zero,offset,"tmp",p->scopebb());
llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb());
Expression* vx = (Expression*)elements->data[i];
if (vx != 0) {
@@ -1380,10 +1387,10 @@ elem* IndexExp::toElem(IRState* p)
arrptr = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb());
}
else if (e1->type->ty == Tsarray) {
arrptr = new llvm::GetElementPtrInst(l->mem, zero, r->getValue(),"tmp",p->scopebb());
arrptr = LLVM_DtoGEP(l->mem, zero, r->getValue(),"tmp",p->scopebb());
}
else if (e1->type->ty == Tarray) {
arrptr = new llvm::GetElementPtrInst(l->mem,zero,one,"tmp",p->scopebb());
arrptr = LLVM_DtoGEP(l->mem,zero,one,"tmp",p->scopebb());
arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb());
arrptr = new llvm::GetElementPtrInst(arrptr,r->getValue(),"tmp",p->scopebb());
}
@@ -1431,7 +1438,7 @@ elem* SliceExp::toElem(IRState* p)
e->mem = v->getValue();
}
else if (e1->type->ty == Tarray) {
llvm::Value* tmp = new llvm::GetElementPtrInst(v->mem,zero,one,"tmp",p->scopebb());
llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb());
e->mem = new llvm::LoadInst(tmp,"tmp",p->scopebb());
}
else
@@ -1444,7 +1451,7 @@ elem* SliceExp::toElem(IRState* p)
}
else
{
llvm::Value* tmp = new llvm::GetElementPtrInst(v->mem,zero,one,"tmp",p->scopebb());
llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb());
tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb());
e->mem = new llvm::GetElementPtrInst(tmp,lo->getValue(),"tmp",p->scopebb());
}
@@ -1834,7 +1841,7 @@ elem* DeleteExp::toElem(IRState* p)
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
llvm::Value* ptr = new llvm::GetElementPtrInst(ldval,zero,one,"tmp",p->scopebb());
llvm::Value* ptr = LLVM_DtoGEP(ldval,zero,one,"tmp",p->scopebb());
ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb());
new llvm::FreeInst(ptr, p->scopebb());
LLVM_DtoNullArray(val);
@@ -1860,7 +1867,7 @@ elem* ArrayLengthExp::toElem(IRState* p)
elem* u = e1->toElem(p);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* ptr = new llvm::GetElementPtrInst(u->mem,zero,zero,"tmp",p->scopebb());
llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb());
e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
e->type = elem::VAL;
@@ -2086,11 +2093,11 @@ elem* DelegateExp::toElem(IRState* p)
llvm::Value* lval = p->toplval();
llvm::Value* context = new llvm::GetElementPtrInst(lval,zero,zero,"tmp",p->scopebb());
llvm::Value* context = LLVM_DtoGEP(lval,zero,zero,"tmp",p->scopebb());
llvm::Value* castcontext = new llvm::BitCastInst(u->getValue(),int8ptrty,"tmp",p->scopebb());
new llvm::StoreInst(castcontext, context, p->scopebb());
llvm::Value* fptr = new llvm::GetElementPtrInst(lval,zero,one,"tmp",p->scopebb());
llvm::Value* fptr = LLVM_DtoGEP(lval,zero,one,"tmp",p->scopebb());
assert(func->llvmValue);
llvm::Value* castfptr = new llvm::BitCastInst(func->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());

View File

@@ -99,15 +99,23 @@ const llvm::Type* LLVM_DtoType(Type* t)
case Tclass: {
if (t->llvmType == 0)
{
// recursive or cyclic declaration
if (!gIR->structs.empty())
{
IRStruct* found = 0;
for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
{
if (t == i->type)
{
return llvm::PointerType::get(i->recty.get());
}
}
}
// forward declaration
TypeClass* tc = (TypeClass*)t;
assert(tc->sym);
if (!tc->sym->llvmInProgress) {
tc->sym->toObjFile();
}
else {
//assert(0 && "circular class referencing");
return llvm::OpaqueType::get();
}
tc->sym->toObjFile();
}
return llvm::PointerType::get(t->llvmType);
}
@@ -122,7 +130,7 @@ const llvm::Type* LLVM_DtoType(Type* t)
return t->llvmType;
}
}
// delegates
case Tdelegate:
{
@@ -803,3 +811,11 @@ llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
}
return _init;
}
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb)
{
std::vector<llvm::Value*> v(2);
v[0] = i0;
v[1] = i1;
return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb);
}

View File

@@ -36,4 +36,6 @@ llvm::Function* LLVM_DeclareMemSet64();
llvm::Function* LLVM_DeclareMemCpy32();
llvm::Function* LLVM_DeclareMemCpy64();
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb);
#include "enums.h"

View File

@@ -48,18 +48,21 @@ Module::genobjfile()
Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n';
LOG_SCOPE;
// start by deleting the old object file
deleteObjFile();
// creaet a new ir state
IRState ir;
gIR = &ir;
ir.dmodule = this;
// name the module
std::string mname(toChars());
if (md != 0)
mname = md->toChars();
ir.module = new llvm::Module(mname);
// set target stuff
std::string target_triple(global.params.tt_arch);
target_triple.append(global.params.tt_os);
ir.module->setTargetTriple(target_triple);
@@ -67,6 +70,7 @@ Module::genobjfile()
gTargetData = new llvm::TargetData(ir.module);
// process module members
for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
assert(dsym);
@@ -76,6 +80,7 @@ Module::genobjfile()
delete gTargetData;
gTargetData = 0;
// verify the llvm
std::string verifyErr;
if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr))
{
@@ -83,6 +88,7 @@ Module::genobjfile()
fatal();
}
// emit the llvm main function if necessary
if (ir.emitMain) {
LLVM_DtoMain();
}
@@ -97,6 +103,7 @@ Module::genobjfile()
ir.module->print(os);
}*/
// write bytecode
//if (global.params.llvmBC) {
Logger::println("Writing LLVM bitcode\n");
std::ofstream os(bcfile->name->toChars(), std::ios::binary);
@@ -131,6 +138,7 @@ void Declaration::toObjFile()
/* ================================================================== */
/// Returns the LLVM style index from a DMD style offset
unsigned AggregateDeclaration::offsetToIndex(unsigned os)
{
for (unsigned i=0; i<fields.dim; ++i) {
@@ -165,6 +173,8 @@ static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsig
return (unsigned)-1;
}
/// Returns the LLVM style index from a DMD style offset
/// Handles class inheritance
unsigned ClassDeclaration::offsetToIndex(unsigned os)
{
unsigned idx = 0;
@@ -308,7 +318,7 @@ void ClassDeclaration::toObjFile()
Logger::print("ClassDeclaration::toObjFile(%d): %s\n", fdi++, toChars());
LOG_SCOPE;
gIR->structs.push_back(IRStruct());
gIR->structs.push_back(IRStruct(ts));
gIR->classes.push_back(this);
gIR->classmethods.push_back(IRState::FuncDeclVec());
gIR->queueClassMethods.push_back(true);
@@ -328,6 +338,14 @@ void ClassDeclaration::toObjFile()
}
llvm::StructType* structtype = llvm::StructType::get(gIR->topstruct().fields);
// refine abstract types for stuff like: class C {C next;}
if (gIR->topstruct().recty != 0)
{
llvm::PATypeHolder& pa = gIR->topstruct().recty;
llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(structtype);
structtype = llvm::cast<llvm::StructType>(pa.get());
}
ts->llvmType = structtype;
llvmType = structtype;
@@ -527,6 +545,12 @@ void VarDeclaration::toObjFile()
std::vector<llvm::Constant*> vals(n,_init);
_init = llvm::ConstantArray::get(arrty, vals);
}
else if (llvm::isa<llvm::StructType>(_type)) {
const llvm::StructType* structty = llvm::cast<llvm::StructType>(_type);
TypeStruct* ts = (TypeStruct*)type;
assert(ts->sym->llvmInitZ);
_init = ts->sym->llvmInitZ;
}
else
assert(0);
}

17
test/classes5.d Normal file
View File

@@ -0,0 +1,17 @@
module classes5;
struct S
{
long l;
}
class C
{
C c;
S s;
}
void main()
{
//C c = new C;
}

View File

@@ -1,9 +1,6 @@
module typeinfo;
typedef int int_t;
void main()
{
int_t i;
i += 3;
auto ti = typeid(int);
}