mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-29 18:40:04 +02:00
[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:
@@ -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);
|
||||
|
||||
@@ -5,5 +5,6 @@ enum
|
||||
LLVMva_arg,
|
||||
LLVMva_start,
|
||||
LLVMva_intrinsic,
|
||||
LLVMnotypeinfo
|
||||
LLVMnotypeinfo,
|
||||
LLVMalloca
|
||||
};
|
||||
|
||||
@@ -38,7 +38,6 @@ IRState::IRState()
|
||||
emitMain = false;
|
||||
mainFunc = 0;
|
||||
ir.state = this;
|
||||
dwarfCompileUnit = 0;
|
||||
}
|
||||
|
||||
IRFunction& IRState::func()
|
||||
|
||||
@@ -162,9 +162,6 @@ struct IRState
|
||||
|
||||
// builder helper
|
||||
IRBuilderHelper ir;
|
||||
|
||||
// Dwarf debugging info
|
||||
llvm::GlobalVariable* dwarfCompileUnit;
|
||||
};
|
||||
|
||||
#endif // LLVMDC_GEN_IRSTATE_H
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
171
gen/toir.cpp
171
gen/toir.cpp
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
gen/tollvm.h
11
gen/tollvm.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user