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