summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm-c/lto.h50
-rw-r--r--llvm/include/llvm/LTO/legacy/LTOModule.h11
-rw-r--r--llvm/lib/LTO/LTOModule.cpp32
-rw-r--r--llvm/test/LTO/X86/Inputs/list-dependent-libraries.ll6
-rw-r--r--llvm/test/LTO/X86/list-dependent-libraries.ll18
-rw-r--r--llvm/test/tools/llvm-lto/error.ll3
-rw-r--r--llvm/tools/llvm-lto/llvm-lto.cpp43
-rw-r--r--llvm/tools/lto/lto.cpp25
-rw-r--r--llvm/tools/lto/lto.exports4
9 files changed, 166 insertions, 26 deletions
diff --git a/llvm/include/llvm-c/lto.h b/llvm/include/llvm-c/lto.h
index 5a33898d0f8..2467722b195 100644
--- a/llvm/include/llvm-c/lto.h
+++ b/llvm/include/llvm-c/lto.h
@@ -298,14 +298,6 @@ extern const char*
lto_module_get_linkeropts(lto_module_t mod);
/**
-* Returns the module's dependent library specifiers.
-*
-* \since LTO_API_VERSION=24
-*/
-extern const char*
-lto_module_get_dependent_libraries(lto_module_t mod);
-
-/**
* Diagnostic severity.
*
* \since LTO_API_VERSION=7
@@ -854,7 +846,47 @@ thinlto_codegen_set_cache_size_megabytes(thinlto_code_gen_t cg,
extern void thinlto_codegen_set_cache_size_files(thinlto_code_gen_t cg,
unsigned max_size_files);
-
+/** Opaque reference to an LTO input file */
+typedef struct LLVMOpaqueLTOInput *lto_input_t;
+
+/**
+ * Creates an LTO input file from a buffer. The path
+ * argument is used for diagnotics as this function
+ * otherwise does not know which file the given buffer
+ * is associated with.
+ *
+ * \since LTO_API_VERSION=24
+ */
+extern lto_input_t lto_input_create(const void *buffer,
+ size_t buffer_size,
+ const char *path);
+
+/**
+ * Frees all memory internally allocated by the LTO input file.
+ * Upon return the lto_module_t is no longer valid.
+ *
+ * \since LTO_API_VERSION=24
+ */
+extern void lto_input_dispose(lto_input_t input);
+
+/**
+ * Returns the number of dependent library specifiers
+ * for the given LTO input file.
+ *
+ * \since LTO_API_VERSION=24
+ */
+extern unsigned lto_input_get_num_dependent_libraries(lto_input_t input);
+
+/**
+ * Returns the ith dependent library specifier
+ * for the given LTO input file. The returned
+ * string is not null-terminated.
+ *
+ * \since LTO_API_VERSION=24
+ */
+extern const char * lto_input_get_dependent_library(lto_input_t input,
+ size_t index,
+ size_t *size);
/**
* @} // endgroup LLVMCTLTO_CACHING
diff --git a/llvm/include/llvm/LTO/legacy/LTOModule.h b/llvm/include/llvm/LTO/legacy/LTOModule.h
index 89d8682a207..84b9b8c0294 100644
--- a/llvm/include/llvm/LTO/legacy/LTOModule.h
+++ b/llvm/include/llvm/LTO/legacy/LTOModule.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/Module.h"
+#include "llvm/LTO/LTO.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Target/TargetMachine.h"
@@ -155,13 +156,19 @@ public:
StringRef getLinkerOpts() { return LinkerOpts; }
- StringRef getDependentLibraries() { return DependentLibraries; }
-
const std::vector<StringRef> &getAsmUndefinedRefs() { return _asm_undefines; }
+ static lto::InputFile *createInputFile(const void *buffer, size_t buffer_size,
+ const char *path, std::string &out_error);
+
+ static size_t getDependentLibraryCount(lto::InputFile *input);
+
+ static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
+
private:
/// Parse metadata from the module
// FIXME: it only parses "llvm.linker.options" metadata at the moment
+ // FIXME: can't access metadata in lazily loaded modules
void parseMetadata();
/// Parse the symbols from the module and model-level ASM and add them to
diff --git a/llvm/lib/LTO/LTOModule.cpp b/llvm/lib/LTO/LTOModule.cpp
index 83e9a09854c..a27c78d2595 100644
--- a/llvm/lib/LTO/LTOModule.cpp
+++ b/llvm/lib/LTO/LTOModule.cpp
@@ -645,10 +645,32 @@ void LTOModule::parseMetadata() {
continue;
emitLinkerFlagsForGlobalCOFF(OS, Sym.symbol, TT, M);
}
+}
+
+lto::InputFile *LTOModule::createInputFile(const void *buffer,
+ size_t buffer_size, const char *path,
+ std::string &outErr) {
+ StringRef Data((const char *)buffer, buffer_size);
+ MemoryBufferRef BufferRef(Data, path);
+
+ Expected<std::unique_ptr<lto::InputFile>> ObjOrErr =
+ lto::InputFile::create(BufferRef);
+
+ if (ObjOrErr)
+ return ObjOrErr->release();
+
+ outErr = std::string(path) +
+ ": Could not read LTO input file: " + toString(ObjOrErr.takeError());
+ return nullptr;
+}
+
+size_t LTOModule::getDependentLibraryCount(lto::InputFile *input) {
+ return input->getDependentLibraries().size();
+}
- // Dependent Libraries
- raw_string_ostream OSD(DependentLibraries);
- if (NamedMDNode *DependentLibraries = getModule().getNamedMetadata("llvm.dependent-libraries"))
- for (MDNode *N : DependentLibraries->operands())
- OSD << " " << cast<MDString>(N->getOperand(0))->getString();
+const char *LTOModule::getDependentLibrary(lto::InputFile *input, size_t index,
+ size_t *size) {
+ StringRef S = input->getDependentLibraries()[index];
+ *size = S.size();
+ return S.data();
}
diff --git a/llvm/test/LTO/X86/Inputs/list-dependent-libraries.ll b/llvm/test/LTO/X86/Inputs/list-dependent-libraries.ll
new file mode 100644
index 00000000000..f40a550021b
--- /dev/null
+++ b/llvm/test/LTO/X86/Inputs/list-dependent-libraries.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+!llvm.dependent-libraries = !{!0, !1, !0}
+
+!0 = !{!"foo"}
+!1 = !{!"b a r"}
diff --git a/llvm/test/LTO/X86/list-dependent-libraries.ll b/llvm/test/LTO/X86/list-dependent-libraries.ll
new file mode 100644
index 00000000000..f2bf27fa62b
--- /dev/null
+++ b/llvm/test/LTO/X86/list-dependent-libraries.ll
@@ -0,0 +1,18 @@
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: llvm-as -o %t/1.bc %s
+; RUN: llvm-as -o %t/2.bc %S/Inputs/list-dependent-libraries.ll
+; RUN: llvm-lto -list-dependent-libraries-only %t/1.bc %t/2.bc | FileCheck %s
+; REQUIRES: default_triple
+
+; CHECK: 1.bc:
+; CHECK-NEXT: wibble
+; CHECK: 2.bc:
+; CHECK-NEXT: foo
+; CHECK-NEXT: b a r
+; CHECK-NEXT: foo
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+!llvm.dependent-libraries = !{!0}
+
+!0 = !{!"wibble"}
diff --git a/llvm/test/tools/llvm-lto/error.ll b/llvm/test/tools/llvm-lto/error.ll
index 96bd56664c2..b7f45dc6cf2 100644
--- a/llvm/test/tools/llvm-lto/error.ll
+++ b/llvm/test/tools/llvm-lto/error.ll
@@ -4,5 +4,8 @@
; RUN: not llvm-lto --list-symbols-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIST
; CHECK-LIST: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': The file was not recognized as a valid object file
+; RUN: not llvm-lto --list-dependent-libraries-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIBS
+; CHECK-LIBS: llvm-lto: {{.*}}/Inputs/empty.bc: Could not read LTO input file: The file was not recognized as a valid object file
+
; RUN: not llvm-lto --thinlto %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-THIN
; CHECK-THIN: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': Invalid bitcode signature
diff --git a/llvm/tools/llvm-lto/llvm-lto.cpp b/llvm/tools/llvm-lto/llvm-lto.cpp
index 9aabe0a4282..585207b2518 100644
--- a/llvm/tools/llvm-lto/llvm-lto.cpp
+++ b/llvm/tools/llvm-lto/llvm-lto.cpp
@@ -204,6 +204,10 @@ static cl::opt<bool> ListSymbolsOnly(
"list-symbols-only", cl::init(false),
cl::desc("Instead of running LTO, list the symbols in each IR file"));
+static cl::opt<bool> ListDependentLibrariesOnly(
+ "list-dependent-libraries-only", cl::init(false),
+ cl::desc("Instead of running LTO, list the dependent libraries in each IR file"));
+
static cl::opt<bool> SetMergedModule(
"set-merged-module", cl::init(false),
cl::desc("Use the first input module as the merged module"));
@@ -372,6 +376,34 @@ static void listSymbols(const TargetOptions &Options) {
}
}
+static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
+ ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
+ "': ");
+ return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
+}
+
+static void listDependentLibraries() {
+ for (auto &Filename : InputFilenames) {
+ auto Buffer = loadFile(Filename);
+ std::string E;
+ std::unique_ptr<lto::InputFile> Input(LTOModule::createInputFile(
+ Buffer->getBufferStart(), Buffer->getBufferSize(), Filename.c_str(),
+ E));
+ if (!Input)
+ error(E);
+
+ // List the dependent libraries.
+ outs() << Filename << ":\n";
+ for (size_t I = 0, C = LTOModule::getDependentLibraryCount(Input.get());
+ I != C; ++I) {
+ size_t L = 0;
+ const char *S = LTOModule::getDependentLibrary(Input.get(), I, &L);
+ assert(S);
+ outs() << StringRef(S, L) << "\n";
+ }
+ }
+}
+
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
@@ -449,12 +481,6 @@ std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
}
-static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
- ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
- "': ");
- return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
-}
-
static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
ExitOnError ExitOnErr("llvm-lto: error loading input '" +
Buffer.getBufferIdentifier().str() + "': ");
@@ -854,6 +880,11 @@ int main(int argc, char **argv) {
return 0;
}
+ if (ListDependentLibrariesOnly) {
+ listDependentLibraries();
+ return 0;
+ }
+
if (IndexStats) {
printIndexStats();
return 0;
diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp
index 01dc141ffd0..fc2d3da43c0 100644
--- a/llvm/tools/lto/lto.cpp
+++ b/llvm/tools/lto/lto.cpp
@@ -18,6 +18,7 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/LTO/LTO.h"
#include "llvm/LTO/legacy/LTOCodeGenerator.h"
#include "llvm/LTO/legacy/LTOModule.h"
#include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
@@ -325,10 +326,6 @@ const char* lto_module_get_linkeropts(lto_module_t mod) {
return unwrap(mod)->getLinkerOpts().data();
}
-const char* lto_module_get_dependent_libraries(lto_module_t mod) {
- return unwrap(mod)->getDependentLibraries().data();
-}
-
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
lto_diagnostic_handler_t diag_handler,
void *ctxt) {
@@ -635,3 +632,23 @@ lto_bool_t thinlto_codegen_set_pic_model(thinlto_code_gen_t cg,
sLastErrorString = "Unknown PIC model";
return true;
}
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(lto::InputFile, lto_input_t)
+
+lto_input_t lto_input_create(const void *buffer, size_t buffer_size, const char *path) {
+ return wrap(LTOModule::createInputFile(buffer, buffer_size, path, sLastErrorString));
+}
+
+void lto_input_dispose(lto_input_t input) {
+ delete unwrap(input);
+}
+
+extern unsigned lto_input_get_num_dependent_libraries(lto_input_t input) {
+ return LTOModule::getDependentLibraryCount(unwrap(input));
+}
+
+extern const char *lto_input_get_dependent_library(lto_input_t input,
+ size_t index,
+ size_t *size) {
+ return LTOModule::getDependentLibrary(unwrap(input), index, size);
+}
diff --git a/llvm/tools/lto/lto.exports b/llvm/tools/lto/lto.exports
index cb881d104fb..34922c820d6 100644
--- a/llvm/tools/lto/lto.exports
+++ b/llvm/tools/lto/lto.exports
@@ -72,3 +72,7 @@ thinlto_codegen_disable_codegen
thinlto_module_get_num_object_files
thinlto_module_get_object_file
thinlto_set_generated_objects_dir
+lto_input_create
+lto_input_destroy
+lto_input_get_num_dependent_libraries
+lto_input_get_dependent_library
OpenPOWER on IntegriCloud