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