comparison gen/toobj.cpp @ 699:ed9a9e6dd1cc

Started changing target triple stuff, part of fixing #97
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Mon, 13 Oct 2008 17:28:39 +0200
parents 931333ea35c6
children 1556a9328ba1
comparison
equal deleted inserted replaced
698:f0ba5d37dd86 699:ed9a9e6dd1cc
57 57
58 // in gen/optimize.cpp 58 // in gen/optimize.cpp
59 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline); 59 void ldc_optimize_module(llvm::Module* m, char lvl, bool doinline);
60 60
61 // fwd decl 61 // fwd decl
62 void write_asm_to_file(llvm::Module& m, llvm::raw_fd_ostream& Out); 62 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out);
63 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, char** envp); 63 void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, char** envp);
64 64
65 ////////////////////////////////////////////////////////////////////////////////////////// 65 //////////////////////////////////////////////////////////////////////////////////////////
66 66
67 void Module::genobjfile(int multiobj, char** envp) 67 void Module::genobjfile(int multiobj, char** envp)
100 // might already exist via import, just overwrite... 100 // might already exist via import, just overwrite...
101 //FIXME: is there a good reason for overwriting? 101 //FIXME: is there a good reason for overwriting?
102 this->ir.irModule = new IrModule(this, srcfile->toChars()); 102 this->ir.irModule = new IrModule(this, srcfile->toChars());
103 103
104 // set target stuff 104 // set target stuff
105 std::string target_triple(global.params.tt_arch); 105
106 target_triple.append(global.params.tt_os); 106 ir.module->setTargetTriple(global.params.targetTriple);
107 ir.module->setTargetTriple(target_triple); 107
108 ir.module->setDataLayout(global.params.data_layout); 108 // get the target machine
109 109 const llvm::TargetMachineRegistry::entry* MArch;
110 gTargetData = new llvm::TargetData(global.params.data_layout); 110
111 std::string Err;
112 MArch = llvm::TargetMachineRegistry::getClosestStaticTargetForModule(*ir.module, Err);
113 if (MArch == 0) {
114 error("error auto-selecting target for module '%s'", Err.c_str());
115 fatal();
116 }
117
118 llvm::SubtargetFeatures Features;
119 //TODO: Features?
120 // Features.setCPU(MCPU);
121 // for (unsigned i = 0; i != MAttrs.size(); ++i)
122 // Features.AddFeature(MAttrs[i]);
123
124 // only generate PIC code when -fPIC switch is used
125 if (global.params.pic)
126 llvm::TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
127
128 // allocate the target machine
129 std::auto_ptr<llvm::TargetMachine> target(MArch->CtorFn(*ir.module, Features.getString()));
130 assert(target.get() && "Could not allocate target machine!");
131 llvm::TargetMachine &Target = *target.get();
132
133 gTargetData = Target.getTargetData();
134 ir.module->setDataLayout(gTargetData->getStringRepresentation());
111 135
112 // debug info 136 // debug info
113 if (global.params.symdebug) { 137 if (global.params.symdebug) {
114 RegisterDwarfSymbols(ir.module); 138 RegisterDwarfSymbols(ir.module);
115 DtoDwarfCompileUnit(this); 139 DtoDwarfCompileUnit(this);
220 } 244 }
221 Logger::println("Writing native asm to: %s\n", spath.c_str()); 245 Logger::println("Writing native asm to: %s\n", spath.c_str());
222 std::string err; 246 std::string err;
223 { 247 {
224 llvm::raw_fd_ostream out(spath.c_str(), err); 248 llvm::raw_fd_ostream out(spath.c_str(), err);
225 write_asm_to_file(*ir.module, out); 249 write_asm_to_file(Target, *ir.module, out);
226 } 250 }
227 251
228 // call gcc to convert assembly to object file 252 // call gcc to convert assembly to object file
229 if (global.params.output_o) { 253 if (global.params.output_o) {
230 LLPath objpath = LLPath(objfile->name->toChars()); 254 LLPath objpath = LLPath(objfile->name->toChars());
249 } 273 }
250 274
251 /* ================================================================== */ 275 /* ================================================================== */
252 276
253 // based on llc code, University of Illinois Open Source License 277 // based on llc code, University of Illinois Open Source License
254 void write_asm_to_file(llvm::Module& m, llvm::raw_fd_ostream& out) 278 void write_asm_to_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out)
255 { 279 {
256 using namespace llvm; 280 using namespace llvm;
257
258 std::string Err;
259
260 const TargetMachineRegistry::entry* MArch;
261 MArch = TargetMachineRegistry::getClosestStaticTargetForModule(m, Err);
262 if (MArch == 0) {
263 error("error auto-selecting target for module '%s'", Err.c_str());
264 fatal();
265 }
266
267 SubtargetFeatures Features;
268 //TODO: Features?
269 // Features.setCPU(MCPU);
270 // for (unsigned i = 0; i != MAttrs.size(); ++i)
271 // Features.AddFeature(MAttrs[i]);
272
273 //FIXME: Only set this if required?
274 TargetMachine::setRelocationModel(Reloc::PIC_);
275
276 std::auto_ptr<TargetMachine> target(MArch->CtorFn(m, Features.getString()));
277 assert(target.get() && "Could not allocate target machine!");
278 TargetMachine &Target = *target.get();
279 281
280 // Build up all of the passes that we want to do to the module. 282 // Build up all of the passes that we want to do to the module.
281 ExistingModuleProvider Provider(&m); 283 ExistingModuleProvider Provider(&m);
282 FunctionPassManager Passes(&Provider); 284 FunctionPassManager Passes(&Provider);
283 //FIXME: Will gTargetData always be Target.getTargetData anyway? 285
284 assert(gTargetData->getStringRepresentation() == Target.getTargetData()->getStringRepresentation());
285 Passes.add(new TargetData(*Target.getTargetData())); 286 Passes.add(new TargetData(*Target.getTargetData()));
286 287
287 // Ask the target to add backend passes as necessary. 288 // Ask the target to add backend passes as necessary.
288 MachineCodeEmitter *MCE = 0; 289 MachineCodeEmitter *MCE = 0;
289 290
303 Passes.run(*I); 304 Passes.run(*I);
304 305
305 Passes.doFinalization(); 306 Passes.doFinalization();
306 307
307 // release module from module provider so we can delete it ourselves 308 // release module from module provider so we can delete it ourselves
309 std::string Err;
308 llvm::Module* rmod = Provider.releaseModule(&Err); 310 llvm::Module* rmod = Provider.releaseModule(&Err);
309 assert(rmod); 311 assert(rmod);
310 } 312 }
311 313
312 /* ================================================================== */ 314 /* ================================================================== */