From 2cf5d8c2a02f7dec2b089d92dd380be68cb1a359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Tue, 2 Oct 2012 21:37:27 +0200 Subject: [PATCH 1/5] Added pragma extractelement --- dmd2/idgen.c | 1 + gen/pragma.cpp | 23 +++++++++++++++++++++++ gen/pragma.h | 1 + gen/toir.cpp | 14 +++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 457220bd..96899737 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -274,6 +274,7 @@ Msgtable msgtable[] = { "no_moduleinfo" }, { "Alloca", "alloca" }, { "Shufflevector", "shufflevector" }, + { "Extractelement", "extractelement" }, { "vastart", "va_start" }, { "vacopy", "va_copy" }, { "vaend", "va_end" }, diff --git a/gen/pragma.cpp b/gen/pragma.cpp index 2ac94850..0ef0b324 100644 --- a/gen/pragma.cpp +++ b/gen/pragma.cpp @@ -116,6 +116,17 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) return LLVMshufflevector; } + // pragma(extractelement) { funcdecl(s) } + else if (ident == Id::Extractelement) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + return LLVMextractelement; + } + // pragma(va_start) { templdecl(s) } else if (ident == Id::vastart) { @@ -375,6 +386,18 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, } break; + case LLVMextractelement: + if (FuncDeclaration* fd = s->isFuncDeclaration()) + { + fd->llvmInternal = llvm_internal; + } + else + { + error("the '%s' pragma must only be used on function declarations.", ident->toChars()); + fatal(); + } + break; + case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { diff --git a/gen/pragma.h b/gen/pragma.h index fc4322c1..6da358c0 100644 --- a/gen/pragma.h +++ b/gen/pragma.h @@ -15,6 +15,7 @@ enum Pragma LLVMno_moduleinfo, LLVMalloca, LLVMshufflevector, + LLVMextractelement, LLVMva_start, LLVMva_copy, LLVMva_end, diff --git a/gen/toir.cpp b/gen/toir.cpp index 3cde74cd..474d8004 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1007,7 +1007,19 @@ DValue* CallExp::toElem(IRState* p) LLValue* v1 = exp1->toElem(p)->getRVal(); LLValue* v2 = exp2->toElem(p)->getRVal(); return new DImValue(type, p->ir->CreateShuffleVector(v1, v2, maskVal)); - } + } + // extractelement + else if(fndecl->llvmInternal == LLVMextractelement) { + Expression* exp2 = static_cast(arguments->data[1]); + if(exp2->op != TOKint64){ + error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); + fatal(); + } + LLConstant* idx = static_cast(arguments->data[1])->toConstElem(p); + Expression* exp1 = static_cast(arguments->data[0]); + LLValue* vec = exp1->toElem(p)->getRVal(); + return new DImValue(type, p->ir->CreateExtractElement(vec, idx)); + } // fence instruction else if (fndecl->llvmInternal == LLVMfence) { if (arguments->dim != 1) { From b798974f3a4100e0733c4df6a5caf1316ce3d6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Tue, 2 Oct 2012 22:22:53 +0200 Subject: [PATCH 2/5] Added pragma insertelement. --- dmd2/idgen.c | 1 + gen/pragma.cpp | 23 +++++++++++++++++++++++ gen/pragma.h | 1 + gen/toir.cpp | 16 +++++++++++++++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/dmd2/idgen.c b/dmd2/idgen.c index 96899737..5334221f 100644 --- a/dmd2/idgen.c +++ b/dmd2/idgen.c @@ -275,6 +275,7 @@ Msgtable msgtable[] = { "Alloca", "alloca" }, { "Shufflevector", "shufflevector" }, { "Extractelement", "extractelement" }, + { "Insertelement", "insertelement" }, { "vastart", "va_start" }, { "vacopy", "va_copy" }, { "vaend", "va_end" }, diff --git a/gen/pragma.cpp b/gen/pragma.cpp index 0ef0b324..588b6568 100644 --- a/gen/pragma.cpp +++ b/gen/pragma.cpp @@ -127,6 +127,17 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) return LLVMextractelement; } + // pragma(insertelement) { funcdecl(s) } + else if (ident == Id::Insertelement) + { + if (args && args->dim > 0) + { + error("takes no parameters"); + fatal(); + } + return LLVMinsertelement; + } + // pragma(va_start) { templdecl(s) } else if (ident == Id::vastart) { @@ -398,6 +409,18 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, } break; + case LLVMinsertelement: + if (FuncDeclaration* fd = s->isFuncDeclaration()) + { + fd->llvmInternal = llvm_internal; + } + else + { + error("the '%s' pragma must only be used on function declarations.", ident->toChars()); + fatal(); + } + break; + case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { diff --git a/gen/pragma.h b/gen/pragma.h index 6da358c0..9895bc2d 100644 --- a/gen/pragma.h +++ b/gen/pragma.h @@ -16,6 +16,7 @@ enum Pragma LLVMalloca, LLVMshufflevector, LLVMextractelement, + LLVMinsertelement, LLVMva_start, LLVMva_copy, LLVMva_end, diff --git a/gen/toir.cpp b/gen/toir.cpp index 474d8004..d9bfdcfd 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1015,11 +1015,25 @@ DValue* CallExp::toElem(IRState* p) error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); fatal(); } - LLConstant* idx = static_cast(arguments->data[1])->toConstElem(p); + LLValue* idx = exp2->toElem(p)->getRVal(); Expression* exp1 = static_cast(arguments->data[0]); LLValue* vec = exp1->toElem(p)->getRVal(); return new DImValue(type, p->ir->CreateExtractElement(vec, idx)); } + // insertelement + else if(fndecl->llvmInternal == LLVMinsertelement) { + Expression* exp3 = static_cast(arguments->data[2]); + if(exp3->op != TOKint64){ + error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); + fatal(); + } + LLValue* idx = exp3->toElem(p)->getRVal(); + Expression* exp1 = static_cast(arguments->data[0]); + LLValue* vec = exp1->toElem(p)->getRVal(); + Expression* exp2 = static_cast(arguments->data[1]); + LLValue* scal = exp2->toElem(p)->getRVal(); + return new DImValue(type, p->ir->CreateInsertElement(vec, scal, idx)); + } // fence instruction else if (fndecl->llvmInternal == LLVMfence) { if (arguments->dim != 1) { From 115bc7113ed82abfcb8a086052b1ecbb896f5924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Wed, 3 Oct 2012 03:44:34 +0200 Subject: [PATCH 3/5] Improved error messages. --- gen/toir.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/gen/toir.cpp b/gen/toir.cpp index d9bfdcfd..be25b755 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -45,6 +45,8 @@ #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" + llvm::cl::opt checkPrintf("check-printf-calls", llvm::cl::desc("Validate printf call format strings against arguments"), llvm::cl::ZeroOrMore); @@ -994,8 +996,8 @@ DValue* CallExp::toElem(IRState* p) llvm::SmallVector mask; for(int i = 2, n = arguments->dim; i < n; i++){ Expression* exp = static_cast(arguments->data[i]); - if(exp->op != TOKint64){ - error("Function %s was declared with pragma shufflevector. Because of that all of its arguments except the first two must be integer literals.", fndecl->toChars()); + if(exp->op != TOKint64 || exp->type->ty != Tint32){ + error("Function %s was declared with pragma shufflevector. Because of that all of its arguments except for the first two must be int literals.", fndecl->toChars()); fatal(); } IntegerExp* iexp = static_cast(arguments->data[i]); @@ -1011,8 +1013,8 @@ DValue* CallExp::toElem(IRState* p) // extractelement else if(fndecl->llvmInternal == LLVMextractelement) { Expression* exp2 = static_cast(arguments->data[1]); - if(exp2->op != TOKint64){ - error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); + if(exp2->op != TOKint64 || exp2->type->ty != Tint32){ + error("Function %s was declared with pragma extractelement. Because of that its second argument must be an int literal.", fndecl->toChars()); fatal(); } LLValue* idx = exp2->toElem(p)->getRVal(); @@ -1023,8 +1025,8 @@ DValue* CallExp::toElem(IRState* p) // insertelement else if(fndecl->llvmInternal == LLVMinsertelement) { Expression* exp3 = static_cast(arguments->data[2]); - if(exp3->op != TOKint64){ - error("Function %s was declared with pragma extractelement. Because of that its second argument must be an integer literal.", fndecl->toChars()); + if(exp3->op != TOKint64 || exp3->type->ty != Tint32){ + error("Function %s was declared with pragma insertelement. Because of that its third argument must be an int literal.", fndecl->toChars()); fatal(); } LLValue* idx = exp3->toElem(p)->getRVal(); From 047dcb5591efcafb65e7141f057ca43765fa7f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Wed, 3 Oct 2012 04:13:21 +0200 Subject: [PATCH 4/5] Fixed D1 build errors. --- dmd/idgen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dmd/idgen.c b/dmd/idgen.c index 0e042e13..12d11463 100644 --- a/dmd/idgen.c +++ b/dmd/idgen.c @@ -230,6 +230,8 @@ Msgtable msgtable[] = { "no_moduleinfo" }, { "Alloca", "alloca" }, { "Shufflevector", "shufflevector" }, + { "Extractelement", "extractelement" }, + { "Insertelement", "insertelement" }, { "vastart", "va_start" }, { "vacopy", "va_copy" }, { "vaend", "va_end" }, From fd3e79b7bb2c19081c8ef69ad2a6632e5b52156f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jernej=20Krempu=C5=A1?= Date: Wed, 3 Oct 2012 15:26:43 +0200 Subject: [PATCH 5/5] Corrections. --- gen/pragma.cpp | 28 +++------------------------- gen/toir.cpp | 2 -- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/gen/pragma.cpp b/gen/pragma.cpp index 588b6568..4118d4d9 100644 --- a/gen/pragma.cpp +++ b/gen/pragma.cpp @@ -116,26 +116,15 @@ Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str) return LLVMshufflevector; } - // pragma(extractelement) { funcdecl(s) } - else if (ident == Id::Extractelement) + // pragma(extractelement or insertelement) { funcdecl(s) } + else if (ident == Id::Extractelement || ident == Id::Insertelement) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } - return LLVMextractelement; - } - - // pragma(insertelement) { funcdecl(s) } - else if (ident == Id::Insertelement) - { - if (args && args->dim > 0) - { - error("takes no parameters"); - fatal(); - } - return LLVMinsertelement; + return ident == Id::Extractelement ? LLVMextractelement : LLVMinsertelement; } // pragma(va_start) { templdecl(s) } @@ -398,17 +387,6 @@ void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, break; case LLVMextractelement: - if (FuncDeclaration* fd = s->isFuncDeclaration()) - { - fd->llvmInternal = llvm_internal; - } - else - { - error("the '%s' pragma must only be used on function declarations.", ident->toChars()); - fatal(); - } - break; - case LLVMinsertelement: if (FuncDeclaration* fd = s->isFuncDeclaration()) { diff --git a/gen/toir.cpp b/gen/toir.cpp index be25b755..f819e36e 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -45,8 +45,6 @@ #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/raw_ostream.h" - llvm::cl::opt checkPrintf("check-printf-calls", llvm::cl::desc("Validate printf call format strings against arguments"), llvm::cl::ZeroOrMore);