Mercurial > projects > ldc
comparison gen/toobj.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 | f756c47f310a |
children | b9f9bde1707e |
comparison
equal
deleted
inserted
replaced
1051:dc608dc33081 | 1052:12ea38902e83 |
---|---|
68 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); | 68 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out); |
69 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); | 69 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath); |
70 | 70 |
71 ////////////////////////////////////////////////////////////////////////////////////////// | 71 ////////////////////////////////////////////////////////////////////////////////////////// |
72 | 72 |
73 void Module::genobjfile(int multiobj) | 73 llvm::Module* Module::genLLVMModule(int multiobj) |
74 { | 74 { |
75 bool logenabled = Logger::enabled(); | 75 bool logenabled = Logger::enabled(); |
76 if (llvmForceLogging && !logenabled) | 76 if (llvmForceLogging && !logenabled) |
77 { | 77 { |
78 Logger::enable(); | 78 Logger::enable(); |
82 LOG_SCOPE; | 82 LOG_SCOPE; |
83 | 83 |
84 //printf("codegen: %s\n", srcfile->toChars()); | 84 //printf("codegen: %s\n", srcfile->toChars()); |
85 | 85 |
86 assert(!global.errors); | 86 assert(!global.errors); |
87 | |
88 // start by deleting the old object file | |
89 deleteObjFile(); | |
90 | 87 |
91 // name the module | 88 // name the module |
92 std::string mname(toChars()); | 89 std::string mname(toChars()); |
93 if (md != 0) | 90 if (md != 0) |
94 mname = md->toChars(); | 91 mname = md->toChars(); |
172 else { | 169 else { |
173 Logger::println("Verification passed!"); | 170 Logger::println("Verification passed!"); |
174 } | 171 } |
175 } | 172 } |
176 | 173 |
174 gIR = NULL; | |
175 | |
176 if (llvmForceLogging && !logenabled) | |
177 { | |
178 Logger::disable(); | |
179 } | |
180 | |
181 return ir.module; | |
182 } | |
183 | |
184 void writeModule(llvm::Module* m, std::string filename) | |
185 { | |
177 // run optimizer | 186 // run optimizer |
178 ldc_optimize_module(ir.module, global.params.optimizeLevel, global.params.llvmInline); | 187 ldc_optimize_module(m, global.params.optimizeLevel, global.params.llvmInline); |
179 | 188 |
180 // verify the llvm | 189 // verify the llvm |
181 if (!noVerify && (global.params.optimizeLevel >= 0 || global.params.llvmInline)) { | 190 if (!noVerify && (global.params.optimizeLevel >= 0 || global.params.llvmInline)) { |
182 std::string verifyErr; | 191 std::string verifyErr; |
183 Logger::println("Verifying module... again..."); | 192 Logger::println("Verifying module... again..."); |
184 LOG_SCOPE; | 193 LOG_SCOPE; |
185 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) | 194 if (llvm::verifyModule(*m,llvm::ReturnStatusAction,&verifyErr)) |
186 { | 195 { |
187 error("%s", verifyErr.c_str()); | 196 //error("%s", verifyErr.c_str()); |
188 fatal(); | 197 fatal(); |
189 } | 198 } |
190 else { | 199 else { |
191 Logger::println("Verification passed!"); | 200 Logger::println("Verification passed!"); |
192 } | 201 } |
195 // eventually do our own path stuff, dmd's is a bit strange. | 204 // eventually do our own path stuff, dmd's is a bit strange. |
196 typedef llvm::sys::Path LLPath; | 205 typedef llvm::sys::Path LLPath; |
197 | 206 |
198 // write LLVM bitcode | 207 // write LLVM bitcode |
199 if (global.params.output_bc) { | 208 if (global.params.output_bc) { |
200 LLPath bcpath = LLPath(objfile->name->toChars()); | 209 LLPath bcpath = LLPath(filename); |
201 bcpath.eraseSuffix(); | 210 bcpath.eraseSuffix(); |
202 bcpath.appendSuffix(std::string(global.bc_ext)); | 211 bcpath.appendSuffix(std::string(global.bc_ext)); |
203 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); | 212 Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str()); |
204 std::ofstream bos(bcpath.c_str(), std::ios::binary); | 213 std::ofstream bos(bcpath.c_str(), std::ios::binary); |
205 llvm::WriteBitcodeToFile(ir.module, bos); | 214 llvm::WriteBitcodeToFile(m, bos); |
206 } | 215 } |
207 | 216 |
208 // write LLVM IR | 217 // write LLVM IR |
209 if (global.params.output_ll) { | 218 if (global.params.output_ll) { |
210 LLPath llpath = LLPath(objfile->name->toChars()); | 219 LLPath llpath = LLPath(filename); |
211 llpath.eraseSuffix(); | 220 llpath.eraseSuffix(); |
212 llpath.appendSuffix(std::string(global.ll_ext)); | 221 llpath.appendSuffix(std::string(global.ll_ext)); |
213 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); | 222 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); |
214 std::ofstream aos(llpath.c_str()); | 223 std::ofstream aos(llpath.c_str()); |
215 ir.module->print(aos, NULL); | 224 m->print(aos, NULL); |
216 } | 225 } |
217 | 226 |
218 // write native assembly | 227 // write native assembly |
219 if (global.params.output_s || global.params.output_o) { | 228 if (global.params.output_s || global.params.output_o) { |
220 LLPath spath = LLPath(objfile->name->toChars()); | 229 LLPath spath = LLPath(filename); |
221 spath.eraseSuffix(); | 230 spath.eraseSuffix(); |
222 spath.appendSuffix(std::string(global.s_ext)); | 231 spath.appendSuffix(std::string(global.s_ext)); |
223 if (!global.params.output_s) { | 232 if (!global.params.output_s) { |
224 spath.createTemporaryFileOnDisk(); | 233 spath.createTemporaryFileOnDisk(); |
225 } | 234 } |
226 Logger::println("Writing native asm to: %s\n", spath.c_str()); | 235 Logger::println("Writing native asm to: %s\n", spath.c_str()); |
227 std::string err; | 236 std::string err; |
228 { | 237 { |
229 llvm::raw_fd_ostream out(spath.c_str(), false, err); | 238 llvm::raw_fd_ostream out(spath.c_str(), false, err); |
230 write_asm_to_file(*gTargetMachine, *ir.module, out); | 239 write_asm_to_file(*gTargetMachine, *m, out); |
231 } | 240 } |
232 | 241 |
233 // call gcc to convert assembly to object file | 242 // call gcc to convert assembly to object file |
234 if (global.params.output_o) { | 243 if (global.params.output_o) { |
235 LLPath objpath = LLPath(objfile->name->toChars()); | 244 LLPath objpath = LLPath(filename); |
236 assemble(spath, objpath); | 245 assemble(spath, objpath); |
237 } | 246 } |
238 | 247 |
239 if (!global.params.output_s) { | 248 if (!global.params.output_s) { |
240 spath.eraseFromDisk(); | 249 spath.eraseFromDisk(); |
241 } | 250 } |
242 } | |
243 | |
244 delete ir.module; | |
245 gIR = NULL; | |
246 | |
247 if (llvmForceLogging && !logenabled) | |
248 { | |
249 Logger::disable(); | |
250 } | 251 } |
251 } | 252 } |
252 | 253 |
253 /* ================================================================== */ | 254 /* ================================================================== */ |
254 | 255 |