Mercurial > projects > ldc
comparison gen/main.cpp @ 1052:12ea38902e83
Add '-singleobj' command line switch that will tell LDC to link LLVM modules internally and only emit a single object file.
The switch allows the optimizer and inliner to run on all modules at once and opens the door for template instantiation improvements that should lower compile time and executable size.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 07 Mar 2009 19:38:00 +0100 |
parents | abfe71f5b911 |
children | 7ce8355fbcc6 |
comparison
equal
deleted
inserted
replaced
1051:dc608dc33081 | 1052:12ea38902e83 |
---|---|
2 | 2 |
3 // some things are taken from llvm's llc tool | 3 // some things are taken from llvm's llc tool |
4 // which uses the llvm license | 4 // which uses the llvm license |
5 | 5 |
6 #include "gen/llvm.h" | 6 #include "gen/llvm.h" |
7 #include "llvm/Linker.h" | |
7 #include "llvm/Target/SubtargetFeature.h" | 8 #include "llvm/Target/SubtargetFeature.h" |
8 #include "llvm/Target/TargetMachine.h" | 9 #include "llvm/Target/TargetMachine.h" |
9 #include "llvm/Target/TargetMachineRegistry.h" | 10 #include "llvm/Target/TargetMachineRegistry.h" |
10 #include "llvm/LinkAllVMCore.h" | 11 #include "llvm/LinkAllVMCore.h" |
11 | 12 |
30 #include "cond.h" | 31 #include "cond.h" |
31 | 32 |
32 #include "gen/logger.h" | 33 #include "gen/logger.h" |
33 #include "gen/linker.h" | 34 #include "gen/linker.h" |
34 #include "gen/irstate.h" | 35 #include "gen/irstate.h" |
36 #include "gen/toobj.h" | |
35 | 37 |
36 #include "gen/cl_options.h" | 38 #include "gen/cl_options.h" |
37 #include "gen/cl_helpers.h" | 39 #include "gen/cl_helpers.h" |
38 using namespace opts; | 40 using namespace opts; |
39 | 41 |
40 extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv); | 42 extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv); |
41 extern void backend_init(); | 43 extern void backend_init(); |
42 extern void backend_term(); | 44 extern void backend_term(); |
45 | |
46 static cl::opt<bool> singleObj("singleobj", | |
47 cl::desc("Create only a single output object file"), | |
48 cl::ZeroOrMore); | |
43 | 49 |
44 static cl::opt<bool> noDefaultLib("nodefaultlib", | 50 static cl::opt<bool> noDefaultLib("nodefaultlib", |
45 cl::desc("Don't add a default library for linking implicitly"), | 51 cl::desc("Don't add a default library for linking implicitly"), |
46 cl::ZeroOrMore); | 52 cl::ZeroOrMore); |
47 | 53 |
794 } | 800 } |
795 #endif | 801 #endif |
796 if (global.errors) | 802 if (global.errors) |
797 fatal(); | 803 fatal(); |
798 | 804 |
805 // collects llvm modules to be linked if singleobj is passed | |
806 std::vector<llvm::Module*> llvmModules; | |
807 | |
799 // Generate output files | 808 // Generate output files |
800 for (int i = 0; i < modules.dim; i++) | 809 for (int i = 0; i < modules.dim; i++) |
801 { | 810 { |
802 m = (Module *)modules.data[i]; | 811 m = (Module *)modules.data[i]; |
803 if (global.params.verbose) | 812 if (global.params.verbose) |
804 printf("code %s\n", m->toChars()); | 813 printf("code %s\n", m->toChars()); |
805 if (global.params.obj) | 814 if (global.params.obj) |
806 { | 815 { |
807 m->genobjfile(0); | 816 llvm::Module* lm = m->genLLVMModule(0); |
808 global.params.objfiles->push(m->objfile->name->str); | 817 if (!singleObj) |
818 { | |
819 m->deleteObjFile(); | |
820 writeModule(lm, m->objfile->name->str); | |
821 global.params.objfiles->push(m->objfile->name->str); | |
822 delete lm; | |
823 } | |
824 else | |
825 llvmModules.push_back(lm); | |
809 } | 826 } |
810 if (global.errors) | 827 if (global.errors) |
811 m->deleteObjFile(); | 828 m->deleteObjFile(); |
812 else | 829 else |
813 { | 830 { |
814 if (global.params.doDocComments) | 831 if (global.params.doDocComments) |
815 m->gendocfile(); | 832 m->gendocfile(); |
816 } | 833 } |
817 } | 834 } |
818 | 835 |
836 // internal linking for singleobj | |
837 if (singleObj && llvmModules.size() > 0) | |
838 { | |
839 Module* m = (Module*)modules.data[0]; | |
840 char* name = m->toChars(); | |
841 char* filename = m->objfile->name->str; | |
842 | |
843 llvm::Linker linker(name, name); | |
844 std::string errormsg; | |
845 for (int i = 0; i < llvmModules.size(); i++) | |
846 { | |
847 if(linker.LinkInModule(llvmModules[i], &errormsg)) | |
848 error(errormsg.c_str()); | |
849 delete llvmModules[i]; | |
850 } | |
851 | |
852 // workaround for llvm::Linker bug, see llvm #3749 | |
853 llvm::GlobalVariable* ctors = linker.getModule()->getGlobalVariable("llvm.global_ctors"); | |
854 if (ctors) | |
855 while (ctors->getNumUses() > 0) | |
856 delete *ctors->use_begin(); | |
857 | |
858 m->deleteObjFile(); | |
859 writeModule(linker.getModule(), filename); | |
860 global.params.objfiles->push(filename); | |
861 } | |
862 | |
819 backend_term(); | 863 backend_term(); |
820 if (global.errors) | 864 if (global.errors) |
821 fatal(); | 865 fatal(); |
822 | 866 |
823 if (!global.params.objfiles->dim) | 867 if (!global.params.objfiles->dim) |