diff options
author | Peter Waller <peter.waller@arm.com> | 2024-05-07 09:13:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-07 09:13:44 +0100 |
commit | 1de0535e84f03941badc8021bbc87a8c674a379f (patch) | |
tree | f808c6fe778fb77c759a3ba6a2c91806993e2e3c | |
parent | f3fbd21fa4e25496725c22d987e4e47e4c39c8b0 (diff) | |
download | llvm-1de0535e84f03941badc8021bbc87a8c674a379f.zip llvm-1de0535e84f03941badc8021bbc87a8c674a379f.tar.gz llvm-1de0535e84f03941badc8021bbc87a8c674a379f.tar.bz2 |
[llvm-mca] Abort on parse error without -skip-unsupported-instructions (#90474)
[llvm-mca] Abort on parse error without -skip-unsupported-instructions
Prior to this patch, llvm-mca would continue executing after parse
errors. These errors can lead to some confusion since some analysis
results are printed on the standard output, and they're printed after
the errors, which could otherwise be easy to miss.
However it is still useful to be able to continue analysis after errors;
so extend the recently added -skip-unsupported-instructions to support
this.
Two tests which have parse errors for some of the 'RUN' branches are
updated to use -skip-unsupported-instructions so they can remain as-is.
Add a description of -skip-unsupported-instructions to the llvm-mca
command guide, and add it to the llvm-mca --help output:
```
--skip-unsupported-instructions=<value> - Force analysis to continue in the presence of unsupported instructions
=none - Exit with an error when an instruction is unsupported for any reason (default)
=lack-sched - Skip instructions on input which lack scheduling information
=parse-failure - Skip lines on the input which fail to parse for any reason
=any - Skip instructions or lines on input which are unsupported for any reason
```
Tests within this patch are intended to cover each of the cases.
Reason | Flag | Comment
--------------|------|-------
none | none | Usual case, existing test suite
lack-sched | none | Advises user to use -skip-unsupported-instructions=lack-sched, tested in llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s
parse-failure | none | Advises user to use -skip-unsupported-instructions=parse-failure, tested in llvm/test/tools/llvm-mca/bad-input.s
any | none | (N/A, covered above)
lack-sched | any | Continues, prints warnings, tested in llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s
parse-failure | any | Continues, prints errors, tested in llvm/test/tools/llvm-mca/bad-input.s
lack-sched | parse-failure | Advises user to use -skip-unsupported-instructions=lack-sched, tested in llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s
parse-failure | lack-sched | Advises user to use -skip-unsupported-instructions=parse-failure, tested in llvm/test/tools/llvm-mca/bad-input.s
none | * | This would be any test case with skip-unsupported-instructions, coverage added in llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s
any | * | (Logically covered by the other cases)
-rw-r--r-- | llvm/docs/CommandGuide/llvm-mca.rst | 10 | ||||
-rw-r--r-- | llvm/docs/ReleaseNotes.rst | 8 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/AArch64/Exynos/float-divide-multiply.s | 2 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/AArch64/Exynos/float-integer.s | 2 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s | 1 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/ARM/cortex-a57-thumb.s | 27 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s | 3 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s | 4 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s | 9 | ||||
-rw-r--r-- | llvm/test/tools/llvm-mca/bad-input.s | 14 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/CodeRegionGenerator.cpp | 13 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/CodeRegionGenerator.h | 34 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/llvm-mca.cpp | 47 |
13 files changed, 138 insertions, 36 deletions
diff --git a/llvm/docs/CommandGuide/llvm-mca.rst b/llvm/docs/CommandGuide/llvm-mca.rst index eae5e14..f610ea2 100644 --- a/llvm/docs/CommandGuide/llvm-mca.rst +++ b/llvm/docs/CommandGuide/llvm-mca.rst @@ -234,6 +234,16 @@ option specifies "``-``", then the output will also be sent to standard output. no extra information, and InstrumentManager never overrides the default schedule class for a given instruction. +.. option:: -skip-unsupported-instructions=<reason> + + Force :program:`llvm-mca` to continue in the presence of instructions which do + not parse or lack key scheduling information. Note that the resulting analysis + is impacted since those unsupported instructions are ignored as-if they are + not supplied as a part of the input. + + The choice of `<reason>` controls the when mca will report an error. + `<reason>` may be `none` (default), `lack-sched`, `parse-failure`, `any`. + EXIT STATUS ----------- diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 0f4e275..3cf65aa 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -223,6 +223,14 @@ Changes to the LLVM tools (`#89162 <https://github.com/llvm/llvm-project/pull/89162>`_) ``--raw-relr`` has been removed. +* llvm-mca now aborts by default if it is given bad input where previously it + would continue. Additionally, it can now continue when it encounters + instructions which lack scheduling information. The behaviour can be + controlled by the newly introduced + `--skip-unsupported-instructions=<none|lack-sched|parse-failure|any>`, as + documented in `--help` output and the command guide. (`#90474 + <https://github.com/llvm/llvm-project/pull/90474>`) + Changes to LLDB --------------------------------- diff --git a/llvm/test/tools/llvm-mca/AArch64/Exynos/float-divide-multiply.s b/llvm/test/tools/llvm-mca/AArch64/Exynos/float-divide-multiply.s index ecfd019..271bd83 100644 --- a/llvm/test/tools/llvm-mca/AArch64/Exynos/float-divide-multiply.s +++ b/llvm/test/tools/llvm-mca/AArch64/Exynos/float-divide-multiply.s @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py -# RUN: llvm-mca -march=aarch64 -mcpu=exynos-m3 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM3 +# RUN: llvm-mca -march=aarch64 -mcpu=exynos-m3 -resource-pressure=false -skip-unsupported-instructions=parse-failure < %s | FileCheck %s -check-prefixes=ALL,EM3 # RUN: llvm-mca -march=aarch64 -mcpu=exynos-m4 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM4 # RUN: llvm-mca -march=aarch64 -mcpu=exynos-m5 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM5 diff --git a/llvm/test/tools/llvm-mca/AArch64/Exynos/float-integer.s b/llvm/test/tools/llvm-mca/AArch64/Exynos/float-integer.s index 16c7105..f95e530 100644 --- a/llvm/test/tools/llvm-mca/AArch64/Exynos/float-integer.s +++ b/llvm/test/tools/llvm-mca/AArch64/Exynos/float-integer.s @@ -1,5 +1,5 @@ # NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py -# RUN: llvm-mca -mtriple=aarch64-linux-gnu -mcpu=exynos-m3 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM3 +# RUN: llvm-mca -mtriple=aarch64-linux-gnu -mcpu=exynos-m3 -resource-pressure=false -skip-unsupported-instructions=parse-failure < %s | FileCheck %s -check-prefixes=ALL,EM3 # RUN: llvm-mca -mtriple=aarch64-linux-gnu -mcpu=exynos-m4 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM4 # RUN: llvm-mca -mtriple=aarch64-linux-gnu -mcpu=exynos-m5 -resource-pressure=false < %s | FileCheck %s -check-prefixes=ALL,EM5 diff --git a/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s b/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s index d686293..9c2ae8f 100644 --- a/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s +++ b/llvm/test/tools/llvm-mca/ARM/cortex-a57-basic-instructions.s @@ -33,7 +33,6 @@ adc pc, r5, r6, ror #2 adc r4, r5, r6, ror #31 adc r6, r7, r8, lsl r9 - adc pc, r7, r8, lsl r9 adc r6, r7, r8, lsr r9 adc r6, r7, r8, asr r9 adc r6, r7, r8, ror r9 diff --git a/llvm/test/tools/llvm-mca/ARM/cortex-a57-thumb.s b/llvm/test/tools/llvm-mca/ARM/cortex-a57-thumb.s index 21accd7..6c56e1d 100644 --- a/llvm/test/tools/llvm-mca/ARM/cortex-a57-thumb.s +++ b/llvm/test/tools/llvm-mca/ARM/cortex-a57-thumb.s @@ -95,12 +95,13 @@ itett ne cmpne r7, #243 addeq r7, r1, r2 + addne r7, r1, r2 + uxthne r7, r7 itttt lt cmplt r7, #243 uxthlt r7, r1 strhlt r2, [r7, #22] lsrlt r1, r6, #3 - uxthne r7, r7 strh r2, [r7, #22] asrs r1, r6, #7 lsrs r1, r6, #31 @@ -253,7 +254,7 @@ ldrd r0, r1, [r2, #-0]! ldrd r0, r1, [r2, #0]! ldrd r0, r1, [r2, #-0] - ldrd r1, r1, [r0], #0 + ldrd r1, r2, [r0], #0 ldrex r1, [r4] ldrex r8, [r4] ldrex r2, [sp, #128] @@ -648,7 +649,7 @@ str r10, [r11], #0 strd r1, r1, [r0], #0 strd r6, r3, [r5], #-8 - strd r8, r5, [r5], #-0 + strd r8, r5, [r6], #-0 strd r7, r4, [r5], #-4 strd r0, r1, [r2, #-0]! strd r0, r1, [r2, #0]! @@ -1010,6 +1011,13 @@ # CHECK-NEXT: 0 0 0.00 U itett ne # CHECK-NEXT: 1 1 0.50 cmpne r7, #243 # CHECK-NEXT: 1 1 0.50 addeq r7, r1, r2 +# CHECK-NEXT: 1 1 0.50 addne r7, r1, r2 +# CHECK-NEXT: 1 1 0.50 uxthne r7, r7 +# CHECK-NEXT: 0 0 0.00 U itttt lt +# CHECK-NEXT: 1 1 0.50 cmplt r7, #243 +# CHECK-NEXT: 1 1 0.50 uxthlt r7, r1 +# CHECK-NEXT: 1 1 1.00 * strhlt r2, [r7, #22] +# CHECK-NEXT: 1 1 0.50 lsrlt r1, r6, #3 # CHECK-NEXT: 1 1 1.00 * strh r2, [r7, #22] # CHECK-NEXT: 1 2 1.00 asrs r1, r6, #7 # CHECK-NEXT: 1 2 1.00 lsrs r1, r6, #31 @@ -1162,6 +1170,7 @@ # CHECK-NEXT: 4 4 2.00 * ldrd r0, r1, [r2, #-0]! # CHECK-NEXT: 4 4 2.00 * ldrd r0, r1, [r2, #0]! # CHECK-NEXT: 2 4 2.00 * ldrd r0, r1, [r2, #-0] +# CHECK-NEXT: 4 4 2.00 * ldrd r1, r2, [r0], #0 # CHECK-NEXT: 0 0 0.00 * * U ldrex r1, [r4] # CHECK-NEXT: 0 0 0.00 * * U ldrex r8, [r4] # CHECK-NEXT: 0 0 0.00 * * U ldrex r2, [sp, #128] @@ -1556,6 +1565,7 @@ # CHECK-NEXT: 2 1 1.00 * str r10, [r11], #0 # CHECK-NEXT: 2 1 1.00 * strd r1, r1, [r0], #0 # CHECK-NEXT: 2 1 1.00 * strd r6, r3, [r5], #-8 +# CHECK-NEXT: 2 1 1.00 * strd r8, r5, [r6], #-0 # CHECK-NEXT: 2 1 1.00 * strd r7, r4, [r5], #-4 # CHECK-NEXT: 2 1 1.00 * strd r0, r1, [r2, #-0]! # CHECK-NEXT: 2 1 1.00 * strd r0, r1, [r2, #0]! @@ -1827,7 +1837,7 @@ # CHECK: Resource pressure per iteration: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] -# CHECK-NEXT: 12.00 164.00 164.00 221.00 313.00 44.00 - - +# CHECK-NEXT: 12.00 168.00 168.00 223.00 313.00 46.00 - - # CHECK: Resource pressure by instruction: # CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions: @@ -1924,6 +1934,13 @@ # CHECK-NEXT: - - - - - - - - itett ne # CHECK-NEXT: - 0.50 0.50 - - - - - cmpne r7, #243 # CHECK-NEXT: - 0.50 0.50 - - - - - addeq r7, r1, r2 +# CHECK-NEXT: - 0.50 0.50 - - - - - addne r7, r1, r2 +# CHECK-NEXT: - 0.50 0.50 - - - - - uxthne r7, r7 +# CHECK-NEXT: - - - - - - - - itttt lt +# CHECK-NEXT: - 0.50 0.50 - - - - - cmplt r7, #243 +# CHECK-NEXT: - 0.50 0.50 - - - - - uxthlt r7, r1 +# CHECK-NEXT: - - - - - 1.00 - - strhlt r2, [r7, #22] +# CHECK-NEXT: - 0.50 0.50 - - - - - lsrlt r1, r6, #3 # CHECK-NEXT: - - - - - 1.00 - - strh r2, [r7, #22] # CHECK-NEXT: - - - - 1.00 - - - asrs r1, r6, #7 # CHECK-NEXT: - - - - 1.00 - - - lsrs r1, r6, #31 @@ -2076,6 +2093,7 @@ # CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldrd r0, r1, [r2, #-0]! # CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldrd r0, r1, [r2, #0]! # CHECK-NEXT: - - - 2.00 - - - - ldrd r0, r1, [r2, #-0] +# CHECK-NEXT: - 1.00 1.00 2.00 - - - - ldrd r1, r2, [r0], #0 # CHECK-NEXT: - - - - - - - - ldrex r1, [r4] # CHECK-NEXT: - - - - - - - - ldrex r8, [r4] # CHECK-NEXT: - - - - - - - - ldrex r2, [sp, #128] @@ -2470,6 +2488,7 @@ # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - str r10, [r11], #0 # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r1, r1, [r0], #0 # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r6, r3, [r5], #-8 +# CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r8, r5, [r6], #-0 # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r7, r4, [r5], #-4 # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r0, r1, [r2, #-0]! # CHECK-NEXT: - 0.50 0.50 - - 1.00 - - strd r0, r1, [r2, #0]! diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s b/llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s index d128544..715f370 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/simple-test.s @@ -1,5 +1,8 @@ # NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py # RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=100 < %s | FileCheck %s +# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=100 -skip-unsupported-instructions=lack-sched < %s | FileCheck %s +# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=100 -skip-unsupported-instructions=parse-failure < %s | FileCheck %s +# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=100 -skip-unsupported-instructions=any < %s | FileCheck %s add %edi, %eax diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s b/llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s index 0d67f53..5bd69103 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s @@ -1,4 +1,4 @@ -# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions %s 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK-SKIP %s +# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions=lack-sched %s 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK-SKIP %s # RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK-ERROR %s # Test defends that if all instructions are skipped leaving an empty input, an error is printed. @@ -7,7 +7,7 @@ bzhi %eax, %ebx, %ecx # CHECK-ALL-NOT: error -# CHECK-ERROR: error: found an unsupported instruction in the input assembly sequence, use -skip-unsupported-instructions to ignore. +# CHECK-ERROR: error: found an unsupported instruction in the input assembly sequence, use -skip-unsupported-instructions=lack-sched to ignore these on the input. # CHECK-SKIP: warning: found an unsupported instruction in the input assembly sequence, skipping with -skip-unsupported-instructions, note accuracy will be impacted: # CHECK-SKIP: note: instruction: bzhil %eax, %ebx, %ecx diff --git a/llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s b/llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s index 3690a11..7d3aee5 100644 --- a/llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s +++ b/llvm/test/tools/llvm-mca/X86/BtVer2/unsupported-instruction.s @@ -1,10 +1,13 @@ -# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions -timeline %s 2>&1 | FileCheck --check-prefix=CHECK-SKIP %s +# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions=any -timeline %s 2>&1 | FileCheck --check-prefix=CHECK-SKIP %s +# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions=lack-sched -timeline %s 2>&1 | FileCheck --check-prefix=CHECK-SKIP %s +# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -skip-unsupported-instructions=parse-failure -timeline %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s # RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s -# Test checks that unsupported instructions exit with an error, unless -skip-unsupported-instructions is passed, in which case the remaining instructions should be analysed. +# Test checks that unsupported instructions exit with an error, unless -skip-unsupported-instructions=lack-sched is passed, in which case the remaining instructions should be analysed. +# Additionally check that -skip-unsupported-instructions=parse-failure continues to raise the lack of scheduling information. # CHECK-SKIP: warning: found an unsupported instruction in the input assembly sequence, skipping with -skip-unsupported-instructions, note accuracy will be impacted: -# CHECK-ERROR: error: found an unsupported instruction in the input assembly sequence, use -skip-unsupported-instructions to ignore. +# CHECK-ERROR: error: found an unsupported instruction in the input assembly sequence, use -skip-unsupported-instructions=lack-sched to ignore these on the input. bzhi %eax, %ebx, %ecx diff --git a/llvm/test/tools/llvm-mca/bad-input.s b/llvm/test/tools/llvm-mca/bad-input.s new file mode 100644 index 0000000..eaf6997 --- /dev/null +++ b/llvm/test/tools/llvm-mca/bad-input.s @@ -0,0 +1,14 @@ +# RUN: not llvm-mca %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK %s +# RUN: not llvm-mca -skip-unsupported-instructions=none %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK %s +# RUN: not llvm-mca -skip-unsupported-instructions=lack-sched %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK %s +# RUN: not llvm-mca -skip-unsupported-instructions=parse-failure %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK-SKIP %s +# RUN: not llvm-mca -skip-unsupported-instructions=any %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK-ALL,CHECK-SKIP %s + +# Test checks that MCA does not produce a total cycles estimate if it encounters parse errors. + +# CHECK-ALL-NOT: Total Cycles: + +# CHECK: error: Assembly input parsing had errors, use -skip-unsupported-instructions=parse-failure to drop failing lines from the input. +# CHECK-SKIP: error: no assembly instructions found. + +This is not a valid assembly file for any architecture (by virtue of this text.) diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp index 5241b58..863766c 100644 --- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp +++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp @@ -29,7 +29,7 @@ namespace mca { CodeRegionGenerator::~CodeRegionGenerator() {} Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions( - const std::unique_ptr<MCInstPrinter> &IP) { + const std::unique_ptr<MCInstPrinter> &IP, bool SkipFailures) { MCTargetOptions Opts; Opts.PreserveAsmComments = false; CodeRegions &Regions = getRegions(); @@ -61,7 +61,16 @@ Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions( "This target does not support assembly parsing.", inconvertibleErrorCode()); Parser->setTargetParser(*TAP); - Parser->Run(false); + // Parser->Run() confusingly returns true on errors, in which case the errors + // were already shown to the user. SkipFailures implies continuing in the + // presence of any kind of failure within the parser, in which case failing + // input lines are not represented, but the rest of the input remains. + if (Parser->Run(false) && !SkipFailures) { + const char *Message = "Assembly input parsing had errors, use " + "-skip-unsupported-instructions=parse-failure " + "to drop failing lines from the input."; + return make_error<StringError>(Message, inconvertibleErrorCode()); + } if (CCP->hadErr()) return make_error<StringError>("There was an error parsing comments.", diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.h b/llvm/tools/llvm-mca/CodeRegionGenerator.h index 68da567..12261e7 100644 --- a/llvm/tools/llvm-mca/CodeRegionGenerator.h +++ b/llvm/tools/llvm-mca/CodeRegionGenerator.h @@ -148,7 +148,8 @@ protected: CodeRegionGenerator(const CodeRegionGenerator &) = delete; CodeRegionGenerator &operator=(const CodeRegionGenerator &) = delete; virtual Expected<const CodeRegions &> - parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0; + parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) = 0; public: CodeRegionGenerator() {} @@ -164,7 +165,8 @@ public: AnalysisRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {} virtual Expected<const AnalysisRegions &> - parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0; + parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) = 0; }; /// Abstract CodeRegionGenerator with InstrumentRegionsRegions member @@ -176,7 +178,8 @@ public: InstrumentRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {} virtual Expected<const InstrumentRegions &> - parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0; + parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) = 0; }; /// This abstract class is responsible for parsing input ASM and @@ -202,7 +205,8 @@ public: unsigned getAssemblerDialect() const { return AssemblerDialect; } Expected<const CodeRegions &> - parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override; + parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) override; }; class AsmAnalysisRegionGenerator final : public AnalysisRegionGenerator, @@ -222,8 +226,10 @@ public: MCStreamerWrapper *getMCStreamer() override { return &Streamer; } Expected<const AnalysisRegions &> - parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP) override { - Expected<const CodeRegions &> RegionsOrErr = parseCodeRegions(IP); + parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) override { + Expected<const CodeRegions &> RegionsOrErr = + parseCodeRegions(IP, SkipFailures); if (!RegionsOrErr) return RegionsOrErr.takeError(); else @@ -231,8 +237,9 @@ public: } Expected<const CodeRegions &> - parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override { - return AsmCodeRegionGenerator::parseCodeRegions(IP); + parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) override { + return AsmCodeRegionGenerator::parseCodeRegions(IP, SkipFailures); } }; @@ -254,8 +261,10 @@ public: MCStreamerWrapper *getMCStreamer() override { return &Streamer; } Expected<const InstrumentRegions &> - parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP) override { - Expected<const CodeRegions &> RegionsOrErr = parseCodeRegions(IP); + parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) override { + Expected<const CodeRegions &> RegionsOrErr = + parseCodeRegions(IP, SkipFailures); if (!RegionsOrErr) return RegionsOrErr.takeError(); else @@ -263,8 +272,9 @@ public: } Expected<const CodeRegions &> - parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override { - return AsmCodeRegionGenerator::parseCodeRegions(IP); + parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP, + bool SkipFailures) override { + return AsmCodeRegionGenerator::parseCodeRegions(IP, SkipFailures); } }; diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp index e037c06..03d7d79 100644 --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -135,6 +135,35 @@ static cl::opt<unsigned> "(instructions per cycle)"), cl::cat(ToolOptions), cl::init(0)); +enum class SkipType { NONE, LACK_SCHED, PARSE_FAILURE, ANY_FAILURE }; + +static cl::opt<enum SkipType> SkipUnsupportedInstructions( + "skip-unsupported-instructions", + cl::desc("Force analysis to continue in the presence of unsupported " + "instructions"), + cl::values( + clEnumValN(SkipType::NONE, "none", + "Exit with an error when an instruction is unsupported for " + "any reason (default)"), + clEnumValN( + SkipType::LACK_SCHED, "lack-sched", + "Skip instructions on input which lack scheduling information"), + clEnumValN( + SkipType::PARSE_FAILURE, "parse-failure", + "Skip lines on the input which fail to parse for any reason"), + clEnumValN(SkipType::ANY_FAILURE, "any", + "Skip instructions or lines on input which are unsupported " + "for any reason")), + cl::init(SkipType::NONE), cl::cat(ViewOptions)); + +bool shouldSkip(enum SkipType skipType) { + if (SkipUnsupportedInstructions == SkipType::NONE) + return false; + if (SkipUnsupportedInstructions == SkipType::ANY_FAILURE) + return true; + return skipType == SkipUnsupportedInstructions; +} + static cl::opt<bool> PrintRegisterFileStats("register-file-stats", cl::desc("Print register file statistics"), @@ -237,11 +266,6 @@ static cl::opt<bool> DisableInstrumentManager( "ignores instruments.)."), cl::cat(ViewOptions), cl::init(false)); -static cl::opt<bool> SkipUnsupportedInstructions( - "skip-unsupported-instructions", - cl::desc("Make unsupported instruction errors into warnings."), - cl::cat(ViewOptions), cl::init(false)); - namespace { const Target *getTarget(const char *ProgName) { @@ -440,7 +464,8 @@ int main(int argc, char **argv) { mca::AsmAnalysisRegionGenerator CRG(*TheTarget, SrcMgr, ACtx, *MAI, *STI, *MCII); Expected<const mca::AnalysisRegions &> RegionsOrErr = - CRG.parseAnalysisRegions(std::move(IPtemp)); + CRG.parseAnalysisRegions(std::move(IPtemp), + shouldSkip(SkipType::PARSE_FAILURE)); if (!RegionsOrErr) { if (auto Err = handleErrors(RegionsOrErr.takeError(), [](const StringError &E) { @@ -482,7 +507,8 @@ int main(int argc, char **argv) { mca::AsmInstrumentRegionGenerator IRG(*TheTarget, SrcMgr, ICtx, *MAI, *STI, *MCII, *IM); Expected<const mca::InstrumentRegions &> InstrumentRegionsOrErr = - IRG.parseInstrumentRegions(std::move(IPtemp)); + IRG.parseInstrumentRegions(std::move(IPtemp), + shouldSkip(SkipType::PARSE_FAILURE)); if (!InstrumentRegionsOrErr) { if (auto Err = handleErrors(InstrumentRegionsOrErr.takeError(), [](const StringError &E) { @@ -593,7 +619,7 @@ int main(int argc, char **argv) { [&IP, &STI](const mca::InstructionError<MCInst> &IE) { std::string InstructionStr; raw_string_ostream SS(InstructionStr); - if (SkipUnsupportedInstructions) + if (shouldSkip(SkipType::LACK_SCHED)) WithColor::warning() << IE.Message << ", skipping with -skip-unsupported-instructions, " @@ -601,7 +627,8 @@ int main(int argc, char **argv) { else WithColor::error() << IE.Message - << ", use -skip-unsupported-instructions to ignore.\n"; + << ", use -skip-unsupported-instructions=lack-sched to " + "ignore these on the input.\n"; IP->printInst(&IE.Inst, 0, "", *STI, SS); SS.flush(); WithColor::note() @@ -610,7 +637,7 @@ int main(int argc, char **argv) { // Default case. WithColor::error() << toString(std::move(NewE)); } - if (SkipUnsupportedInstructions) { + if (shouldSkip(SkipType::LACK_SCHED)) { DroppedInsts.insert(&MCI); continue; } |