comparison gen/toobj.cpp @ 673:37a7688a7494

Add basics for direct assembly output.
author Christian Kamm <kamm incasoftware de>
date Sat, 11 Oct 2008 11:07:53 +0200
parents 6aaa3d3c1183
children db6a7e574cbd
comparison
equal deleted inserted replaced
672:22b6947fd30c 673:37a7688a7494
12 #include <fstream> 12 #include <fstream>
13 13
14 #include "gen/llvm.h" 14 #include "gen/llvm.h"
15 #include "llvm/Analysis/Verifier.h" 15 #include "llvm/Analysis/Verifier.h"
16 #include "llvm/Bitcode/ReaderWriter.h" 16 #include "llvm/Bitcode/ReaderWriter.h"
17 #include "llvm/Target/SubtargetFeature.h"
17 #include "llvm/Target/TargetMachine.h" 18 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/TargetMachineRegistry.h" 19 #include "llvm/Target/TargetMachineRegistry.h"
20 #include "llvm/Module.h"
21 #include "llvm/ModuleProvider.h"
22 #include "llvm/PassManager.h"
19 #include "llvm/System/Path.h" 23 #include "llvm/System/Path.h"
24 #include "llvm/Support/raw_ostream.h"
20 25
21 #include "mars.h" 26 #include "mars.h"
22 #include "module.h" 27 #include "module.h"
23 #include "mtype.h" 28 #include "mtype.h"
24 #include "declaration.h" 29 #include "declaration.h"
188 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str()); 193 Logger::println("Writing LLVM asm to: %s\n", llpath.c_str());
189 std::ofstream aos(llpath.c_str()); 194 std::ofstream aos(llpath.c_str());
190 ir.module->print(aos, NULL); 195 ir.module->print(aos, NULL);
191 } 196 }
192 197
198
199 //TODO: Move all of this into a helper function?
200 if(false)
201 {
202 using namespace llvm;
203
204 //FIXME: Proper out file name.
205 std::string Err;
206 raw_fd_ostream Out("test.s", Err);
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 }
259
193 delete ir.module; 260 delete ir.module;
194 gTargetData = 0; 261 gTargetData = 0;
195 gIR = NULL; 262 gIR = NULL;
196 263
197 if (llvmForceLogging && !logenabled) 264 if (llvmForceLogging && !logenabled)