97827643e8573ef0446726e40656a5a49da1bcda
[oota-llvm.git] / tools / lto / LTOCodeGenerator.cpp
1 //===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Link Time Optimization library. This library is 
11 // intended to be used by linker to optimize code at link time.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "LTOModule.h"
16 #include "LTOCodeGenerator.h"
17
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Linker.h"
21 #include "llvm/LLVMContext.h"
22 #include "llvm/Module.h"
23 #include "llvm/PassManager.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/ADT/Triple.h"
26 #include "llvm/Analysis/Passes.h"
27 #include "llvm/Bitcode/ReaderWriter.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/Target/Mangler.h"
31 #include "llvm/Target/SubtargetFeature.h"
32 #include "llvm/Target/TargetOptions.h"
33 #include "llvm/Target/TargetData.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetRegistry.h"
36 #include "llvm/Target/TargetSelect.h"
37 #include "llvm/Support/CommandLine.h"
38 #include "llvm/Support/FormattedStream.h"
39 #include "llvm/Support/MemoryBuffer.h"
40 #include "llvm/Support/StandardPasses.h"
41 #include "llvm/Support/SystemUtils.h"
42 #include "llvm/Support/ToolOutputFile.h"
43 #include "llvm/System/Host.h"
44 #include "llvm/System/Program.h"
45 #include "llvm/System/Signals.h"
46 #include "llvm/Config/config.h"
47 #include <cstdlib>
48 #include <unistd.h>
49 #include <fcntl.h>
50
51
52 using namespace llvm;
53
54 static cl::opt<bool> DisableInline("disable-inlining",
55   cl::desc("Do not run the inliner pass"));
56
57
58 const char* LTOCodeGenerator::getVersionString()
59 {
60 #ifdef LLVM_VERSION_INFO
61     return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
62 #else
63     return PACKAGE_NAME " version " PACKAGE_VERSION;
64 #endif
65 }
66
67
68 LTOCodeGenerator::LTOCodeGenerator() 
69     : _context(getGlobalContext()),
70       _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
71       _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
72       _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC),
73       _nativeObjectFile(NULL), _assemblerPath(NULL)
74 {
75     InitializeAllTargets();
76     InitializeAllAsmPrinters();
77 }
78
79 LTOCodeGenerator::~LTOCodeGenerator()
80 {
81     delete _target;
82     delete _nativeObjectFile;
83 }
84
85
86
87 bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
88 {
89     return _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
90 }
91     
92
93 bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg)
94 {
95     switch (debug) {
96         case LTO_DEBUG_MODEL_NONE:
97             _emitDwarfDebugInfo = false;
98             return false;
99             
100         case LTO_DEBUG_MODEL_DWARF:
101             _emitDwarfDebugInfo = true;
102             return false;
103     }
104     errMsg = "unknown debug format";
105     return true;
106 }
107
108
109 bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model, 
110                                        std::string& errMsg)
111 {
112     switch (model) {
113         case LTO_CODEGEN_PIC_MODEL_STATIC:
114         case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
115         case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
116             _codeModel = model;
117             return false;
118     }
119     errMsg = "unknown pic model";
120     return true;
121 }
122
123 void LTOCodeGenerator::setCpu(const char* mCpu)
124 {
125   _mCpu = mCpu;
126 }
127
128 void LTOCodeGenerator::setAssemblerPath(const char* path)
129 {
130     if ( _assemblerPath )
131         delete _assemblerPath;
132     _assemblerPath = new sys::Path(path);
133 }
134
135 void LTOCodeGenerator::setAssemblerArgs(const char** args, int nargs)
136 {
137   for (int i = 0; i < nargs; ++i) {
138     const char *arg = args[i];
139     _assemblerArgs.push_back(arg);
140   }
141 }
142
143 void LTOCodeGenerator::addMustPreserveSymbol(const char* sym)
144 {
145     _mustPreserveSymbols[sym] = 1;
146 }
147
148
149 bool LTOCodeGenerator::writeMergedModules(const char *path,
150                                           std::string &errMsg) {
151   if (determineTarget(errMsg))
152     return true;
153
154   // mark which symbols can not be internalized 
155   applyScopeRestrictions();
156
157   // create output file
158   std::string ErrInfo;
159   tool_output_file Out(path, ErrInfo,
160                        raw_fd_ostream::F_Binary);
161   if (!ErrInfo.empty()) {
162     errMsg = "could not open bitcode file for writing: ";
163     errMsg += path;
164     return true;
165   }
166     
167   // write bitcode to it
168   WriteBitcodeToFile(_linker.getModule(), Out.os());
169   Out.os().close();
170
171   if (Out.os().has_error()) {
172     errMsg = "could not write bitcode file: ";
173     errMsg += path;
174     Out.os().clear_error();
175     return true;
176   }
177   
178   Out.keep();
179   return false;
180 }
181
182
183 const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
184 {
185     // make unique temp .s file to put generated assembly code
186     sys::Path uniqueAsmPath("lto-llvm.s");
187     if ( uniqueAsmPath.createTemporaryFileOnDisk(true, &errMsg) )
188         return NULL;
189     sys::RemoveFileOnSignal(uniqueAsmPath);
190        
191     // generate assembly code
192     bool genResult = false;
193     {
194       tool_output_file asmFile(uniqueAsmPath.c_str(), errMsg);
195       if (!errMsg.empty())
196         return NULL;
197       genResult = this->generateAssemblyCode(asmFile.os(), errMsg);
198       asmFile.os().close();
199       if (asmFile.os().has_error()) {
200         asmFile.os().clear_error();
201         return NULL;
202       }
203       asmFile.keep();
204     }
205     if ( genResult ) {
206         uniqueAsmPath.eraseFromDisk();
207         return NULL;
208     }
209     
210     // make unique temp .o file to put generated object file
211     sys::PathWithStatus uniqueObjPath("lto-llvm.o");
212     if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) {
213         uniqueAsmPath.eraseFromDisk();
214         return NULL;
215     }
216     sys::RemoveFileOnSignal(uniqueObjPath);
217
218     // assemble the assembly code
219     const std::string& uniqueObjStr = uniqueObjPath.str();
220     bool asmResult = this->assemble(uniqueAsmPath.str(), uniqueObjStr, errMsg);
221     if ( !asmResult ) {
222         // remove old buffer if compile() called twice
223         delete _nativeObjectFile;
224         
225         // read .o file into memory buffer
226         _nativeObjectFile = MemoryBuffer::getFile(uniqueObjStr.c_str(),&errMsg);
227     }
228
229     // remove temp files
230     uniqueAsmPath.eraseFromDisk();
231     uniqueObjPath.eraseFromDisk();
232
233     // return buffer, unless error
234     if ( _nativeObjectFile == NULL )
235         return NULL;
236     *length = _nativeObjectFile->getBufferSize();
237     return _nativeObjectFile->getBufferStart();
238 }
239
240
241 bool LTOCodeGenerator::assemble(const std::string& asmPath, 
242                                 const std::string& objPath, std::string& errMsg)
243 {
244     sys::Path tool;
245     bool needsCompilerOptions = true;
246     if ( _assemblerPath ) {
247         tool = *_assemblerPath;
248         needsCompilerOptions = false;
249     } else {
250         // find compiler driver
251         tool = sys::Program::FindProgramByName("gcc");
252         if ( tool.isEmpty() ) {
253             errMsg = "can't locate gcc";
254             return true;
255         }
256     }
257
258     // build argument list
259     std::vector<const char*> args;
260     llvm::Triple targetTriple(_linker.getModule()->getTargetTriple());
261     const char *arch = targetTriple.getArchNameForAssembler();
262
263     args.push_back(tool.c_str());
264
265     if (targetTriple.getOS() == Triple::Darwin) {
266         // darwin specific command line options
267         if (arch != NULL) {
268             args.push_back("-arch");
269             args.push_back(arch);
270         }
271         // add -static to assembler command line when code model requires
272         if ( (_assemblerPath != NULL) &&
273             (_codeModel == LTO_CODEGEN_PIC_MODEL_STATIC) )
274             args.push_back("-static");
275     }
276     if ( needsCompilerOptions ) {
277         args.push_back("-c");
278         args.push_back("-x");
279         args.push_back("assembler");
280     } else {
281         for (std::vector<std::string>::iterator I = _assemblerArgs.begin(),
282                E = _assemblerArgs.end(); I != E; ++I) {
283             args.push_back(I->c_str());
284         }
285     }
286     args.push_back("-o");
287     args.push_back(objPath.c_str());
288     args.push_back(asmPath.c_str());
289     args.push_back(0);
290
291     // invoke assembler
292     if ( sys::Program::ExecuteAndWait(tool, &args[0], 0, 0, 0, 0, &errMsg) ) {
293         errMsg = "error in assembly";    
294         return true;
295     }
296     return false; // success
297 }
298
299
300
301 bool LTOCodeGenerator::determineTarget(std::string& errMsg)
302 {
303     if ( _target == NULL ) {
304         std::string Triple = _linker.getModule()->getTargetTriple();
305         if (Triple.empty())
306           Triple = sys::getHostTriple();
307
308         // create target machine from info for merged modules
309         const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
310         if ( march == NULL )
311             return true;
312
313         // The relocation model is actually a static member of TargetMachine
314         // and needs to be set before the TargetMachine is instantiated.
315         switch( _codeModel ) {
316         case LTO_CODEGEN_PIC_MODEL_STATIC:
317             TargetMachine::setRelocationModel(Reloc::Static);
318             break;
319         case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
320             TargetMachine::setRelocationModel(Reloc::PIC_);
321             break;
322         case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
323             TargetMachine::setRelocationModel(Reloc::DynamicNoPIC);
324             break;
325         }
326
327         // construct LTModule, hand over ownership of module and target
328         SubtargetFeatures Features;
329         Features.getDefaultSubtargetFeatures(_mCpu, llvm::Triple(Triple));
330         std::string FeatureStr = Features.getString();
331         _target = march->createTargetMachine(Triple, FeatureStr);
332     }
333     return false;
334 }
335
336 void LTOCodeGenerator::applyScopeRestrictions() {
337   if (_scopeRestrictionsDone) return;
338   Module *mergedModule = _linker.getModule();
339
340   // Start off with a verification pass.
341   PassManager passes;
342   passes.add(createVerifierPass());
343
344   // mark which symbols can not be internalized 
345   if (!_mustPreserveSymbols.empty()) {
346     MCContext Context(*_target->getMCAsmInfo());
347     Mangler mangler(Context, *_target->getTargetData());
348     std::vector<const char*> mustPreserveList;
349     for (Module::iterator f = mergedModule->begin(),
350          e = mergedModule->end(); f != e; ++f) {
351       if (!f->isDeclaration() &&
352           _mustPreserveSymbols.count(mangler.getNameWithPrefix(f)))
353         mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
354     }
355     for (Module::global_iterator v = mergedModule->global_begin(), 
356          e = mergedModule->global_end(); v !=  e; ++v) {
357       if (!v->isDeclaration() &&
358           _mustPreserveSymbols.count(mangler.getNameWithPrefix(v)))
359         mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
360     }
361     passes.add(createInternalizePass(mustPreserveList));
362   }
363   
364   // apply scope restrictions
365   passes.run(*mergedModule);
366   
367   _scopeRestrictionsDone = true;
368 }
369
370 /// Optimize merged modules using various IPO passes
371 bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out,
372                                             std::string& errMsg)
373 {
374     if ( this->determineTarget(errMsg) ) 
375         return true;
376
377     // mark which symbols can not be internalized 
378     this->applyScopeRestrictions();
379
380     Module* mergedModule = _linker.getModule();
381
382     // if options were requested, set them
383     if ( !_codegenOptions.empty() )
384         cl::ParseCommandLineOptions(_codegenOptions.size(), 
385                                     const_cast<char **>(&_codegenOptions[0]));
386
387     // Instantiate the pass manager to organize the passes.
388     PassManager passes;
389
390     // Start off with a verification pass.
391     passes.add(createVerifierPass());
392
393     // Add an appropriate TargetData instance for this module...
394     passes.add(new TargetData(*_target->getTargetData()));
395     
396     createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline,
397                             /*VerifyEach=*/ false);
398
399     // Make sure everything is still good.
400     passes.add(createVerifierPass());
401
402     FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule);
403
404     codeGenPasses->add(new TargetData(*_target->getTargetData()));
405
406     formatted_raw_ostream Out(out);
407
408     if (_target->addPassesToEmitFile(*codeGenPasses, Out,
409                                      TargetMachine::CGFT_AssemblyFile,
410                                      CodeGenOpt::Aggressive)) {
411       errMsg = "target file type not supported";
412       return true;
413     }
414
415     // Run our queue of passes all at once now, efficiently.
416     passes.run(*mergedModule);
417
418     // Run the code generator, and write assembly file
419     codeGenPasses->doInitialization();
420
421     for (Module::iterator
422            it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
423       if (!it->isDeclaration())
424         codeGenPasses->run(*it);
425
426     codeGenPasses->doFinalization();
427
428     return false; // success
429 }
430
431
432 /// Optimize merged modules using various IPO passes
433 void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
434 {
435     for (std::pair<StringRef, StringRef> o = getToken(options);
436          !o.first.empty(); o = getToken(o.second)) {
437         // ParseCommandLineOptions() expects argv[0] to be program name.
438         // Lazily add that.
439         if ( _codegenOptions.empty() ) 
440             _codegenOptions.push_back("libLTO");
441         _codegenOptions.push_back(strdup(o.first.str().c_str()));
442     }
443 }