summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-dis/llvm-dis.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-06-21 23:42:48 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-06-21 23:42:48 +0000
commit21521891a2e3492f22455af6c1c1a903a723115c (patch)
treed87dc59fe74622378723f1d795f09c44aacc3789 /llvm/tools/llvm-dis/llvm-dis.cpp
parentbc1570848fd279aff53d37c2da0ade99079526b0 (diff)
downloadbcm5719-llvm-21521891a2e3492f22455af6c1c1a903a723115c.tar.gz
bcm5719-llvm-21521891a2e3492f22455af6c1c1a903a723115c.zip
IR: Allow metadata attachments on declarations, and fix lazy loaded metadata issue with globals.
This change is motivated by an upcoming change to the metadata representation used for CFI. The indirect function call checker needs type information for external function declarations in order to correctly generate jump table entries for such declarations. We currently associate such type information with declarations using a global metadata node, but I plan [1] to move all such metadata to global object attachments. In bitcode, metadata attachments for function declarations appear in the global metadata block. This seems reasonable to me because I expect metadata attachments on declarations to be uncommon. In the long term I'd also expect this to be the case for CFI, because we'd want to use some specialized bitcode format for this metadata that could be read as part of the ThinLTO thin-link phase, which would mean that it would not appear in the global metadata block. To solve the lazy loaded metadata issue I was seeing with D20147, I use the same bitcode representation for metadata attachments for global variables as I do for function declarations. Since there's a use case for metadata attachments in the global metadata block, we might as well use that representation for global variables as well, at least until we have a mechanism for lazy loading global variables. In the assembly format, the metadata attachments appear after the "declare" keyword in order to avoid a parsing ambiguity. [1] http://lists.llvm.org/pipermail/llvm-dev/2016-June/100462.html Differential Revision: http://reviews.llvm.org/D21052 llvm-svn: 273336
Diffstat (limited to 'llvm/tools/llvm-dis/llvm-dis.cpp')
-rw-r--r--llvm/tools/llvm-dis/llvm-dis.cpp63
1 files changed, 45 insertions, 18 deletions
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index 46892b6731a..88333aeb688 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ManagedStatic.h"
@@ -59,6 +60,11 @@ static cl::opt<bool> PreserveAssemblyUseListOrder(
cl::desc("Preserve use-list order when writing LLVM assembly."),
cl::init(false), cl::Hidden);
+static cl::opt<bool>
+ MaterializeMetadata("materialize-metadata",
+ cl::desc("Load module without materializing metadata, "
+ "then materialize only the metadata"));
+
namespace {
static void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) {
@@ -132,6 +138,37 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
exit(1);
}
+static Expected<std::unique_ptr<Module>> openInputFile(LLVMContext &Context) {
+ if (MaterializeMetadata) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFileOrSTDIN(InputFilename);
+ if (!MBOrErr)
+ return errorCodeToError(MBOrErr.getError());
+ ErrorOr<std::unique_ptr<Module>> MOrErr =
+ getLazyBitcodeModule(std::move(*MBOrErr), Context,
+ /*ShouldLazyLoadMetadata=*/true);
+ if (!MOrErr)
+ return errorCodeToError(MOrErr.getError());
+ (*MOrErr)->materializeMetadata();
+ return std::move(*MOrErr);
+ } else {
+ std::string ErrorMessage;
+ std::unique_ptr<DataStreamer> Streamer =
+ getDataFileStreamer(InputFilename, &ErrorMessage);
+ if (!Streamer)
+ return make_error<StringError>(ErrorMessage, inconvertibleErrorCode());
+ std::string DisplayFilename;
+ if (InputFilename == "-")
+ DisplayFilename = "<stdin>";
+ else
+ DisplayFilename = InputFilename;
+ ErrorOr<std::unique_ptr<Module>> MOrErr =
+ getStreamedBitcodeModule(DisplayFilename, std::move(Streamer), Context);
+ (*MOrErr)->materializeAll();
+ return std::move(*MOrErr);
+ }
+}
+
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal(argv[0]);
@@ -144,26 +181,16 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
- std::string ErrorMessage;
- std::unique_ptr<Module> M;
-
- // Use the bitcode streaming interface
- std::unique_ptr<DataStreamer> Streamer =
- getDataFileStreamer(InputFilename, &ErrorMessage);
- if (Streamer) {
- std::string DisplayFilename;
- if (InputFilename == "-")
- DisplayFilename = "<stdin>";
- else
- DisplayFilename = InputFilename;
- ErrorOr<std::unique_ptr<Module>> MOrErr =
- getStreamedBitcodeModule(DisplayFilename, std::move(Streamer), Context);
- M = std::move(*MOrErr);
- M->materializeAll();
- } else {
- errs() << argv[0] << ": " << ErrorMessage << '\n';
+ Expected<std::unique_ptr<Module>> MOrErr = openInputFile(Context);
+ if (!MOrErr) {
+ handleAllErrors(MOrErr.takeError(), [&](ErrorInfoBase &EIB) {
+ errs() << argv[0] << ": ";
+ EIB.log(errs());
+ errs() << '\n';
+ });
return 1;
}
+ std::unique_ptr<Module> M = std::move(*MOrErr);
// Just use stdout. We won't actually print anything on it.
if (DontPrint)
OpenPOWER on IntegriCloud