summaryrefslogtreecommitdiff
path: root/tools/lto/LTOPartition.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lto/LTOPartition.h')
-rw-r--r--tools/lto/LTOPartition.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/tools/lto/LTOPartition.h b/tools/lto/LTOPartition.h
new file mode 100644
index 0000000000..e251555abf
--- /dev/null
+++ b/tools/lto/LTOPartition.h
@@ -0,0 +1,187 @@
+//===-------- 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<const char *, 4> 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<IPOFile *> 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<IPOPartition *> 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