1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 17a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang#include <list> 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <memory> 196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <string> 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <vector> 216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Analysis/Verifier.h" 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h" 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 26835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Linker.h" 27835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/LLVMContext.h" 28835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Metadata.h" 29835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Module.h" 307f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 31835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Support/CommandLine.h" 32835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Support/ManagedStatic.h" 33835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Support/MemoryBuffer.h" 34835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Support/raw_ostream.h" 35df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao#include "llvm/Support/ToolOutputFile.h" 36be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "llvm/Support/system_error.h" 377f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 389207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/PassManager.h" 399207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO.h" 409207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h" 419207a2e495c8363606861e4f034504ec5c153dabLogan Chien 42835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao#include "llvm/Target/TargetData.h" 437f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 447f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang#include "slang_rs_metadata.h" 45835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing llvm::errs; 47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing llvm::LLVMContext; 48e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing llvm::MemoryBuffer; 49e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesusing llvm::Module; 50835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 51e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstatic llvm::cl::list<std::string> 52e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen HinesInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore, 53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::cl::desc("<input bitcode files>")); 54835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 55e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstatic llvm::cl::list<std::string> 56e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen HinesOutputFilenames("o", llvm::cl::desc("Override output filename"), 57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::cl::value_desc("<output bitcode file>")); 58a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 59e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstatic llvm::cl::opt<bool> 60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen HinesNoStdLib("nostdlib", llvm::cl::desc("Don't link RS default libraries")); 61a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 62e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstatic llvm::cl::list<std::string> 63e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines AdditionalLibs("l", llvm::cl::Prefix, 64e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::cl::desc("Specify additional libraries to link to"), 65e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::cl::value_desc("<library bitcode>")); 66835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesstatic bool GetExportSymbolNames(llvm::NamedMDNode *N, 687f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang unsigned NameOpIdx, 697f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang std::vector<const char *> &Names) { 707f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang if (N == NULL) 717f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang return true; 727f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 737f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::MDNode *V = N->getOperand(i); 757f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang if (V == NULL) 767f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang continue; 777f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 787f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang if (V->getNumOperands() < (NameOpIdx + 1)) { 797f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang errs() << "Invalid metadata spec of " << N->getName() 80b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines << " in Renderscript executable. (#op)\n"; 817f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang return false; 82835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 83835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 84e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::MDString *Name = 85e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::dyn_cast<llvm::MDString>(V->getOperand(NameOpIdx)); 867f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang if (Name == NULL) { 877f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang errs() << "Invalid metadata spec of " << N->getName() 88b7d1269f983f28d9fe625a96439fa88b39dc96f6Stephen Hines << " in Renderscript executable. (#name)\n"; 897f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang return false; 90835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 91835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 927f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang Names.push_back(Name->getString().data()); 93835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 947f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang return true; 95835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao} 96835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 977f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Changstatic bool GetExportSymbols(Module *M, std::vector<const char *> &Names) { 987f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang bool Result = true; 997f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang // Variables marked as export must be externally visible 100e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (llvm::NamedMDNode *EV = M->getNamedMetadata(RS_EXPORT_VAR_MN)) 1017f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang Result |= GetExportSymbolNames(EV, RS_EXPORT_VAR_NAME, Names); 1027f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang // So are those exported functions 103e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (llvm::NamedMDNode *EF = M->getNamedMetadata(RS_EXPORT_FUNC_MN)) 1047f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang Result |= GetExportSymbolNames(EF, RS_EXPORT_FUNC_NAME, Names); 1057f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang return Result; 106835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao} 107835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 108a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changstatic inline MemoryBuffer *LoadFileIntoMemory(const std::string &F) { 109be27482cdeaf08576bc39b72a15d35d13014a636Logan llvm::OwningPtr<MemoryBuffer> MB; 110835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 111be27482cdeaf08576bc39b72a15d35d13014a636Logan if (llvm::error_code EC = MemoryBuffer::getFile(F, MB)) { 112be27482cdeaf08576bc39b72a15d35d13014a636Logan errs() << "Failed to load `" << F << "' (" + EC.message() + ")\n"; 113be27482cdeaf08576bc39b72a15d35d13014a636Logan } 114835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 115be27482cdeaf08576bc39b72a15d35d13014a636Logan return MB.take(); 116835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao} 117835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 118a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changstatic inline Module *ParseBitcodeFromMemoryBuffer(MemoryBuffer *MB, 119a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LLVMContext& Context) { 120a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::string Err; 121a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Module *M = ParseBitcodeFile(MB, Context, &Err); 122835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 123a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (M == NULL) 124a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang errs() << "Corrupted bitcode file `" << MB->getBufferIdentifier() 125a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang << "' (" << Err << ")\n"; 126835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 127a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return M; 128a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 129a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 130a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang// LoadBitcodeFile - Read the specified bitcode file in and return it. 131a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changstatic inline Module *LoadBitcodeFile(const std::string &F, 132a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LLVMContext& Context) { 133a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang MemoryBuffer *MB = LoadFileIntoMemory(F); 134a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (MB == NULL) 135a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return NULL; 136a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 137a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Module *M = ParseBitcodeFromMemoryBuffer(MB, Context); 138a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (M == NULL) 139a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang delete MB; 140a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 141a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return M; 142a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 143a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 144a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changextern const char rslib_bc[]; 145a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changextern unsigned rslib_bc_size; 146a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 147a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changstatic bool PreloadLibraries(bool NoStdLib, 148a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang const std::vector<std::string> &AdditionalLibs, 149552b581ecc3070b2344a00da9e6f247648167b4dShih-wei Liao std::list<MemoryBuffer *> &LibBitcode) { 150a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang MemoryBuffer *MB; 151a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 152a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LibBitcode.clear(); 153a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 154a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (!NoStdLib) { 155a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // rslib.bc 156e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines MB = MemoryBuffer::getMemBuffer(llvm::StringRef(rslib_bc, rslib_bc_size), 157d124ee6cfcb90229e7121fe81742d23a05375ce8Zonr Chang "rslib.bc"); 158a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (MB == NULL) { 159a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang errs() << "Failed to load (in-memory) `rslib.bc'!\n"; 160a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return false; 161835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 162a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 163a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LibBitcode.push_back(MB); 164835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 165835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 166a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // Load additional libraries 167a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang for (std::vector<std::string>::const_iterator 168a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I = AdditionalLibs.begin(), E = AdditionalLibs.end(); 169a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I != E; 170a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I++) { 171a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang MB = LoadFileIntoMemory(*I); 172a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (MB == NULL) 173a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return false; 174a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LibBitcode.push_back(MB); 175835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 176835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 177a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return true; 178a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 179a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 180a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changstatic void UnloadLibraries(std::list<MemoryBuffer *>& LibBitcode) { 181a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang for (std::list<MemoryBuffer *>::iterator 182a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I = LibBitcode.begin(), E = LibBitcode.end(); 183a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I != E; 184a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I++) 185a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang delete *I; 186a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LibBitcode.clear(); 187a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return; 188a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 189a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 190a02010cd90184a9c1be7b451fe32e114ffb1810fZonr ChangModule *PerformLinking(const std::string &InputFile, 191a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang const std::list<MemoryBuffer *> &LibBitcode, 192a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang LLVMContext &Context) { 193a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::string Err; 194a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::auto_ptr<Module> Composite(LoadBitcodeFile(InputFile, Context)); 195a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 196a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (Composite.get() == NULL) 197a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return NULL; 198a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 199a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang for (std::list<MemoryBuffer *>::const_iterator I = LibBitcode.begin(), 200a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang E = LibBitcode.end(); 201a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I != E; 202a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang I++) { 203a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Module *Lib = ParseBitcodeFromMemoryBuffer(*I, Context); 204a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (Lib == NULL) 205a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return NULL; 206a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 2079207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (llvm::Linker::LinkModules(Composite.get(), Lib, 2089207a2e495c8363606861e4f034504ec5c153dabLogan Chien llvm::Linker::DestroySource, &Err)) { 209a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang errs() << "Failed to link `" << InputFile << "' with library bitcode `" 210a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang << (*I)->getBufferIdentifier() << "' (" << Err << ")\n"; 211a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return NULL; 212a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang } 213835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao } 214835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 215a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return Composite.release(); 216a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 217a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 218a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changbool OptimizeModule(Module *M) { 219e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::PassManager Passes; 220835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 221a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang const std::string &ModuleDataLayout = M->getDataLayout(); 2227f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang if (!ModuleDataLayout.empty()) 223e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (llvm::TargetData *TD = new llvm::TargetData(ModuleDataLayout)) 224835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao Passes.add(TD); 225835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 2267f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang // Some symbols must not be internalized 2277f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang std::vector<const char *> ExportList; 2287f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang ExportList.push_back("init"); 2297f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang ExportList.push_back("root"); 230688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines ExportList.push_back(".rs.dtor"); 2319c9bbc87c525e4f3c5f529dadea3f3cd8bd69010Shih-wei Liao 232a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (!GetExportSymbols(M, ExportList)) { 233a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return false; 234a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang } 235835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 236e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Passes.add(llvm::createInternalizePass(ExportList)); 237835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 238fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao // TODO(sliao): Do we need to run all LTO passes? 239fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao llvm::PassManagerBuilder PMBuilder; 240fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao PMBuilder.populateLTOPassManager(Passes, 241fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao /* Internalize = */false, 242fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao /* RunInliner = */true); 243a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Passes.run(*M); 244a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 245a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return true; 246a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang} 247a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 248a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Changint main(int argc, char **argv) { 249e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::llvm_shutdown_obj X; // Call llvm_shutdown() on exit. 250a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 251e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::cl::ParseCommandLineOptions(argc, argv, "llvm-rs-link\n"); 252a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 253a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::list<MemoryBuffer *> LibBitcode; 254a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 255a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (!PreloadLibraries(NoStdLib, AdditionalLibs, LibBitcode)) 256a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return 1; 257a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 258a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // No libraries specified to be linked 259a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (LibBitcode.size() == 0) 260a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return 0; 261a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 262e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines LLVMContext &Context = llvm::getGlobalContext(); 263a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang bool HasError = true; 264a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::string Err; 265a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 266a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang for (unsigned i = 0, e = InputFilenames.size(); i != e; i++) { 267a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang std::auto_ptr<Module> Linked( 268a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang PerformLinking(InputFilenames[i], LibBitcode, Context)); 269a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 270a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // Failed to link with InputFilenames[i] with LibBitcode 271a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (Linked.get() == NULL) 272a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang break; 273a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 274a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // Verify linked module 275e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines if (verifyModule(*Linked, llvm::ReturnStatusAction, &Err)) { 276a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang errs() << InputFilenames[i] << " linked, but does not verify as " 277a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang "correct! (" << Err << ")\n"; 278a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang break; 279a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang } 280a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 281a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (!OptimizeModule(Linked.get())) 282a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang break; 283a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 284a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // Write out the module 285e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::tool_output_file Out(InputFilenames[i].c_str(), Err, 286e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines llvm::raw_fd_ostream::F_Binary); 287a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 288a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (!Err.empty()) { 289a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang errs() << InputFilenames[i] << " linked, but failed to write out! " 290a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang "(" << Err << ")\n"; 291a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang break; 292a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang } 293a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 294df5bcce1582d839eead432a5e24435236c90fb05Shih-wei Liao WriteBitcodeToFile(Linked.get(), Out.os()); 295a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 296a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Out.keep(); 297a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang Linked.reset(); 298a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang 299a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang if (i == (InputFilenames.size() - 1)) 300a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang // This is the last file and no error occured. 301a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang HasError = false; 302a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang } 303835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao 304a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang UnloadLibraries(LibBitcode); 3057f2f385d3129ba4de82ef56adb9cb4385fd33001Zonr Chang 306a02010cd90184a9c1be7b451fe32e114ffb1810fZonr Chang return HasError; 307835a7b773631261b9ea2fb448a4c8a7a8cacfaabShih-wei Liao} 308