From 69e7907875726acee32e2589d61e8db773c89949 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sun, 28 Jul 2013 21:17:03 +0400 Subject: [PATCH 1/6] Move implementation of Module::buildTargetFiles and Module::buildFilePath to gem/module.cpp --- dmd2/module.c | 133 ------------------------------------------------ driver/main.cpp | 4 +- gen/module.cpp | 116 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 136 deletions(-) diff --git a/dmd2/module.c b/dmd2/module.c index b62807c3..a68c6247 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -37,16 +37,6 @@ #include "llvm/LLVMContext.h" #include "llvm/DerivedTypes.h" #endif -#include "llvm/Support/CommandLine.h" -#include - -static llvm::cl::opt preservePaths("op", - llvm::cl::desc("Do not strip paths from source file"), - llvm::cl::ZeroOrMore); - -static llvm::cl::opt fqnNames("oq", - llvm::cl::desc("Write object files with fully qualified names"), - llvm::cl::ZeroOrMore); #endif AggregateDeclaration *Module::moduleinfo; @@ -161,58 +151,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen this->arrayfuncs = 0; #endif } -#if IN_LLVM -File* Module::buildFilePath(const char* forcename, const char* path, const char* ext) -{ - const char *argobj; - if (forcename) - argobj = forcename; - else - { - if (preservePaths) - argobj = (char*)this->arg; - else - argobj = FileName::name((char*)this->arg); - if (fqnNames) - { - if(md) - argobj = FileName::replaceName((char*)argobj, md->toChars()); - else - argobj = FileName::replaceName((char*)argobj, toChars()); - - // add ext, otherwise forceExt will make nested.module into nested.bc - size_t len = strlen(argobj); - size_t extlen = strlen(ext); - char* s = (char *)alloca(len + 1 + extlen + 1); - memcpy(s, argobj, len); - s[len] = '.'; - memcpy(s + len + 1, ext, extlen + 1); - s[len+1+extlen] = 0; - argobj = s; - } - } - - if (!FileName::absolute(argobj)) - { - argobj = FileName::combine(path, argobj); - } - - FileName::ensurePathExists(FileName::path(argobj)); - -// always append the extension! otherwise hard to make output switches consistent -// if (forcename) -// return new File(argobj); -// else - // allow for .o and .obj on windows -#if _WIN32 - if (ext == global.params.objdir && FileName::ext(argobj) - && Port::stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0) - return new File((char*)argobj); -#endif - return new File(FileName::forceExt(argobj, ext)); -} -#endif #if IN_DMD void Module::setDocfile() { @@ -263,78 +202,6 @@ File *Module::setOutfile(const char *name, const char *dir, const char *arg, con } #endif -#if IN_LLVM - -// LDC -static void check_and_add_output_file(Module* NewMod, const std::string& str) -{ - typedef std::map map_t; - static map_t files; - - map_t::iterator i = files.find(str); - if (i != files.end()) - { - Module* ThisMod = i->second; - error(Loc(), "Output file '%s' for module '%s' collides with previous module '%s'. See the -oq option", - str.c_str(), NewMod->toPrettyChars(), ThisMod->toPrettyChars()); - fatal(); - } - files.insert(std::make_pair(str, NewMod)); -} - -void Module::buildTargetFiles(bool singleObj) -{ - if(objfile && - (!doDocComment || docfile) && - (!doHdrGen || hdrfile)) - return; - - if(!objfile) - { - if (global.params.output_o) - objfile = Module::buildFilePath(global.params.objname, global.params.objdir, - global.params.targetTriple.isOSWindows() ? global.obj_ext_alt : global.obj_ext); - else if (global.params.output_bc) - objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.bc_ext); - else if (global.params.output_ll) - objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.ll_ext); - else if (global.params.output_s) - objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.s_ext); - } - if(doDocComment && !docfile) - docfile = Module::buildFilePath(global.params.docname, global.params.docdir, global.doc_ext); - if(doHdrGen && !hdrfile) - hdrfile = Module::buildFilePath(global.params.hdrname, global.params.hdrdir, global.hdr_ext); - - // safety check: never allow obj, doc or hdr file to have the source file's name - if(Port::stricmp(FileName::name(objfile->name->str), FileName::name((char*)this->arg)) == 0) - { - error("Output object files with the same name as the source file are forbidden"); - fatal(); - } - if(docfile && Port::stricmp(FileName::name(docfile->name->str), FileName::name((char*)this->arg)) == 0) - { - error("Output doc files with the same name as the source file are forbidden"); - fatal(); - } - if(hdrfile && Port::stricmp(FileName::name(hdrfile->name->str), FileName::name((char*)this->arg)) == 0) - { - error("Output header files with the same name as the source file are forbidden"); - fatal(); - } - - // LDC - // another safety check to make sure we don't overwrite previous output files - if (!singleObj) - check_and_add_output_file(this, objfile->name->str); - if (docfile) - check_and_add_output_file(this, docfile->name->str); - if (hdrfile) - check_and_add_output_file(this, hdrfile->name->str); -} - -#endif - void Module::deleteObjFile() { if (global.params.obj) diff --git a/driver/main.cpp b/driver/main.cpp index dcd6f021..f72b674a 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -209,9 +209,7 @@ int main(int argc, char** argv) ConfigFile cfg_file; // just ignore errors for now, they are still printed -#define CFG_FILENAME "ldc2.conf" - cfg_file.read(global.params.argv0, (void*)main, CFG_FILENAME); -#undef CFG_FILENAME + cfg_file.read(global.params.argv0, (void*)main, "ldc2.conf"); // insert config file additions to the argument list final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end()); diff --git a/gen/module.cpp b/gen/module.cpp index 7ff40101..7e3db31d 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -40,6 +40,7 @@ #include "ir/irmodule.h" #include "ir/irtype.h" #include "ir/irvar.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Analysis/Verifier.h" #include "llvm/LinkAllPasses.h" #if LDC_LLVM_VER >= 303 @@ -54,6 +55,121 @@ #endif #endif +static llvm::cl::opt preservePaths("op", + llvm::cl::desc("Do not strip paths from source file"), + llvm::cl::ZeroOrMore); + +static llvm::cl::opt fqnNames("oq", + llvm::cl::desc("Write object files with fully qualified names"), + llvm::cl::ZeroOrMore); + +static void check_and_add_output_file(Module* NewMod, const std::string& str) +{ + typedef std::map map_t; + static map_t files; + + map_t::iterator i = files.find(str); + if (i != files.end()) { + Module* ThisMod = i->second; + error(Loc(), "Output file '%s' for module '%s' collides with previous module '%s'. See the -oq option", + str.c_str(), NewMod->toPrettyChars(), ThisMod->toPrettyChars()); + fatal(); + } + files.insert(std::make_pair(str, NewMod)); +} + +void Module::buildTargetFiles(bool singleObj) +{ + if (objfile && + (!doDocComment || docfile) && + (!doHdrGen || hdrfile)) + return; + + if (!objfile) { + if (global.params.output_o) + objfile = Module::buildFilePath(global.params.objname, global.params.objdir, + global.params.targetTriple.isOSWindows() ? global.obj_ext_alt : global.obj_ext); + else if (global.params.output_bc) + objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.bc_ext); + else if (global.params.output_ll) + objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.ll_ext); + else if (global.params.output_s) + objfile = Module::buildFilePath(global.params.objname, global.params.objdir, global.s_ext); + } + if (doDocComment && !docfile) + docfile = Module::buildFilePath(global.params.docname, global.params.docdir, global.doc_ext); + if (doHdrGen && !hdrfile) + hdrfile = Module::buildFilePath(global.params.hdrname, global.params.hdrdir, global.hdr_ext); + + // safety check: never allow obj, doc or hdr file to have the source file's name + if (Port::stricmp(FileName::name(objfile->name->str), FileName::name((char*)this->arg)) == 0) { + error("Output object files with the same name as the source file are forbidden"); + fatal(); + } + if (docfile && Port::stricmp(FileName::name(docfile->name->str), FileName::name((char*)this->arg)) == 0) { + error("Output doc files with the same name as the source file are forbidden"); + fatal(); + } + if (hdrfile && Port::stricmp(FileName::name(hdrfile->name->str), FileName::name((char*)this->arg)) == 0) { + error("Output header files with the same name as the source file are forbidden"); + fatal(); + } + + // LDC + // another safety check to make sure we don't overwrite previous output files + if (!singleObj) + check_and_add_output_file(this, objfile->name->str); + if (docfile) + check_and_add_output_file(this, docfile->name->str); + if (hdrfile) + check_and_add_output_file(this, hdrfile->name->str); +} + +File* Module::buildFilePath(const char* forcename, const char* path, const char* ext) +{ + const char *argobj; + if (forcename) { + argobj = forcename; + } else { + if (preservePaths) + argobj = (char*)this->arg; + else + argobj = FileName::name((char*)this->arg); + + if (fqnNames) { + char *name = md ? md->toChars() : toChars(); + argobj = FileName::replaceName((char*)argobj, name); + + // add ext, otherwise forceExt will make nested.module into nested.bc + size_t len = strlen(argobj); + size_t extlen = strlen(ext); + char* s = (char *)alloca(len + 1 + extlen + 1); + memcpy(s, argobj, len); + s[len] = '.'; + memcpy(s + len + 1, ext, extlen + 1); + s[len+1+extlen] = 0; + argobj = s; + } + } + + if (!FileName::absolute(argobj)) + argobj = FileName::combine(path, argobj); + + FileName::ensurePathExists(FileName::path(argobj)); + + // always append the extension! otherwise hard to make output switches consistent + // if (forcename) + // return new File(argobj); + // else + // allow for .o and .obj on windows +#if _WIN32 + if (ext == global.params.objdir && FileName::ext(argobj) + && Port::stricmp(FileName::ext(argobj), global.obj_ext_alt) == 0) + return new File((char*)argobj); +#endif + return new File(FileName::forceExt(argobj, ext)); +} + static llvm::Function* build_module_function(const std::string &name, const std::list &funcs, const std::list &gates = std::list()) { From 21b07c783af680b14f385f771ce88646d1e82241 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sun, 28 Jul 2013 21:59:01 +0400 Subject: [PATCH 2/6] Remove Module::moduleInfoType --- dmd2/module.c | 16 ---------------- dmd2/module.h | 1 - gen/module.cpp | 19 ++++++++++--------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/dmd2/module.c b/dmd2/module.c index a68c6247..56411c5a 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -27,18 +27,6 @@ #include "d-dmd-gcc.h" #endif -#if IN_LLVM -#if LDC_LLVM_VER >= 303 -#include "llvm/IR/Type.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/DerivedTypes.h" -#else -#include "llvm/Type.h" -#include "llvm/LLVMContext.h" -#include "llvm/DerivedTypes.h" -#endif -#endif - AggregateDeclaration *Module::moduleinfo; Module *Module::rootModule; @@ -144,7 +132,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen // LDC llvmForceLogging = false; moduleInfoVar = NULL; - moduleInfoType = llvm::StructType::create(llvm::getGlobalContext()); this->doDocComment = doDocComment; this->doHdrGen = doHdrGen; this->isRoot = false; @@ -214,9 +201,6 @@ void Module::deleteObjFile() Module::~Module() { -#if IN_LLVM - delete moduleInfoType; -#endif } const char *Module::kind() diff --git a/dmd2/module.h b/dmd2/module.h index fe213fc3..648e527e 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -201,7 +201,6 @@ struct Module : Package bool llvmForceLogging; llvm::GlobalVariable* moduleInfoVar; - llvm::StructType* moduleInfoType; // array ops emitted in this module already AA *arrayfuncs; diff --git a/gen/module.cpp b/gen/module.cpp index 7e3db31d..f7fc0d8a 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -453,13 +453,13 @@ llvm::GlobalVariable* Module::moduleInfoSymbol() return var; } - if (moduleInfoVar) - return moduleInfoVar; - - // declare global - // flags will be modified at runtime so can't make it constant - moduleInfoVar = getOrCreateGlobal(loc, *gIR->module, moduleInfoType, - false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); + if (!moduleInfoVar) { + // declare global + // flags will be modified at runtime so can't make it constant + LLType *moduleInfoType = llvm::StructType::create(llvm::getGlobalContext()); + moduleInfoVar = getOrCreateGlobal(loc, *gIR->module, moduleInfoType, + false, llvm::GlobalValue::ExternalLinkage, NULL, MIname); + } return moduleInfoVar; } @@ -637,10 +637,11 @@ void Module::genmoduleinfo() b.push(toConstantArray(it, at, name, len, false)); // create and set initializer - b.finalize(moduleInfoType, moduleInfoSymbol()); + LLGlobalVariable *moduleInfoSym = moduleInfoSymbol(); + b.finalize(moduleInfoSym->getType()->getPointerElementType(), moduleInfoSym); // build the modulereference and ctor for registering it - LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol()); + LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSym); AppendFunctionToLLVMGlobalCtorsDtors(mictor, 65535, true); } From 153febd093889343cfe677ab9603562c54ddc072 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sun, 28 Jul 2013 22:28:43 +0400 Subject: [PATCH 3/6] Remove minor differences with upstream --- dmd2/apply.c | 2 +- dmd2/clone.c | 2 +- dmd2/declaration.h | 2 +- dmd2/dsymbol.h | 2 +- dmd2/init.c | 2 +- dmd2/module.c | 12 ++++++------ dmd2/module.h | 11 +++++++---- dmd2/mtype.h | 3 +++ dmd2/statement.h | 11 +++++------ dmd2/target.h | 2 +- dmd2/template.c | 4 +++- 11 files changed, 30 insertions(+), 23 deletions(-) diff --git a/dmd2/apply.c b/dmd2/apply.c index 320b24a8..47f8844b 100644 --- a/dmd2/apply.c +++ b/dmd2/apply.c @@ -129,7 +129,7 @@ int StructLiteralExp::apply(fp_t fp, void *param) stageflags |= stageApply; int ret = condApply(elements, fp, param) || (*fp)(this, param); - stageflags = old; + stageflags = old; return ret; } diff --git a/dmd2/clone.c b/dmd2/clone.c index 03ea82c2..c465a553 100644 --- a/dmd2/clone.c +++ b/dmd2/clone.c @@ -164,7 +164,7 @@ Lneed: * Note that s will be constructed onto the stack, and probably * copy-constructed in caller site. * - * If S has copy copy construction and/or destructor, + * If S has copy copy construction and/or destructor, * the body will make bit-wise object swap: * S __tmp = this; // bit copy * this = s; // bit copy diff --git a/dmd2/declaration.h b/dmd2/declaration.h index 27211c5a..a9bbc1ad 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -145,7 +145,7 @@ struct Declaration : Dsymbol enum PROT protection; enum LINK linkage; int inuse; // used to detect cycles - const char *mangleOverride; // overridden symbol with pragma(mangle, "...") + const char *mangleOverride; // overridden symbol with pragma(mangle, "...") enum Semantic sem; Declaration(Identifier *id); diff --git a/dmd2/dsymbol.h b/dmd2/dsymbol.h index 54b56669..585aae33 100644 --- a/dmd2/dsymbol.h +++ b/dmd2/dsymbol.h @@ -163,7 +163,7 @@ struct Dsymbol : Object void deprecation(Loc loc, const char *format, ...); void deprecation(const char *format, ...); void checkDeprecated(Loc loc, Scope *sc); - Module *getModule(); // module where declared + Module *getModule(); Module *getAccessModule(); Dsymbol *pastMixin(); Dsymbol *toParent(); diff --git a/dmd2/init.c b/dmd2/init.c index d59a66ff..0bbe76aa 100644 --- a/dmd2/init.c +++ b/dmd2/init.c @@ -907,7 +907,7 @@ bool hasNonConstPointers(Expression *e) int old = se->stageflags; se->stageflags |= stageSearchPointers; bool ret = arrayHasNonConstPointers(se->elements); - se->stageflags = old; + se->stageflags = old; return ret; } else diff --git a/dmd2/module.c b/dmd2/module.c index 56411c5a..ec4ca973 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -741,7 +741,7 @@ void Module::importAll(Scope *prevsc) sc->pop(); // 2 pops because Scope::createGlobal() created 2 } -void Module::semantic(Scope* unused_sc) +void Module::semantic() { if (semanticstarted) return; @@ -811,7 +811,7 @@ void Module::semantic(Scope* unused_sc) //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); } -void Module::semantic2(Scope* unused_sc) +void Module::semantic2() { if (deferred.dim) { @@ -851,7 +851,7 @@ void Module::semantic2(Scope* unused_sc) //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent); } -void Module::semantic3(Scope* unused_sc) +void Module::semantic3() { //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent); if (semanticstarted >= 3) @@ -904,8 +904,7 @@ void Module::inlineScan() /**************************************************** */ -// is this used anywhere? -/* +#if IN_DMD void Module::gensymfile() { OutBuffer buf; @@ -927,7 +926,8 @@ void Module::gensymfile() buf.data = NULL; symfile->writev(); -}*/ +} +#endif /********************************** * Determine if we need to generate an instance of ModuleInfo diff --git a/dmd2/module.h b/dmd2/module.h index 648e527e..c2365545 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -143,12 +143,15 @@ struct Module : Package void parse(); // syntactic parse #endif void importAll(Scope *sc); - void semantic(Scope* unused_sc = NULL); // semantic analysis - void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis - void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis + void semantic(); // semantic analysis + void semantic2(); // pass 2 semantic analysis + void semantic3(); // pass 3 semantic analysis void inlineScan(); // scan for functions to inline void genhdrfile(); // generate D import file -// void gensymfile(); +#if IN_DMD + void genobjfile(int multiobj); + void gensymfile(); +#endif void gendocfile(); int needModuleInfo(); Dsymbol *search(Loc loc, Identifier *ident, int flags); diff --git a/dmd2/mtype.h b/dmd2/mtype.h index 3c34827b..d8354585 100644 --- a/dmd2/mtype.h +++ b/dmd2/mtype.h @@ -52,6 +52,9 @@ struct Parameter; #ifdef IN_GCC union tree_node; typedef union tree_node TYPE; typedef TYPE type; +#elif IN_LLVM +#else +typedef struct TYPE type; #endif #if IN_DMD diff --git a/dmd2/statement.h b/dmd2/statement.h index 6a2edf4c..3636ec79 100644 --- a/dmd2/statement.h +++ b/dmd2/statement.h @@ -75,17 +75,16 @@ typedef bool (*sapply_fp_t)(Statement *, void *); // Back end struct IRState; struct Blockx; -#if IN_LLVM -class DValue; -typedef DValue elem; -#endif #ifdef IN_GCC union tree_node; typedef union tree_node block; -//union tree_node; typedef union tree_node elem; +union tree_node; typedef union tree_node elem; +#elif IN_LLVM +class DValue; +typedef DValue elem; #else struct block; -//struct elem; +struct elem; #endif struct code; diff --git a/dmd2/target.h b/dmd2/target.h index ad3d956d..4ec6f3d3 100644 --- a/dmd2/target.h +++ b/dmd2/target.h @@ -22,7 +22,7 @@ struct Target static int realsize; // size a real consumes in memory static int realpad; // 'padding' added to the CPU real size to bring it up to realsize static int realalignsize; // alignment for reals - + static void init(); static unsigned alignsize(Type* type); static unsigned fieldalign(Type* type); diff --git a/dmd2/template.c b/dmd2/template.c index 35687d6a..a8fb8229 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -5509,7 +5509,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int f { ea = ea->optimize(WANTvalue); } - } + } else if (ea->op == TOKvar) { /* This test is to skip substituting a const var with * its initializer. The problem is the initializer won't @@ -6999,3 +6999,5 @@ void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writebyte(';'); buf->writenl(); } + + From d45931972c0358f2c20eb75a70f1a9bb7fde66d4 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sun, 28 Jul 2013 22:51:27 +0400 Subject: [PATCH 4/6] Move Target implementation out of dmdfe --- dmd2/target.c | 125 ------------------------------------------------- gen/target.cpp | 53 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 125 deletions(-) delete mode 100644 dmd2/target.c create mode 100644 gen/target.cpp diff --git a/dmd2/target.c b/dmd2/target.c deleted file mode 100644 index 84205471..00000000 --- a/dmd2/target.c +++ /dev/null @@ -1,125 +0,0 @@ - -// Copyright (c) 2013 by Digital Mars -// All Rights Reserved -// written by Iain Buclaw -// http://www.digitalmars.com -// License for redistribution is by either the Artistic License -// in artistic.txt, or the GNU General Public License in gnu.txt. -// See the included readme.txt for details. - -#include - -#include "target.h" -#include "mars.h" -#include "mtype.h" - -#if IN_LLVM -unsigned GetTypeAlignment(Type* t); -unsigned GetPointerSize(); -unsigned GetTypeStoreSize(Type* t); -unsigned GetTypeAllocSize(Type* t); -#endif - -int Target::ptrsize; -int Target::realsize; -int Target::realpad; -int Target::realalignsize; - -void Target::init() -{ -#if IN_LLVM - ptrsize = GetPointerSize(); - realsize = GetTypeAllocSize(Type::basic[Tfloat80]); - realpad = realsize - GetTypeStoreSize(Type::basic[Tfloat80]); - realalignsize = GetTypeAlignment(Type::basic[Tfloat80]); -#else - // These have default values for 32 bit code, they get - // adjusted for 64 bit code. - ptrsize = 4; - - if (global.params.isLinux || global.params.isFreeBSD - || global.params.isOpenBSD || global.params.isSolaris) - { - realsize = 12; - realpad = 2; - realalignsize = 4; - } - else if (global.params.isOSX) - { - realsize = 16; - realpad = 6; - realalignsize = 16; - } - else if (global.params.isWindows) - { - realsize = 10; - realpad = 0; - realalignsize = 2; - } - else - assert(0); - - if (global.params.is64bit) - { - ptrsize = 8; - if (global.params.isLinux || global.params.isFreeBSD || global.params.isSolaris) - { - realsize = 16; - realpad = 6; - realalignsize = 16; - } - } -#endif -} - -/****************************** - * Return memory alignment size of type. - */ - -unsigned Target::alignsize (Type* type) -{ - assert (type->isTypeBasic()); - -#if IN_LLVM - if (type->ty == Tvoid) return 1; - return GetTypeAlignment(type); -#else - switch (type->ty) - { - case Tfloat80: - case Timaginary80: - case Tcomplex80: - return Target::realalignsize; - - case Tcomplex32: - if (global.params.isLinux || global.params.isOSX || global.params.isFreeBSD - || global.params.isOpenBSD || global.params.isSolaris) - return 4; - break; - - case Tint64: - case Tuns64: - case Tfloat64: - case Timaginary64: - case Tcomplex64: - if (global.params.isLinux || global.params.isOSX || global.params.isFreeBSD - || global.params.isOpenBSD || global.params.isSolaris) - return global.params.is64bit ? 8 : 4; - break; - - default: - break; - } - return type->size(Loc()); -#endif -} - -/****************************** - * Return field alignment size of type. - */ - -unsigned Target::fieldalign (Type* type) -{ - // LDC_FIXME: Verify this. - return type->alignsize(); -} diff --git a/gen/target.cpp b/gen/target.cpp new file mode 100644 index 00000000..f4babdfa --- /dev/null +++ b/gen/target.cpp @@ -0,0 +1,53 @@ +//===-- target.cpp -------------------------------------------------------===// +// +// LDC – the LLVM D compiler +// +// This file is distributed under the BSD-style LDC license. See the LICENSE +// file for details. +// +//===----------------------------------------------------------------------===// + +#include + +#include "target.h" +#include "mars.h" +#include "mtype.h" + +unsigned GetTypeAlignment(Type* t); +unsigned GetPointerSize(); +unsigned GetTypeStoreSize(Type* t); +unsigned GetTypeAllocSize(Type* t); + +int Target::ptrsize; +int Target::realsize; +int Target::realpad; +int Target::realalignsize; + +void Target::init() +{ + ptrsize = GetPointerSize(); + realsize = GetTypeAllocSize(Type::basic[Tfloat80]); + realpad = realsize - GetTypeStoreSize(Type::basic[Tfloat80]); + realalignsize = GetTypeAlignment(Type::basic[Tfloat80]); +} + +/****************************** + * Return memory alignment size of type. + */ + +unsigned Target::alignsize (Type* type) +{ + assert (type->isTypeBasic()); + if (type->ty == Tvoid) return 1; + return GetTypeAlignment(type); +} + +/****************************** + * Return field alignment size of type. + */ + +unsigned Target::fieldalign (Type* type) +{ + // LDC_FIXME: Verify this. + return type->alignsize(); +} From fb31047dcd5d9c495838200b3659f489f982aba0 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Mon, 29 Jul 2013 16:29:23 +0400 Subject: [PATCH 5/6] Prettify our C functions' signatures patch to have a chance to be included into dmd --- dmd2/arrayop.c | 2 +- dmd2/mtype.c | 131 ++++++++++++++++++++--------------------------- dmd2/statement.c | 96 +++++++++++++--------------------- 3 files changed, 93 insertions(+), 136 deletions(-) diff --git a/dmd2/arrayop.c b/dmd2/arrayop.c index d0bad81a..3f9f9a48 100644 --- a/dmd2/arrayop.c +++ b/dmd2/arrayop.c @@ -251,7 +251,7 @@ int isDruntimeArrayOp(Identifier *ident) ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc) { ArrayOp *op = new ArrayOp; -#if IN_LLVM +#if IN_LLVM // LDC: Build parameters. Parameters *fparams = new Parameters(); Expression *loopbody = exp->buildArrayLoop(fparams); if (isDruntimeArrayOp(ident)) diff --git a/dmd2/mtype.c b/dmd2/mtype.c index e7747c40..1baaa9b0 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -3624,37 +3624,24 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f if (ident == Id::reverse && (n->ty == Tchar || n->ty == Twchar)) { - -#if IN_LLVM - Expression *ec; - - //LDC: Build arguments. - static FuncDeclaration *adReverseChar_fd = NULL; - if(!adReverseChar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::tchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar"); - } - static FuncDeclaration *adReverseWchar_fd = NULL; - if(!adReverseWchar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::twchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar"); - } - - if(n->ty == Twchar) - ec = new VarExp(Loc(), adReverseWchar_fd); - else - ec = new VarExp(Loc(), adReverseChar_fd); -#else static const char *name[2] = { "_adReverseChar", "_adReverseWchar" }; +#if IN_LLVM // LDC: Build parameters. + static FuncDeclaration *funcs[2] = { 0, 0 }; + int i = n->ty == Twchar; + if (!funcs[i]) { + Parameters *args = new Parameters; + Type *next = n->ty == Twchar ? Type::twchar : Type::tchar; + Type *arrty = next->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + funcs[i] = FuncDeclaration::genCfunc(args, arrty, name[i]); + } + FuncDeclaration *fd = funcs[i]; +#else const char *nm = name[n->ty == Twchar]; FuncDeclaration *fd = FuncDeclaration::genCfunc(Type::tindex, nm); - Expression *ec = new VarExp(Loc(), fd); #endif + Expression *ec = new VarExp(Loc(), fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array Expressions *arguments = new Expressions(); arguments->push(e); @@ -3664,34 +3651,28 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f else if (ident == Id::sort && (n->ty == Tchar || n->ty == Twchar)) { Expression *ec; + FuncDeclaration *fd; Expressions *arguments; + const char *nm; + static const char *name[2] = { "_adSortChar", "_adSortWchar" }; -#if IN_LLVM - //LDC: Build arguments. - static FuncDeclaration *adSortChar_fd = NULL; - if(!adSortChar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::tchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar"); +#if IN_LLVM // LDC: Build parameters. + static FuncDeclaration *funcs[2] = { 0, 0 }; + int i = n->ty == Twchar; + if (!funcs[i]) { + Parameters *args = new Parameters; + Type *next = n->ty == Twchar ? Type::twchar : Type::tchar; + Type *arrty = next->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + funcs[i] = FuncDeclaration::genCfunc(args, arrty, name[i]); } - static FuncDeclaration *adSortWchar_fd = NULL; - if(!adSortWchar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::twchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar"); - } - - if(n->ty == Twchar) - ec = new VarExp(Loc(), adSortWchar_fd); - else - ec = new VarExp(Loc(), adSortChar_fd); + fd = funcs[i]; #else nm = name[n->ty == Twchar]; fd = FuncDeclaration::genCfunc(Type::tindex, nm); - ec = new VarExp(Loc(), fd); #endif + ec = new VarExp(Loc(), fd); + e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); arguments->push(e); @@ -3701,6 +3682,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f else if (ident == Id::reverse || ident == Id::dup || ident == Id::idup) { Expression *ec; + FuncDeclaration *fd; Expressions *arguments; int size = next->size(e->loc); int dup; @@ -3708,31 +3690,31 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f Expression *olde = e; assert(size); dup = (ident == Id::dup || ident == Id::idup); -#if IN_LLVM - //LDC: Build arguments. - static FuncDeclaration *adDup_fd = NULL; - if(!adDup_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); +#if IN_LLVM // LDC: Build parameters. + Parameters *args = new Parameters; + if (dup) { + static FuncDeclaration *adDup_fd = 0; + if (!adDup_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); + } + fd = adDup_fd; + } else { + static FuncDeclaration *adReverse_fd = 0; + if (!adReverse_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); + adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); + } + fd = adReverse_fd; } - static FuncDeclaration *adReverse_fd = NULL; - if(!adReverse_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); - adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); - } - - if(dup) - ec = new VarExp(Loc(), adDup_fd); - else - ec = new VarExp(Loc(), adReverse_fd); #else fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse); - ec = new VarExp(Loc(), fd); #endif + ec = new VarExp(Loc(), fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); if (dup) @@ -3768,21 +3750,18 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int f Expression *ec; Expressions *arguments; -#if IN_LLVM - //LDC: Build arguments. - static FuncDeclaration *adSort_fd = NULL; - if(!adSort_fd) { +#if IN_LLVM // LDC: Build parameters. + static FuncDeclaration *fd = NULL; + if (!fd) { Parameters* args = new Parameters; args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); - adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); + fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); } - - ec = new VarExp(Loc(), adSort_fd); #else fd = FuncDeclaration::genCfunc(tint32->arrayOf(), "_adSort"); - ec = new VarExp(Loc(), fd); #endif + ec = new VarExp(Loc(), fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); arguments->push(e); diff --git a/dmd2/statement.c b/dmd2/statement.c index 9d9c5454..28f4d77d 100644 --- a/dmd2/statement.c +++ b/dmd2/statement.c @@ -1989,11 +1989,6 @@ Lagain: { Expression *ec; Expression *e; -#if IN_LLVM - FuncDeclaration *fdapply; - TypeDelegate* dgty; - TypeDelegate* fldeTy; -#endif if (!checkForArgTypes()) { body = body->semanticNoScope(sc); @@ -2135,46 +2130,36 @@ Lagain: /* Call: * _aaApply(aggr, keysize, flde) */ -#if !IN_LLVM +#if IN_LLVM // LDC: Build parameters. + static const char *names[2] = { "_aaApply", "_aaApply2" }; + static FuncDeclaration *funcs[2] = { NULL, NULL }; + static TypeDelegate *dgs[2] = { NULL, NULL }; + FuncDeclaration *fdapply; - if (dim == 2) - fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2"); - else - fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply"); -#else - //LDC: Build arguments. - static FuncDeclaration *aaApply2_fd = NULL; - static TypeDelegate* aaApply2_dg; - if(!aaApply2_fd) { + TypeDelegate *fldeTy; + + unsigned char i = dim == 2; + if (!funcs[i]) { Parameters* args = new Parameters; args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); Parameters* dgargs = new Parameters; dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); - args->push(new Parameter(STCin, aaApply2_dg, NULL, NULL)); - aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply2"); - } - static FuncDeclaration *aaApply_fd = NULL; - static TypeDelegate* aaApply_dg; - if(!aaApply_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL)); // FIXME: Real parameter type is AA. - args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); - Parameters* dgargs = new Parameters; - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); - args->push(new Parameter(STCin, aaApply_dg, NULL, NULL)); - aaApply_fd = FuncDeclaration::genCfunc(args, Type::tint32, "_aaApply"); - } - if (dim == 2) { - fdapply = aaApply2_fd; - fldeTy = aaApply2_dg; - } else { - fdapply = aaApply_fd; - fldeTy = aaApply_dg; + if (dim == 2) + dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); + dgs[i] = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); + args->push(new Parameter(STCin, dgs[i], NULL, NULL)); + funcs[i] = FuncDeclaration::genCfunc(args, Type::tint32, names[i]); } + fdapply = funcs[i]; + fldeTy = dgs[i]; + +#else + FuncDeclaration *fdapply; + if (dim == 2) + fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2"); + else + fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply"); #endif ec = new VarExp(Loc(), fdapply); Expressions *exps = new Expressions(); @@ -2229,24 +2214,19 @@ Lagain: const char *r = (op == TOKforeach_reverse) ? "R" : ""; int j = sprintf(fdname, "_aApply%s%.*s%llu", r, 2, fntab[flag], (ulonglong)dim); assert(j < sizeof(fdname) / sizeof(fdname[0])); -#if IN_LLVM - //LDC: Build arguments. +#if IN_LLVM // LDC: Build parameters. + FuncDeclaration *fdapply; + TypeDelegate *dgty; Parameters* args = new Parameters; args->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL)); - if (dim == 2) { - Parameters* dgargs = new Parameters; + Parameters* dgargs = new Parameters; + dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); + if (dim == 2) dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); - args->push(new Parameter(STCin, dgty, NULL, NULL)); - fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); - } else { - Parameters* dgargs = new Parameters; - dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL)); - dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); - args->push(new Parameter(STCin, dgty, NULL, NULL)); - fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); - } + dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tint32, 0, LINKd)); + args->push(new Parameter(STCin, dgty, NULL, NULL)); + fdapply = FuncDeclaration::genCfunc(args, Type::tint32, fdname); + #else FuncDeclaration *fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname); #endif @@ -4419,8 +4399,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc) Statements *cs = new Statements(); cs->push(new ExpStatement(loc, tmp)); -#if IN_LLVM - // LDC: Build args +#if IN_LLVM // LDC: Build parameters. Parameters* args = new Parameters; args->push(new Parameter(STCin, ClassDeclaration::object->type, NULL, NULL)); FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorenter); @@ -4431,7 +4410,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc) e->type = Type::tvoid; // do not run semantic on e cs->push(new ExpStatement(loc, e)); -#if IN_LLVM +#if IN_LLVM // LDC: Build parameters. FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::monitorexit); #else FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::monitorexit); @@ -4465,8 +4444,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc) Statements *cs = new Statements(); cs->push(new ExpStatement(loc, tmp)); -#if IN_LLVM - // LDC: Build args +#if IN_LLVM // LDC: Build parameters. Parameters* args = new Parameters; args->push(new Parameter(STCin, t->pointerTo(), NULL, NULL)); @@ -4480,7 +4458,7 @@ Statement *SynchronizedStatement::semantic(Scope *sc) e->type = Type::tvoid; // do not run semantic on e cs->push(new ExpStatement(loc, e)); -#if IN_LLVM +#if IN_LLVM // LDC: Build parameters. FuncDeclaration *fdexit = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalexit); #else FuncDeclaration *fdexit = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalexit); From 54078eca665094c42af18022ad296d694de43314 Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Mon, 29 Jul 2013 18:49:09 +0400 Subject: [PATCH 6/6] Set global.params.isOS variables so we do not have to modify dmd frontend to use targetTriple --- dmd2/class.c | 4 ---- dmd2/cppmangle.c | 4 ---- dmd2/func.c | 10 +--------- dmd2/mars.h | 7 +++++++ dmd2/parse.c | 2 +- driver/main.cpp | 10 +++++++++- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/dmd2/class.c b/dmd2/class.c index ce85a096..db93aa58 100644 --- a/dmd2/class.c +++ b/dmd2/class.c @@ -588,11 +588,7 @@ void ClassDeclaration::semantic(Scope *sc) if (isCOMclass()) { -#if IN_LLVM - if (global.params.targetTriple.isOSWindows()) -#else if (global.params.isWindows) -#endif sc->linkage = LINKwindows; else /* This enables us to use COM objects under Linux and diff --git a/dmd2/cppmangle.c b/dmd2/cppmangle.c index 78750549..686d61bd 100644 --- a/dmd2/cppmangle.c +++ b/dmd2/cppmangle.c @@ -160,11 +160,7 @@ char *cpp_mangle(Dsymbol *s) cms.components.setDim(0); OutBuffer buf; -#if IN_LLVM - buf.writestring("__Z" + !(global.params.targetTriple.isMacOSX())); // "_Z" for OSX -#else buf.writestring("__Z" + !global.params.isOSX); // "_Z" for OSX -#endif cpp_mangle_name(&buf, &cms, s); diff --git a/dmd2/func.c b/dmd2/func.c index 61595c02..7a9dc42e 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -1888,16 +1888,8 @@ void FuncDeclaration::semantic3(Scope *sc) if (cd) { if (!global.params.is64bit && -#if IN_LLVM - global.params.targetTriple.isOSWindows() && -#else global.params.isWindows && -#endif - !isStatic() && !fbody->usesEH() -#if !IN_LLVM - && !global.params.trace -#endif - ) + !isStatic() && !fbody->usesEH() && !global.params.trace) { /* The back end uses the "jmonitor" hack for syncing; * no need to do the sync at this level. diff --git a/dmd2/mars.h b/dmd2/mars.h index 2a6bff31..e36b0ab3 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -162,7 +162,14 @@ struct Param bool vtls; // identify thread local variables bool vfield; // identify non-mutable field variables ubyte symdebug; // insert debug symbolic information + bool trace; // insert profiling hooks bool is64bit; // generate 64 bit code + bool isLinux; // generate code for linux + bool isOSX; // generate code for Mac OSX + bool isWindows; // generate code for Windows + bool isFreeBSD; // generate code for FreeBSD + bool isOpenBSD; // generate code for OpenBSD + bool isSolaris; // generate code for Solaris #else char dll; // generate shared dynamic library char lib; // write library file instead of object file(s) diff --git a/dmd2/parse.c b/dmd2/parse.c index 28b7e664..0f827fdf 100644 --- a/dmd2/parse.c +++ b/dmd2/parse.c @@ -993,7 +993,7 @@ enum LINK Parser::parseLinkage() else if (id == Id::System) { #if IN_LLVM - if (global.params.targetTriple.isOSWindows()) + if (global.params.isWindows) link = LINKwindows; else link = LINKc; diff --git a/driver/main.cpp b/driver/main.cpp index f72b674a..e97b7ba7 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -475,7 +475,15 @@ int main(int argc, char** argv) gTargetMachine = createTargetMachine(mTargetTriple, mArch, mCPU, mAttrs, bitness, mRelocModel, mCodeModel, codeGenOptLevel(), global.params.symdebug); - global.params.targetTriple = llvm::Triple(gTargetMachine->getTargetTriple()); + llvm::Triple targetTriple = llvm::Triple(gTargetMachine->getTargetTriple()); + global.params.targetTriple = targetTriple; + global.params.trace = false; + global.params.isLinux = targetTriple.getOS() == llvm::Triple::Linux; + global.params.isOSX = targetTriple.isMacOSX(); + global.params.isWindows = targetTriple.isOSWindows(); + global.params.isFreeBSD = targetTriple.getOS() == llvm::Triple::FreeBSD; + global.params.isOpenBSD = targetTriple.getOS() == llvm::Triple::OpenBSD; + global.params.isSolaris = targetTriple.getOS() == llvm::Triple::Solaris; #if LDC_LLVM_VER >= 302 gDataLayout = gTargetMachine->getDataLayout();