~ubuntu-branches/ubuntu/quantal/llvm-3.1/quantal

« back to all changes in this revision

Viewing changes to tools/lto/LTOCodeGenerator.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2012-04-01 23:45:03 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120401234503-c04qxrk7s9my53uy
Tags: 3.1~svn153852-1
New snapshot release

Show diffs side-by-side

added added

removed removed

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