Merge pull request #386 from klickverbot/store-bool-as-i8

Store bool as i8.
This commit is contained in:
David Nadlinger
2013-06-07 10:32:50 -07:00
29 changed files with 168 additions and 116 deletions

View File

@@ -72,7 +72,7 @@ struct elem;
#if IN_LLVM #if IN_LLVM
struct IRState; struct IRState;
struct DValue; class DValue;
namespace llvm { namespace llvm {
class Constant; class Constant;
class ConstantInt; class ConstantInt;

View File

@@ -21,7 +21,7 @@ struct Symbol;
struct FuncDeclaration; struct FuncDeclaration;
struct Blockx; struct Blockx;
#if IN_LLVM #if IN_LLVM
struct DValue; class DValue;
typedef DValue elem; typedef DValue elem;
#else #else
struct elem; struct elem;

View File

@@ -29,7 +29,7 @@ class Library;
// Back end // Back end
#if IN_LLVM #if IN_LLVM
class Ir; class Ir;
struct DValue; class DValue;
typedef DValue elem; typedef DValue elem;
namespace llvm { namespace llvm {
class LLVMContext; class LLVMContext;

View File

@@ -75,7 +75,7 @@ namespace llvm
struct IRState; struct IRState;
struct Blockx; struct Blockx;
#if IN_LLVM #if IN_LLVM
struct DValue; class DValue;
typedef DValue elem; typedef DValue elem;
#endif #endif

View File

@@ -74,7 +74,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
} }
// cast return value // cast return value
LLType* targettype = getPtrToType(DtoType(type)); LLType* targettype = getPtrToType(i1ToI8(DtoType(type)));
if (ret->getType() != targettype) if (ret->getType() != targettype)
ret = DtoBitCast(ret, targettype); ret = DtoBitCast(ret, targettype);

View File

@@ -17,7 +17,7 @@
#include "lexer.h" #include "lexer.h"
enum TOK; enum TOK;
struct DValue; class DValue;
struct Loc; struct Loc;
struct Type; struct Type;
namespace llvm { class Value; } namespace llvm { class Value; }

View File

@@ -28,7 +28,7 @@
struct Type; struct Type;
struct TypeFunction; struct TypeFunction;
struct IrFuncTyArg; struct IrFuncTyArg;
struct DValue; class DValue;
namespace llvm namespace llvm
{ {

View File

@@ -64,9 +64,7 @@ static LLValue *DtoSlicePtr(DValue *dval)
LLStructType* DtoArrayType(Type* arrayTy) LLStructType* DtoArrayType(Type* arrayTy)
{ {
assert(arrayTy->nextOf()); assert(arrayTy->nextOf());
LLType* elemty = DtoType(arrayTy->nextOf()); LLType* elemty = i1ToI8(voidToI8(DtoType(arrayTy->nextOf())));
if (elemty == LLType::getVoidTy(gIR->context()))
elemty = LLType::getInt8Ty(gIR->context());
llvm::Type *elems[] = { DtoSize_t(), getPtrToType(elemty) }; llvm::Type *elems[] = { DtoSize_t(), getPtrToType(elemty) };
return llvm::StructType::get(gIR->context(), elems, false); return llvm::StructType::get(gIR->context(), elems, false);
@@ -87,10 +85,7 @@ LLArrayType* DtoStaticArrayType(Type* t)
TypeSArray* tsa = static_cast<TypeSArray*>(t); TypeSArray* tsa = static_cast<TypeSArray*>(t);
Type* tnext = tsa->nextOf(); Type* tnext = tsa->nextOf();
LLType* elemty = DtoType(tnext); LLType* elemty = i1ToI8(voidToI8(DtoType(tnext)));
if (elemty == LLType::getVoidTy(gIR->context()))
elemty = LLType::getInt8Ty(gIR->context());
return LLArrayType::get(elemty, tsa->dim->toUInteger()); return LLArrayType::get(elemty, tsa->dim->toUInteger());
} }
@@ -291,7 +286,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
// get elem type // get elem type
Type* elemty = arrty->nextOf(); Type* elemty = arrty->nextOf();
LLType* llelemty = DtoTypeNotVoid(elemty); LLType* llelemty = i1ToI8(voidToI8(DtoType(elemty)));
// true if array elements differ in type, can happen with array of unions // true if array elements differ in type, can happen with array of unions
bool mismatch = false; bool mismatch = false;
@@ -424,7 +419,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
LLValue* dstarr = get_slice_ptr(dst,sz1); LLValue* dstarr = get_slice_ptr(dst,sz1);
LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType()); LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType());
LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype()); LLType* arrayelemty = voidToI8(DtoType(src->getType()->nextOf()->toBasetype()));
LLValue* sz2 = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(arrayelemty)), DtoArrayLen(src), "tmp"); LLValue* sz2 = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(arrayelemty)), DtoArrayLen(src), "tmp");
copySlice(dstarr, sz1, srcarr, sz2); copySlice(dstarr, sz1, srcarr, sz2);
@@ -939,7 +934,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
Logger::cout() << "to array" << '\n'; Logger::cout() << "to array" << '\n';
LLType* ptrty = DtoArrayType(totype)->getContainedType(1); LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
LLType* ety = DtoTypeNotVoid(fromtype->nextOf()); LLType* ety = voidToI8(DtoType(fromtype->nextOf()));
if (fromtype->ty == Tsarray) { if (fromtype->ty == Tsarray) {
LLValue* uval = u->getRVal(); LLValue* uval = u->getRVal();

View File

@@ -18,8 +18,8 @@
#include "gen/llvm.h" #include "gen/llvm.h"
struct ArrayInitializer; struct ArrayInitializer;
struct DSliceValue; class DSliceValue;
struct DValue; class DValue;
struct Expression; struct Expression;
struct Loc; struct Loc;
struct Type; struct Type;

View File

@@ -497,7 +497,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
} }
// cast it to the right type // cast it to the right type
val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); val = DtoBitCast(val, getPtrToType(i1ToI8(DtoType(vd->type))));
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "value: " << *val << '\n'; Logger::cout() << "value: " << *val << '\n';

View File

@@ -17,7 +17,7 @@
#include "lexer.h" #include "lexer.h"
#include "longdouble.h" #include "longdouble.h"
struct DValue; class DValue;
struct Loc; struct Loc;
struct Type; struct Type;
namespace llvm namespace llvm

View File

@@ -172,7 +172,7 @@ void VarDeclaration::codegen(Ir* p)
// this->ir.irGlobal->value!), and in case we also do an initializer // this->ir.irGlobal->value!), and in case we also do an initializer
// with a different type later, swap it out and replace any existing // with a different type later, swap it out and replace any existing
// uses with bitcasts to the previous type. // uses with bitcasts to the previous type.
llvm::GlobalVariable* gvar = createGlobal(DtoType(type), isLLConst, llvm::GlobalVariable* gvar = createGlobal(i1ToI8(DtoType(type)), isLLConst,
llLinkage, llName, isThreadlocal()); llLinkage, llName, isThreadlocal());
this->ir.irGlobal->value = gvar; this->ir.irGlobal->value = gvar;
@@ -206,7 +206,7 @@ void VarDeclaration::codegen(Ir* p)
ir.irGlobal->constInit = initVal; ir.irGlobal->constInit = initVal;
gvar->setInitializer(initVal); gvar->setInitializer(initVal);
// Also set up the debug info. // Also set up the edbug info.
DtoDwarfGlobalVariable(gvar, this); DtoDwarfGlobalVariable(gvar, this);
} }

View File

@@ -18,18 +18,36 @@
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
static bool checkVarValueType(LLType* t, bool extraDeref)
{
if (extraDeref)
{
llvm::PointerType* pt = llvm::dyn_cast<llvm::PointerType>(t);
if (!pt) return false;
t = pt->getElementType();
}
llvm::PointerType* pt = llvm::dyn_cast<llvm::PointerType>(t);
if (!pt) return false;
// bools should not be stored as i1 any longer.
if (pt->getElementType() == llvm::Type::getInt1Ty(gIR->context()))
return false;
return true;
}
DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue)
: DValue(t), var(vd), val(llvmValue) : DValue(t), var(vd), val(llvmValue)
{ {
assert(isaPointer(llvmValue)); assert(checkVarValueType(llvmValue->getType(), isSpecialRefVar(vd)));
assert(!isSpecialRefVar(vd) ||
isaPointer(isaPointer(llvmValue)->getElementType()));
} }
DVarValue::DVarValue(Type* t, LLValue* llvmValue) DVarValue::DVarValue(Type* t, LLValue* llvmValue)
: DValue(t), var(0), val(llvmValue) : DValue(t), var(0), val(llvmValue)
{ {
assert(isaPointer(llvmValue)); assert(checkVarValueType(llvmValue->getType(), false));
} }
LLValue* DVarValue::getLVal() LLValue* DVarValue::getLVal()
@@ -43,15 +61,24 @@ LLValue* DVarValue::getLVal()
LLValue* DVarValue::getRVal() LLValue* DVarValue::getRVal()
{ {
assert(val); assert(val);
Type* bt = type->toBasetype();
LLValue* tmp = val; llvm::Value* storage = val;
if (var && isSpecialRefVar(var)) if (var && isSpecialRefVar(var))
tmp = DtoLoad(tmp); storage = DtoLoad(storage);
if (DtoIsPassedByRef(bt)) if (DtoIsPassedByRef(type->toBasetype()))
return tmp; return storage;
return DtoLoad(tmp);
llvm::Value* rawValue = DtoLoad(storage);
if (type->toBasetype()->ty == Tbool)
{
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
return gIR->ir->CreateTrunc(rawValue,
llvm::Type::getInt1Ty(gIR->context()));
}
return rawValue;
} }
LLValue* DVarValue::getRefStorage() LLValue* DVarValue::getRefStorage()

View File

@@ -32,19 +32,21 @@ namespace llvm
class Constant; class Constant;
} }
struct DImValue; class DImValue;
struct DConstValue; class DConstValue;
struct DNullValue; class DNullValue;
struct DVarValue; class DVarValue;
struct DFieldValue; class DFieldValue;
struct DFuncValue; class DFuncValue;
struct DSliceValue; class DSliceValue;
// base class for d-values // base class for d-values
struct DValue : Object class DValue
{ {
public:
Type* type; Type* type;
DValue(Type* ty) : type(ty) {} DValue(Type* ty) : type(ty) {}
virtual ~DValue() {}
Type*& getType() { assert(type); return type; } Type*& getType() { assert(type); return type; }
@@ -60,6 +62,7 @@ struct DValue : Object
virtual DFieldValue* isField() { return NULL; } virtual DFieldValue* isField() { return NULL; }
virtual DSliceValue* isSlice() { return NULL; } virtual DSliceValue* isSlice() { return NULL; }
virtual DFuncValue* isFunc() { return NULL; } virtual DFuncValue* isFunc() { return NULL; }
protected: protected:
DValue() {} DValue() {}
DValue(const DValue&) { } DValue(const DValue&) { }
@@ -67,42 +70,44 @@ protected:
}; };
// immediate d-value // immediate d-value
struct DImValue : DValue class DImValue : public DValue
{ {
llvm::Value* val; public:
DImValue(Type* t, llvm::Value* v) : DValue(t), val(v) { } DImValue(Type* t, llvm::Value* v) : DValue(t), val(v) { }
virtual llvm::Value* getRVal() { assert(val); return val; } virtual llvm::Value* getRVal() { assert(val); return val; }
virtual DImValue* isIm() { return this; } virtual DImValue* isIm() { return this; }
protected:
llvm::Value* val;
}; };
// constant d-value // constant d-value
struct DConstValue : DValue class DConstValue : public DValue
{ {
llvm::Constant* c; public:
DConstValue(Type* t, llvm::Constant* con) : DValue(t), c(con) {} DConstValue(Type* t, llvm::Constant* con) : DValue(t), c(con) {}
virtual llvm::Value* getRVal(); virtual llvm::Value* getRVal();
virtual DConstValue* isConst() { return this; } virtual DConstValue* isConst() { return this; }
llvm::Constant* c;
}; };
// null d-value // null d-value
struct DNullValue : DConstValue class DNullValue : public DConstValue
{ {
public:
DNullValue(Type* t, llvm::Constant* con) : DConstValue(t,con) {} DNullValue(Type* t, llvm::Constant* con) : DConstValue(t,con) {}
virtual DNullValue* isNull() { return this; } virtual DNullValue* isNull() { return this; }
}; };
// variable d-value // variable d-value
struct DVarValue : DValue class DVarValue : public DValue
{ {
VarDeclaration* var; public:
llvm::Value* val;
DVarValue(Type* t, VarDeclaration* vd, llvm::Value* llvmValue); DVarValue(Type* t, VarDeclaration* vd, llvm::Value* llvmValue);
DVarValue(Type* t, llvm::Value* llvmValue); DVarValue(Type* t, llvm::Value* llvmValue);
@@ -115,40 +120,47 @@ struct DVarValue : DValue
virtual llvm::Value* getRefStorage(); virtual llvm::Value* getRefStorage();
virtual DVarValue* isVar() { return this; } virtual DVarValue* isVar() { return this; }
VarDeclaration* var;
protected:
llvm::Value* val;
}; };
// field d-value // field d-value
struct DFieldValue : DVarValue class DFieldValue : public DVarValue
{ {
public:
DFieldValue(Type* t, llvm::Value* llvmValue) : DVarValue(t, llvmValue) {} DFieldValue(Type* t, llvm::Value* llvmValue) : DVarValue(t, llvmValue) {}
virtual DFieldValue* isField() { return this; } virtual DFieldValue* isField() { return this; }
}; };
// slice d-value // slice d-value
struct DSliceValue : DValue class DSliceValue : public DValue
{ {
llvm::Value* len; public:
llvm::Value* ptr;
DSliceValue(Type* t, llvm::Value* l, llvm::Value* p) : DValue(t), len(l), ptr(p) {} DSliceValue(Type* t, llvm::Value* l, llvm::Value* p) : DValue(t), len(l), ptr(p) {}
virtual llvm::Value* getRVal(); virtual llvm::Value* getRVal();
virtual DSliceValue* isSlice() { return this; } virtual DSliceValue* isSlice() { return this; }
llvm::Value* len;
llvm::Value* ptr;
}; };
// function d-value // function d-value
struct DFuncValue : DValue class DFuncValue : public DValue
{ {
FuncDeclaration* func; public:
llvm::Value* val;
llvm::Value* vthis;
DFuncValue(FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0); DFuncValue(FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0);
virtual llvm::Value* getRVal(); virtual llvm::Value* getRVal();
virtual DFuncValue* isFunc() { return this; } virtual DFuncValue* isFunc() { return this; }
FuncDeclaration* func;
llvm::Value* val;
llvm::Value* vthis;
}; };
#endif // LDC_GEN_DVALUE_H #endif // LDC_GEN_DVALUE_H

View File

@@ -1059,7 +1059,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
if (lazy) if (lazy)
argt = irparam->value->getType(); argt = irparam->value->getType();
else else
argt = DtoType(vd->type); argt = i1ToI8(DtoType(vd->type));
LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars()); LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
// let the abi transform the argument back first // let the abi transform the argument back first

View File

@@ -16,7 +16,7 @@
#include "mars.h" #include "mars.h"
struct DValue; class DValue;
struct Expression; struct Expression;
struct FuncDeclaration; struct FuncDeclaration;
struct IRAsmBlock; struct IRAsmBlock;

View File

@@ -49,7 +49,7 @@ LLValue* DtoNew(Type* newtype)
// call runtime allocator // call runtime allocator
LLValue* mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem").getInstruction(); LLValue* mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem").getInstruction();
// cast // cast
return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); return DtoBitCast(mem, getPtrToType(i1ToI8(DtoType(newtype))), ".gc_mem");
} }
void DtoDeleteMemory(LLValue* ptr) void DtoDeleteMemory(LLValue* ptr)
@@ -113,7 +113,7 @@ void DtoDeleteArray(DValue* arr)
llvm::AllocaInst* DtoAlloca(Type* type, const char* name) llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
{ {
LLType* lltype = DtoType(type); LLType* lltype = i1ToI8(DtoType(type));
llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint());
ai->setAlignment(type->alignsize()); ai->setAlignment(type->alignsize());
return ai; return ai;
@@ -373,13 +373,12 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPostblit)
Type* t = lhs->getType()->toBasetype(); Type* t = lhs->getType()->toBasetype();
Type* t2 = rhs->getType()->toBasetype(); Type* t2 = rhs->getType()->toBasetype();
if (t->ty == Tvoid) { assert(t->ty != Tvoid && "Cannot assign values of type void.");
// This is a frontend regression in DMD 2.061; should be removed once
// DMD Bugzilla issue 9268 is fixed.
error(loc, "Cannot assign values of type void.");
}
if (t->ty == Tstruct) { if (t->ty == Tbool) {
DtoStoreZextI8(rhs->getRVal(), lhs->getLVal());
}
else if (t->ty == Tstruct) {
llvm::Value* src = rhs->getRVal(); llvm::Value* src = rhs->getRVal();
llvm::Value* dst = lhs->getLVal(); llvm::Value* dst = lhs->getLVal();
@@ -627,7 +626,10 @@ DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to)
if (totype->ty == Tpointer || totype->ty == Tclass) { if (totype->ty == Tpointer || totype->ty == Tclass) {
LLValue* src = val->getRVal(); LLValue* src = val->getRVal();
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; {
Logger::cout() << "src: " << *src << '\n';
Logger::cout() << "to type: " << *tolltype << '\n';
}
rval = DtoBitCast(src, tolltype); rval = DtoBitCast(src, tolltype);
} }
else if (totype->ty == Tbool) { else if (totype->ty == Tbool) {
@@ -1060,9 +1062,9 @@ void DtoVarDeclaration(VarDeclaration* vd)
} }
Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type; Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type;
LLType* lltype = DtoType(type);
llvm::Value* allocainst; llvm::Value* allocainst;
LLType* lltype = DtoType(type);
if(gDataLayout->getTypeSizeInBits(lltype) == 0) if(gDataLayout->getTypeSizeInBits(lltype) == 0)
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype)); allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
else else
@@ -1302,7 +1304,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
else if (init->isVoidInitializer()) else if (init->isVoidInitializer())
{ {
Logger::println("const void initializer"); Logger::println("const void initializer");
LLType* ty = DtoTypeNotVoid(type); LLType* ty = voidToI8(DtoType(type));
_init = LLConstant::getNullValue(ty); _init = LLConstant::getNullValue(ty);
} }
else { else {
@@ -1370,14 +1372,14 @@ LLConstant* DtoConstExpInit(Loc loc, Type* targetType, Expression* exp)
Type* expBase = stripModifiers(exp->type->toBasetype())->merge(); Type* expBase = stripModifiers(exp->type->toBasetype())->merge();
Type* targetBase = stripModifiers(targetType->toBasetype())->merge(); Type* targetBase = stripModifiers(targetType->toBasetype())->merge();
if (expBase->equals(targetBase)) if (expBase->equals(targetBase) && targetBase->ty != Tbool)
{ {
Logger::println("Matching D types, nothing left to do."); Logger::println("Matching D types, nothing left to do.");
return val; return val;
} }
llvm::Type* llType = val->getType(); llvm::Type* llType = val->getType();
llvm::Type* targetLLType = DtoType(targetBase); llvm::Type* targetLLType = i1ToI8(DtoType(targetBase));
if (llType == targetLLType) if (llType == targetLLType)
{ {
Logger::println("Matching LLVM types, ignoring frontend glitch."); Logger::println("Matching LLVM types, ignoring frontend glitch.");

View File

@@ -372,14 +372,14 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
if (lazy) if (lazy)
types.push_back(irparam->value->getType()->getContainedType(0)); types.push_back(irparam->value->getType()->getContainedType(0));
else else
types.push_back(DtoType(vd->type)); types.push_back(i1ToI8(DtoType(vd->type)));
} else { } else {
types.push_back(irparam->value->getType()); types.push_back(irparam->value->getType());
} }
} else if (isSpecialRefVar(vd)) { } else if (isSpecialRefVar(vd)) {
types.push_back(DtoType(vd->type->pointerTo())); types.push_back(DtoType(vd->type->pointerTo()));
} else { } else {
types.push_back(DtoType(vd->type)); types.push_back(i1ToI8(DtoType(vd->type)));
} }
if (Logger::enabled()) { if (Logger::enabled()) {
Logger::cout() << "Nested var '" << vd->toChars() << Logger::cout() << "Nested var '" << vd->toChars() <<

View File

@@ -95,12 +95,12 @@ void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* ma
void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, Dsymbol * mangle_sym) void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, Dsymbol * mangle_sym)
{ {
std::string tmpStr(valtype->arrayOf()->toChars()); std::string tmpStr(valtype->arrayOf()->toChars());
tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), '[' ), tmpStr.end() ); tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), '[' ), tmpStr.end() );
tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), ']' ), tmpStr.end() ); tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), ']' ), tmpStr.end() );
tmpStr.append("arr"); tmpStr.append("arr");
std::string initname(mangle_sym?mangle_sym->mangle():".ldc"); std::string initname(mangle_sym?mangle_sym->mangle():".ldc");
initname.append(".rtti."); initname.append(".rtti.");
initname.append(tmpStr); initname.append(tmpStr);
initname.append(".data"); initname.append(".data");

View File

@@ -138,7 +138,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
} }
// cast it to the right type // cast it to the right type
val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); val = DtoBitCast(val, getPtrToType(i1ToI8(DtoType(vd->type))));
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "value: " << *val << '\n'; Logger::cout() << "value: " << *val << '\n';

View File

@@ -17,7 +17,7 @@
#include "lexer.h" #include "lexer.h"
#include <vector> #include <vector>
struct DValue; class DValue;
struct StructDeclaration; struct StructDeclaration;
struct StructInitializer; struct StructInitializer;
struct Type; struct Type;

View File

@@ -246,7 +246,7 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
{ {
Expression* argexp = static_cast<Expression*>(arguments->data[i]); Expression* argexp = static_cast<Expression*>(arguments->data[i]);
LLValue* argdst = DtoGEPi(mem,0,k); LLValue* argdst = DtoGEPi(mem,0,k);
argdst = DtoBitCast(argdst, getPtrToType(DtoType(argexp->type))); argdst = DtoBitCast(argdst, getPtrToType(i1ToI8(DtoType(argexp->type))));
DtoVariadicArgument(argexp, argdst); DtoVariadicArgument(argexp, argdst);
} }

View File

@@ -215,7 +215,7 @@ DValue* VarExp::toElem(IRState* p)
if (isGlobal) if (isGlobal)
{ {
llvm::Type* expectedType = DtoType(type->pointerTo()); llvm::Type* expectedType = llvm::PointerType::getUnqual(i1ToI8(DtoType(type)));
// The type of globals is determined by their initializer, so // The type of globals is determined by their initializer, so
// we might need to cast. Make sure that the type sizes fit - // we might need to cast. Make sure that the type sizes fit -
// '==' instead of '<=' should probably work as well. // '==' instead of '<=' should probably work as well.
@@ -438,7 +438,7 @@ DValue* StringExp::toElem(IRState* p)
Type* dtype = type->toBasetype(); Type* dtype = type->toBasetype();
Type* cty = dtype->nextOf()->toBasetype(); Type* cty = dtype->nextOf()->toBasetype();
LLType* ct = DtoTypeNotVoid(cty); LLType* ct = voidToI8(DtoType(cty));
//printf("ct = %s\n", type->nextOf()->toChars()); //printf("ct = %s\n", type->nextOf()->toChars());
LLArrayType* at = LLArrayType::get(ct,len+1); LLArrayType* at = LLArrayType::get(ct,len+1);
@@ -496,7 +496,7 @@ LLConstant* StringExp::toConstElem(IRState* p)
bool nullterm = (t->ty != Tsarray); bool nullterm = (t->ty != Tsarray);
size_t endlen = nullterm ? len+1 : len; size_t endlen = nullterm ? len+1 : len;
LLType* ct = DtoTypeNotVoid(cty); LLType* ct = voidToI8(DtoType(cty));
LLArrayType* at = LLArrayType::get(ct,endlen); LLArrayType* at = LLArrayType::get(ct,endlen);
LLConstant* _init; LLConstant* _init;
@@ -2496,7 +2496,7 @@ DValue* CondExp::toElem(IRState* p)
LLValue* resval = DtoAlloca(dtype,"condtmp"); LLValue* resval = DtoAlloca(dtype,"condtmp");
dvv = new DVarValue(type, resval); dvv = new DVarValue(type, resval);
} else { } else {
dvv = new DConstValue(type, getNullValue(DtoTypeNotVoid(dtype))); dvv = new DConstValue(type, getNullValue(voidToI8(DtoType(dtype))));
} }
llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* oldend = p->scopeend();
@@ -2726,7 +2726,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
// llvm storage type // llvm storage type
LLType* llElemType = DtoTypeNotVoid(elemType); LLType* llElemType = voidToI8(DtoType(elemType));
LLType* llStoType = LLArrayType::get(llElemType, len); LLType* llStoType = LLArrayType::get(llElemType, len);
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
@@ -2785,7 +2785,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
Type* elemt = bt->nextOf(); Type* elemt = bt->nextOf();
// build llvm array type // build llvm array type
LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim); LLArrayType* arrtype = LLArrayType::get(i1ToI8(voidToI8(DtoType(elemt))), elements->dim);
// dynamic arrays can occur here as well ... // dynamic arrays can occur here as well ...
bool dyn = (bt->ty != Tsarray); bool dyn = (bt->ty != Tsarray);
@@ -3190,7 +3190,7 @@ DValue* TupleExp::toElem(IRState *p)
for (size_t i = 0; i < exps->dim; i++) for (size_t i = 0; i < exps->dim; i++)
{ {
Expression *el = static_cast<Expression *>(exps->data[i]); Expression *el = static_cast<Expression *>(exps->data[i]);
types.push_back(DtoTypeNotVoid(el->type)); types.push_back(voidToI8(DtoType(el->type)));
} }
LLValue *val = DtoRawAlloca(LLStructType::get(gIR->context(), types),0, "tuple"); LLValue *val = DtoRawAlloca(LLStructType::get(gIR->context(), types),0, "tuple");
for (size_t i = 0; i < exps->dim; i++) for (size_t i = 0; i < exps->dim; i++)

View File

@@ -246,12 +246,20 @@ LLType* DtoStructTypeFromArguments(Arguments* arguments)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
LLType* DtoTypeNotVoid(Type* t) LLType* voidToI8(LLType* t)
{ {
LLType* lt = DtoType(t); if (t == LLType::getVoidTy(gIR->context()))
if (lt == LLType::getVoidTy(gIR->context()))
return LLType::getInt8Ty(gIR->context()); return LLType::getInt8Ty(gIR->context());
return lt; return t;
}
//////////////////////////////////////////////////////////////////////////////////////////
LLType* i1ToI8(LLType* t)
{
if (t == LLType::getInt1Ty(gIR->context()))
return LLType::getInt8Ty(gIR->context());
return t;
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@@ -717,15 +725,27 @@ LLValue* DtoAlignedLoad(LLValue* src, const char* name)
void DtoStore(LLValue* src, LLValue* dst) void DtoStore(LLValue* src, LLValue* dst)
{ {
// if (Logger::enabled()) assert(src->getType() != llvm::Type::getInt1Ty(gIR->context()) &&
// Logger::cout() << "storing " << *src << " into " << *dst << '\n'; "Should store bools as i8 instead of i1.");
gIR->ir->CreateStore(src,dst); gIR->ir->CreateStore(src,dst);
//st->setVolatile(gIR->func()->inVolatile); }
void DtoStoreZextI8(LLValue* src, LLValue* dst)
{
if (src->getType() == llvm::Type::getInt1Ty(gIR->context()))
{
llvm::Type* i8 = llvm::Type::getInt8Ty(gIR->context());
assert(dst->getType()->getContainedType(0) == i8);
src = gIR->ir->CreateZExt(src, i8);
}
gIR->ir->CreateStore(src, dst);
} }
// Like DtoStore, but the pointer is guaranteed to be aligned appropriately for the type. // Like DtoStore, but the pointer is guaranteed to be aligned appropriately for the type.
void DtoAlignedStore(LLValue* src, LLValue* dst) void DtoAlignedStore(LLValue* src, LLValue* dst)
{ {
assert(src->getType() != llvm::Type::getInt1Ty(gIR->context()) &&
"Should store bools as i8 instead of i1.");
llvm::StoreInst* st = gIR->ir->CreateStore(src,dst); llvm::StoreInst* st = gIR->ir->CreateStore(src,dst);
st->setAlignment(getABITypeAlign(src->getType())); st->setAlignment(getABITypeAlign(src->getType()));
} }

View File

@@ -25,9 +25,8 @@
// D->LLVM type handling stuff // D->LLVM type handling stuff
LLType* DtoType(Type* t); LLType* DtoType(Type* t);
LLType* voidToI8(LLType* t);
// same as DtoType except it converts 'void' to 'i8' LLType* i1ToI8(LLType* t);
LLType* DtoTypeNotVoid(Type* t);
// returns true is the type must be passed by pointer // returns true is the type must be passed by pointer
bool DtoIsPassedByRef(Type* type); bool DtoIsPassedByRef(Type* type);
@@ -82,6 +81,7 @@ LLConstant* DtoConstBool(bool);
LLValue* DtoLoad(LLValue* src, const char* name=0); LLValue* DtoLoad(LLValue* src, const char* name=0);
LLValue* DtoAlignedLoad(LLValue* src, const char* name=0); LLValue* DtoAlignedLoad(LLValue* src, const char* name=0);
void DtoStore(LLValue* src, LLValue* dst); void DtoStore(LLValue* src, LLValue* dst);
void DtoStoreZextI8(LLValue* src, LLValue* dst);
void DtoAlignedStore(LLValue* src, LLValue* dst); void DtoAlignedStore(LLValue* src, LLValue* dst);
LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0); LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0);
LLConstant* DtoBitCast(LLConstant* v, LLType* t); LLConstant* DtoBitCast(LLConstant* v, LLType* t);

View File

@@ -96,5 +96,5 @@ void IrFuncTy::getParam(Type* dty, size_t idx, DValue* val, llvm::Value* lval)
return; return;
} }
DtoStore(val->getRVal(), lval); DtoStoreZextI8(val->getRVal(), lval);
} }

View File

@@ -26,7 +26,7 @@
#include <vector> #include <vector>
struct DValue; class DValue;
struct ABIRewrite; struct ABIRewrite;
namespace llvm { namespace llvm {
class Type; class Type;

View File

@@ -188,9 +188,9 @@ IrTypePointer* IrTypePointer::get(Type* dt)
} }
} }
elemType = DtoTypeNotVoid(dt->nextOf()); elemType = i1ToI8(voidToI8(DtoType(dt->nextOf())));
// DtoTypeNotVoid could have already created the same type, e.g. for // DtoType could have already created the same type, e.g. for
// dt == Node* in struct Node { Node* n; }. // dt == Node* in struct Node { Node* n; }.
if (dt->irtype) if (dt->irtype)
return dt->irtype->isPointer(); return dt->irtype->isPointer();
@@ -226,9 +226,7 @@ llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
assert(t->ty == Tsarray && "not static array type"); assert(t->ty == Tsarray && "not static array type");
TypeSArray* tsa = static_cast<TypeSArray*>(t); TypeSArray* tsa = static_cast<TypeSArray*>(t);
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger()); uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
LLType* elemType = DtoType(t->nextOf()); LLType* elemType = i1ToI8(voidToI8(DtoType(t->nextOf())));
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
return llvm::ArrayType::get(elemType, dim); return llvm::ArrayType::get(elemType, dim);
} }
@@ -248,7 +246,7 @@ IrTypeArray* IrTypeArray::get(Type* dt)
assert(!dt->irtype); assert(!dt->irtype);
assert(dt->ty == Tarray && "not dynamic array type"); assert(dt->ty == Tarray && "not dynamic array type");
LLType* elemType = DtoTypeNotVoid(dt->nextOf()); LLType* elemType = i1ToI8(voidToI8(DtoType(dt->nextOf())));
// Could have already built the type as part of a struct forward reference, // Could have already built the type as part of a struct forward reference,
// just as for pointers. // just as for pointers.
@@ -289,9 +287,7 @@ llvm::Type* IrTypeVector::vector2llvm(Type* dt)
assert(tv->basetype->ty == Tsarray); assert(tv->basetype->ty == Tsarray);
TypeSArray* tsa = static_cast<TypeSArray*>(tv->basetype); TypeSArray* tsa = static_cast<TypeSArray*>(tv->basetype);
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger()); uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
LLType* elemType = DtoType(tsa->next); LLType* elemType = voidToI8(DtoType(tsa->next));
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
return llvm::VectorType::get(elemType, dim); return llvm::VectorType::get(elemType, dim);
} }

View File

@@ -169,7 +169,7 @@ void IrTypeClass::addBaseClassData(
} }
// add default type // add default type
defaultTypes.push_back(DtoType(vd->type)); defaultTypes.push_back(DtoType(vd->type)); // @@@ i1ToI8?!
// advance offset to right past this field // advance offset to right past this field
offset = vd->offset + vd->type->size(); offset = vd->offset + vd->type->size();