[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").

Added support for array .sort and .reverse properties.
Fixed some bugs with pointer arithmetic.
Disabled some DMD AST optimizations that was messing things up, destroying valuable information.
Added a KDevelop project file, this is what I use for coding LLVMDC now :)
Other minor stuff.
This commit is contained in:
Tomas Lindquist Olsen
2007-11-12 06:32:46 +01:00
parent b32e04cacd
commit 3b4c818082
46 changed files with 2817 additions and 254 deletions

View File

@@ -21,14 +21,6 @@ const llvm::StructType* DtoArrayType(Type* t)
const llvm::Type* at = DtoType(t->next);
const llvm::Type* arrty;
/*if (t->ty == Tsarray) {
TypeSArray* tsa = (TypeSArray*)t;
assert(tsa->dim->type->isintegral());
arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
}
else {
arrty = llvm::ArrayType::get(at,0);
}*/
if (at == llvm::Type::VoidTy) {
at = llvm::Type::Int8Ty;
}
@@ -648,12 +640,17 @@ llvm::Value* DtoDynArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
//////////////////////////////////////////////////////////////////////////////////////////
llvm::Value* DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty)
{
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
assert(fn);
size_t esz = gTargetData->getTypeSize(elemty);
size_t nsz = gTargetData->getTypeSize(newelemty);
if (esz == nsz)
return len;
std::vector<llvm::Value*> args;
args.push_back(len);
args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(elemty), false));
args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(newelemty), false));
args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
}
@@ -722,7 +719,9 @@ llvm::Value* DtoArrayLen(DValue* v)
return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
}
else if (t->ty == Tsarray) {
const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(v->getLVal()->getType());
llvm::Value* rv = v->getRVal();
Logger::cout() << "casting: " << *rv << '\n';
const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(rv->getType()->getContainedType(0));
return DtoConstSize_t(t->getNumElements());
}
assert(0);

View File

@@ -5,5 +5,6 @@ enum
LLVMva_arg,
LLVMva_start,
LLVMva_intrinsic,
LLVMnotypeinfo
LLVMnotypeinfo,
LLVMalloca
};

View File

@@ -38,7 +38,6 @@ IRState::IRState()
emitMain = false;
mainFunc = 0;
ir.state = this;
dwarfCompileUnit = 0;
}
IRFunction& IRState::func()

View File

@@ -162,9 +162,6 @@ struct IRState
// builder helper
IRBuilderHelper ir;
// Dwarf debugging info
llvm::GlobalVariable* dwarfCompileUnit;
};
#endif // LLVMDC_GEN_IRSTATE_H

View File

@@ -62,5 +62,13 @@ namespace Logger
{
enabled = false;
}
void attention(const char* fmt,...)
{
printf("***ATTENTION*** ");
va_list va;
va_start(va,fmt);
vprintf(fmt,va);
va_end(va);
printf("\n");
}
}

View File

@@ -12,14 +12,14 @@ namespace Logger
void print(const char* fmt, ...);
void enable();
void disable();
void attention(const char* fmt, ...);
struct LoggerScope
{
LoggerScope()
{
Logger::indent();
}
~LoggerScope()
{

View File

@@ -7,7 +7,6 @@
#include <iostream>
#include "gen/llvm.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "total.h"
#include "init.h"
@@ -39,8 +38,7 @@ void CompoundStatement::toIR(IRState* p)
if (s)
s->toIR(p);
else {
Logger::println("*** ATTENTION: null statement found in CompoundStatement");
//assert(0);
Logger::println("??? null statement found in CompoundStatement");
}
}
}
@@ -133,8 +131,8 @@ void ExpStatement::toIR(IRState* p)
Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars());
LOG_SCOPE;
if (global.params.symdebug)
DtoDwarfStopPoint(loc.linnum);
// if (global.params.symdebug)
// DtoDwarfStopPoint(loc.linnum);
if (exp != 0) {
elem* e = exp->toElem(p);
@@ -255,8 +253,10 @@ void WhileStatement::toIR(IRState* p)
// rewrite scope
gIR->scope() = IRScope(whilebodybb,endbb);
// do while body code
// while body code
p->loopbbs.push_back(IRScope(whilebb,endbb));
body->toIR(p);
p->loopbbs.pop_back();
// loop
new llvm::BranchInst(whilebb, gIR->scopebegin());
@@ -284,7 +284,7 @@ void DoStatement::toIR(IRState* p)
// replace current scope
gIR->scope() = IRScope(dowhilebb,endbb);
// do do-while body code
// do-while body code
body->toIR(p);
// create the condition
@@ -363,8 +363,7 @@ void ForStatement::toIR(IRState* p)
void BreakStatement::toIR(IRState* p)
{
static int wsi = 0;
Logger::println("BreakStatement::toIR(%d): %s", wsi++, toChars());
Logger::println("BreakStatement::toIR(): %s", toChars());
LOG_SCOPE;
if (ident != 0) {
@@ -380,8 +379,7 @@ void BreakStatement::toIR(IRState* p)
void ContinueStatement::toIR(IRState* p)
{
static int wsi = 0;
Logger::println("ContinueStatement::toIR(%d): %s", wsi++, toChars());
Logger::println("ContinueStatement::toIR(): %s", toChars());
LOG_SCOPE;
if (ident != 0) {
@@ -397,8 +395,7 @@ void ContinueStatement::toIR(IRState* p)
void OnScopeStatement::toIR(IRState* p)
{
static int wsi = 0;
Logger::println("OnScopeStatement::toIR(%d): %s", wsi++, toChars());
Logger::println("OnScopeStatement::toIR(): %s", toChars());
LOG_SCOPE;
assert(statement);
@@ -407,10 +404,6 @@ void OnScopeStatement::toIR(IRState* p)
//////////////////////////////////////////////////////////////////////////////
static void replaceFinallyBBs(std::vector<llvm::BasicBlock*>& a, std::vector<llvm::BasicBlock*>& b)
{
}
void TryFinallyStatement::toIR(IRState* p)
{
Logger::println("TryFinallyStatement::toIR(): %s", toChars());
@@ -495,7 +488,7 @@ void TryCatchStatement::toIR(IRState* p)
Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars());
LOG_SCOPE;
Logger::println("*** ATTENTION: try-catch is not yet fully implemented, only the try block will be emitted.");
Logger::attention("try-catch is not yet fully implemented, only the try block will be emitted.");
assert(body);
body->toIR(p);
@@ -516,10 +509,9 @@ void ThrowStatement::toIR(IRState* p)
Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars());
LOG_SCOPE;
Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);");
Logger::attention("throw is not yet implemented, replacing expression with assert(0);");
llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
DtoAssert(NULL, line, NULL);
DtoAssert(NULL, &loc, NULL);
/*
assert(exp);
@@ -657,42 +649,62 @@ void ForeachStatement::toIR(IRState* p)
//Logger::println("Argument is %s", arg->toChars());
Logger::println("aggr = %s", aggr->toChars());
Logger::println("func = %s", func->toChars());
DValue* arr = aggr->toElem(p);
llvm::Value* val = 0;
if (!arr->isSlice()) {
val = arr->getRVal();
Logger::cout() << "aggr2llvm = " << *val << '\n';
}
llvm::Value* numiters = 0;
// 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;
llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false);
// value
const llvm::Type* valtype = DtoType(value->type);
llvm::Value* valvar = !(value->isRef() || value->isOut()) ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL;
llvm::Value* valvar = NULL;
if (!value->isRef() && !value->isOut())
valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
// what to iterate
DValue* aggrval = aggr->toElem(p);
Type* aggrtype = DtoDType(aggr->type);
// get length and pointer
llvm::Value* val = 0;
llvm::Value* niters = 0;
// static array
if (aggrtype->ty == Tsarray)
{
Logger::println("foreach over static array");
val = aggrval->getRVal();
assert(llvm::isa<llvm::PointerType>(val->getType()));
assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0)));
size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
assert(n > 0);
numiters = llvm::ConstantInt::get(keytype,n,false);
size_t nelems = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
assert(nelems > 0);
niters = llvm::ConstantInt::get(keytype,nelems,false);
}
// dynamic array
else if (aggrtype->ty == Tarray)
{
if (DSliceValue* slice = arr->isSlice()) {
numiters = slice->len;
if (DSliceValue* slice = aggrval->isSlice()) {
Logger::println("foreach over slice");
niters = slice->len;
assert(niters);
if (llvm::isa<llvm::ConstantInt>(niters)) {
llvm::ConstantInt* ci = llvm::cast<llvm::ConstantInt>(niters);
Logger::println("const num iters: %u", ci);
}
else {
Logger::cout() << "numiters: " << *niters <<'\n';
}
val = slice->ptr;
assert(val);
}
else {
numiters = p->ir->CreateLoad(DtoGEPi(val,0,0,"tmp",p->scopebb()));
val = p->ir->CreateLoad(DtoGEPi(val,0,1,"tmp",p->scopebb()));
Logger::println("foreach over dynamic array");
val = aggrval->getRVal();
niters = DtoGEPi(val,0,0,"tmp",p->scopebb());
niters = p->ir->CreateLoad(niters, "numiterations");
val = DtoGEPi(val,0,1,"tmp",p->scopebb());
val = p->ir->CreateLoad(val, "collection");
}
}
else
@@ -700,41 +712,39 @@ void ForeachStatement::toIR(IRState* p)
assert(0 && "aggregate type is not Tarray or Tsarray");
}
llvm::Constant* delta = 0;
if (op == TOKforeach) {
new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb());
new llvm::StoreInst(zerokey, keyvar, p->scopebb());
}
else if (op == TOKforeach_reverse) {
llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb());
new llvm::StoreInst(v, keyvar, p->scopebb());
else {
new llvm::StoreInst(niters, keyvar, p->scopebb());
}
delete arr;
llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend);
llvm::BasicBlock* condbb = new llvm::BasicBlock("foreachcond", p->topfunc(), oldend);
llvm::BasicBlock* bodybb = new llvm::BasicBlock("foreachbody", p->topfunc(), oldend);
llvm::BasicBlock* nextbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend);
new llvm::BranchInst(begbb, p->scopebb());
new llvm::BranchInst(condbb, p->scopebb());
// condition
p->scope() = IRScope(condbb,bodybb);
// next
p->scope() = IRScope(nexbb,begbb);
llvm::Value* done = 0;
llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
if (op == TOKforeach) {
load = llvm::BinaryOperator::createAdd(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
new llvm::StoreInst(load, keyvar, p->scopebb());
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, numiters, "tmp", p->scopebb());
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
}
else if (op == TOKforeach_reverse) {
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, llvm::ConstantInt::get(keytype, 0, false), "tmp", p->scopebb());
done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, zerokey, "tmp", p->scopebb());
load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb());
new llvm::StoreInst(load, keyvar, p->scopebb());
}
new llvm::BranchInst(begbb, endbb, done, p->scopebb());
new llvm::BranchInst(bodybb, endbb, done, p->scopebb());
// begin
p->scope() = IRScope(begbb,nexbb);
// body
p->scope() = IRScope(bodybb,nextbb);
// get value for this iteration
llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false);
@@ -754,13 +764,21 @@ void ForeachStatement::toIR(IRState* p)
}
// body
p->scope() = IRScope(p->scopebb(),endbb);
p->loopbbs.push_back(IRScope(nexbb,endbb));
p->loopbbs.push_back(IRScope(nextbb,endbb));
body->toIR(p);
p->loopbbs.pop_back();
if (!p->scopereturned())
new llvm::BranchInst(nexbb, p->scopebb());
new llvm::BranchInst(nextbb, p->scopebb());
// next
p->scope() = IRScope(nextbb,endbb);
if (op == TOKforeach) {
llvm::Value* load = DtoLoad(keyvar);
load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp");
DtoStore(load, keyvar);
}
new llvm::BranchInst(condbb, p->scopebb());
// end
p->scope() = IRScope(endbb,oldend);
@@ -828,13 +846,25 @@ void WithStatement::toIR(IRState* p)
//////////////////////////////////////////////////////////////////////////////
void SynchronizedStatement::toIR(IRState* p)
{
Logger::println("SynchronizedStatement::toIR(): %s", toChars());
LOG_SCOPE;
Logger::attention("synchronized is currently ignored. only the body will be emitted");
body->toIR(p);
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
//STUBST(BreakStatement);
//STUBST(ForStatement);
//STUBST(WithStatement);
STUBST(SynchronizedStatement);
//STUBST(SynchronizedStatement);
//STUBST(ReturnStatement);
//STUBST(ContinueStatement);
STUBST(DefaultStatement);

View File

@@ -56,7 +56,7 @@ const llvm::StructType* GetDwarfAnchorType()
*/
if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
vals.push_back(DtoConstUint(DW_TAG_compile_unit));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module);
@@ -64,7 +64,7 @@ const llvm::StructType* GetDwarfAnchorType()
}
if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
vals.push_back(DtoConstUint(DW_TAG_variable));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module);
@@ -72,7 +72,7 @@ const llvm::StructType* GetDwarfAnchorType()
}
if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) {
std::vector<llvm::Constant*> vals;
vals.push_back(DtoConstUint(0));
vals.push_back(DtoConstUint(llvm::LLVMDebugVersion));
vals.push_back(DtoConstUint(DW_TAG_subprogram));
llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module);
@@ -110,30 +110,33 @@ const llvm::StructType* GetDwarfSubProgramType() {
//////////////////////////////////////////////////////////////////////////////////////////////////
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define)
{
std::vector<llvm::Constant*> vals;
vals.push_back(llvm::ConstantExpr::getAdd(
DtoConstUint(DW_TAG_compile_unit),
DtoConstUint(llvm::LLVMDebugVersion)));
vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
llvm::Constant* c = NULL;
if (1 || define) {
std::vector<llvm::Constant*> vals;
vals.push_back(llvm::ConstantExpr::getAdd(
DtoConstUint(DW_TAG_compile_unit),
DtoConstUint(llvm::LLVMDebugVersion)));
vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
vals.push_back(DtoConstUint(DW_LANG_D));
vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
std::string srcpath(FileName::path(m->srcfile->name->toChars()));
srcpath.append("/");
vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
vals.push_back(DtoConstUint(DW_LANG_D));
vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
std::string srcpath(FileName::path(m->srcfile->name->toChars()));
srcpath.append("/");
vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
}
llvm::GlobalVariable* gv = new llvm::GlobalVariable(GetDwarfCompileUnitType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
gv->setSection("llvm.metadata");
return gv;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
{
std::vector<llvm::Constant*> vals;
vals.push_back(llvm::ConstantExpr::getAdd(
@@ -141,11 +144,11 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
DtoConstUint(llvm::LLVMDebugVersion)));
vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_subprogram)));
vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
vals.push_back(dbgToArrTy(compileUnit));
vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"));
vals.push_back(vals.back());
vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata"));
vals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
vals.push_back(dbgToArrTy(compileUnit));
vals.push_back(DtoConstUint(fd->loc.linnum));
vals.push_back(llvm::ConstantPointerNull::get(dbgArrTy()));
vals.push_back(DtoConstBool(fd->protection == PROTprivate));
@@ -178,6 +181,7 @@ void DtoDwarfStopPoint(unsigned ln)
std::vector<llvm::Value*> args;
args.push_back(DtoConstUint(ln));
args.push_back(DtoConstUint(0));
args.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
assert(gIR->dmodule->llvmCompileUnit);
args.push_back(dbgToArrTy(gIR->dmodule->llvmCompileUnit));
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
}

View File

@@ -7,8 +7,8 @@ const llvm::StructType* GetDwarfAnchorType();
const llvm::StructType* GetDwarfCompileUnitType();
const llvm::StructType* GetDwarfSubProgramType();
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m);
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define);
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit);
void DtoDwarfFuncStart(FuncDeclaration* fd);
void DtoDwarfFuncEnd(FuncDeclaration* fd);

View File

@@ -66,9 +66,7 @@ DValue* DeclarationExp::toElem(IRState* p)
//allocainst->setAlignment(vd->type->alignsize()); // TODO
vd->llvmValue = allocainst;
}
DVarValue* vv = new DVarValue(type, vd->llvmValue, true);
DValue* ie = DtoInitializer(vd->init, vv);
delete ie;
DValue* ie = DtoInitializer(vd->init);
}
return new DVarValue(vd, vd->llvmValue, true);
@@ -465,6 +463,7 @@ DValue* AssignExp::toElem(IRState* p)
DImValue* im = r->isIm();
if (!im || !im->inPlace()) {
Logger::println("assignment not inplace");
if (l->isArrayLen())
DtoResizeDynArray(l->getLVal(), r->getRVal());
else
@@ -659,7 +658,14 @@ DValue* AddExp::toElem(IRState* p)
return new DFieldValue(type, v, true);
}
else if (e1type->ty == Tpointer) {
Logger::println("add to AddrExp of struct");
Logger::println("add to pointer");
if (r->isConst()) {
llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
if (cofs->isZero()) {
Logger::println("is zero");
return new DImValue(type, l->getRVal());
}
}
llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
return new DImValue(type, v);
}
@@ -728,9 +734,14 @@ DValue* MinExp::toElem(IRState* p)
DValue* r = e2->toElem(p);
if (DtoDType(e1->type)->ty == Tpointer) {
llvm::Value* left = p->ir->CreatePtrToInt(l->getRVal(), DtoSize_t(), "tmp");
llvm::Value* right = p->ir->CreatePtrToInt(r->getRVal(), DtoSize_t(), "tmp");
llvm::Value* diff = p->ir->CreateSub(left,right,"tmp");
llvm::Value* lv = l->getRVal();
llvm::Value* rv = r->getRVal();
Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n';
if (isaPointer(lv))
lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp");
if (isaPointer(rv))
rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp");
llvm::Value* diff = p->ir->CreateSub(lv,rv,"tmp");
if (diff->getType() != DtoType(type))
diff = p->ir->CreateIntToPtr(diff, DtoType(type));
return new DImValue(type, diff);
@@ -1095,6 +1106,13 @@ DValue* CallExp::toElem(IRState* p)
llt = llvm::PointerType::get(llt);
return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
}
else if (fndecl->llvmInternal == LLVMalloca) {
//Argument* fnarg = Argument::getNth(tf->parameters, 0);
Expression* exp = (Expression*)arguments->data[0];
DValue* expv = exp->toElem(p);
llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
return new DImValue(type, alloc);
}
}
// args
@@ -1545,14 +1563,13 @@ DValue* SymOffExp::toElem(IRState* p)
if (offset != 0) {
Logger::println("offset = %d\n", offset);
}
if (llvalue->getType() != llt) {
varmem = p->ir->CreateBitCast(llvalue, llt, "tmp");
if (offset != 0)
varmem = DtoGEPi(varmem, offset, "tmp");
if (offset == 0) {
varmem = llvalue;
}
else {
assert(offset == 0);
varmem = DtoGEPi(llvalue,0,0,"tmp");
const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0);
size_t elemsz = gTargetData->getTypeSize(elemtype);
varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp");
}
}
else if (offset == 0) {
@@ -1571,17 +1588,30 @@ DValue* SymOffExp::toElem(IRState* p)
}
return new DFieldValue(type, varmem, true);
}
else if (FuncDeclaration* fd = var->isFuncDeclaration())
assert(0);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////
DValue* AddrExp::toElem(IRState* p)
{
Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
DValue* v = e1->toElem(p);
if (v->isField())
return v;
if (DFuncValue* fv = v->isFunc())
{
Logger::println("FuncDeclaration");
FuncDeclaration* fd = fv->func;
assert(fd);
if (fd->llvmValue == 0)
fd->toObjFile();
return new DFuncValue(fd, fd->llvmValue);
}
assert(0);
return 0;
return new DFieldValue(type, v->getLVal(), false);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -1700,18 +1730,6 @@ DValue* ThisExp::toElem(IRState* p)
//////////////////////////////////////////////////////////////////////////////////////////
DValue* AddrExp::toElem(IRState* p)
{
Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
DValue* v = e1->toElem(p);
if (v->isField())
return v;
return new DFieldValue(type, v->getLVal(), false);
}
//////////////////////////////////////////////////////////////////////////////////////////
DValue* IndexExp::toElem(IRState* p)
{
Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars());
@@ -1755,7 +1773,7 @@ DValue* SliceExp::toElem(IRState* p)
Type* e1type = DtoDType(e1->type);
DValue* v = e1->toElem(p);
llvm::Value* vmem = v->isIm() ? v->getRVal() : v->getLVal();
llvm::Value* vmem = v->getRVal();
assert(vmem);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
@@ -2100,47 +2118,46 @@ DValue* NewExp::toElem(IRState* p)
const llvm::Type* t = DtoType(ntype);
llvm::Value* emem = 0;
bool inplace = true;
bool inplace = false;
if (onstack) {
assert(ntype->ty == Tclass);
emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint());
}
else {
if (ntype->ty == Tclass) {
emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
}
else if (ntype->ty == Tarray) {
assert(arguments);
if (arguments->dim == 1) {
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
llvm::Value* dimval = sz->getRVal();
Type* nnt = DtoDType(ntype->next);
if (nnt->ty == Tvoid)
nnt = Type::tint8;
if (!p->topexp() || p->topexp()->e2 != this) {
const llvm::Type* restype = DtoType(type);
Logger::cout() << "restype = " << *restype << '\n';
emem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint());
DtoNewDynArray(emem, dimval, nnt);
inplace = false;
}
else if (p->topexp() || p->topexp()->e2 != this) {
assert(p->topexp()->v);
emem = p->topexp()->v->getLVal();
DtoNewDynArray(emem, dimval, nnt);
}
else
assert(0);
else if (ntype->ty == Tclass) {
emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb());
}
else if (ntype->ty == Tarray) {
assert(arguments);
if (arguments->dim == 1) {
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
llvm::Value* dimval = sz->getRVal();
Type* nnt = DtoDType(ntype->next);
if (nnt->ty == Tvoid)
nnt = Type::tint8;
if (!p->topexp() || p->topexp()->e2 != this) {
const llvm::Type* restype = DtoType(type);
Logger::cout() << "restype = " << *restype << '\n';
emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
DtoNewDynArray(emem, dimval, nnt);
return new DVarValue(newtype, emem, true);
}
else {
assert(0);
else if (p->topexp() && p->topexp()->e2 == this) {
assert(p->topexp()->v);
emem = p->topexp()->v->getLVal();
DtoNewDynArray(emem, dimval, nnt);
inplace = true;
}
else
assert(0);
}
else {
emem = new llvm::MallocInst(t,"tmp",p->scopebb());
assert(0);
}
}
else {
emem = new llvm::MallocInst(t,"tmp",p->scopebb());
}
if (ntype->ty == Tclass) {
// first apply the static initializer
@@ -2175,10 +2192,7 @@ DValue* NewExp::toElem(IRState* p)
}
}
if (inplace)
return new DImValue(type, emem, true);
return new DVarValue(type, emem, true);
return new DImValue(type, emem, inplace);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2264,8 +2278,7 @@ DValue* AssertExp::toElem(IRState* p)
DValue* u = e1->toElem(p);
DValue* m = msg ? msg->toElem(p) : NULL;
llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
DtoAssert(u->getRVal(), loca, m ? m->getRVal() : NULL);
DtoAssert(u->getRVal(), &loc, m);
return 0;
}
@@ -2401,8 +2414,7 @@ DValue* HaltExp::toElem(IRState* p)
Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false);
DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL);
DtoAssert(DtoConstBool(false), &loc, NULL);
new llvm::UnreachableInst(p->scopebb());
return 0;
@@ -2634,18 +2646,18 @@ DValue* FuncExp::toElem(IRState* p)
fd->toObjFile();
bool temp = false;
llvm::Value* lval = NULL;
if (!p->topexp() || p->topexp()->e2 != this) {
if (p->topexp() && p->topexp()->e2 == this) {
assert(p->topexp()->v);
lval = p->topexp()->v->getLVal();
}
else {
const llvm::Type* dgty = DtoType(type);
Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n';
lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
temp = true;
}
else if (p->topexp()->e2 == this) {
assert(p->topexp()->v);
lval = p->topexp()->v->getLVal();;
}
else
assert(0);
llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0));
@@ -2665,7 +2677,10 @@ DValue* FuncExp::toElem(IRState* p)
llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
new llvm::StoreInst(castfptr, fptr, p->scopebb());
return new DImValue(type, lval, true);
if (temp)
return new DVarValue(type, lval, true);
else
return new DImValue(type, lval, true);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -3093,7 +3108,7 @@ void obj_includelib(char*){}
AsmStatement::AsmStatement(Loc loc, Token *tokens) :
Statement(loc)
{
assert(0);
Logger::println("Ignoring AsmStatement");
}
Statement *AsmStatement::syntaxCopy()
{

View File

@@ -797,15 +797,13 @@ llvm::Constant* DtoConstInitializer(Type* type, Initializer* init)
//////////////////////////////////////////////////////////////////////////////////////////
DValue* DtoInitializer(Initializer* init, DValue* v)
DValue* DtoInitializer(Initializer* init)
{
if (ExpInitializer* ex = init->isExpInitializer())
{
Logger::println("expression initializer");
assert(ex->exp);
if (v) gIR->exps.push_back(IRExp(NULL,ex->exp,v));
return ex->exp->toElem(gIR);
if (v) gIR->exps.pop_back();
}
else if (init->isVoidInitializer())
{
@@ -1050,16 +1048,17 @@ llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg)
void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg)
{
assert(loc);
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
const llvm::FunctionType* fnt = fn->getFunctionType();
std::vector<llvm::Value*> llargs;
llargs.resize(3);
llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse();
llargs[1] = loc;
llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
llargs[1] = DtoConstUint(loc->linnum);
llargs[2] = msg ? msg->getRVal() : llvm::Constant::getNullValue(fnt->getParamType(2));
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
assert(fn);
llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
call->setCallingConv(llvm::CallingConv::C);
@@ -1301,6 +1300,11 @@ void DtoAssign(DValue* lhs, DValue* rhs)
llvm::Value* r = rhs->getRVal();
llvm::Value* l = lhs->getLVal();
Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
const llvm::Type* lit = l->getType()->getContainedType(0);
if (r->getType() != lit) {
r = DtoBitCast(r, lit);
Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
}
gIR->ir->CreateStore(r, l);
}
}
@@ -1404,6 +1408,31 @@ llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
return gIR->ir->CreateBitCast(v, t, "tmp");
}
const llvm::PointerType* isaPointer(llvm::Value* v)
{
return llvm::dyn_cast<llvm::PointerType>(v->getType());
}
const llvm::ArrayType* isaArray(llvm::Value* v)
{
return llvm::dyn_cast<llvm::ArrayType>(v->getType());
}
const llvm::StructType* isaStruct(llvm::Value* v)
{
return llvm::dyn_cast<llvm::StructType>(v->getType());
}
llvm::Constant* isaConstant(llvm::Value* v)
{
return llvm::dyn_cast<llvm::Constant>(v);
}
llvm::ConstantInt* isaConstantInt(llvm::Value* v)
{
return llvm::dyn_cast<llvm::ConstantInt>(v);
}
//////////////////////////////////////////////////////////////////////////////////////////
bool DtoIsTemplateInstance(Dsymbol* s)
@@ -1431,7 +1460,7 @@ void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type*
llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
gIR->ir->CreateCondBr(cond, initbb, endinitbb);
gIR->scope() = IRScope(initbb,endinitbb);
DValue* ie = DtoInitializer(init, NULL);
DValue* ie = DtoInitializer(init);
if (!ie->inPlace()) {
DValue* dst = new DVarValue(t, gvar, true);
DtoAssign(dst, ie);

View File

@@ -34,7 +34,7 @@ void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance);
void DtoInitClass(TypeClass* tc, llvm::Value* dst);
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
DValue* DtoInitializer(Initializer* init, DValue* v);
DValue* DtoInitializer(Initializer* init);
llvm::Function* LLVM_DeclareMemSet32();
llvm::Function* LLVM_DeclareMemSet64();
@@ -49,7 +49,7 @@ llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::stri
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg);
void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg);
llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp);
@@ -75,6 +75,13 @@ llvm::Value* DtoLoad(llvm::Value* src);
void DtoStore(llvm::Value* src, llvm::Value* dst);
llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t);
// llvm::dyn_cast wrappers
const llvm::PointerType* isaPointer(llvm::Value* v);
const llvm::ArrayType* isaArray(llvm::Value* v);
const llvm::StructType* isaStruct(llvm::Value* v);
llvm::Constant* isaConstant(llvm::Value* v);
llvm::ConstantInt* isaConstantInt(llvm::Value* v);
// basic operations
void DtoAssign(DValue* lhs, DValue* rhs);

View File

@@ -81,7 +81,7 @@ Module::genobjfile()
// debug info
if (global.params.symdebug) {
RegisterDwarfSymbols(ir.module);
ir.dwarfCompileUnit = DtoDwarfCompileUnit(this);
ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true);
}
// process module members
@@ -162,7 +162,7 @@ void Module::genmoduleinfo()
Logger::println("vmoduleinfo");
}
if (needModuleInfo()) {
Logger::println("**** ATTENTION: module info is needed but skipped");
Logger::attention("module info is needed but skipped");
}
@@ -905,7 +905,7 @@ void FuncDeclaration::toObjFile()
}
if (isUnitTestDeclaration()) {
Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars());
Logger::attention("ignoring unittest declaration: %s", toChars());
return;
}
@@ -948,7 +948,11 @@ void FuncDeclaration::toObjFile()
// debug info
if (global.params.symdebug) {
llvmDwarfSubProgram = DtoDwarfSubProgram(this);
Module* mo = getModule();
if (!mo->llvmCompileUnit) {
mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
}
llvmDwarfSubProgram = DtoDwarfSubProgram(this, mo->llvmCompileUnit);
}
assert(f->llvmType);
@@ -1033,7 +1037,7 @@ void FuncDeclaration::toObjFile()
vd->llvmValue = v;
}
else {
Logger::println("*** ATTENTION: some unknown argument: %s", arg ? arg->toChars() : 0);
Logger::attention("some unknown argument: %s", arg ? arg->toChars() : 0);
}
}