Mercurial > projects > ldc
comparison gen/toobj.cpp @ 674:db6a7e574cbd
Move to separate function and cleanup.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 11 Oct 2008 11:41:56 +0200 |
parents | 37a7688a7494 |
children | bfe5229f9d8e |
comparison
equal
deleted
inserted
replaced
673:37a7688a7494 | 674:db6a7e574cbd |
---|---|
54 ////////////////////////////////////////////////////////////////////////////////////////// | 54 ////////////////////////////////////////////////////////////////////////////////////////// |
55 | 55 |
56 // in gen/optimize.cpp | 56 // in gen/optimize.cpp |
57 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline); | 57 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline); |
58 | 58 |
59 // fwd decl | |
60 void write_asm_to_file(llvm::Module& m, llvm::raw_fd_ostream& Out); | |
61 | |
59 ////////////////////////////////////////////////////////////////////////////////////////// | 62 ////////////////////////////////////////////////////////////////////////////////////////// |
60 | 63 |
61 void Module::genobjfile(int multiobj) | 64 void Module::genobjfile(int multiobj) |
62 { | 65 { |
63 bool logenabled = Logger::enabled(); | 66 bool logenabled = Logger::enabled(); |
193 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); | 196 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); |
194 std::ofstream aos(llpath.c_str()); | 197 std::ofstream aos(llpath.c_str()); |
195 ir.module->print(aos, NULL); | 198 ir.module->print(aos, NULL); |
196 } | 199 } |
197 | 200 |
198 | 201 //TODO: command line switch |
199 //TODO: Move all of this into a helper function? | |
200 if(false) | 202 if(false) |
201 { | 203 { |
202 using namespace llvm; | 204 //FIXME: Proper out file name. |
203 | 205 Logger::println("Writing native asm to: %s\n", ""); |
204 //FIXME: Proper out file name. | 206 std::string err; |
205 std::string Err; | 207 llvm::raw_fd_ostream out("test.s", err); |
206 raw_fd_ostream Out("test.s", Err); | 208 write_asm_to_file(*ir.module, out); |
207 if(!Err.empty()) {} | |
208 | |
209 const TargetMachineRegistry::entry* MArch; | |
210 MArch = TargetMachineRegistry::getClosestStaticTargetForModule(*ir.module, Err); | |
211 if (MArch == 0) { | |
212 error("error auto-selecting target for module '%s'", Err.c_str()); | |
213 fatal(); | |
214 } | |
215 | |
216 SubtargetFeatures Features; | |
217 //TODO: Features? | |
218 // Features.setCPU(MCPU); | |
219 // for (unsigned i = 0; i != MAttrs.size(); ++i) | |
220 // Features.AddFeature(MAttrs[i]); | |
221 | |
222 //TODO: Set PIC if shared (or just do it always?) | |
223 // TargetMachine::setRelocationModel(...); | |
224 | |
225 std::auto_ptr<TargetMachine> target(MArch->CtorFn(*ir.module, Features.getString())); | |
226 assert(target.get() && "Could not allocate target machine!"); | |
227 TargetMachine &Target = *target.get(); | |
228 | |
229 // Build up all of the passes that we want to do to the module. | |
230 ExistingModuleProvider Provider(ir.module); | |
231 FunctionPassManager Passes(&Provider); | |
232 //FIXME does this TargetData match gTargetData? | |
233 Passes.add(new TargetData(*Target.getTargetData())); | |
234 | |
235 // Ask the target to add backend passes as necessary. | |
236 MachineCodeEmitter *MCE = 0; | |
237 | |
238 //TODO: May want to switch it on for -O0? | |
239 bool Fast = false; | |
240 FileModel::Model mod = Target.addPassesToEmitFile(Passes, Out, TargetMachine::AssemblyFile, Fast); | |
241 assert(mod == FileModel::AsmFile); | |
242 | |
243 bool err = Target.addPassesToEmitFileFinish(Passes, MCE, Fast); | |
244 assert(!err); | |
245 | |
246 Passes.doInitialization(); | |
247 | |
248 // Run our queue of passes all at once now, efficiently. | |
249 for (llvm::Module::iterator I = ir.module->begin(), E = ir.module->end(); I != E; ++I) | |
250 if (!I->isDeclaration()) | |
251 Passes.run(*I); | |
252 | |
253 Passes.doFinalization(); | |
254 | |
255 // release module from module provider so we can delete it ourselves | |
256 llvm::Module* rmod = Provider.releaseModule(&Err); | |
257 assert(rmod); | |
258 } | 209 } |
259 | 210 |
260 delete ir.module; | 211 delete ir.module; |
261 gTargetData = 0; | 212 gTargetData = 0; |
262 gIR = NULL; | 213 gIR = NULL; |
263 | 214 |
264 if (llvmForceLogging && !logenabled) | 215 if (llvmForceLogging && !logenabled) |
265 { | 216 { |
266 Logger::disable(); | 217 Logger::disable(); |
267 } | 218 } |
219 } | |
220 | |
221 /* ================================================================== */ | |
222 | |
223 void write_asm_to_file(llvm::Module& m, llvm::raw_fd_ostream& out) | |
224 { | |
225 using namespace llvm; | |
226 | |
227 std::string Err; | |
228 | |
229 const TargetMachineRegistry::entry* MArch; | |
230 MArch = TargetMachineRegistry::getClosestStaticTargetForModule(m, Err); | |
231 if (MArch == 0) { | |
232 error("error auto-selecting target for module '%s'", Err.c_str()); | |
233 fatal(); | |
234 } | |
235 | |
236 SubtargetFeatures Features; | |
237 //TODO: Features? | |
238 // Features.setCPU(MCPU); | |
239 // for (unsigned i = 0; i != MAttrs.size(); ++i) | |
240 // Features.AddFeature(MAttrs[i]); | |
241 | |
242 //FIXME: Only set this if required? | |
243 TargetMachine::setRelocationModel(Reloc::PIC_); | |
244 | |
245 std::auto_ptr<TargetMachine> target(MArch->CtorFn(m, Features.getString())); | |
246 assert(target.get() && "Could not allocate target machine!"); | |
247 TargetMachine &Target = *target.get(); | |
248 | |
249 // Build up all of the passes that we want to do to the module. | |
250 ExistingModuleProvider Provider(&m); | |
251 FunctionPassManager Passes(&Provider); | |
252 //FIXME: Will gTargetData always be Target.getTargetData anyway? | |
253 assert(gTargetData->getStringRepresentation() == Target.getTargetData()->getStringRepresentation()); | |
254 Passes.add(new TargetData(*Target.getTargetData())); | |
255 | |
256 // Ask the target to add backend passes as necessary. | |
257 MachineCodeEmitter *MCE = 0; | |
258 | |
259 //TODO: May want to switch it on for -O0? | |
260 bool Fast = false; | |
261 FileModel::Model mod = Target.addPassesToEmitFile(Passes, out, TargetMachine::AssemblyFile, Fast); | |
262 assert(mod == FileModel::AsmFile); | |
263 | |
264 bool err = Target.addPassesToEmitFileFinish(Passes, MCE, Fast); | |
265 assert(!err); | |
266 | |
267 Passes.doInitialization(); | |
268 | |
269 // Run our queue of passes all at once now, efficiently. | |
270 for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) | |
271 if (!I->isDeclaration()) | |
272 Passes.run(*I); | |
273 | |
274 Passes.doFinalization(); | |
275 | |
276 // release module from module provider so we can delete it ourselves | |
277 llvm::Module* rmod = Provider.releaseModule(&Err); | |
278 assert(rmod); | |
268 } | 279 } |
269 | 280 |
270 /* ================================================================== */ | 281 /* ================================================================== */ |
271 | 282 |
272 // build module ctor | 283 // build module ctor |