1 //===-- LTOPartition.cpp - Parition Merged Module --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "LTOPartition.h"
11 #include "llvm/ADT/SetVector.h"
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/Analysis/CallGraph.h"
14 #include "llvm/Bitcode/ReaderWriter.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/MemoryBuffer.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/Transforms/Utils/ValueMapper.h"
22 #include "llvm/Transforms/Utils/Cloning.h"
27 // /////////////////////////////////////////////////////////////////////////////
29 // Implementation of IPOPartition and IPOPartMgr
31 // /////////////////////////////////////////////////////////////////////////////
33 IPOPartition::IPOPartition(Module *M, const char *NameWoExt, IPOFileMgr &FM) :
34 Mod(0), Ctx(0), IRFile(0), ObjFile(0), FileNameWoExt(NameWoExt), FileMgr(FM) {
37 IPOFile &IPOPartition::getIRFile() const {
41 std::string FN(FileNameWoExt + ".bc");
42 return *(IRFile = FileMgr.createIRFile(FN.c_str()));
46 IPOFile &IPOPartition::getObjFile() const {
50 std::string FN(FileNameWoExt + ".o");
51 return *(ObjFile = FileMgr.createObjFile(FN.c_str()));
55 bool IPOPartition::saveBitCode() {
57 // The bit-code have already saved in disk.
61 IPOFile &F = getIRFile();
65 raw_fd_ostream OF(F.getPath().c_str(), F.getLastErrStr(),
67 WriteBitcodeToFile(Mod, OF);
77 bool IPOPartition::loadBitCode() {
81 IPOFile &F = getIRFile();
85 Ctx = new LLVMContext;
87 error_code &EC = F.getLastErrCode();
88 std::string &ErrMsg = F.getLastErrStr();
90 OwningPtr<MemoryBuffer> Buf;
91 if (error_code ec = MemoryBuffer::getFile(F.getPath(), Buf, -1, false)) {
93 ErrMsg += ec.message();
97 Mod = ParseBitcodeFile(Buf.get(), *Ctx, &ErrMsg);
102 IPOPartition *IPOPartMgr::createIPOPart(Module *M) {
103 std::string PartName;
104 raw_string_ostream OS(PartName);
105 OS << "part" << NextPartId++;
107 IPOPartition *P = new IPOPartition(M, OS.str().c_str(), FileMgr);
109 IPOParts.push_back(P);
113 // ///////////////////////////////////////////////////////////////////////////
115 // Implementation of IPOFile and IPOFileMgr
117 // ///////////////////////////////////////////////////////////////////////////
119 IPOFile::IPOFile(const char *DirName, const char *BaseName, bool KeepFile)
120 : Fname(BaseName), Keep(KeepFile) {
121 // Concatenate dirname and basename
122 StringRef D(DirName);
123 SmallVector<char, 64> Path(D.begin(), D.end());
124 sys::path::append(Path, Twine(BaseName));
125 Fpath = StringRef(Path.data(), Path.size());
128 IPOFileMgr::IPOFileMgr() {
130 ObjFiles.reserve(20);
131 OtherFiles.reserve(8);
133 WorkDirCreated = false;
136 bool IPOFileMgr::createWorkDir(std::string &ErrorInfo) {
141 if (WorkDir.empty()) {
142 // If the workdir is not specified, then create workdir under current
146 if (sys::fs::current_path(D) != error_code::success()) {
147 ErrorInfo += "fail to get current directory";
150 sys::path::append(D, "llvmipo");
151 sys::fs::make_absolute(D);
153 SmallVector<char, 64> ResPath;
154 EC = sys::fs::createUniqueDirectory(Twine(StringRef(D.data(), D.size())),
156 WorkDir = StringRef(ResPath.data(), ResPath.size());
159 EC = sys::fs::create_directory(Twine(WorkDir), Exist);
162 if (EC == error_code::success()) {
163 WorkDirCreated = true;
170 IPOFile *IPOFileMgr::createIRFile(const char *Name) {
171 IPOFile *F = CreateFile(Name);
172 IRFiles.push_back(F);
176 IPOFile *IPOFileMgr::createObjFile(const char *Name) {
177 IPOFile *F = CreateFile(Name);
178 ObjFiles.push_back(F);
182 IPOFile *IPOFileMgr::createMakefile(const char *Name) {
183 IPOFile *F = CreateFile(Name);
184 OtherFiles.push_back(F);
188 void IPOFileMgr::removeAllUnneededFiles() {
190 getFilesNeedToRemove(ToRm);
192 for (SmallVector<const char *, 4>::iterator I = ToRm.begin(), E = ToRm.end();
195 sys::fs::file_status Stat;
196 if (sys::fs::status(Twine(FN), Stat) != error_code::success())
200 if (sys::fs::is_directory(FN))
201 sys::fs::remove_all(Twine(FN), Dummy);
203 sys::fs::remove(Twine(FN));