LTOCodeGenerator.cpp revision 9ac0aaa6afe4162b4db32833f9f176ac05ce6f8f
1584ff407482fd3baf5ce081dbbf9653eb76c40f1Eric Anholt//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===// 2af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// 3af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// The LLVM Compiler Infrastructure 4af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// 5af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// This file is distributed under the University of Illinois Open Source 6af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// License. See LICENSE.TXT for details. 7af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// 8af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt//===----------------------------------------------------------------------===// 9af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// 10af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// This file implements the Link Time Optimization library. This library is 11af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// intended to be used by linker to optimize code at link time. 12af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt// 13af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt//===----------------------------------------------------------------------===// 14af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 15af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "LTOCodeGenerator.h" 16af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "LTOModule.h" 17af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Constants.h" 18af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/DerivedTypes.h" 19af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Linker.h" 20af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/LLVMContext.h" 21af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Module.h" 22af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/PassManager.h" 23af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Analysis/Passes.h" 242f0edc60f4bd2ae5999a6afa656e3bb3f181bf0fChad Versace#include "llvm/Analysis/Verifier.h" 25af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Bitcode/ReaderWriter.h" 26af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Config/config.h" 27af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/MC/MCAsmInfo.h" 282e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke#include "llvm/MC/MCContext.h" 29af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/MC/SubtargetFeature.h" 30af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Target/Mangler.h" 31af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Target/TargetOptions.h" 32af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Target/TargetData.h" 33af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Target/TargetMachine.h" 34af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Target/TargetRegisterInfo.h" 35af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Transforms/IPO.h" 36af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Transforms/IPO/PassManagerBuilder.h" 37af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/CommandLine.h" 38af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/FormattedStream.h" 391c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholt#include "llvm/Support/MemoryBuffer.h" 40af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/ToolOutputFile.h" 41af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/Host.h" 42af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/Signals.h" 43af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/TargetRegistry.h" 44af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/TargetSelect.h" 45af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/Support/system_error.h" 46af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#include "llvm/ADT/StringExtras.h" 47af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtusing namespace llvm; 48af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 491c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholtstatic cl::opt<bool> 501c65abb211e6a3df8c46180ae3242486ee97dc8dEric AnholtDisableInline("disable-inlining", cl::init(false), 511c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholt cl::desc("Do not run the inliner pass")); 521c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholt 531c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholtstatic cl::opt<bool> 541c65abb211e6a3df8c46180ae3242486ee97dc8dEric AnholtDisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), 551c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholt cl::desc("Do not run the GVN load PRE pass")); 561c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholt 571c65abb211e6a3df8c46180ae3242486ee97dc8dEric Anholtconst char* LTOCodeGenerator::getVersionString() { 58905f3d03090c7b86e410959c5640054f5f6894efEric Anholt#ifdef LLVM_VERSION_INFO 59905f3d03090c7b86e410959c5640054f5f6894efEric Anholt return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; 60af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt#else 6181a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt return PACKAGE_NAME " version " PACKAGE_VERSION; 6281a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt#endif 6381a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt} 6481a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt 6581a0b2166991a3015f8336e184c34cf6a92adfe0Eric AnholtLTOCodeGenerator::LTOCodeGenerator() 6681a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt : _context(getGlobalContext()), 6781a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL), 6881a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), 6981a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), 7081a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt _nativeObjectFile(NULL) { 7181a0b2166991a3015f8336e184c34cf6a92adfe0Eric Anholt InitializeAllTargets(); 72af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt InitializeAllTargetMCs(); 73af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt InitializeAllAsmPrinters(); 74af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 75af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 76a55fbbc1a2b579aed1e80036367b521ef6928f66Eric AnholtLTOCodeGenerator::~LTOCodeGenerator() { 7754e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt delete _target; 7854e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt delete _nativeObjectFile; 7954e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt 8029e2bc8b13be0f7ec48f8514e47322353e041365Paul Berry for (std::vector<char*>::iterator I = _codegenOptions.begin(), 8154e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt E = _codegenOptions.end(); I != E; ++I) 8254e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt free(*I); 8354e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt} 8454e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt 8554e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholtbool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { 86af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg); 8754e66a0a6327b55f15a7c641ec68da505ff19a35Eric Anholt 88af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs(); 89af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt for (int i = 0, e = undefs.size(); i != e; ++i) 90af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt _asmUndefinedRefs[undefs[i]] = 1; 91af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 92af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return ret; 93af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 94af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 95af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtbool LTOCodeGenerator::setDebugInfo(lto_debug_model debug, 96af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt std::string& errMsg) { 97af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt switch (debug) { 98af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt case LTO_DEBUG_MODEL_NONE: 99f0cecd43d6b6d3f5def3fd43b9c95baaf3be9b16Eric Anholt _emitDwarfDebugInfo = false; 1002e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke return false; 1012e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke 1022e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke case LTO_DEBUG_MODEL_DWARF: 1032e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke _emitDwarfDebugInfo = true; 1042e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke return false; 1052e712e41db0c0676e9f30fc73172c0e8de8d84d4Kenneth Graunke } 106a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt llvm_unreachable("Unknown debug format!"); 107af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 108af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 109a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholtbool LTOCodeGenerator::setCodePICModel(lto_codegen_model model, 110a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt std::string& errMsg) { 111af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt switch (model) { 112a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt case LTO_CODEGEN_PIC_MODEL_STATIC: 113a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt case LTO_CODEGEN_PIC_MODEL_DYNAMIC: 114a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: 115eca762d831e099b549dafa0be896eac82b3fceb9Eric Anholt _codeModel = model; 116483f5b348b0f3c0ca7082fd2047c354e8af285e7Eric Anholt return false; 117a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt } 118a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt llvm_unreachable("Unknown PIC model!"); 119a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt} 120ee41383ab31f6ef5f1d18961de78371d4f52065bKenneth Graunke 121ee41383ab31f6ef5f1d18961de78371d4f52065bKenneth Graunkebool LTOCodeGenerator::writeMergedModules(const char *path, 122a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt std::string &errMsg) { 123a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt if (determineTarget(errMsg)) 124a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt return true; 125eca762d831e099b549dafa0be896eac82b3fceb9Eric Anholt 126a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt // mark which symbols can not be internalized 127a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt applyScopeRestrictions(); 128a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt 129a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt // create output file 130a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt std::string ErrInfo; 131a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt tool_output_file Out(path, ErrInfo, 132af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt raw_fd_ostream::F_Binary); 133a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt if (!ErrInfo.empty()) { 134a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt errMsg = "could not open bitcode file for writing: "; 135a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt errMsg += path; 136a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt return true; 137a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt } 138a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt 139a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt // write bitcode to it 140a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt WriteBitcodeToFile(_linker.getModule(), Out.os()); 141a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt Out.os().close(); 142a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt 143a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt if (Out.os().has_error()) { 144a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt errMsg = "could not write bitcode file: "; 145a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt errMsg += path; 146a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt Out.os().clear_error(); 147a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt return true; 148af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 149a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt 150a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt Out.keep(); 151a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt return false; 152af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 153af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 154af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtbool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { 155af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // make unique temp .o file to put generated object file 156af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt sys::PathWithStatus uniqueObjPath("lto-llvm.o"); 157af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) { 158af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt uniqueObjPath.eraseFromDisk(); 159af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return true; 160af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 161af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt sys::RemoveFileOnSignal(uniqueObjPath); 162af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 163af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // generate object file 164af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt bool genResult = false; 165af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt tool_output_file objFile(uniqueObjPath.c_str(), errMsg); 166af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (!errMsg.empty()) 167af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return true; 16865d46c96c2540f8181293c318b412446a953faefEric Anholt 16965d46c96c2540f8181293c318b412446a953faefEric Anholt genResult = this->generateObjectFile(objFile.os(), errMsg); 17065d46c96c2540f8181293c318b412446a953faefEric Anholt objFile.os().close(); 17165d46c96c2540f8181293c318b412446a953faefEric Anholt if (objFile.os().has_error()) { 17265d46c96c2540f8181293c318b412446a953faefEric Anholt objFile.os().clear_error(); 17365d46c96c2540f8181293c318b412446a953faefEric Anholt return true; 174af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 175af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 176af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt objFile.keep(); 177af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if ( genResult ) { 178af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt uniqueObjPath.eraseFromDisk(); 179af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return true; 180af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 181af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 182af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt _nativeObjectPath = uniqueObjPath.str(); 183af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt *name = _nativeObjectPath.c_str(); 184af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return false; 185af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 186af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 187af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtconst void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { 188af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt const char *name; 189af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (compile_to_file(&name, errMsg)) 190af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return NULL; 191af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 192af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // remove old buffer if compile() called twice 193af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt delete _nativeObjectFile; 194af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 195af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // read .o file into memory buffer 196af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt OwningPtr<MemoryBuffer> BuffPtr; 197af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { 198af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt errMsg = ec.message(); 199af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return NULL; 200af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 201af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt _nativeObjectFile = BuffPtr.take(); 202af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 203af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // remove temp files 204af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt sys::Path(_nativeObjectPath).eraseFromDisk(); 205af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 206af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // return buffer, unless error 207af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if ( _nativeObjectFile == NULL ) 208af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return NULL; 209af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt *length = _nativeObjectFile->getBufferSize(); 210af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return _nativeObjectFile->getBufferStart(); 211af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 212af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 213af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtbool LTOCodeGenerator::determineTarget(std::string& errMsg) { 214af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if ( _target == NULL ) { 215af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt std::string Triple = _linker.getModule()->getTargetTriple(); 216af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (Triple.empty()) 217af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt Triple = sys::getDefaultTargetTriple(); 218af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 219af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // create target machine from info for merged modules 220af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt const Target *march = TargetRegistry::lookupTarget(Triple, errMsg); 221af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if ( march == NULL ) 222af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return true; 223af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 224a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt // The relocation model is actually a static member of TargetMachine and 225a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt // needs to be set before the TargetMachine is instantiated. 226a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt Reloc::Model RelocModel = Reloc::Default; 227a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt switch( _codeModel ) { 228a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt case LTO_CODEGEN_PIC_MODEL_STATIC: 229a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt RelocModel = Reloc::Static; 230a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt break; 231a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt case LTO_CODEGEN_PIC_MODEL_DYNAMIC: 232a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt RelocModel = Reloc::PIC_; 233a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt break; 234483f5b348b0f3c0ca7082fd2047c354e8af285e7Eric Anholt case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: 235483f5b348b0f3c0ca7082fd2047c354e8af285e7Eric Anholt RelocModel = Reloc::DynamicNoPIC; 236483f5b348b0f3c0ca7082fd2047c354e8af285e7Eric Anholt break; 237a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt } 238a070d5f363e99b0f846d555e9ca3a74ec807fdc0Eric Anholt 239af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt // construct LTOModule, hand over ownership of module and target 240af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt SubtargetFeatures Features; 241af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); 242af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt std::string FeatureStr = Features.getString(); 243af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt TargetOptions Options; 244af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt LTOModule::getTargetOptions(Options); 245af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options, 246af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt RelocModel, CodeModel::Default, 247af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt CodeGenOpt::Aggressive); 248af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt } 249af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return false; 250af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 251af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 252af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtvoid LTOCodeGenerator:: 253af3c9803d818fd33139f1247a387d64b967b8992Eric AnholtapplyRestriction(GlobalValue &GV, 254af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt std::vector<const char*> &mustPreserveList, 255af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt SmallPtrSet<GlobalValue*, 8> &asmUsed, 256af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt Mangler &mangler) { 257af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt SmallString<64> Buffer; 258af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt mangler.getNameWithPrefix(Buffer, &GV, false); 259af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 260af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (GV.isDeclaration()) 261af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt return; 262af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (_mustPreserveSymbols.count(Buffer)) 263af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt mustPreserveList.push_back(GV.getName().data()); 264af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (_asmUndefinedRefs.count(Buffer)) 265af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt asmUsed.insert(&GV); 266af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt} 2679f842886077258ddda5d5a32b1f5d9fe2e5818bcEric Anholt 268af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtstatic void findUsedValues(GlobalVariable *LLVMUsed, 269af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt SmallPtrSet<GlobalValue*, 8> &UsedValues) { 270af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (LLVMUsed == 0) return; 271abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 272abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer()); 273abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt if (Inits == 0) return; 274abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 275abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 276abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt if (GlobalValue *GV = 2778ccbcda5c64a8bea47f6b41d46bf015ba8e515fcChris Wilson dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 278abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt UsedValues.insert(GV); 279abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt} 280af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 281af3c9803d818fd33139f1247a387d64b967b8992Eric Anholtvoid LTOCodeGenerator::applyScopeRestrictions() { 282af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt if (_scopeRestrictionsDone) return; 283af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt Module *mergedModule = _linker.getModule(); 284af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 285250770b74d33bb8625c780a74a89477af033d13aEric Anholt // Start off with a verification pass. 286250770b74d33bb8625c780a74a89477af033d13aEric Anholt PassManager passes; 287abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt passes.add(createVerifierPass()); 288250770b74d33bb8625c780a74a89477af033d13aEric Anholt 289250770b74d33bb8625c780a74a89477af033d13aEric Anholt // mark which symbols can not be internalized 290af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL); 291af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt Mangler mangler(Context, *_target->getTargetData()); 292af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt std::vector<const char*> mustPreserveList; 293af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt SmallPtrSet<GlobalValue*, 8> asmUsed; 294af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt 295af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt for (Module::iterator f = mergedModule->begin(), 296af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt e = mergedModule->end(); f != e; ++f) 297250770b74d33bb8625c780a74a89477af033d13aEric Anholt applyRestriction(*f, mustPreserveList, asmUsed, mangler); 298af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt for (Module::global_iterator v = mergedModule->global_begin(), 299af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt e = mergedModule->global_end(); v != e; ++v) 300af3c9803d818fd33139f1247a387d64b967b8992Eric Anholt applyRestriction(*v, mustPreserveList, asmUsed, mangler); 301a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke for (Module::alias_iterator a = mergedModule->alias_begin(), 302a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke e = mergedModule->alias_end(); a != e; ++a) 303a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke applyRestriction(*a, mustPreserveList, asmUsed, mangler); 304a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke 305a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke GlobalVariable *LLVMCompilerUsed = 306a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke mergedModule->getGlobalVariable("llvm.compiler.used"); 307a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke findUsedValues(LLVMCompilerUsed, asmUsed); 308a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke if (LLVMCompilerUsed) 309a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke LLVMCompilerUsed->eraseFromParent(); 310a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke 311a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); 312a73c65c5342bf41fa0dfefe7daa9197ce6a11db4Kenneth Graunke std::vector<Constant*> asmUsed2; 313abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(), 314abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt e = asmUsed.end(); i !=e; ++i) { 315abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt GlobalValue *GV = *i; 316abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt Constant *c = ConstantExpr::getBitCast(GV, i8PTy); 317abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt asmUsed2.push_back(c); 318abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt } 319abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 320abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); 321abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt LLVMCompilerUsed = 322abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt new llvm::GlobalVariable(*mergedModule, ATy, false, 323abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt llvm::GlobalValue::AppendingLinkage, 324abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt llvm::ConstantArray::get(ATy, asmUsed2), 325abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt "llvm.compiler.used"); 326abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 327abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt LLVMCompilerUsed->setSection("llvm.metadata"); 328abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 329abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt passes.add(createInternalizePass(mustPreserveList)); 330abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 331abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // apply scope restrictions 332abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt passes.run(*mergedModule); 333abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 334abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt _scopeRestrictionsDone = true; 335abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt} 336abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 337abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt/// Optimize merged modules using various IPO passes 338b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunkebool LTOCodeGenerator::generateObjectFile(raw_ostream &out, 339b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke std::string &errMsg) { 340b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke if ( this->determineTarget(errMsg) ) 341b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke return true; 342b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke 343b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke Module* mergedModule = _linker.getModule(); 344b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke 345b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke // if options were requested, set them 346b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke if ( !_codegenOptions.empty() ) 347b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke cl::ParseCommandLineOptions(_codegenOptions.size(), 348b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke const_cast<char **>(&_codegenOptions[0])); 349b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke 350b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke // mark which symbols can not be internalized 351b0adbda75a092a92211bb519a395494532ddb17eEric Anholt this->applyScopeRestrictions(); 352b0adbda75a092a92211bb519a395494532ddb17eEric Anholt 353b0adbda75a092a92211bb519a395494532ddb17eEric Anholt // Instantiate the pass manager to organize the passes. 354b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke PassManager passes; 355b0adbda75a092a92211bb519a395494532ddb17eEric Anholt 356abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // Start off with a verification pass. 357abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt passes.add(createVerifierPass()); 358abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt 359abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // Add an appropriate TargetData instance for this module... 360abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt passes.add(new TargetData(*_target->getTargetData())); 361b9af592dfa8f8d0fe9f29c2d48bf6846cbd5c50fKenneth Graunke 362abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // Enabling internalize here would use its AllButMain variant. It 363abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // keeps only main if it exists and does nothing for libraries. Instead 364abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt // we create the pass ourselves with the symbol list provided by the linker. 365abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false, 366abf843a797876b5e3c5c91dbec25b6553d2cc281Eric Anholt !DisableInline, 367ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke DisableGVNLoadPRE); 368ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 369ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke // Make sure everything is still good. 370ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke passes.add(createVerifierPass()); 371ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 372ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); 373ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 374ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke codeGenPasses->add(new TargetData(*_target->getTargetData())); 375ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 376ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke formatted_raw_ostream Out(out); 377ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 378ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke if (_target->addPassesToEmitFile(*codeGenPasses, Out, 379ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke TargetMachine::CGFT_ObjectFile)) { 380ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke errMsg = "target file type not supported"; 381ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke return true; 382ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke } 383ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 384d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke // Run our queue of passes all at once now, efficiently. 385d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke passes.run(*mergedModule); 386d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke 387d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke // Run the code generator, and write assembly file 388d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke codeGenPasses->doInitialization(); 389d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke 390d02343e5016a5795451af3e0315b658b39463a30Kenneth Graunke for (Module::iterator 391ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) 392ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke if (!it->isDeclaration()) 393ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke codeGenPasses->run(*it); 394ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 395ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke codeGenPasses->doFinalization(); 396ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke delete codeGenPasses; 397ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 398ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke return false; // success 399ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke} 400ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke 401ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging 402ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke/// LTO problems. 403ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunkevoid LTOCodeGenerator::setCodeGenDebugOptions(const char *options) { 404ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke for (std::pair<StringRef, StringRef> o = getToken(options); 405ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke !o.first.empty(); o = getToken(o.second)) { 406ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add 407ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke // that. 408ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke if ( _codegenOptions.empty() ) 409ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke _codegenOptions.push_back(strdup("libLTO")); 410ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke _codegenOptions.push_back(strdup(o.first.str().c_str())); 411ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke } 412ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke} 413ca182cd0fa338ad39d531cb1be6a5a1bbf455771Kenneth Graunke