Commit Graph

748 Commits

Author SHA1 Message Date
Fangrui Song 4e62072ca1 [Passes] llvm::Optional => std::optional 2022-12-04 20:44:52 +00:00
Kazu Hirata bb666c6930 [CodeGen] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 11:13:43 -08:00
Krzysztof Parzyszek 8c7c20f033 Convert Optional<CodeModel> to std::optional<CodeModel> 2022-12-03 12:08:47 -06:00
Marco Elver b95646fe70 Revert "Use-after-return sanitizer binary metadata"
This reverts commit d3c851d3fc.

Some bots broke:

- https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8796062278266465473/overview
- https://lab.llvm.org/buildbot/#/builders/124/builds/5759/steps/7/logs/stdio
2022-11-30 23:35:50 +01:00
Dmitry Vyukov d3c851d3fc Use-after-return sanitizer binary metadata
Currently per-function metadata consists of:
(start-pc, size, features)

This adds a new UAR feature and if it's set an additional element:
(start-pc, size, features, stack-args-size)

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D136078
2022-11-30 14:50:22 +01:00
Dmitry Vyukov 0aedf9d714 Revert "Use-after-return sanitizer binary metadata"
This reverts commit e6aea4a5db.

Broke tests:
https://lab.llvm.org/buildbot/#/builders/16/builds/38992
2022-11-30 09:38:56 +01:00
Dmitry Vyukov e6aea4a5db Use-after-return sanitizer binary metadata
Currently per-function metadata consists of:
(start-pc, size, features)

This adds a new UAR feature and if it's set an additional element:
(start-pc, size, features, stack-args-size)

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D136078
2022-11-30 09:14:19 +01:00
Kazu Hirata dbb1130966 Revert "Use-after-return sanitizer binary metadata"
This reverts commit a1255dc467.

This patch results in:

  llvm/lib/CodeGen/SanitizerBinaryMetadata.cpp:57:17: error: no member
  named 'size' in 'llvm::MDTuple'
2022-11-29 09:04:00 -08:00
Dmitry Vyukov a1255dc467 Use-after-return sanitizer binary metadata
Currently per-function metadata consists of:
(start-pc, size, features)

This adds a new UAR feature and if it's set an additional element:
(start-pc, size, features, stack-args-size)

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D136078
2022-11-29 17:37:36 +01:00
Evgeniy Brevnov 721f975d35 Use PassGate from LLVMContext if any otherwise global one
Differential Revision: https://reviews.llvm.org/D137149
2022-11-25 15:13:04 +07:00
Sami Tolvanen cacd3e73d7 Add generic KCFI operand bundle lowering
The KCFI sanitizer emits "kcfi" operand bundles to indirect
call instructions, which the LLVM back-end lowers into an
architecture-specific type check with a known machine instruction
sequence. Currently, KCFI operand bundle lowering is supported only
on 64-bit X86 and AArch64 architectures.

As a lightweight forward-edge CFI implementation that doesn't
require LTO is also useful for non-Linux low-level targets on
other machine architectures, add a generic KCFI operand bundle
lowering pass that's only used when back-end lowering support is not
available and allows -fsanitize=kcfi to be enabled in Clang on all
architectures.

This relands commit eb2a57ebc7 with
fixes.

Reviewed By: nickdesaulniers, MaskRay

Differential Revision: https://reviews.llvm.org/D135411
2022-11-22 23:01:18 +00:00
Zequan Wu 84be92d26f Reland "[LTO][COFF] Use bitcode file names in lto native object file names."
This reverts commit 3410808294 with fixes.
2022-11-22 13:46:42 -08:00
Roman Lebedev 3410808294
Revert "Reland "[LTO][COFF] Use bitcode file names in lto native object file names.""
Breaks build of LLVMgold here:
```
/repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1108:19: error: no matching function for call to 'localCache'
    Cache = check(localCache("ThinLTO", "Thin", options::cache_dir, AddBuffer));
                  ^~~~~~~~~~
/repositories/llvm-project/llvm/include/llvm/Support/Caching.h:72:21: note: candidate function not viable: no known conversion from '(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1102:20)' to 'llvm::AddBufferFn' (aka 'function<void (unsigned int, const llvm::Twine &, std::unique_ptr<MemoryBuffer>)>') for 4th argument
Expected<FileCache> localCache(
                    ^
/repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1110:18: error: no viable conversion from '(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20)' to 'llvm::AddStreamFn' (aka 'function<Expected<std::unique_ptr<CachedFileStream>> (unsigned int, const llvm::Twine &)>')
  check(Lto->run(AddStream, Cache));
                 ^~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:375:7: note: candidate constructor not viable: no known conversion from '(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20)' to 'std::nullptr_t' for 1st argument
      function(nullptr_t) noexcept
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:386:7: note: candidate constructor not viable: no known conversion from '(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20)' to 'const std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream>> (unsigned int, const llvm::Twine &)> &' for 1st argument
      function(const function& __x)
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:404:7: note: candidate constructor not viable: no known conversion from '(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20)' to 'std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream>> (unsigned int, const llvm::Twine &)> &&' for 1st argument
      function(function&& __x) noexcept
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:435:2: note: candidate template ignored: requirement '_Callable<(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20) &, (lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20), std::__invoke_result<(lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20) &, unsigned int, const llvm::Twine &>>::value' was not satisfied [with _Functor = (lambda at /repositories/llvm-project/llvm/tools/gold/gold-plugin.cpp:1094:20) &]
        function(_Functor&& __f)
        ^
/repositories/llvm-project/llvm/include/llvm/LTO/LTO.h:278:25: note: passing argument to parameter 'AddStream' here
  Error run(AddStreamFn AddStream, FileCache Cache = nullptr);
                        ^

```

This reverts commit 387620aa8c.
2022-11-23 00:40:12 +03:00
Zequan Wu 387620aa8c Reland "[LTO][COFF] Use bitcode file names in lto native object file names."
This reverts commit eef5405f74.
2022-11-22 11:26:18 -08:00
Zequan Wu eef5405f74 Revert "[LTO][COFF] Use bitcode file names in lto native object file names."
This reverts commit 531ed6d5aa.
2022-11-22 10:55:05 -08:00
Zequan Wu 531ed6d5aa [LTO][COFF] Use bitcode file names in lto native object file names.
Currently the lto native object files have names like main.exe.lto.1.obj. In
PDB, those names are used as names for each compiland. Microsoft’s tool
SizeBench uses those names to present to users the size of each object files.
So, names like main.exe.lto.1.obj is not user friendly.

This patch makes the lto native object file names more readable by using
the bitcode file names as part of the file names. For example, if the input
bitcode file has path like "path/to/foo.obj", its corresponding lto native
object file path would be "path/to/main.exe.lto.foo.obj". Since the lto native
object file name only bothers PDB, this patch only changes the lld-linker's
behavior.

Reviewed By: tejohnson, MaskRay, #lld-macho

Differential Revision: https://reviews.llvm.org/D137217
2022-11-22 10:19:58 -08:00
Fangrui Song d1163784b5 Remove unused llvm/IRPrinter/IRPrintingPasses.h or reorder #include after D137768 2022-11-19 22:09:05 +00:00
Alexander Shaposhnikov f102fe7304 Revert "Revert "[opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm""
This reverts commit 7f608a2497
and removes the dependency of Object on IRPrinter.
2022-11-18 08:58:31 +00:00
Mikhail Goncharov 7f608a2497 Revert "[opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm"
This reverts commit 34ab474348.

as it has introduced circular dependency lib - analysis
2022-11-18 09:25:45 +01:00
Alexander Shaposhnikov 34ab474348 [opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm
Enable using -module-summary with -S
(similarly to what currently can be achieved with opt <input> -o - | llvm-dis).
This is a recommit of ef9e62469.

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D137768
2022-11-18 05:04:07 +00:00
Alexander Shaposhnikov 7059a6c32c [IR] Split out IR printing passes into IRPrinter
This diff splits out (from LLVMCore) IR printing passes into IRPrinter.
This structure is similar to what we already have for IRReader and
enables us to avoid circular dependencies between LLVMCore and Analysis
(this is a preparation for https://reviews.llvm.org/D137768).
The legacy interface is left unchanged, once the legacy pass manager
is removed (in the future) we will be able to clean it up further.
The bazel build configuration has been updated as well.

Test plan:
1/ Tested the following cmake configurations: static/dynamic linking * lld/gold * clang/gcc
2/ bazel build --config=generic_clang @llvm-project//...

Differential revision: https://reviews.llvm.org/D138081
2022-11-18 01:47:56 +00:00
Fangrui Song fc91c70593 Revert D135411 "Add generic KCFI operand bundle lowering"
This reverts commit eb2a57ebc7.

llvm/include/llvm/Transforms/Instrumentation/KCFI.h including
llvm/CodeGen is a layering violation. We should use an approach where
Instrumementation/ doesn't need to include CodeGen/.
Sorry for not spotting this in the review.
2022-11-17 22:45:30 +00:00
Sami Tolvanen eb2a57ebc7 Add generic KCFI operand bundle lowering
The KCFI sanitizer emits "kcfi" operand bundles to indirect
call instructions, which the LLVM back-end lowers into an
architecture-specific type check with a known machine instruction
sequence. Currently, KCFI operand bundle lowering is supported only
on 64-bit X86 and AArch64 architectures.

As a lightweight forward-edge CFI implementation that doesn't
require LTO is also useful for non-Linux low-level targets on
other machine architectures, add a generic KCFI operand bundle
lowering pass that's only used when back-end lowering support is not
available and allows -fsanitize=kcfi to be enabled in Clang on all
architectures.

Reviewed By: nickdesaulniers, MaskRay

Differential Revision: https://reviews.llvm.org/D135411
2022-11-17 21:55:00 +00:00
Michele Scandale b7d7c448df Fix `unsafe-fp-math` attribute emission.
The conditions for which Clang emits the `unsafe-fp-math` function
attribute has been modified as part of
`84a9ec2ff1ee97fd7e8ed988f5e7b197aab84a7`.
In the backend code generators `"unsafe-fp-math"="true"` enable floating
point contraction for the whole function.
The intent of the change in `84a9ec2ff1ee97fd7e8ed988f5e7b197aab84a7`
was to prevent backend code generators performing contractions when that
is not expected.
However the change is inaccurate and incomplete because it allows
`unsafe-fp-math` to be set also when only in-statement contraction is
allowed.

Consider the following example
```
float foo(float a, float b, float c) {
  float tmp = a * b;
  return tmp + c;
}
```
and compile it with the command line
```
clang -fno-math-errno -funsafe-math-optimizations -ffp-contract=on \
  -O2 -mavx512f -S -o -
```
The resulting assembly has a `vfmadd213ss` instruction which corresponds
to a fused multiply-add. From the user perspective there shouldn't be
any contraction because the multiplication and the addition are not in
the same statement.

The optimized IR is:
```
define float @test(float noundef %a, float noundef %b, float noundef %c) #0 {
  %mul = fmul reassoc nsz arcp afn float %b, %a
  %add = fadd reassoc nsz arcp afn float %mul, %c
  ret float %add
}

attributes #0 = {
  [...]
  "no-signed-zeros-fp-math"="true"
  "no-trapping-math"="true"
  [...]
  "unsafe-fp-math"="true"
}
```
The `"unsafe-fp-math"="true"` function attribute allows the backend code
generator to perform `(fadd (fmul a, b), c) -> (fmadd a, b, c)`.

In the current IR representation there is no way to determine the
statement boundaries from the original source code.
Because of this for in-statement only contraction the generated IR
doesn't have instructions with the `contract` fast-math flag and
`llvm.fmuladd` is being used to represent contractions opportunities
that occur within a single statement.
Therefore `"unsafe-fp-math"="true"` can only be emitted when contraction
across statements is allowed.

Moreover the change in `84a9ec2ff1ee97fd7e8ed988f5e7b197aab84a7` doesn't
take into account that the floating point math function attributes can
be refined during IR code generation of a function to handle the cases
where the floating point math options are modified within a compound
statement via pragmas (see `CGFPOptionsRAII`).
For consistency `unsafe-fp-math` needs to be disabled if the contraction
mode for any scope/operation is not `fast`.
Similarly for consistency reason the initialization of `UnsafeFPMath` of
in `TargetOptions` for the backend code generation should take into
account the contraction mode as well.

Reviewed By: zahiraam

Differential Revision: https://reviews.llvm.org/D136786
2022-11-14 20:40:57 -08:00
Fangrui Song 77bf0df376 Revert "[opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm"
This reverts commit bf8381a8bc.

There is a layering violation: LLVMAnalysis depends on LLVMCore, so
LLVMCore should not include LLVMAnalysis header
llvm/Analysis/ModuleSummaryAnalysis.h
2022-11-14 15:51:03 -08:00
Alexander Shaposhnikov bf8381a8bc [opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm
Enable using -module-summary with -S
(similarly to what currently can be achieved with opt <input> -o - | llvm-dis).
This is a recommit of ef9e62469.

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D137768
2022-11-14 23:24:08 +00:00
Alexander Shaposhnikov 8c15c17e3b Revert "[opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm"
This reverts commit ef9e624694
for further investigation offline.
It appears to break the buildbot
llvm-clang-x86_64-sie-ubuntu-fast.
2022-11-14 21:31:30 +00:00
Alexander Shaposhnikov ef9e624694 [opt][clang] Enable using -module-summary/-flto=thin with -S/-emit-llvm
Enable using -module-summary with -S
(similarly to what currently can be achieved with opt <input> -o - | llvm-dis).

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D137768
2022-11-14 21:11:07 +00:00
Arthur Eubanks cbcf123af2 [LegacyPM] Remove cl::opts controlling optimization pass manager passes
Move these to the new PM if they're used there.

Part of removing the legacy pass manager for optimization pipeline.

Reland with UseNewGVN usage in clang removed.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D137915
2022-11-14 09:38:17 -08:00
OCHyams 4b6b2b1a42 Reapply: [Assignment Tracking][7/*] Add assignment tracking functionality to clang
Reverted in 98fa95492f.

The Assignment Tracking debug-info feature is outlined in this RFC:

https://discourse.llvm.org/t/
rfc-assignment-tracking-a-better-way-of-specifying-variable-locations-in-ir

This patch plumbs the AssignmentTrackingPass (AKA declare-to-assign), added in
the previous patch in this set, into the optimisation pipeline from
clang. clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp is the
main test for this patch.

Note: while clang (with the help of the declare-to-assign pass) can now emit
Assignment Tracking metadata, the llvm middle and back ends don't yet
understand it.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D132226
2022-11-09 09:28:41 +00:00
OCHyams 98fa95492f Revert "[Assignment Tracking][7/*] Add assignment tracking functionality to clang"
This reverts commit 28f9636edd.

Bot failure: https://lab.llvm.org/buildbot/#/builders/109/builds/50251
2022-11-08 18:43:05 +00:00
OCHyams 28f9636edd [Assignment Tracking][7/*] Add assignment tracking functionality to clang
The Assignment Tracking debug-info feature is outlined in this RFC:

https://discourse.llvm.org/t/
rfc-assignment-tracking-a-better-way-of-specifying-variable-locations-in-ir

This patch plumbs the AssignmentTrackingPass (AKA declare-to-assign), added in
the previous patch in this set, into the optimisation pipeline from
clang. clang/test/CodeGen/assignment-tracking/assignment-tracking.cpp is the
main test for this patch.

Note: while clang (with the help of the declare-to-assign pass) can now emit
Assignment Tracking metadata, the llvm middle and back ends don't yet
understand it.

Reviewed By: jmorse

Differential Revision: https://reviews.llvm.org/D132226
2022-11-08 17:49:08 +00:00
Ben Langmuir e1f9983022 Move getenv for AS_SECURE_LOG_FILE to clang
Avoid calling getenv in the MC layer and let the clang driver do it so
that it is reflected in the command-line as an -mllvm option.

rdar://101558354

Differential Revision: https://reviews.llvm.org/D136888
2022-10-28 16:08:04 -07:00
Navid Emamdoost 3e52c0926c Add -fsanitizer-coverage=control-flow
Reviewed By: kcc, vitalybuka, MaskRay

Differential Revision: https://reviews.llvm.org/D133157
2022-09-15 15:56:04 -07:00
Vitaly Buka c69b269111 [pipelines] Require GlobalsAA after sanitizers
Restore GlobalsAA if sanitizers inserted at early optimize callback.
The analysis can be useful for the following FunctionPassManager.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D133537
2022-09-14 13:33:53 -07:00
Vitaly Buka 270c843005 [NFC][CodeGen] Remove empty line 2022-09-14 13:29:15 -07:00
Martin Storsjö fbfe1db4a9 [clang] Explicitly set the EmulatedTLS codegen option. NFC.
Set the EmulatedTLS option based on `Triple::hasDefaultEmulatedTLS()`
if the user didn't specify it; set `ExplicitEmulatedTLS` to true
in `llvm::TargetOptions` and set `EmulatedTLS` to Clang's
opinion of what the default or preference is.

This avoids any risk of deviance between the two.

This affects one check of `getCodeGenOpts().EmulatedTLS` in
`shouldAssumeDSOLocal` in CodeGenModule, but as that check only
is done for `TT.isWindowsGNUEnvironment()`, and
`hasDefaultEmulatedTLS()` returns false for such environments
it doesn't make any current testable difference - thus NFC.

Some mingw distributions carry a downstream patch, that enables
emulated TLS by default for mingw targets in `hasDefaultEmulatedTLS()`
- and for such cases, this patch does make a difference and fixes the
detection of emulated TLS, if it is implicitly enabled.

Differential Revision: https://reviews.llvm.org/D132916
2022-09-13 10:40:54 +03:00
Vitaly Buka 7dc0734567 [msan] Insert simplification passes after instrumentation
This resolves TODO from D96406.
InstCombine issue is fixed with D133394.

Save 4.5% of .text on CTMark.
2022-09-09 00:33:04 -07:00
Vitaly Buka e261b03396 [sanitizers] Add experimental flag to insert sanitizers earlier 2022-09-08 19:05:17 -07:00
Marco Elver c4842bb2e9 [Clang] Introduce -fexperimental-sanitize-metadata=
Introduces the frontend flag -fexperimental-sanitize-metadata=, which
enables SanitizerBinaryMetadata instrumentation.

The first intended user of the binary metadata emitted will be a variant
of GWP-TSan [1]. The plan is to open source a stable and production
quality version of GWP-TSan. The development of which, however, requires
upstream compiler support.

[1] https://llvm.org/devmtg/2020-09/slides/Morehouse-GWP-Tsan.pdf

Until the tool has been open sourced, we mark this kind of
instrumentation as "experimental", and reserve the option to change
binary format, remove features, and similar.

Reviewed By: vitalybuka, MaskRay

Differential Revision: https://reviews.llvm.org/D130888
2022-09-07 21:25:40 +02:00
Vitaly Buka 4c18670776 [NFC][sancov] Rename ModuleSanitizerCoveragePass 2022-09-06 20:55:39 -07:00
Vitaly Buka 5e38b2a456 [NFC][msan] Rename ModuleMemorySanitizerPass 2022-09-06 20:30:35 -07:00
Vitaly Buka 93600eb50c [NFC][asan] Rename ModuleAddressSanitizerPass 2022-09-06 15:02:11 -07:00
Vitaly Buka e7bac3b9fa [msan] Convert Msan to ModulePass
MemorySanitizerPass function pass violatied requirement 4 of function
pass to do not insert globals. Msan nees to insert globals for origin
tracking, and paramereters tracking.

https://llvm.org/docs/WritingAnLLVMPass.html#the-functionpass-class

Reviewed By: kstoimenov, fmayer

Differential Revision: https://reviews.llvm.org/D133336
2022-09-06 15:01:04 -07:00
Nikola Tesic b5b6d3a41b [Debugify] Port verify-debuginfo-preserve to NewPM
Debugify in OriginalDebugInfo mode, introduced with D82545,
runs only with legacy PassManager.

This patch enables this utility for the NewPM.

Differential Revision: https://reviews.llvm.org/D115351
2022-07-06 17:07:20 +02:00
Mitch Phillips dacfa24f75 Delete 'llvm.asan.globals' for global metadata.
Now that we have the sanitizer metadata that is actually on the global
variable, and now that we use debuginfo in order to do symbolization of
globals, we can delete the 'llvm.asan.globals' IR synthesis.

This patch deletes the 'location' part of the __asan_global that's
embedded in the binary as well, because it's unnecessary. This saves
about ~1.7% of the optimised non-debug with-asserts clang binary.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D127911
2022-06-27 14:40:40 -07:00
Kazu Hirata 452db157c9 [clang] Don't use Optional::hasValue (NFC) 2022-06-20 10:51:34 -07:00
Jez Ng d4bcb45db7 [MC][re-land] Omit DWARF unwind info if compact unwind is present where eligible
This reverts commit d941d59783.

Differential Revision: https://reviews.llvm.org/D122258
2022-06-12 17:24:19 -04:00
Jez Ng d941d59783 Revert "[MC] Omit DWARF unwind info if compact unwind is present where eligible"
This reverts commit ef501bf85d.
2022-06-12 10:47:08 -04:00
Jez Ng ef501bf85d [MC] Omit DWARF unwind info if compact unwind is present where eligible
Previously, omitting unnecessary DWARF unwinds was only done in two
cases:
* For Darwin + aarch64, if no DWARF unwind info is needed for all the
  functions in a TU, then the `__eh_frame` section would be omitted
  entirely. If any one function needed DWARF unwind, then MC would emit
  DWARF unwind entries for all the functions in the TU.
* For watchOS, MC would omit DWARF unwind on a per-function basis, as
  long as compact unwind was available for that function.

This diff makes it so that we omit DWARF unwind on a per-function basis
for Darwin + aarch64 as well. In addition, we introduce the flag
`--emit-dwarf-unwind=` which can toggle between `always`,
`no-compact-unwind` (only emit DWARF when CU cannot be emitted for a
given function), and the target platform `default`.  `no-compact-unwind`
is particularly useful for newer x86_64 platforms: we don't want to omit
DWARF unwind for x86_64 in general due to possible backwards compat
issues, but we should make it possible for people to opt into this
behavior if they are only targeting newer platforms.

**Motivation:** I'm working on adding support for `__eh_frame` to LLD,
but I'm concerned that we would suffer a perf hit. Processing compact
unwind is already expensive, and that's a simpler format than EH frames.
Given that MC currently produces one EH frame entry for every compact
unwind entry, I don't think processing them will be cheap. I tried to do
something clever on LLD's end to drop the unnecessary EH frames at parse
time, but this made the code significantly more complex. So I'm looking
at fixing this at the MC level instead.

**Addendum:** It turns out that there was a latent bug in the X86
backend when `OmitDwarfIfHaveCompactUnwind` is naively enabled, which is
not too surprising given that this combination has not been heretofore
used.

For functions that have unwind info that cannot be encoded with CU, MC
would end up dropping both the compact unwind entry (OK; existing
behavior) as well as the DWARF entries (not OK).  This diff fixes things
so that we emit the DWARF entry, as well as a CU entry with encoding
`UNWIND_X86_MODE_DWARF` -- this basically tells the unwinder to look for
the DWARF entry. I'm not 100% sure the `UNWIND_X86_MODE_DWARF` CU entry
is necessary, this was the simplest fix. ld64 seems to be able to handle
both the absence and presence of this CU entry. Ultimately ld64 (and
LLD) will synthesize `UNWIND_X86_MODE_DWARF` if it is absent, so there
is no impact to the final binary size.

Reviewed By: davide, lhames

Differential Revision: https://reviews.llvm.org/D122258
2022-06-12 10:03:56 -04:00