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