5
5
// This file is distributed under the University of Illinois Open Source
6
6
// License. See LICENSE.TXT for details.
8
8
//===----------------------------------------------------------------------===//
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.
13
13
//===----------------------------------------------------------------------===//
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"
46
#include "llvm/ADT/StringExtras.h"
56
47
using namespace llvm;
58
49
static cl::opt<bool> DisableInline("disable-inlining",
59
50
cl::desc("Do not run the inliner pass"));
62
const char* LTOCodeGenerator::getVersionString()
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;
67
return PACKAGE_NAME " version " PACKAGE_VERSION;
56
return PACKAGE_NAME " version " PACKAGE_VERSION;
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)
79
InitializeAllTargets();
80
InitializeAllTargetMCs();
81
InitializeAllAsmPrinters();
84
LTOCodeGenerator::~LTOCodeGenerator()
87
delete _nativeObjectFile;
92
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
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();
71
LTOCodeGenerator::~LTOCodeGenerator() {
73
delete _nativeObjectFile;
75
for (std::vector<char*>::iterator I = _codegenOptions.begin(),
76
E = _codegenOptions.end(); I != E; ++I)
80
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
94
81
bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
96
83
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
104
bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg)
107
case LTO_DEBUG_MODEL_NONE:
108
_emitDwarfDebugInfo = false;
111
case LTO_DEBUG_MODEL_DWARF:
112
_emitDwarfDebugInfo = true;
115
llvm_unreachable("Unknown debug format!");
119
bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
123
case LTO_CODEGEN_PIC_MODEL_STATIC:
124
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
125
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
129
llvm_unreachable("Unknown PIC model!");
132
void LTOCodeGenerator::setCpu(const char* mCpu)
137
void LTOCodeGenerator::addMustPreserveSymbol(const char* sym)
139
_mustPreserveSymbols[sym] = 1;
90
bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug,
91
std::string& errMsg) {
93
case LTO_DEBUG_MODEL_NONE:
94
_emitDwarfDebugInfo = false;
97
case LTO_DEBUG_MODEL_DWARF:
98
_emitDwarfDebugInfo = true;
101
llvm_unreachable("Unknown debug format!");
104
bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
105
std::string& errMsg) {
107
case LTO_CODEGEN_PIC_MODEL_STATIC:
108
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
109
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
113
llvm_unreachable("Unknown PIC model!");
143
116
bool LTOCodeGenerator::writeMergedModules(const char *path,
144
117
std::string &errMsg) {
145
118
if (determineTarget(errMsg))
148
// mark which symbols can not be internalized
121
// mark which symbols can not be internalized
149
122
applyScopeRestrictions();
151
124
// create output file
233
205
return _nativeObjectFile->getBufferStart();
236
bool LTOCodeGenerator::determineTarget(std::string& errMsg)
238
if ( _target == NULL ) {
239
std::string Triple = _linker.getModule()->getTargetTriple();
241
Triple = sys::getDefaultTargetTriple();
243
// create target machine from info for merged modules
244
const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
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;
255
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
256
RelocModel = Reloc::PIC_;
258
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
259
RelocModel = Reloc::DynamicNoPIC;
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,
208
bool LTOCodeGenerator::determineTarget(std::string& errMsg) {
209
if ( _target == NULL ) {
210
std::string Triple = _linker.getModule()->getTargetTriple();
212
Triple = sys::getDefaultTargetTriple();
214
// create target machine from info for merged modules
215
const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
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;
226
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
227
RelocModel = Reloc::PIC_;
229
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
230
RelocModel = Reloc::DynamicNoPIC;
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,
274
void LTOCodeGenerator::applyRestriction(GlobalValue &GV,
275
std::vector<const char*> &mustPreserveList,
276
SmallPtrSet<GlobalValue*, 8> &asmUsed,
245
void LTOCodeGenerator::
246
applyRestriction(GlobalValue &GV,
247
std::vector<const char*> &mustPreserveList,
248
SmallPtrSet<GlobalValue*, 8> &asmUsed,
278
250
SmallString<64> Buffer;
279
251
mangler.getNameWithPrefix(Buffer, &GV, false);
352
324
// apply scope restrictions
353
325
passes.run(*mergedModule);
355
327
_scopeRestrictionsDone = true;
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) )
364
// mark which symbols can not be internalized
365
this->applyScopeRestrictions();
367
Module* mergedModule = _linker.getModule();
369
// if options were requested, set them
370
if ( !_codegenOptions.empty() )
371
cl::ParseCommandLineOptions(_codegenOptions.size(),
372
const_cast<char **>(&_codegenOptions[0]));
374
// Instantiate the pass manager to organize the passes.
377
// Start off with a verification pass.
378
passes.add(createVerifierPass());
380
// Add an appropriate TargetData instance for this module...
381
passes.add(new TargetData(*_target->getTargetData()));
383
PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
386
// Make sure everything is still good.
387
passes.add(createVerifierPass());
389
FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
391
codeGenPasses->add(new TargetData(*_target->getTargetData()));
393
formatted_raw_ostream Out(out);
395
if (_target->addPassesToEmitFile(*codeGenPasses, Out,
396
TargetMachine::CGFT_ObjectFile,
397
CodeGenOpt::Aggressive)) {
398
errMsg = "target file type not supported";
402
// Run our queue of passes all at once now, efficiently.
403
passes.run(*mergedModule);
405
// Run the code generator, and write assembly file
406
codeGenPasses->doInitialization();
408
for (Module::iterator
409
it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
410
if (!it->isDeclaration())
411
codeGenPasses->run(*it);
413
codeGenPasses->doFinalization();
414
delete codeGenPasses;
416
return false; // success
333
if ( this->determineTarget(errMsg) )
336
// mark which symbols can not be internalized
337
this->applyScopeRestrictions();
339
Module* mergedModule = _linker.getModule();
341
// if options were requested, set them
342
if ( !_codegenOptions.empty() )
343
cl::ParseCommandLineOptions(_codegenOptions.size(),
344
const_cast<char **>(&_codegenOptions[0]));
346
// Instantiate the pass manager to organize the passes.
349
// Start off with a verification pass.
350
passes.add(createVerifierPass());
352
// Add an appropriate TargetData instance for this module...
353
passes.add(new TargetData(*_target->getTargetData()));
355
PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
358
// Make sure everything is still good.
359
passes.add(createVerifierPass());
361
FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
363
codeGenPasses->add(new TargetData(*_target->getTargetData()));
365
formatted_raw_ostream Out(out);
367
if (_target->addPassesToEmitFile(*codeGenPasses, Out,
368
TargetMachine::CGFT_ObjectFile,
369
CodeGenOpt::Aggressive)) {
370
errMsg = "target file type not supported";
374
// Run our queue of passes all at once now, efficiently.
375
passes.run(*mergedModule);
377
// Run the code generator, and write assembly file
378
codeGenPasses->doInitialization();
380
for (Module::iterator
381
it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it)
382
if (!it->isDeclaration())
383
codeGenPasses->run(*it);
385
codeGenPasses->doFinalization();
386
delete codeGenPasses;
388
return false; // success
420
/// Optimize merged modules using various IPO passes
421
void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
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.
427
if ( _codegenOptions.empty() )
428
_codegenOptions.push_back("libLTO");
429
_codegenOptions.push_back(strdup(o.first.str().c_str()));
391
/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
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
398
if ( _codegenOptions.empty() )
399
_codegenOptions.push_back(strdup("libLTO"));
400
_codegenOptions.push_back(strdup(o.first.str().c_str()));