summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src/mir
AgeCommit message (Collapse)AuthorLines
2021-04-21rustc: Use LLVM's new saturating float-to-int intrinsicsAlex Crichton-132/+36
This commit updates rustc, with an applicable LLVM version, to use LLVM's new `llvm.fpto{u,s}i.sat.*.*` intrinsics to implement saturating floating-point-to-int conversions. This results in a little bit tighter codegen for x86/x86_64, but the main purpose of this is to prepare for upcoming changes to the WebAssembly backend in LLVM where wasm's saturating float-to-int instructions will now be implemented with these intrinsics. This change allows simplifying a good deal of surrounding code, namely removing a lot of wasm-specific behavior. WebAssembly no longer has any special-casing of saturating arithmetic instructions and the need for `fptoint_may_trap` is gone and all handling code for that is now removed. This means that the only wasm-specific logic is in the `fpto{s,u}i` instructions which only get used for "out of bounds is undefined behavior". This does mean that for the WebAssembly target specifically the Rust compiler will no longer be 100% compatible with pre-LLVM 12 versions, but it seems like that's unlikely to be relied on by too many folks. Note that this change does immediately regress the codegen of saturating float-to-int casts on WebAssembly due to the specialization of the LLVM intrinsic not being present in our LLVM fork just yet. I'll be following up with an LLVM update to pull in those patches, but affects a few other SIMD things in flight for WebAssembly so I wanted to separate this change. Eventually the entire `cast_float_to_int` function can be removed when LLVM 12 is the minimum version, but that will require sinking the complexity of it into other backends such as Cranelfit.
2021-04-08Fix closed over variables not available in debuginfo for Windows MSVCWesley Wiser-15/+51
The issue was that the resulting debuginfo was too complex for LLVM to translate into CodeView records correctly. As a result, it simply ignored the debuginfo which meant Windows debuggers could not display any closed over variables when stepping inside a closure. This fixes that by spilling additional variables to the stack so that the resulting debuginfo is simple (just `*my_variable.dbg.spill`) and LLVM can generate the correct CV records.
2021-04-07Rollup merge of #83916 - Amanieu:asm_anonconst, r=petrochenkovDylan DPC-34/+30
Use AnonConst for asm! constants This replaces the old system which used explicit promotion. See #83169 for more background. The syntax for `const` operands is still the same as before: `const <expr>`. Fixes #83169 Because the implementation is heavily based on inline consts, we suffer from the same issues: - We lose the ability to use expressions derived from generics. See the deleted tests in `src/test/ui/asm/const.rs`. - We are hitting the same ICEs as inline consts, for example #78174. It is unlikely that we will be able to stabilize this before inline consts are stabilized.
2021-04-06Use AnonConst for asm! constantsAmanieu d'Antras-34/+30
2021-04-02Translate counters from Rust 1-based to LLVM 0-based counter idsRich Kadel-1/+1
A colleague contacted me and asked why Rust's counters start at 1, when Clangs appear to start at 0. There is a reason why Rust's internal counters start at 1 (see the docs), and I tried to keep them consistent when codegenned to LLVM's coverage mapping format. LLVM should be tolerant of missing counters, but as my colleague pointed out, `llvm-cov` will silently fail to generate a coverage report for a function based on LLVM's assumption that the counters are 0-based. See: https://github.com/llvm/llvm-project/blob/main/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp#L170 Apparently, if, for example, a function has no branches, it would have exactly 1 counter. `CounterValues.size()` would be 1, and (with the 1-based index), the counter ID would be 1. This would fail the check and abort reporting coverage for the function. It turns out that by correcting for this during coverage map generation, by subtracting 1 from the Rust Counter ID (both when generating the counter increment intrinsic call, and when adding counters to the map), some uncovered functions (including in tests) now appear covered! This corrects the coverage for a few tests!
2021-03-26Use iter::zip in compiler/Josh Stone-3/+1
2021-03-25Auto merge of #83307 - richkadel:cov-unused-functions-1.1, r=tmandrybors-1/+1
coverage bug fixes and optimization support Adjusted LLVM codegen for code compiled with `-Zinstrument-coverage` to address multiple, somewhat related issues. Fixed a significant flaw in prior coverage solution: Every counter generated a new counter variable, but there should have only been one counter variable per function. This appears to have bloated .profraw files significantly. (For a small program, it increased the size by about 40%. I have not tested large programs, but there is anecdotal evidence that profraw files were way too large. This is a good fix, regardless, but hopefully it also addresses related issues. Fixes: #82144 Invalid LLVM coverage data produced when compiled with -C opt-level=1 Existing tests now work up to at least `opt-level=3`. This required a detailed analysis of the LLVM IR, comparisons with Clang C++ LLVM IR when compiled with coverage, and a lot of trial and error with codegen adjustments. The biggest hurdle was figuring out how to continue to support coverage results for unused functions and generics. Rust's coverage results have three advantages over Clang's coverage results: 1. Rust's coverage map does not include any overlapping code regions, making coverage counting unambiguous. 2. Rust generates coverage results (showing zero counts) for all unused functions, including generics. (Clang does not generate coverage for uninstantiated template functions.) 3. Rust's unused functions produce minimal stubbed functions in LLVM IR, sufficient for including in the coverage results; while Clang must generate the complete LLVM IR for each unused function, even though it will never be called. This PR removes the previous hack of attempting to inject coverage into some other existing function instance, and generates dedicated instances for each unused function. This change, and a few other adjustments (similar to what is required for `-C link-dead-code`, but with lower impact), makes it possible to support LLVM optimizations. Fixes: #79651 Coverage report: "Unexecuted instantiation:..." for a generic function from multiple crates Fixed by removing the aforementioned hack. Some "Unexecuted instantiation" notices are unavoidable, as explained in the `used_crate.rs` test, but `-Zinstrument-coverage` has new options to back off support for either unused generics, or all unused functions, which avoids the notice, at the cost of less coverage of unused functions. Fixes: #82875 Invalid LLVM coverage data produced with crate brotli_decompressor Fixed by disabling the LLVM function attribute that forces inlining, if `-Z instrument-coverage` is enabled. This attribute is applied to Rust functions with `#[inline(always)], and in some cases, the forced inlining breaks coverage instrumentation and reports. FYI: `@wesleywiser` r? `@tmandry`
2021-03-20update `const_eval_resolve`lcnr-2/+2
2021-03-20extract `ConstKind::Unevaluated` into a structlcnr-1/+1
2021-03-19coverage bug fixes and optimization supportRich Kadel-1/+1
Adjusted LLVM codegen for code compiled with `-Zinstrument-coverage` to address multiple, somewhat related issues. Fixed a significant flaw in prior coverage solution: Every counter generated a new counter variable, but there should have only been one counter variable per function. This appears to have bloated .profraw files significantly. (For a small program, it increased the size by about 40%. I have not tested large programs, but there is anecdotal evidence that profraw files were way too large. This is a good fix, regardless, but hopefully it also addresses related issues. Fixes: #82144 Invalid LLVM coverage data produced when compiled with -C opt-level=1 Existing tests now work up to at least `opt-level=3`. This required a detailed analysis of the LLVM IR, comparisons with Clang C++ LLVM IR when compiled with coverage, and a lot of trial and error with codegen adjustments. The biggest hurdle was figuring out how to continue to support coverage results for unused functions and generics. Rust's coverage results have three advantages over Clang's coverage results: 1. Rust's coverage map does not include any overlapping code regions, making coverage counting unambiguous. 2. Rust generates coverage results (showing zero counts) for all unused functions, including generics. (Clang does not generate coverage for uninstantiated template functions.) 3. Rust's unused functions produce minimal stubbed functions in LLVM IR, sufficient for including in the coverage results; while Clang must generate the complete LLVM IR for each unused function, even though it will never be called. This PR removes the previous hack of attempting to inject coverage into some other existing function instance, and generates dedicated instances for each unused function. This change, and a few other adjustments (similar to what is required for `-C link-dead-code`, but with lower impact), makes it possible to support LLVM optimizations. Fixes: #79651 Coverage report: "Unexecuted instantiation:..." for a generic function from multiple crates Fixed by removing the aforementioned hack. Some "Unexecuted instantiation" notices are unavoidable, as explained in the `used_crate.rs` test, but `-Zinstrument-coverage` has new options to back off support for either unused generics, or all unused functions, which avoids the notice, at the cost of less coverage of unused functions. Fixes: #82875 Invalid LLVM coverage data produced with crate brotli_decompressor Fixed by disabling the LLVM function attribute that forces inlining, if `-Z instrument-coverage` is enabled. This attribute is applied to Rust functions with `#[inline(always)], and in some cases, the forced inlining breaks coverage instrumentation and reports.
2021-03-18Rollup merge of #83080 - tmiasko:inline-coverage, r=wesleywiserDylan DPC-8/+19
Make source-based code coverage compatible with MIR inlining When codegenning code coverage use the instance that coverage data was originally generated for, to ensure basic level of compatibility with MIR inlining. Fixes #83061
2021-03-16Auto merge of #82936 - oli-obk:valtree, r=RalfJung,lcnr,matthewjasperbors-12/+13
Implement (but don't use) valtree and refactor in preparation of use This PR does not cause any functional change. It refactors various things that are needed to make valtrees possible. This refactoring got big enough that I decided I'd want it reviewed as a PR instead of trying to make one huge PR with all the changes. cc `@rust-lang/wg-const-eval` on the following commits: * 2027184 implement valtree * eeecea9 fallible Scalar -> ScalarInt * 042f663 ScalarInt convenience methods cc `@eddyb` on ef04a6d cc `@rust-lang/wg-mir-opt` for cf1700c (`mir::Constant` can now represent either a `ConstValue` or a `ty::Const`, and it is totally possible to have two different representations for the same value)
2021-03-15Make source-based code coverage compatible with MIR inliningTomasz Miąsko-8/+19
When codegenning code coverage use the instance that coverage data was originally generated for, to ensure basic level of compatibility with MIR inlining.
2021-03-15s/ConstantSource/ConstantKind/Oli Scherer-2/+2
2021-03-13Do not emit alloca for ZST local even if it is uninitializedSimon Vandel Sillesen-1/+12
2021-03-12Prepare mir::Constant for ty::Const only supporting valtreesOli Scherer-2/+7
2021-03-12Add `ty` helper function for mir constantsOli Scherer-10/+6
This is in preparation of the `literal` field becoming an enum that distinguishes between type level constants and runtime constants
2021-03-12Emit the enum range assumption if the range only contains one elementhi-rustin-1/+1
test: add test case make tidy happy
2021-03-10Remove the -Zinsert-sideeffectSimonas Kazlauskas-52/+8
This removes all of the code we had in place to work-around LLVM's handling of forward progress. From this removal excluded is a workaround where we'd insert a `sideeffect` into clearly infinite loops such as `loop {}`. This code remains conditionally effective when the LLVM version is earlier than 12.0, which fixed the forward progress related miscompilations at their root.
2021-03-09Switch to changing cp_non_overlap in tformkadmin-24/+2
It was suggested to lower this in MIR instead of ssa, so do that instead.
2021-03-09Build StKind::CopyOverlappingkadmin-73/+84
This replaces where it was previously being constructed in intrinsics, with direct construction of the Statement.
2021-03-09Change CopyNonOverlapping::codegen_ssakadmin-13/+15
Fixes copy_non_overlapping codegen_ssa to properly handle pointees, and use bytes instead of elem count
2021-03-09Replace todos with implskadmin-2/+1
Changed to various implementations, copying the style of prior function calls in places I was unsure of. Also one minor style nit.
2021-03-09Update craneliftkadmin-6/+5
2021-03-09Update match brancheskadmin-12/+14
This updates all places where match branches check on StatementKind or UseContext. This doesn't properly implement them, but adds TODOs where they are, and also adds some best guesses to what they should be in some cases.
2021-03-09Update fmt and use of memcpykadmin-9/+14
I'm still not totally sure if this is the right way to implement the memcpy, but that portion compiles correctly now. Now to fix the compile errors everywhere else :).
2021-03-09Impl StatementKind::CopyNonOverlappingkadmin-2/+19
2021-03-05Shrink the size of Rvalue by 16 bytesOli Scherer-2/+2
2021-02-23Rollup merge of #82091 - henryboisdequin:use-place-ref-more, r=RalfJungDylan DPC-1/+1
use PlaceRef abstractions more consistently Addresses this [comment](https://github.com/rust-lang/rust/pull/80865/files#r558978715) Associated issue: #80647 r? ```@RalfJung```
2021-02-17Rollup merge of #81898 - ↵Dylan DPC-5/+25
nanguye2496:nanguye2496/fix_str_and_slice_visualization, r=varkor Fix debug information for function arguments of type &str or slice. Issue details: When lowering MIR to LLVM IR, the compiler decomposes every &str and slice argument into a data pointer and a usize. Then, the original argument is reconstructed from the pointer and the usize arguments in the body of the function that owns it. Since the original argument is declared in the body of a function, it should be marked as a LocalVariable instead of an ArgumentVairable. This confusion causes MSVC debuggers unable to visualize &str and slice arguments correctly. (See https://github.com/rust-lang/rust/issues/81894 for more details). Fix details: Making sure that the debug variable for every &str and slice argument is marked as LocalVariable instead of ArgumentVariable in computing_per_local_var_debug_info. This change has been verified on VS Code debugger, VS debugger, WinDbg and LLDB.
2021-02-16make `visit_projection` take a `PlaceRef`Henry Boisdequin-1/+1
2021-02-16avoid full-slicing slicesMatthias Krüger-1/+1
If we already have a slice, there is no need to get another full-range slice from that, just use the original. clippy::redundant_slicing
2021-02-09Set the kind for local variables created by &str and slice arguments to ↵Nam Nguyen-5/+25
LocalVariable
2021-01-31Auto merge of #81327 - RalfJung:codegen-no-const-fail, r=oli-obkbors-21/+12
codegen: assume constants cannot fail to evaluate https://github.com/rust-lang/rust/pull/80579 landed, so we can finally remove this old hack from codegen and instead assume that consts never fail to evaluate. :) r? `@oli-obk`
2021-01-30codegen: assume constants cannot fail to evaluateRalf Jung-21/+12
also don't submit code to LLVM when the session has errors
2021-01-29Rollup merge of #81333 - RalfJung:const-err-simplify, r=oli-obkYuki Okushi-6/+1
clean up some const error reporting around promoteds These are some error reporting simplifications enabled by https://github.com/rust-lang/rust/pull/80579. Further simplifications are possible but could be blocked on making `const_err` a hard error. r? ``````@oli-obk``````
2021-01-28Rollup merge of #79951 - LeSeulArtichaut:ty-ir, r=nikomatsakisYuki Okushi-12/+8
Refractor a few more types to `rustc_type_ir` In the continuation of #79169, ~~blocked on that PR~~. This PR: - moves `IntVarValue`, `FloatVarValue`, `InferTy` (and friends) and `Variance` - creates the `IntTy`, `UintTy` and `FloatTy` enums in `rustc_type_ir`, based on their `ast` and `chalk_ir` equilavents, and uses them for types in the rest of the compiler. ~~I will split up that commit to make this easier to review and to have a better commit history.~~ EDIT: done, I split the PR in commits of 200-ish lines each r? `````@nikomatsakis````` cc `````@jackh726`````
2021-01-24clean up some const error reporting around promotedsRalf Jung-6/+1
2021-01-18Use ty::{IntTy,UintTy,FloatTy} in rustcLeSeulArtichaut-12/+8
2021-01-16PlaceRef::ty: use method call syntaxRalf Jung-2/+2
2021-01-07Auto merge of #80200 - mahkoh:dst-offset, r=nagisabors-10/+44
Optimize DST field access For struct X<T: ?Sized>(T) struct Y<T: ?Sized>(u8, T) the offset of the unsized field is 0 mem::align_of_val(&self.1) respectively. This patch changes the expression used to compute these offsets so that the optimizer can perform this optimization. Consider ```rust fn f(x: &X<dyn Any>) -> &dyn Any { &x.0 } ``` Before: ```asm test: movq %rsi, %rdx movq 16(%rsi), %rax leaq -1(%rax), %rcx negq %rax andq %rcx, %rax addq %rdi, %rax retq ``` After: ```asm test: movq %rsi, %rdx movq %rdi, %rax retq ```
2021-01-03use PlaceRef more consistently instead of loosely coupled local+projectionRalf Jung-9/+4
2020-12-30Rollup merge of #80495 - jyn514:rename-empty, r=petrochenkovMara Bos-2/+2
Rename kw::Invalid -> kw::Empty See https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Is.20there.20a.20symbol.20for.20the.20empty.20string.3F/near/220054471 for context. r? `@petrochenkov`
2020-12-30Rename kw::Invalid -> kw::EmptyJoshua Nelson-2/+2
See https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Is.20there.20a.20symbol.20for.20the.20empty.20string.3F/near/220054471 for context.
2020-12-30where possible, pass slices instead of &Vec or &String (clippy::ptr_arg)Matthias Krüger-1/+1
2020-12-24use matches!() macro in more placesMatthias Krüger-4/+4
2020-12-20Use pointer type in AtomicPtr::swap implementationTomasz Miąsko-2/+13
2020-12-19Optimize DST field accessJulian Orth-10/+44
For struct X<T: ?Sized>(T) struct Y<T: ?Sized>(u8, T) the offset of the unsized field is 0 mem::align_of_val(&self.1) respectively. This patch changes the expression used to compute these offsets so that the optimizer can perform this optimization. Consider ```rust fn test(x: &X<dyn Any>) -> &dyn Any { &x.0 } ``` Before: ```asm test: movq %rsi, %rdx movq 16(%rsi), %rax leaq -1(%rax), %rcx negq %rax andq %rcx, %rax addq %rdi, %rax retq ``` After: ```asm test: movq %rsi, %rdx movq %rdi, %rax retq ```
2020-12-15Always run intrinsics lowering passTomasz Miąsko-15/+1
Move intrinsics lowering pass from the optimization phase (where it would not run if -Zmir-opt-level=0), to the drop lowering phase where it runs unconditionally. The implementation of those intrinsics in code generation and interpreter is unnecessary. Remove it.
2020-12-15Auto merge of #73210 - wesleywiser:consts_in_debuginfo, r=oli-obkbors-35/+76
[mir-opt] Allow debuginfo to be generated for a constant or a Place Prior to this commit, debuginfo was always generated by mapping a name to a Place. This has the side-effect that `SimplifyLocals` cannot remove locals that are only used for debuginfo because their other uses have been const-propagated. To allow these locals to be removed, we now allow debuginfo to point to a constant value. The `ConstProp` pass detects when debuginfo points to a local with a known constant value and replaces it with the value. This allows the later `SimplifyLocals` pass to remove the local.