#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
-#include "llvm/IR/FunctionInfo.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
-#include "llvm/Object/FunctionIndexObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
cl::desc(
"input bitcode file which can override previously defined symbol(s)"));
-// Option to simulate function importing for testing. This enables using
-// llvm-link to simulate ThinLTO backend processes.
-static cl::list<std::string> Imports(
- "import", cl::ZeroOrMore, cl::value_desc("function:filename"),
- cl::desc("Pair of function name and filename, where function should be "
- "imported from bitcode in filename"));
-
-// Option to support testing of function importing. The function index
-// must be specified in the case were we request imports via the -import
-// option, as well as when compiling any module with functions that may be
-// exported (imported by a different llvm-link -import invocation), to ensure
-// consistent promotion and renaming of locals.
-static cl::opt<std::string> FunctionIndex("functionindex",
- cl::desc("Function index filename"),
- cl::init(""),
- cl::value_desc("filename"));
-
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
cl::value_desc("filename"));
errs() << '\n';
}
-/// Load a function index if requested by the -functionindex option.
-static ErrorOr<std::unique_ptr<FunctionInfoIndex>>
-loadIndex(LLVMContext &Context, const Module *ExportingModule = nullptr) {
- assert(!FunctionIndex.empty());
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFileOrSTDIN(FunctionIndex);
- std::error_code EC = FileOrErr.getError();
- if (EC)
- return EC;
- MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
- ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
- object::FunctionIndexObjectFile::create(BufferRef, Context,
- ExportingModule);
- EC = ObjOrErr.getError();
- if (EC)
- return EC;
-
- object::FunctionIndexObjectFile &Obj = **ObjOrErr;
- return Obj.takeIndex();
-}
-
-/// Import any functions requested via the -import option.
-static bool importFunctions(const char *argv0, LLVMContext &Context,
- Linker &L) {
- for (const auto &Import : Imports) {
- // Identify the requested function and its bitcode source file.
- size_t Idx = Import.find(':');
- if (Idx == std::string::npos) {
- errs() << "Import parameter bad format: " << Import << "\n";
- return false;
- }
- std::string FunctionName = Import.substr(0, Idx);
- std::string FileName = Import.substr(Idx + 1, std::string::npos);
-
- // Load the specified source module.
- std::unique_ptr<Module> M = loadFile(argv0, FileName, Context);
- if (!M.get()) {
- errs() << argv0 << ": error loading file '" << FileName << "'\n";
- return false;
- }
-
- if (verifyModule(*M, &errs())) {
- errs() << argv0 << ": " << FileName
- << ": error: input module is broken!\n";
- return false;
- }
-
- Function *F = M->getFunction(FunctionName);
- if (!F) {
- errs() << "Ignoring import request for non-existent function "
- << FunctionName << " from " << FileName << "\n";
- continue;
- }
- // We cannot import weak_any functions without possibly affecting the
- // order they are seen and selected by the linker, changing program
- // semantics.
- if (F->hasWeakAnyLinkage()) {
- errs() << "Ignoring import request for weak-any function " << FunctionName
- << " from " << FileName << "\n";
- continue;
- }
-
- if (Verbose)
- errs() << "Importing " << FunctionName << " from " << FileName << "\n";
-
- std::unique_ptr<FunctionInfoIndex> Index;
- if (!FunctionIndex.empty()) {
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
- loadIndex(Context);
- std::error_code EC = IndexOrErr.getError();
- if (EC) {
- errs() << EC.message() << '\n';
- return false;
- }
- Index = std::move(IndexOrErr.get());
- }
-
- // Link in the specified function.
- if (L.linkInModule(M.get(), false, Index.get(), F))
- return false;
- }
- return true;
-}
-
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
const cl::list<std::string> &Files,
unsigned Flags) {
return false;
}
- // If a function index is supplied, load it so linkInModule can treat
- // local functions/variables as exported and promote if necessary.
- std::unique_ptr<FunctionInfoIndex> Index;
- if (!FunctionIndex.empty()) {
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
- loadIndex(Context, &*M);
- std::error_code EC = IndexOrErr.getError();
- if (EC) {
- errs() << EC.message() << '\n';
- return false;
- }
- Index = std::move(IndexOrErr.get());
- }
-
if (Verbose)
errs() << "Linking in '" << File << "'\n";
- if (L.linkInModule(M.get(), ApplicableFlags, Index.get()))
+ if (L.linkInModule(M.get(), ApplicableFlags))
return false;
// All linker flags apply to linking of subsequent files.
ApplicableFlags = Flags;
Flags | Linker::Flags::OverrideFromSrc))
return 1;
- // Import any functions requested via -import
- if (!importFunctions(argv[0], Context, L))
- return 1;
-
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
std::error_code EC;