OSDN Git Service

[llc] New diagnostic handler
authorRenato Golin <renato.golin@linaro.org>
Sat, 14 May 2016 13:15:22 +0000 (13:15 +0000)
committerRenato Golin <renato.golin@linaro.org>
Sat, 14 May 2016 13:15:22 +0000 (13:15 +0000)
Without a diagnostic handler installed, llc's behaviour is to exit on the first
error that it encounters. This is very different from the behaviour of clang
and other front ends, which try to gather as many errors as possible before
exiting.

This commit adds a diagnostic handler to llc, allowing it to find and report
more than one error. The old behaviour is preserved under a flag (-exit-on-error).

Some of the tests fail with the new diagnostic handler, so they have to use the
new flag in order to run under the previous behaviour. Some of these are known
bugs, others need further investigation. Ideally, we should fix the tests and
remove the flag at some point in the future.

Reapplied after fixing the LLDB build that was broken due to the new
DiagnosticSeverity in LLVMContext.h.

Patch by Diana Picus.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269563 91177308-0d34-0410-b5e6-96231b3b80d8

31 files changed:
include/llvm/IR/DiagnosticInfo.h
include/llvm/IR/LLVMContext.h
lib/IR/LLVMContext.cpp
test/CodeGen/AArch64/arm64-inline-asm-error-I.ll
test/CodeGen/AArch64/arm64-inline-asm-error-J.ll
test/CodeGen/AArch64/arm64-inline-asm-error-K.ll
test/CodeGen/AArch64/arm64-inline-asm-error-L.ll
test/CodeGen/AArch64/arm64-inline-asm-error-M.ll
test/CodeGen/AArch64/arm64-inline-asm-error-N.ll
test/CodeGen/AMDGPU/call.ll
test/CodeGen/AMDGPU/dynamic_stackalloc.ll
test/CodeGen/AMDGPU/no-hsa-graphics-shaders.ll
test/CodeGen/AMDGPU/private-memory-broken.ll
test/CodeGen/AMDGPU/promote-alloca-bitcast-function.ll
test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
test/CodeGen/BPF/many_args1.ll
test/CodeGen/BPF/many_args2.ll
test/CodeGen/BPF/struct_ret1.ll
test/CodeGen/BPF/struct_ret2.ll
test/CodeGen/MIR/Generic/invalid-jump-table-kind.mir
test/CodeGen/MIR/Generic/llvm-ir-error-reported.mir
test/CodeGen/MIR/Generic/machine-function-missing-function.mir
test/CodeGen/MIR/Generic/machine-function-missing-name.mir
test/CodeGen/MIR/Generic/machine-function-redefinition-error.mir
test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-aliased.mir
test/CodeGen/MIR/X86/spill-slot-fixed-stack-object-immutable.mir
test/CodeGen/MIR/X86/variable-sized-stack-object-size-error.mir
test/CodeGen/PowerPC/crbit-asm-disabled.ll
test/CodeGen/PowerPC/vec-asm-disabled.ll
test/CodeGen/X86/asm-reject-reg-type-mismatch.ll
tools/llc/llc.cpp

index 78d7de2..9e5bb2b 100644 (file)
@@ -34,7 +34,7 @@ class Module;
 class SMDiagnostic;
 
 /// \brief Defines the different supported severity of a diagnostic.
-enum DiagnosticSeverity {
+enum DiagnosticSeverity : char {
   DS_Error,
   DS_Warning,
   DS_Remark,
index 8f13171..c199918 100644 (file)
@@ -29,6 +29,7 @@ class MDString;
 class DICompositeType;
 class SMDiagnostic;
 class DiagnosticInfo;
+enum DiagnosticSeverity : char;
 template <typename T> class SmallVectorImpl;
 class Function;
 class DebugLoc;
@@ -172,6 +173,10 @@ public:
   /// setDiagnosticContext.
   void *getDiagnosticContext() const;
 
+  /// \brief Get the prefix that should be printed in front of a diagnostic of
+  ///        the given \p Severity
+  static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity);
+
   /// \brief Report a message to the currently installed diagnostic handler.
   ///
   /// This function returns, in particular in the case of error reporting
index 9369cbd..9f8680c 100644 (file)
@@ -231,7 +231,8 @@ static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
   return true;
 }
 
-static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
+const char *
+LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
   switch (Severity) {
   case DS_Error:
     return "error";
index a7aaf9e..ec4934a 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index 077e1b8..a155c14 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index 2a7f961..99b88b8 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index 1701943..b8afc9b 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index 952bf60..7586750 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index b4a199f..32c7d32 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=arm64 < %s  2> %t
+; RUN: not llc -march=arm64 -exit-on-error < %s  2> %t
 ; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
 
 ; Check for at least one invalid constant.
index 82e7735..168952c 100644 (file)
@@ -1,6 +1,6 @@
-; RUN: not llc -march=amdgcn -mcpu=SI -verify-machineinstrs< %s 2>&1 | FileCheck %s
-; RUN: not llc -march=amdgcn -mcpu=tonga -verify-machineinstrs< %s 2>&1 | FileCheck %s
-; RUN: not llc -march=r600 -mcpu=cypress < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=SI -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tonga -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=r600 -mcpu=cypress -exit-on-error < %s 2>&1 | FileCheck %s
 
 ; CHECK: in function test_call_external{{.*}}: unsupported call to function external_function
 
index 580dc00..5d23056 100644 (file)
@@ -1,6 +1,6 @@
-; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=+promote-alloca -verify-machineinstrs < %s 2>&1 | FileCheck %s
-; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -verify-machineinstrs < %s 2>&1 | FileCheck %s
-; RUN: not llc -march=r600 -mcpu=cypress < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=+promote-alloca -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -verify-machineinstrs -exit-on-error < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=r600 -mcpu=cypress -exit-on-error < %s 2>&1 | FileCheck %s
 
 ; CHECK: in function test_dynamic_stackalloc{{.*}}: unsupported dynamic alloca
 
index 0a7cd57..e6f51fa 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=amdgcn -mtriple=amdgcn-unknown-amdhsa < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mtriple=amdgcn-unknown-amdhsa -exit-on-error < %s 2>&1 | FileCheck %s
 
 ; CHECK: in function pixel_s{{.*}}: unsupported non-compute shaders with HSA
 define amdgpu_ps void @pixel_shader() #0 {
index 6b18a19..17a54c7 100644 (file)
@@ -1,5 +1,5 @@
-; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=SI %s -o /dev/null 2>&1 | FileCheck %s
-; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=tonga %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=SI -exit-on-error %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -verify-machineinstrs -march=amdgcn -mcpu=tonga -exit-on-error %s -o /dev/null 2>&1 | FileCheck %s
 
 ; Make sure promote alloca pass doesn't crash
 
index 6090017..095996d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=amdgcn < %s 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -exit-on-error < %s 2>&1 | FileCheck %s
 
 ; Make sure that AMDGPUPromoteAlloca doesn't crash if the called
 ; function is a constantexpr cast of a function.
index b47247c..170c09f 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=arm-eabi -mcpu=cortex-a8 -exit-on-error %s -o - 2>&1 | FileCheck %s
 
 ; Check for error message:
 ; CHECK: scalar-to-vector conversion failed, possible invalid constraint for vector type
index 08218f4..a5500da 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=bpf < %s 2> %t1
+; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1
 ; RUN: FileCheck %s < %t1
 ; CHECK: too many args
 
index a69886c..08a1179 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=bpf < %s 2> %t1
+; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1
 ; RUN: FileCheck %s < %t1
 ; CHECK: too many args
 
index 29486b5..c6d3f89 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=bpf < %s 2> %t1
+; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1
 ; RUN: FileCheck %s < %t1
 ; CHECK: only integer returns
 
index 9046120..5266efe 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -march=bpf < %s 2> %t1
+; RUN: not llc -march=bpf -exit-on-error < %s 2> %t1
 ; RUN: FileCheck %s < %t1
 ; CHECK: only small returns
 
index 576de4b..04e5606 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 
 --- |
 
index 3508c34..e404b26 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 # This test ensures an error is reported if the embedded LLVM IR contains an
 # error.
 
index 6800f87..128a987 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 # This test ensures that an error is reported when the mir file has LLVM IR and
 # one of the machine functions has a name that doesn't match any function in
 # the LLVM IR.
index f65b778..150b923 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 # This test ensures that an error is reported when a machine function doesn't
 # have a name attribute.
 
index be84161..57f3834 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 # This test ensures that the machine function errors are reported correctly.
 
 ---
index b62cd75..f0bb16d 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 
 --- |
 
index c89216b..b07a961 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 
 --- |
 
index e6a9ef8..d348cbe 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 --- |
 
   define i32 @test(i32 %a) {
index 56ec8ec..e05b09f 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -mcpu=pwr7 -o /dev/null %s 2>&1 | FileCheck %s
+; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
index 333ccce..6e4176e 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -mcpu=pwr7 -o /dev/null %s 2>&1 | FileCheck %s
+; RUN: not llc -mcpu=pwr7 -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 target datalayout = "E-m:e-i64:64-n32:64"
 target triple = "powerpc64-unknown-linux-gnu"
 
index c7e86f5..77f8ac4 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: not llc -o /dev/null %s 2>&1 | FileCheck %s
+; RUN: not llc -exit-on-error -o /dev/null %s 2>&1 | FileCheck %s
 target triple = "x86_64--"
 
 ; CHECK: error: couldn't allocate output register for constraint '{ax}'
index e219c94..252952b 100644 (file)
@@ -25,6 +25,8 @@
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -111,6 +113,11 @@ static cl::opt<bool> DiscardValueNames(
     cl::desc("Discard names from Value (other than GlobalValue)."),
     cl::init(false), cl::Hidden);
 
+static cl::opt<bool> ExitOnError(
+    "exit-on-error",
+    cl::desc("Exit as soon as an error is encountered."),
+    cl::init(false), cl::Hidden);
+
 static int compileModule(char **, LLVMContext &);
 
 static std::unique_ptr<tool_output_file>
@@ -181,6 +188,17 @@ GetOutputStream(const char *TargetName, Triple::OSType OS,
   return FDOut;
 }
 
+static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
+  bool *HasError = static_cast<bool *>(Context);
+  if (DI.getSeverity() == DS_Error)
+    *HasError = true;
+
+  DiagnosticPrinterRawOStream DP(errs());
+  errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
+  DI.print(DP);
+  errs() << "\n";
+}
+
 // main - Entry point for the llc compiler.
 //
 int main(int argc, char **argv) {
@@ -215,6 +233,12 @@ int main(int argc, char **argv) {
 
   Context.setDiscardValueNames(DiscardValueNames);
 
+  // Set a diagnostic handler that doesn't exit on the first error
+  if (!ExitOnError) {
+    bool HasError = false;
+    Context.setDiagnosticHandler(DiagnosticHandler, &HasError);
+  }
+
   // Compile the module TimeCompilations times to give better compile time
   // metrics.
   for (unsigned I = TimeCompilations; I; --I)
@@ -441,6 +465,12 @@ static int compileModule(char **argv, LLVMContext &Context) {
 
     PM.run(*M);
 
+    if (!ExitOnError) {
+      auto HasError = *static_cast<bool *>(Context.getDiagnosticContext());
+      if (HasError)
+        return 1;
+    }
+
     // Compare the two outputs and make sure they're the same
     if (CompileTwice) {
       if (Buffer.size() != CompileTwiceBuffer.size() ||