//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
-// This file implements the Link Time Optimization library. This library is
+// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//
-#include "LTOModule.h"
#include "LTOCodeGenerator.h"
+#include "LTOModule.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/PassManagerBuilder.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
#include "llvm/Config/config.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
-
-
using namespace llvm;
static cl::opt<bool> DisableInline("disable-inlining",
cl::desc("Do not run the inliner pass"));
-
-const char* LTOCodeGenerator::getVersionString()
-{
+const char* LTOCodeGenerator::getVersionString() {
#ifdef LLVM_VERSION_INFO
- return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
+ return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
#else
- return PACKAGE_NAME " version " PACKAGE_VERSION;
+ return PACKAGE_NAME " version " PACKAGE_VERSION;
#endif
}
-
-LTOCodeGenerator::LTOCodeGenerator()
+LTOCodeGenerator::LTOCodeGenerator()
: _context(getGlobalContext()),
_linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL),
_emitDwarfDebugInfo(false), _scopeRestrictionsDone(false),
_nativeObjectFile(NULL)
{
InitializeAllTargets();
+ InitializeAllTargetMCs();
InitializeAllAsmPrinters();
}
-LTOCodeGenerator::~LTOCodeGenerator()
-{
- delete _target;
- delete _nativeObjectFile;
-}
-
+LTOCodeGenerator::~LTOCodeGenerator() {
+ delete _target;
+ delete _nativeObjectFile;
+ for (std::vector<char*>::iterator I = _codegenOptions.begin(),
+ E = _codegenOptions.end(); I != E; ++I)
+ free(*I);
+}
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg)
{
-
- if(mod->getLLVVMModule()->MaterializeAllPermanently(&errMsg))
- return true;
-
bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg);
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
return ret;
}
-
+
bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, std::string& errMsg)
{
case LTO_DEBUG_MODEL_NONE:
_emitDwarfDebugInfo = false;
return false;
-
+
case LTO_DEBUG_MODEL_DWARF:
_emitDwarfDebugInfo = true;
return false;
}
- errMsg = "unknown debug format";
- return true;
+ llvm_unreachable("Unknown debug format!");
}
-bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
+bool LTOCodeGenerator::setCodePICModel(lto_codegen_model model,
std::string& errMsg)
{
switch (model) {
_codeModel = model;
return false;
}
- errMsg = "unknown pic model";
- return true;
+ llvm_unreachable("Unknown PIC model!");
}
void LTOCodeGenerator::setCpu(const char* mCpu)
if (determineTarget(errMsg))
return true;
- // mark which symbols can not be internalized
+ // mark which symbols can not be internalized
applyScopeRestrictions();
// create output file
errMsg += path;
return true;
}
-
+
// write bitcode to it
WriteBitcodeToFile(_linker.getModule(), Out.os());
Out.os().close();
Out.os().clear_error();
return true;
}
-
+
Out.keep();
return false;
}
bool genResult = false;
tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
if (!errMsg.empty())
- return NULL;
+ return true;
genResult = this->generateObjectFile(objFile.os(), errMsg);
objFile.os().close();
if (objFile.os().has_error()) {
if ( _target == NULL ) {
std::string Triple = _linker.getModule()->getTargetTriple();
if (Triple.empty())
- Triple = sys::getHostTriple();
+ Triple = sys::getDefaultTargetTriple();
// create target machine from info for merged modules
const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
// The relocation model is actually a static member of TargetMachine
// and needs to be set before the TargetMachine is instantiated.
+ Reloc::Model RelocModel = Reloc::Default;
switch( _codeModel ) {
case LTO_CODEGEN_PIC_MODEL_STATIC:
- TargetMachine::setRelocationModel(Reloc::Static);
+ RelocModel = Reloc::Static;
break;
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
- TargetMachine::setRelocationModel(Reloc::PIC_);
+ RelocModel = Reloc::PIC_;
break;
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
- TargetMachine::setRelocationModel(Reloc::DynamicNoPIC);
+ RelocModel = Reloc::DynamicNoPIC;
break;
}
- // construct LTModule, hand over ownership of module and target
+ // construct LTOModule, hand over ownership of module and target
SubtargetFeatures Features;
- Features.getDefaultSubtargetFeatures(_mCpu, llvm::Triple(Triple));
+ Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
std::string FeatureStr = Features.getString();
- _target = march->createTargetMachine(Triple, FeatureStr);
+ TargetOptions Options;
+ _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options,
+ RelocModel);
}
return false;
}
if (Inits == 0) return;
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
- if (GlobalValue *GV =
+ if (GlobalValue *GV =
dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
UsedValues.insert(GV);
}
PassManager passes;
passes.add(createVerifierPass());
- // mark which symbols can not be internalized
- MCContext Context(*_target->getMCAsmInfo(), NULL);
+ // mark which symbols can not be internalized
+ MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL);
Mangler mangler(Context, *_target->getTargetData());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
for (Module::iterator f = mergedModule->begin(),
e = mergedModule->end(); f != e; ++f)
applyRestriction(*f, mustPreserveList, asmUsed, mangler);
- for (Module::global_iterator v = mergedModule->global_begin(),
+ for (Module::global_iterator v = mergedModule->global_begin(),
e = mergedModule->global_end(); v != e; ++v)
applyRestriction(*v, mustPreserveList, asmUsed, mangler);
for (Module::alias_iterator a = mergedModule->alias_begin(),
if (LLVMCompilerUsed)
LLVMCompilerUsed->eraseFromParent();
- const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
+ llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
std::vector<Constant*> asmUsed2;
for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(),
e = asmUsed.end(); i !=e; ++i) {
// apply scope restrictions
passes.run(*mergedModule);
-
+
_scopeRestrictionsDone = true;
}
/// Optimize merged modules using various IPO passes
bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
std::string &errMsg) {
- if ( this->determineTarget(errMsg) )
+ if ( this->determineTarget(errMsg) )
return true;
- // mark which symbols can not be internalized
+ // mark which symbols can not be internalized
this->applyScopeRestrictions();
Module* mergedModule = _linker.getModule();
// if options were requested, set them
if ( !_codegenOptions.empty() )
- cl::ParseCommandLineOptions(_codegenOptions.size(),
+ cl::ParseCommandLineOptions(_codegenOptions.size(),
const_cast<char **>(&_codegenOptions[0]));
// Instantiate the pass manager to organize the passes.
// Add an appropriate TargetData instance for this module...
passes.add(new TargetData(*_target->getTargetData()));
-
+
PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/ false,
!DisableInline);
return false; // success
}
-
-/// Optimize merged modules using various IPO passes
-void LTOCodeGenerator::setCodeGenDebugOptions(const char* options)
-{
- for (std::pair<StringRef, StringRef> o = getToken(options);
- !o.first.empty(); o = getToken(o.second)) {
- // ParseCommandLineOptions() expects argv[0] to be program name.
- // Lazily add that.
- if ( _codegenOptions.empty() )
- _codegenOptions.push_back("libLTO");
- _codegenOptions.push_back(strdup(o.first.str().c_str()));
- }
+/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
+/// LTO problems.
+void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
+ for (std::pair<StringRef, StringRef> o = getToken(options);
+ !o.first.empty(); o = getToken(o.second)) {
+ // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
+ // that.
+ if ( _codegenOptions.empty() )
+ _codegenOptions.push_back(strdup("libLTO"));
+ _codegenOptions.push_back(strdup(o.first.str().c_str()));
+ }
}