Diagnose use of incompatible sanitizers
Emit an error when incompatible sanitizer are configured through command
line options. Previously the last one configured prevailed and others
were silently ignored.
Additionally use a set to represent configured sanitizers, making it
possible to enable multiple sanitizers at once. At least in principle,
since currently all of them are considered to be incompatible with
others.
first stage of implementing LLVM code coverage
This PR replaces #70680 (WIP toward LLVM Code Coverage for Rust) since I am re-implementing the Rust LLVM code coverage feature in a different part of the compiler (in MIR pass(es) vs AST).
This PR updates rustc with `-Zinstrument-coverage` option that injects the llvm intrinsic `instrprof.increment()` for code generation.
This initial version only injects counters at the top of each function, and does not yet implement the required coverage map.
Upcoming PRs will add the coverage map, and add more counters and/or counter expressions for each conditional code branch.
Rust compiler MCP https://github.com/rust-lang/compiler-team/issues/278
Relevant issue: #34701 - Implement support for LLVMs code coverage instrumentation
***[I put together some development notes here, under a separate branch.](cfa0b21d34/src/test/codegen/coverage-experiments/README-THIS-IS-TEMPORARY.md)***
This initial version only injects counters at the top of each function.
Rust Coverage will require injecting additional counters at each
conditional code branch.
Emit an error when incompatible sanitizer are configured through command
line options. Previously the last one configured prevailed and others
were silently ignored.
Additionally use a set to represent configured sanitizers, making it
possible to enable multiple sanitizers at once. At least in principle,
since currently all of them are considered to be incompatible with
others.
Enable AVR as a Tier 3 target upstream
Tracking issue: #44052.
Things intentionally left out of the initial upstream:
* The `target_cpu` flag
I have made the cleanup suggestions by @jplatte and @jplatte in 043550d9db.
Anybody feel free to give the branch a test and see how it fares, or make suggestions on the code patch itself.
Ensure that inliner inserts lifetime markers if they have been emitted during
codegen. Otherwise if allocas from inlined functions are merged together,
lifetime markers from one function might invalidate load & stores performed
by the other one.
rustllvm: Use .init_array rather than .ctors
LLVM TargetMachines default to using the (now-legacy) .ctors
representation of init functions. Mixing .ctors and .init_array
representations can cause issues when linking with lld.
This happens in practice for:
* Our profiling runtime which is currently implicitly built with
.init_array since it is built by clang, which sets this field.
* External C/C++ code that may be linked into the same process.
Fixes: #71233
Store LLVM bitcode in object files, not compressed
This commit is an attempted resurrection of #70458 where LLVM bitcode
emitted by rustc into rlibs is stored into object file sections rather
than in a separate file. The main rationale for doing this is that when
rustc emits bitcode it will no longer use a custom compression scheme
which makes it both easier to interoperate with existing tools and also
cuts down on compile time since this compression isn't happening.
The blocker for this in #70458 turned out to be that native linkers
didn't handle the new sections well, causing the sections to either
trigger bugs in the linker or actually end up in the final linked
artifact. This commit attempts to address these issues by ensuring that
native linkers ignore the new sections by inserting custom flags with
module-level inline assembly.
Note that this does not currently change the API of the compiler at all.
The pre-existing `-C bitcode-in-rlib` flag is co-opted to indicate
whether the bitcode should be present in the object file or not.
Finally, note that an important consequence of this commit, which is also
one of its primary purposes, is to enable rustc's `-Clto` bitcode
loading to load rlibs produced with `-Clinker-plugin-lto`. The goal here
is that when you're building with LTO Cargo will tell rustc to skip
codegen of all intermediate crates and only generate LLVM IR. Today
rustc will generate both object code and LLVM IR, but the object code is
later simply thrown away, wastefully.
LLVM TargetMachines default to using the (now-legacy) .ctors
representation of init functions. Mixing .ctors and .init_array
representations can cause issues when linking with lld.
This happens in practice for:
* Our profiling runtime which is currently implicitly built with
.init_array since it is built by clang, which sets this field.
* External C/C++ code that may be linked into the same process.
To support legacy systems which may use .ctors, targets may now specify
that they use .ctors via the use_ctors attribute which defaults to
false.
For debugging and manual control, -Z use-ctors-section=yes/no will allow
manual override.
Fixes: #71233
This commit is an attempted resurrection of #70458 where LLVM bitcode
emitted by rustc into rlibs is stored into object file sections rather
than in a separate file. The main rationale for doing this is that when
rustc emits bitcode it will no longer use a custom compression scheme
which makes it both easier to interoperate with existing tools and also
cuts down on compile time since this compression isn't happening.
The blocker for this in #70458 turned out to be that native linkers
didn't handle the new sections well, causing the sections to either
trigger bugs in the linker or actually end up in the final linked
artifact. This commit attempts to address these issues by ensuring that
native linkers ignore the new sections by inserting custom flags with
module-level inline assembly.
Note that this does not currently change the API of the compiler at all.
The pre-existing `-C bitcode-in-rlib` flag is co-opted to indicate
whether the bitcode should be present in the object file or not.
Finally, note that an important consequence of this commit, which is also
one of its primary purposes, is to enable rustc's `-Clto` bitcode
loading to load rlibs produced with `-Clinker-plugin-lto`. The goal here
is that when you're building with LTO Cargo will tell rustc to skip
codegen of all intermediate crates and only generate LLVM IR. Today
rustc will generate both object code and LLVM IR, but the object code is
later simply thrown away, wastefully.
The default ThinLTO pre-link pipeline does not include optimizer last
extension points. Thus, when using the new LLVM pass manager & ThinLTO
& sanitizers on any opt-level different from zero, the sanitizer
function passes would be omitted from the pipeline.
Add optimizer last extensions points manually to the pipeline, but guard
registration with stage check in the case this behaviour changes in the
future.
Support new LLVM pass manager
Add support for the new LLVM pass manager behind a `-Z new-llvm-pass-manager=on` option. Both the pre-link optimization and LTO pipelines use the new pass manager. There's some bits that are not supported yet:
* `-C passes`. NewPM requires an entirely different way of specifying custom pass pipelines. We should probably expose that functionality, but it doesn't directly map to what `-C passes` does.
* NewPM has no support for custom inline parameters right now. We'd have to add upstream support for that first.
* NewPM does not support PGO at O0 in LLVM 9 (which is why those tests fail with NewPM enabled). This is supported in LLVM 10.
* NewPM does not support MergeFunctions in LLVM 9. I've landed this upstream just before the cut, so we'll be able to re-enable that with LLVM 10.
Closes#64289.
r? @ghost
Enable use-after-scope checks by default when using AddressSanitizer.
They allow to detect incorrect use of stack objects after their scope
have already ended. The detection is based on LLVM lifetime intrinsics.
To facilitate the use of this functionality, the lifetime intrinsics are
now emitted regardless of optimization level if enabled sanitizer makes
use of them.