From cfaa636a1d31f2db71df627e4882e9d5c066c419 Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Mon, 12 Aug 2013 21:07:31 +0000 Subject: Revert r188188 and r188200. In order to appease people (in Apple) who accuse me for committing "huge change" (?) without proper review. Thank Eric for fixing a compile-warning. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188204 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm-c/lto.h | 12 --- tools/gold/gold-plugin.cpp | 32 ++----- tools/lto/CMakeLists.txt | 2 - tools/lto/LTOCodeGenerator.cpp | 195 ++++++++------------------------------- tools/lto/LTOCodeGenerator.h | 39 +------- tools/lto/LTOPartition.cpp | 205 ----------------------------------------- tools/lto/LTOPartition.h | 187 ------------------------------------- tools/lto/LTOPostIPODriver.cpp | 180 ------------------------------------ tools/lto/LTOPostIPODriver.h | 51 ---------- tools/lto/lto.cpp | 13 --- tools/lto/lto.exports | 1 - 11 files changed, 45 insertions(+), 872 deletions(-) delete mode 100644 tools/lto/LTOPartition.cpp delete mode 100644 tools/lto/LTOPartition.h delete mode 100644 tools/lto/LTOPostIPODriver.cpp delete mode 100644 tools/lto/LTOPostIPODriver.h diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index a7a942d2b3..40110fddfc 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -284,18 +284,6 @@ lto_codegen_compile(lto_code_gen_t cg, size_t* length); extern bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); -/** - * Get intermediate files that need to be removed before linker exit. Upon - * return, the paths of the files need to be removed is written to "paths". The - * paths are separated by a single '\0', and the last path is ended by double - * '\0's. A file could be a directory; in this case, the entire directory needs - * to be removed recursively. - * - * It is only necessary to call this function after \p lto_codegen_compile was - * successfully called. - */ -extern void -lto_codegen_get_files_need_remove(lto_code_gen_t cg, const char **paths); /** * Sets options to help debug codegen bugs. diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 7918324702..77717098d6 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -74,6 +74,7 @@ namespace options { static bool generate_api_file = false; static generate_bc generate_bc_file = BC_NO; static std::string bc_path; + static std::string obj_path; static std::string extra_library_path; static std::string triple; static std::string mcpu; @@ -98,6 +99,8 @@ namespace options { extra_library_path = opt.substr(strlen("extra_library_path=")); } else if (opt.startswith("mtriple=")) { triple = opt.substr(strlen("mtriple=")); + } else if (opt.startswith("obj-path=")) { + obj_path = opt.substr(strlen("obj-path=")); } else if (opt == "emit-llvm") { generate_bc_file = BC_ONLY; } else if (opt == "also-emit-llvm") { @@ -422,14 +425,6 @@ static ld_plugin_status all_symbols_read_hook(void) { (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); } - // Get files that need to be removed in cleanup_hook. - const char *ToRm; - lto_codegen_get_files_need_remove(code_gen, &ToRm); - while (*ToRm) { - Cleanup.push_back(std::string(ToRm)); - ToRm += strlen(ToRm) + 1; - } - lto_codegen_dispose(code_gen); for (std::list::iterator I = Modules.begin(), E = Modules.end(); I != E; ++I) { @@ -451,28 +446,17 @@ static ld_plugin_status all_symbols_read_hook(void) { return LDPS_ERR; } + if (options::obj_path.empty()) + Cleanup.push_back(objPath); + return LDPS_OK; } static ld_plugin_status cleanup_hook(void) { for (int i = 0, e = Cleanup.size(); i != e; ++i) { - const char *FN = Cleanup[i].c_str(); - sys::fs::file_status Stat; - error_code EC = sys::fs::status(Twine(FN), Stat); - if (EC) { - (*message)(LDPL_ERROR, "Failed to stat '%s': %s", FN, - EC.message().c_str()); - continue; - } - - uint32_t Dummy; - if (sys::fs::is_directory(FN)) - EC = sys::fs::remove_all(Twine(FN), Dummy); - else - EC = sys::fs::remove(Twine(FN)); - + error_code EC = sys::fs::remove(Cleanup[i]); if (EC) - (*message)(LDPL_ERROR, "Failed to remove '%s': %s", FN, + (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), EC.message().c_str()); } diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 7667449a34..5820b1415b 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,8 +9,6 @@ set(SOURCES LTODisassembler.cpp lto.cpp LTOModule.cpp - LTOPartition.cpp - LTOPostIPODriver.cpp ) set(LLVM_COMMON_DEPENDS intrinsics_gen) diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index bcbd01752a..3fe7af25af 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -14,8 +14,6 @@ #include "LTOCodeGenerator.h" #include "LTOModule.h" -#include "LTOPartition.h" -#include "LTOPostIPODriver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" @@ -37,13 +35,11 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/system_error.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -51,16 +47,8 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/ObjCARC.h" - using namespace llvm; -using namespace lto; -// ///////////////////////////////////////////////////////////////////////////// -// -// Internal options. To avoid collision, most options start with "lto-". -// -// ///////////////////////////////////////////////////////////////////////////// -// static cl::opt DisableOpt("disable-opt", cl::init(false), cl::desc("Do not run any optimization passes")); @@ -73,28 +61,6 @@ static cl::opt DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), cl::desc("Do not run the GVN load PRE pass")); -// To break merged module into partitions, and compile them independently. -static cl::opt -EnablePartition("lto-partition", cl::init(false), - cl::desc("Partition program and compile each piece in parallel")); - -// Specify the work-directory for the LTO compilation. All intermeidate -// files will be created immediately under this dir. If it is not -// specified, compiler will create an unique directory under current-dir. -// -static cl::opt -TmpWorkDir("lto-workdir", cl::init(""), cl::desc("Specify working directory")); - -static cl::opt -KeepWorkDir("lto-keep", cl::init(false), cl::desc("Keep working directory")); - - -// ///////////////////////////////////////////////////////////////////////////// -// -// Implementation of LTOCodeGenerator -// -// ///////////////////////////////////////////////////////////////////////////// -// const char* LTOCodeGenerator::getVersionString() { #ifdef LLVM_VERSION_INFO return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; @@ -108,8 +74,7 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL), PartitionMgr(FileMgr), - OptionsParsed(false) { + _nativeObjectFile(NULL) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -222,41 +187,35 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, return true; } -// This function is to ensure cl::ParseCommandLineOptions() is called no more -// than once. It would otherwise complain and exit the compilation prematurely. -// -void LTOCodeGenerator::parseOptions() { - if (OptionsParsed) - return; - - if (!_codegenOptions.empty()) - cl::ParseCommandLineOptions(_codegenOptions.size(), - const_cast(&_codegenOptions[0])); - - OptionsParsed = true; -} - -// Do some prepartion right before compilation starts. -bool LTOCodeGenerator::prepareBeforeCompile(std::string &ErrMsg) { - parseOptions(); - - if (!determineTarget(ErrMsg)) +bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { + // make unique temp .o file to put generated object file + SmallString<128> Filename; + int FD; + error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); + if (EC) { + errMsg = EC.message(); return false; + } - FileMgr.setWorkDir(TmpWorkDir.c_str()); - FileMgr.setKeepWorkDir(KeepWorkDir); - return FileMgr.createWorkDir(ErrMsg); -} + // generate object file + tool_output_file objFile(Filename.c_str(), FD); -bool LTOCodeGenerator::compile_to_file(const char** Name, std::string& ErrMsg) { - if (!prepareBeforeCompile(ErrMsg)) + bool genResult = generateObjectFile(objFile.os(), errMsg); + objFile.os().close(); + if (objFile.os().has_error()) { + objFile.os().clear_error(); + sys::fs::remove(Twine(Filename)); return false; + } - performIPO(EnablePartition, ErrMsg); - if (!performPostIPO(ErrMsg)) + objFile.keep(); + if (!genResult) { + sys::fs::remove(Twine(Filename)); return false; + } - *Name = PartitionMgr.getSinglePartition()->getObjFilePath().c_str(); + _nativeObjectPath = Filename.c_str(); + *name = _nativeObjectPath.c_str(); return true; } @@ -270,41 +229,21 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { // read .o file into memory buffer OwningPtr BuffPtr; - const char *BufStart = 0; - if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { errMsg = ec.message(); - _nativeObjectFile = 0; - } else { - if ((_nativeObjectFile = BuffPtr.take())) { - *length = _nativeObjectFile->getBufferSize(); - BufStart = _nativeObjectFile->getBufferStart(); - } + sys::fs::remove(_nativeObjectPath); + return NULL; } + _nativeObjectFile = BuffPtr.take(); - // Now that the resulting single object file is handed to linker via memory - // buffer, it is safe to remove all intermediate files now. - // - FileMgr.removeAllUnneededFiles(); - - return BufStart; -} - -const char *LTOCodeGenerator::getFilesNeedToRemove() { - IPOFileMgr::FileNameVect ToRm; - FileMgr.getFilesNeedToRemove(ToRm); + // remove temp files + sys::fs::remove(_nativeObjectPath); - ConcatStrings.clear(); - for (IPOFileMgr::FileNameVect::iterator I = ToRm.begin(), E = ToRm.end(); - I != E; I++) { - StringRef S(*I); - ConcatStrings.append(S.begin(), S.end()); - ConcatStrings.push_back('\0'); - } - ConcatStrings.push_back('\0'); - ConcatStrings.push_back('\0'); - - return ConcatStrings.data(); + // return buffer, unless error + if (_nativeObjectFile == NULL) + return NULL; + *length = _nativeObjectFile->getBufferSize(); + return _nativeObjectFile->getBufferStart(); } bool LTOCodeGenerator::determineTarget(std::string &errMsg) { @@ -312,7 +251,9 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { return true; // if options were requested, set them - parseOptions(); + if (!_codegenOptions.empty()) + cl::ParseCommandLineOptions(_codegenOptions.size(), + const_cast(&_codegenOptions[0])); std::string TripleStr = _linker.getModule()->getTargetTriple(); if (TripleStr.empty()) @@ -443,70 +384,6 @@ void LTOCodeGenerator::applyScopeRestrictions() { _scopeRestrictionsDone = true; } -void LTOCodeGenerator::performIPO(bool ToPartition, std::string &errMsg) { - // Mark which symbols can not be internalized - applyScopeRestrictions(); - - // Instantiate the pass manager to organize the passes. - PassManager Passes; - - // Start off with a verification pass. - Passes.add(createVerifierPass()); - - // Add an appropriate DataLayout instance for this module... - Passes.add(new DataLayout(*_target->getDataLayout())); - _target->addAnalysisPasses(Passes); - - // Enabling internalize here would use its AllButMain variant. It - // keeps only main if it exists and does nothing for libraries. Instead - // we create the pass ourselves with the symbol list provided by the linker. - if (!DisableOpt) - PassManagerBuilder().populateLTOPassManager(Passes, - /*Internalize=*/false, - !DisableInline, - DisableGVNLoadPRE); - // Make sure everything is still good. - Passes.add(createVerifierPass()); - - Module* M = _linker.getModule(); - if (ToPartition) - assert(false && "TBD"); - else { - Passes.run(*M); - - // Create a partition for the merged module. - PartitionMgr.createIPOPart(M); - } -} - -// Perform Post-IPO compilation. If the partition is enabled, there may -// be multiple partitions, and therefore there may be multiple objects. -// In this case, "MergeObjs" indicates to merge all object together (via ld -r) -// and return the path to the merged object via "MergObjPath". -// -bool LTOCodeGenerator::performPostIPO(std::string &ErrMsg, - bool MergeObjs, - const char **MergObjPath) { - // Determine the variant of post-ipo driver - PostIPODriver::VariantTy DrvTy; - if (!EnablePartition) { - assert(!MergeObjs && !MergObjPath && "Invalid parameter"); - DrvTy = PostIPODriver::PIDV_SERIAL; - } else { - DrvTy = PostIPODriver::PIDV_Invalid; - assert(false && "TBD"); - } - - PostIPODriver D(DrvTy, _target, PartitionMgr, FileMgr, MergeObjs); - if (D.Compile(ErrMsg)) { - if (MergeObjs) - *MergObjPath = D.getSingleObjFile()->getPath().c_str(); - return true; - } - - return false; -} - /// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 5dda5d9c3e..8f37cf0e1d 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -41,7 +41,6 @@ #include "llvm/Linker.h" #include #include -#include "LTOPartition.h" namespace llvm { class LLVMContext; @@ -103,34 +102,16 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); - // Return the paths of the intermediate files that linker needs to delete - // before it exits. The paths are delimited by a single '\0', and the last - // path is ended by double '\0's. The file could be a directory. In that - // case, the entire directory should be erased recusively. This function - // must be called after the compilexxx() is successfuly called, because - // only after that moment, compiler is aware which files need to be removed. - // If calling compilexxx() is not successful, it is up to compiler to clean - // up all the intermediate files generated during the compilation process. - // - const char *getFilesNeedToRemove(); - private: void initializeLTOPasses(); - bool determineTarget(std::string &errMsg); - void parseOptions(); - bool prepareBeforeCompile(std::string &ErrMsg); - void performIPO(bool PerformPartition, std::string &ErrMsg); - bool performPostIPO(std::string &ErrMsg, bool MergeObjs = false, - const char **MergObjPath = 0); bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); - void applyScopeRestrictions(); void applyRestriction(llvm::GlobalValue &GV, std::vector &mustPreserveList, llvm::SmallPtrSet &asmUsed, llvm::Mangler &mangler); - + bool determineTarget(std::string &errMsg); typedef llvm::StringMap StringSet; @@ -146,24 +127,6 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; - - // To manage the partitions. If partition is not enabled, the whole merged - // module is considered as a single degenerated partition, and the "manager" - // is still active. - lto::IPOPartMgr PartitionMgr; - - // To manage the intermediate files during the compilations. - lto::IPOFileMgr FileMgr; - - // Sometimes we need to return a vector of strings in a "C" way (to work with - // the C-APIs). We encode such C-thinking string vector by concatenating all - // strings tegother with a single '\0' as the delimitor, the last string ended - // by double '\0's. - SmallVector ConcatStrings; - - // Make sure command line is parsed only once. It would otherwise complain - // and quite prematurely. - bool OptionsParsed; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/LTOPartition.cpp b/tools/lto/LTOPartition.cpp deleted file mode 100644 index a056b718f1..0000000000 --- a/tools/lto/LTOPartition.cpp +++ /dev/null @@ -1,205 +0,0 @@ -//===-- LTOPartition.cpp - Parition Merged Module --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LTOPartition.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Path.h" -#include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/Transforms/Utils/Cloning.h" - -using namespace llvm; -using namespace lto; - -// ///////////////////////////////////////////////////////////////////////////// -// -// Implementation of IPOPartition and IPOPartMgr -// -// ///////////////////////////////////////////////////////////////////////////// -// -IPOPartition::IPOPartition(Module *M, const char *NameWoExt, IPOFileMgr &FM) : - Mod(0), Ctx(0), IRFile(0), ObjFile(0), FileNameWoExt(NameWoExt), FileMgr(FM) { -} - -IPOFile &IPOPartition::getIRFile() const { - if (IRFile) - return *IRFile; - else { - std::string FN(FileNameWoExt + ".bc"); - return *(IRFile = FileMgr.createIRFile(FN.c_str())); - } -} - -IPOFile &IPOPartition::getObjFile() const { - if (ObjFile) - return *ObjFile; - else { - std::string FN(FileNameWoExt + ".o"); - return *(ObjFile = FileMgr.createObjFile(FN.c_str())); - } -} - -bool IPOPartition::saveBitCode() { - if (!Mod) { - // The bit-code have already saved in disk. - return true; - } - - IPOFile &F = getIRFile(); - if (F.errOccur()) - return false; - - raw_fd_ostream OF(F.getPath().c_str(), F.getLastErrStr(), - sys::fs::F_Binary); - WriteBitcodeToFile(Mod, OF); - OF.close(); - - Mod = 0; - delete Ctx; - Ctx = 0; - - return !F.errOccur(); -} - -bool IPOPartition::loadBitCode() { - if (Mod) - return true; - - IPOFile &F = getIRFile(); - if (F.errOccur()) - return false; - - Ctx = new LLVMContext; - - error_code &EC = F.getLastErrCode(); - std::string &ErrMsg = F.getLastErrStr(); - - OwningPtr Buf; - if (error_code ec = MemoryBuffer::getFile(F.getPath(), Buf, -1, false)) { - EC = ec; - ErrMsg += ec.message(); - return false; - } - - Mod = ParseBitcodeFile(Buf.get(), *Ctx, &ErrMsg); - - return Mod != 0; -} - -IPOPartition *IPOPartMgr::createIPOPart(Module *M) { - std::string PartName; - raw_string_ostream OS(PartName); - OS << "part" << NextPartId++; - - IPOPartition *P = new IPOPartition(M, OS.str().c_str(), FileMgr); - P->Mod = M; - IPOParts.push_back(P); - return P; -} - -// /////////////////////////////////////////////////////////////////////////// -// -// Implementation of IPOFile and IPOFileMgr -// -// /////////////////////////////////////////////////////////////////////////// -// -IPOFile::IPOFile(const char *DirName, const char *BaseName, bool KeepFile) - : Fname(BaseName), Keep(KeepFile) { - // Concatenate dirname and basename - StringRef D(DirName); - SmallVector Path(D.begin(), D.end()); - sys::path::append(Path, Twine(BaseName)); - Fpath = StringRef(Path.data(), Path.size()); -} - -IPOFileMgr::IPOFileMgr() { - IRFiles.reserve(20); - ObjFiles.reserve(20); - OtherFiles.reserve(8); - KeepWorkDir = false; - WorkDirCreated = false; -} - -bool IPOFileMgr::createWorkDir(std::string &ErrorInfo) { - if (WorkDirCreated) - return true; - - error_code EC; - if (WorkDir.empty()) { - // If the workdir is not specified, then create workdir under current - // directory. - // - SmallString<128> D; - if (sys::fs::current_path(D) != error_code::success()) { - ErrorInfo += "fail to get current directory"; - return false; - } - sys::path::append(D, "llvmipo"); - sys::fs::make_absolute(D); - - SmallVector ResPath; - EC = sys::fs::createUniqueDirectory(Twine(StringRef(D.data(), D.size())), - ResPath); - WorkDir = StringRef(ResPath.data(), ResPath.size()); - } else { - bool Exist; - EC = sys::fs::create_directory(Twine(WorkDir), Exist); - } - - if (EC == error_code::success()) { - WorkDirCreated = true; - return true; - } - - return false; -} - -IPOFile *IPOFileMgr::createIRFile(const char *Name) { - IPOFile *F = CreateFile(Name); - IRFiles.push_back(F); - return F; -} - -IPOFile *IPOFileMgr::createObjFile(const char *Name) { - IPOFile *F = CreateFile(Name); - ObjFiles.push_back(F); - return F; -} - -IPOFile *IPOFileMgr::createMakefile(const char *Name) { - IPOFile *F = CreateFile(Name); - OtherFiles.push_back(F); - return F; -} - -void IPOFileMgr::removeAllUnneededFiles() { - FileNameVect ToRm; - getFilesNeedToRemove(ToRm); - - for (SmallVector::iterator I = ToRm.begin(), E = ToRm.end(); - I != E; I++) { - const char *FN = *I; - sys::fs::file_status Stat; - if (sys::fs::status(Twine(FN), Stat) != error_code::success()) - continue; - - uint32_t Dummy; - if (sys::fs::is_directory(FN)) - sys::fs::remove_all(Twine(FN), Dummy); - else - sys::fs::remove(Twine(FN)); - } -} diff --git a/tools/lto/LTOPartition.h b/tools/lto/LTOPartition.h deleted file mode 100644 index e251555abf..0000000000 --- a/tools/lto/LTOPartition.h +++ /dev/null @@ -1,187 +0,0 @@ -//===-------- LTOPartition.h - Partition related classes and functions ---===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declare the partition related classes and functions. A partition -// is a portion of the merged module. In case partition is disabled, the entire -// merged module is considered as a degenerated partition. -// -// The classes declared in this file are: -// o. IPOPartition : to depicit a partition -// o. IPOFile: It is a "container" collecting miscellaneous information about -// an intermeidate file, including file name, path, last-err-message etc. -// o. IPOPartMgr, IPOFileMgr: as the name suggests, it's the manager of -// IPOPartitions and IPOFiles, respectively. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_PARTITION_H -#define LTO_PARTITION_H - -#include "llvm/Pass.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/Support/system_error.h" - -using namespace llvm; - -namespace lto { - /// \brief To collect miscellaneous information about an intermdiate file. - /// - /// These informration include file name, path, last error message etc. - /// - class IPOFile { - public: - const std::string &getName() { return Fname; } - const std::string &getPath() { return Fpath; } - - error_code &getLastErrCode() { return LastErr; } - std::string &getLastErrStr() { return LastErrStr; } - - bool errOccur() const { - return LastErr != error_code::success() || !LastErrStr.empty(); - } - - // To keep this file after compilation finish. - void setKeep() { Keep = true; } - bool isKept() const { return Keep; } - - private: - friend class IPOFileMgr; - IPOFile(const char* DirName, const char *BaseName, bool Keep=false); - ~IPOFile(); - - private: - std::string Fname; - std::string Fpath; - error_code LastErr; - std::string LastErrStr; - bool Keep; - }; - - /// \brief To manage IPOFiles, create and remove work-directory. - /// - class IPOFileMgr { - public: - typedef SmallVector FileNameVect; - - IPOFileMgr(); - - // NOTE: Do not delete intermeidate in the destructor as we never know - // if these files out-last the class or not. It is safe to let linker's - // clean-up hook to take care these files. - ~IPOFileMgr() {}; - - void setWorkDir(const char* WD) { - assert(!WorkDirCreated /* Too late to change mind */ && - WorkDir.empty() /* don't change back and forth */ && - "Cannot change work dir"); - WorkDir = WD; - } - void setKeepWorkDir(bool Keep) { KeepWorkDir = Keep; } - bool IsToKeepWorkDir() const { return KeepWorkDir; } - const std::string &getWorkDir() { return WorkDir; } - - bool createWorkDir(std::string &ErrorInfo); - - IPOFile *createIRFile(const char *Name); - IPOFile *createObjFile(const char *Name); - IPOFile *createMakefile(const char *Name); - - typedef std::vector FileVect; - FileVect &getIRFiles() { return IRFiles; } - FileVect &getObjFiles() { return ObjFiles; } - - // Get all files/dirs that need to removed after the LTO complete. - void getFilesNeedToRemove(FileNameVect &ToRm) { - ToRm.clear(); - if (!IsToKeepWorkDir() && WorkDirCreated) - ToRm.push_back(WorkDir.c_str()); - } - - // Remove all files/dirs returned from getFilesNeedToRemove(). - void removeAllUnneededFiles(); - - private: - IPOFile *CreateFile(const char *Name) { - return new IPOFile(WorkDir.c_str(), Name); - } - - private: - FileVect IRFiles; - FileVect ObjFiles; - FileVect OtherFiles; - std::string WorkDir; - bool KeepWorkDir; - bool WorkDirCreated; - }; - - /// \brief Describe a partition of the merged module. - /// - class IPOPartition { - public: - llvm::Module *getModule() const { return Mod; } - IPOFile &getIRFile() const; - IPOFile &getObjFile() const; - const std::string &getIRFilePath() const { return getIRFile().getPath(); } - const std::string &getObjFilePath() const { return getObjFile().getPath(); } - - // If the bitcode reside in memory or disk - bool isInMemory() const { return Mod != 0; } - - // Load/store bitcode from/to disk file. - bool saveBitCode(); - bool loadBitCode(); - - private: - friend class IPOPartMgr; - IPOPartition(llvm::Module *M, const char *FileNameWoExt, IPOFileMgr &FM); - - // The module associated with this partition - Module *Mod; - LLVMContext *Ctx; - - // The bitcode file and its corresponding object file associated with - // this partition. The names of these two files are different only in - // extension; the "FileNameWoExt" record their (common) name without - // extension. - // - mutable IPOFile *IRFile; - mutable IPOFile *ObjFile; - std::string FileNameWoExt; - - IPOFileMgr &FileMgr; - }; - - /// \brief To manage IPOPartitions - /// - class IPOPartMgr { - public: - IPOPartMgr(IPOFileMgr &IFM) : FileMgr(IFM), NextPartId(1) {} - - typedef std::vector IPOPartsTy; - typedef IPOPartsTy::iterator iterator; - typedef IPOPartsTy::const_iterator const_iterator; - - iterator begin() { return IPOParts.begin(); } - iterator end() { return IPOParts.end(); } - const_iterator begin() const { return IPOParts.begin(); } - const_iterator end() const { return IPOParts.end(); } - - IPOPartition *createIPOPart(Module *); - IPOPartition *getSinglePartition() { - assert(IPOParts.size() == 1 && "Has multiple partition"); - return IPOParts[0]; - } - - private: - IPOPartsTy IPOParts; - IPOFileMgr &FileMgr; - int NextPartId; - }; - -} - -#endif //LTO_PARTITION_H diff --git a/tools/lto/LTOPostIPODriver.cpp b/tools/lto/LTOPostIPODriver.cpp deleted file mode 100644 index 2bb833a5ca..0000000000 --- a/tools/lto/LTOPostIPODriver.cpp +++ /dev/null @@ -1,180 +0,0 @@ -//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PostIPODriver class which is the driver for Post-IPO -// compilation. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/PassManager.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Transforms/ObjCARC.h" -#include "LTOPartition.h" -#include "LTOPostIPODriver.h" - -using namespace llvm; -using namespace lto; - -// ///////////////////////////////////////////////////////////////////////////// -// -// Declare all variants of Post-IPO drivers -// -// ///////////////////////////////////////////////////////////////////////////// -// -namespace { - /// \breif Base class for all driver variants. - /// - class PostIPODrvBaseImpl { - public: - PostIPODrvBaseImpl(TargetMachine *Targ, IPOPartMgr &IPM, IPOFileMgr &IFM, - bool ToMergeObjs): - PartMgr(IPM), FileMgr(IFM), MergedObjFile(0), Target(Targ), - MergeObjs(ToMergeObjs) {} - - virtual ~PostIPODrvBaseImpl() {}; - - IPOPartMgr &getPartitionMgr() { return PartMgr; } - IPOFileMgr &getFileMgr() { return FileMgr; } - - // Implement the PostIPODriver::getSingleObjFile() - virtual IPOFile *getSingleObjFile() const = 0; - - bool IsToMergeObj() const { return MergeObjs; } - - virtual bool Compile(std::string &ErrMsg) = 0; - - protected: - // Populate post-IPO scalar optimization pass manager - bool PopulatePostIPOOptPM(PassManager &PM); - - // Populate post-IPO machine-specific CodeGen pass manager - bool PopulateCodeGenPM(PassManager &PM, formatted_raw_ostream &OutFile, - std::string &Err); - - protected: - IPOPartMgr &PartMgr; - IPOFileMgr &FileMgr; - IPOFile *MergedObjFile; - TargetMachine *Target; - bool MergeObjs; - }; - - /// \breif PostIPO driver for the compiling the entire program without - /// partition. - class PostIPODrvSerial : public PostIPODrvBaseImpl { - public: - PostIPODrvSerial(TargetMachine *T, IPOPartMgr &IPM, IPOFileMgr &IFM, - bool ToMergeObjs) : - PostIPODrvBaseImpl(T, IPM, IFM, ToMergeObjs) {} - - virtual bool Compile(std::string &ErrMsg); - virtual IPOFile *getSingleObjFile() const; - - private: - Module *getModule() const { return (*PartMgr.begin())->getModule(); } - }; -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODriver -// -// //////////////////////////////////////////////////////////////////////////// -// -PostIPODriver::PostIPODriver(VariantTy V, TargetMachine *TM, IPOPartMgr &IPM, - IPOFileMgr &IFM, bool ToMergeObjs) { - if (V == PIDV_SERIAL) - DrvImpl = new PostIPODrvSerial(TM, IPM, IFM, ToMergeObjs); - else - assert(false && "TBD"); -} - -bool PostIPODriver::Compile(std::string &ErrMsg) { - PostIPODrvBaseImpl *P = static_cast(DrvImpl); - return P->Compile(ErrMsg); -} - -IPOFile *PostIPODriver::getSingleObjFile() const { - PostIPODrvBaseImpl *P = static_cast(DrvImpl); - return P->getSingleObjFile(); -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODrvBaseImpl -// -// //////////////////////////////////////////////////////////////////////////// -// -bool PostIPODrvBaseImpl::PopulatePostIPOOptPM(PassManager &PM) { - (void)PM; - return true; -} - -bool PostIPODrvBaseImpl::PopulateCodeGenPM(PassManager &PM, - formatted_raw_ostream &OutFile, - std::string &Err) { - PM.add(new DataLayout(*Target->getDataLayout())); - Target->addAnalysisPasses(PM); - - // If the bitcode files contain ARC code and were compiled with optimization, - // the ObjCARCContractPass must be run, so do it unconditionally here. - PM.add(createObjCARCContractPass()); - - if (Target->addPassesToEmitFile(PM, OutFile, - TargetMachine::CGFT_ObjectFile)) { - Err = "target file type not supported"; - return false; - } - return true; -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODrvSerial -// -// //////////////////////////////////////////////////////////////////////////// -// -bool PostIPODrvSerial::Compile(std::string &ErrMsg) { - Module *M = getModule(); - - // Step 1: Run the post-IPO scalar optimizations - { - PassManager SoptPM; - PopulatePostIPOOptPM(SoptPM); - SoptPM.run(*M); - } - - // Step 2: Run the post-IPO machine-specific code-generation passes - { - IPOFile &Obj = (*PartMgr.begin())->getObjFile(); - raw_fd_ostream ros(Obj.getPath().c_str(), Obj.getLastErrStr(), - sys::fs::F_Binary); - formatted_raw_ostream OutFile(ros); - - PassManager CodGenPM; - if (!PopulateCodeGenPM(CodGenPM, OutFile, ErrMsg)) { - ErrMsg += Obj.getLastErrStr(); - return false; - } - - CodGenPM.run(*M); - } - - return true; -} - -IPOFile *PostIPODrvSerial::getSingleObjFile() const { - assert(!MergedObjFile && "No need to *merge* a single object file"); - IPOPartition *P = *PartMgr.begin(); - return &P->getObjFile(); -} diff --git a/tools/lto/LTOPostIPODriver.h b/tools/lto/LTOPostIPODriver.h deleted file mode 100644 index 548e732157..0000000000 --- a/tools/lto/LTOPostIPODriver.h +++ /dev/null @@ -1,51 +0,0 @@ -//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declare the PostIPODriver class which is the driver for -// Post-IPO compilation phase. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_POSTIPO_DRIVER_H -#define LTO_POSTIPO_DRIVER_H - -#include "llvm/Target/TargetMachine.h" - -namespace lto { - class IPOPartMgr; - class IPOFileMgr; - class IPOFile; - - class PostIPODriver { - public: - typedef enum { - PIDV_Invalid, - PIDV_SERIAL, // No partition - PIDV_MultiThread, // Each partition is compiled by a thread - PIDV_MultiProc, // Each partition is compiled by a process - PIDV_MakeUtil // Partitions compilation is driven by a make-utility - } VariantTy; - - PostIPODriver(VariantTy Var, TargetMachine *TM, IPOPartMgr &IPM, - IPOFileMgr &IFM, bool ToMergeObjs = false); - - // Return the single resulting object file. If there is no prior - // compilation failure, this function may return NULL iff: - // 1) Partition is enabled, and - // 2) Multiple partitions are generated, and - // 3) It is not asked to merge together the objects corresponding to the - // the partions. - IPOFile *getSingleObjFile() const; - - bool Compile(std::string &ErrMsg); - - private: - void *DrvImpl; - }; -} - -#endif // LTO_POSTIPO_DRIVER_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index c7009d69e1..db7147c2bc 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,19 +207,6 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } -/// Get intermediate files that need to be removed before linker exit. Upon -/// return, the paths of the files need to be removed is written to "paths". The -/// paths are separated by a single '\0', and the last path is ended by double -/// '\0's. A file could be a directory; in this case, the entire directory needs -/// to be removed recursively. -/// -/// It is only necessary to call this function after \p lto_codegen_compile was -/// successfully called. -void -lto_codegen_get_files_need_remove(lto_code_gen_t cg, const char **paths) { - *paths = cg->getFilesNeedToRemove(); -} - /// lto_codegen_debug_options - Used to pass extra options to the code /// generator. void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 41a81dd91f..46d0d74c82 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -20,7 +20,6 @@ lto_codegen_add_must_preserve_symbol lto_codegen_compile lto_codegen_create lto_codegen_dispose -lto_codegen_get_files_need_remove lto_codegen_set_debug_model lto_codegen_set_pic_model lto_codegen_write_merged_modules -- cgit v1.2.3