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)