From ae7f0ca7e724ee5718449820b114c2d50093470b Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Wed, 15 Feb 2012 17:28:10 +0400 Subject: [PATCH] Preliminary vector support --- dmd2/declaration.h | 4 ++++ dmd2/expression.h | 3 +++ dmd2/mtype.c | 4 ++-- dmd2/mtype.h | 2 +- gen/llvmhelpers.cpp | 38 ++++++++++++++++++++++++++++++++++++-- gen/toir.cpp | 29 ++++++++++++++++++++++++++++- gen/tollvm.cpp | 30 ++++++++++++++++++++++++++++++ gen/tollvm.h | 4 ++++ gen/typinf.cpp | 21 +++++++++++++++++++++ ir/irtype.cpp | 34 ++++++++++++++++++++++++++++++++++ ir/irtype.h | 27 +++++++++++++++++++++++++++ runtime/CMakeLists.txt | 3 --- 12 files changed, 190 insertions(+), 9 deletions(-) diff --git a/dmd2/declaration.h b/dmd2/declaration.h index c887e6eb..4539209a 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -660,6 +660,10 @@ struct TypeInfoVectorDeclaration : TypeInfoDeclaration #if IN_DMD void toDt(dt_t **pdt); #endif + +#if IN_LLVM + void llvmDefine(); +#endif }; #endif diff --git a/dmd2/expression.h b/dmd2/expression.h index 70c8981e..b2fbb4a6 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -1337,6 +1337,9 @@ struct VectorExp : UnaExp #if IN_DMD elem *toElem(IRState *irs); #endif +#if IN_LLVM + DValue* toElem(IRState* irs); +#endif }; struct SliceExp : UnaExp diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 3818e0f4..561bef95 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -3455,14 +3455,14 @@ void TypeVector::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) buf->writestring(")"); } -void TypeVector::toDecoBuffer(OutBuffer *buf, int flag) +void TypeVector::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) { if (flag != mod && flag != 0x100) { MODtoDecoBuffer(buf, mod); } buf->writestring("Nh"); - basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); + basetype->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle); } d_uns64 TypeVector::size(Loc loc) diff --git a/dmd2/mtype.h b/dmd2/mtype.h index fe58c7df..587c9965 100644 --- a/dmd2/mtype.h +++ b/dmd2/mtype.h @@ -447,7 +447,7 @@ struct TypeVector : Type Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); char *toChars(); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); - void toDecoBuffer(OutBuffer *buf, int flag); + void toDecoBuffer(OutBuffer *buf, int flag, bool mangle); #if CPP_MANGLE void toCppMangle(OutBuffer *buf, CppMangleState *cms); #endif diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 096331f3..13a2f343 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -736,7 +736,6 @@ DValue* DtoCastDelegate(Loc& loc, DValue* val, Type* to) } } - DValue* DtoCastNull(Loc& loc, DValue* val, Type* to) { Type* totype = to->toBasetype(); @@ -756,6 +755,38 @@ DValue* DtoCastNull(Loc& loc, DValue* val, Type* to) } } +DValue* DtoCastVector(Loc& loc, DValue* val, Type* to) +{ + assert(val->getType()->toBasetype()->ty == Tvector); + Type* totype = to->toBasetype(); + LLType* tolltype = DtoType(to); + LLValue *vector = val->getRVal(); + TypeVector *type = (TypeVector *)val->getType()->toBasetype(); + + if (totype->ty == Tsarray) + { + if (Logger::enabled()) + Logger::cout() << "src: " << *vector << "to type: " << *tolltype << '\n'; + LLValue *array = DtoAlloca(to); + + TypeSArray *st = (TypeSArray*)totype; + + for (int i = 0, n = st->dim->toInteger(); i < n; ++i) { + LLValue *lelem = DtoExtractElement(vector, i); + DImValue elem(type->elementType(), lelem); + lelem = DtoCast(loc, &elem, to->nextOf())->getRVal(); + DtoStore(lelem, DtoGEPi(array, 0, i)); + } + + return new DImValue(to, array); + } + else + { + error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); + fatal(); + } +} + DValue* DtoCast(Loc& loc, DValue* val, Type* to) { Type* fromtype = val->getType()->toBasetype(); @@ -774,7 +805,10 @@ DValue* DtoCast(Loc& loc, DValue* val, Type* to) Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); LOG_SCOPE; - if (fromtype->isintegral()) { + if (fromtype->ty == Tvector) { + return DtoCastVector(loc, val, to); + } + else if (fromtype->isintegral()) { return DtoCastInt(loc, val, to); } else if (fromtype->iscomplex()) { diff --git a/gen/toir.cpp b/gen/toir.cpp index 02c09697..7579726f 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1051,7 +1051,7 @@ DValue* CallExp::toElem(IRState* p) fndecl->llvmInternal == LLVMbitop_bts) { if (arguments->dim != 2) { - error("bitop intrinsic %s expects 2 arguments"); + error("bitop intrinsic expects 2 arguments"); return NULL; } @@ -3139,6 +3139,33 @@ DValue* TupleExp::toElem(IRState *p) return new DImValue(type, val); } +////////////////////////////////////////////////////////////////////////////////////////// + +#if DMDV2 + +DValue* VectorExp::toElem(IRState* p) +{ + Logger::print("VectorExp::toElem() %s\n", toChars()); + + TypeVector *type = (TypeVector*)to->toBasetype(); + assert(type->ty == Tvector); + + DValue *val = e1->toElem(p); + val = DtoCast(loc, val, type->elementType()); + LLValue *rval = val->getRVal(); + LLValue *vector = DtoAlloca(to); + + for (int i = 0; i < dim; ++i) { + LLValue *elem = DtoGEPi(vector, 0, i); + DtoStore(rval, elem); + } + + return new DVarValue(to, vector); +} + +#endif + + ////////////////////////////////////////////////////////////////////////////////////////// #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index f9c4d127..25e316e5 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -158,6 +158,14 @@ LLType* DtoType(Type* t) case Taarray: return getVoidPtrType(); +#if DMDV2 + case Tvector: + { + t->irtype = new IrTypeVector(t); + return t->irtype->buildType(); + } +#endif + /* Not needed atm as VarDecls for tuples are rewritten as a string of VarDecls for the fields (u -> _u_field_0, ...) @@ -679,6 +687,28 @@ LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name) ////////////////////////////////////////////////////////////////////////////////////////// +LLValue* DtoInsertElement(LLValue* vec, LLValue* v, LLValue *idx, const char* name) +{ + return gIR->ir->CreateInsertElement(vec, v, idx, name ? name : "tmp"); +} + +LLValue* DtoExtractElement(LLValue* vec, LLValue *idx, const char* name) +{ + return gIR->ir->CreateExtractElement(vec, idx, name ? name : "tmp"); +} + +LLValue* DtoInsertElement(LLValue* vec, LLValue* v, unsigned idx, const char* name) +{ + return DtoInsertElement(vec, v, DtoConstUint(idx), name); +} + +LLValue* DtoExtractElement(LLValue* vec, unsigned idx, const char* name) +{ + return DtoExtractElement(vec, DtoConstUint(idx), name); +} + +////////////////////////////////////////////////////////////////////////////////////////// + LLPointerType* isaPointer(LLValue* v) { return llvm::dyn_cast(v->getType()); diff --git a/gen/tollvm.h b/gen/tollvm.h index 2e197b3b..c6972008 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -70,6 +70,10 @@ LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0); LLConstant* DtoBitCast(LLConstant* v, LLType* t); LLValue* DtoInsertValue(LLValue* aggr, LLValue* v, unsigned idx, const char* name=0); LLValue* DtoExtractValue(LLValue* aggr, unsigned idx, const char* name=0); +LLValue* DtoInsertElement(LLValue* vec, LLValue* v, LLValue *idx, const char* name=0); +LLValue* DtoExtractElement(LLValue* vec, LLValue *idx, const char* name=0); +LLValue* DtoInsertElement(LLValue* vec, LLValue* v, unsigned idx, const char* name=0); +LLValue* DtoExtractElement(LLValue* vec, unsigned idx, const char* name=0); // llvm::dyn_cast wrappers LLPointerType* isaPointer(LLValue* v); diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 0de0c26e..12d104a5 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -895,4 +895,25 @@ void TypeInfoWildDeclaration::llvmDefine() b.finalize(ir.irGlobal); } +/* ========================================================================= */ + +#if DMDV2 + +void TypeInfoVectorDeclaration::llvmDefine() +{ + Logger::println("TypeInfoVectorDeclaration::llvmDefine() %s", toChars()); + LOG_SCOPE; + + assert(tinfo->ty == Tvector); + TypeVector *tv = (TypeVector *)tinfo; + + RTTIBuilder b(Type::typeinfovector); + // TypeInfo base + b.push_typeinfo(tv->basetype); + // finish + b.finalize(ir.irGlobal); +} + +#endif + #endif diff --git a/ir/irtype.cpp b/ir/irtype.cpp index 28fe067b..27cec84d 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -233,5 +233,39 @@ llvm::Type * IrTypeArray::array2llvm(Type * t) return at; } +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// +#if DMDV2 + +IrTypeVector::IrTypeVector(Type* dt) +: IrType(dt, vector2llvm(dt)) +{ +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type* IrTypeVector::buildType() +{ + return type; +} + +////////////////////////////////////////////////////////////////////////////// + +llvm::Type* IrTypeVector::vector2llvm(Type* dt) +{ + assert(dt->ty == Tvector && "not vector type"); + TypeVector* tv = (TypeVector*)dt; + assert(tv->basetype->ty == Tsarray); + TypeSArray* tsa = (TypeSArray*)tv->basetype; + dim = (uint64_t)tsa->dim->toUInteger(); + LLType* elemType = DtoType(tsa->next); + if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) + elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); + return llvm::VectorType::get(elemType, dim); +} + +#endif + +////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irtype.h b/ir/irtype.h index d0fc4e6a..743737b4 100644 --- a/ir/irtype.h +++ b/ir/irtype.h @@ -18,6 +18,9 @@ class IrTypeFunction; class IrTypePointer; class IrTypeSArray; class IrTypeStruct; +#if DMDV2 +class IrTypeVector; +#endif ////////////////////////////////////////////////////////////////////////////// @@ -46,6 +49,10 @@ public: virtual IrTypeSArray* isSArray() { return NULL; } /// virtual IrTypeStruct* isStruct() { return NULL; } +#if DMDV2 + /// + IrTypeVector* isVector() { return NULL; } +#endif /// Type* getD() { return dtype; } @@ -154,4 +161,24 @@ protected: ////////////////////////////////////////////////////////////////////////////// +#if DMDV2 +/// IrType for vectors +class IrTypeVector : public IrType +{ +public: + /// + IrTypeVector(Type* dt); + + /// + IrTypeVector* isVector() { return this; } + + /// + llvm::Type* buildType(); +protected: + llvm::Type* vector2llvm(Type* dt); + /// Dimension. + uint64_t dim; +}; +#endif + #endif diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 27fdfc8f..63d853a5 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -64,9 +64,6 @@ list(REMOVE_ITEM DCRT_D ${RUNTIME_DC_DIR}/qsort2.d ${RUNTIME_DC_DIR}/trace.d ) -list(REMOVE_ITEM CORE_D - ${RUNTIME_DIR}/src/core/simd.d -) file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c) list(REMOVE_ITEM DCRT_C ${RUNTIME_DC_DIR}/deh.c ${RUNTIME_DC_DIR}/dylib_fixes.c) if(UNIX)