summary refs log tree commit diff
path: root/src/librustc_codegen_ssa/mir
AgeCommit message (Collapse)AuthorLines
2020-07-02Rollup merge of #73724 - CryZe:wasm-saturating-casts, r=alexcrichtonManish Goregaokar-3/+8
Use WASM's saturating casts if they are available WebAssembly supports saturating floating point to integer casts behind a target feature. The feature is already available on many browsers. Beginning with 1.45 Rust will start defining the behavior of floating point to integer casts to be saturating as well. For this Rust constructs additional checks on top of the `fptoui` / `fptosi` instructions it emits. Here we introduce the possibility for the codegen backend to construct saturating casts itself and only fall back to constructing the checks ourselves if that is not possible. Resolves part of #73591
2020-07-02Use WASM's saturating casts if they are availableChristopher Serr-3/+8
WebAssembly supports saturating floating point to integer casts behind a target feature. The feature is already available on many browsers. Beginning with 1.45 Rust will start defining the behavior of floating point to integer casts to be saturating as well. For this Rust constructs additional checks on top of the `fptoui` / `fptosi` instructions it emits. Here we introduce the possibility for the codegen backend to construct saturating casts itself and only fall back to constructing the checks ourselves if that is not possible.
2020-06-29add spans to injected coverage countersRich Kadel-1/+13
added regions with counter expressions and counters. Added codegen_llvm/coverageinfo mod for upcoming coverage map Move coverage region collection to CodegenCx finalization Moved from `query coverageinfo` (renamed from `query coverage_data`), as discussed in the PR at: https://github.com/rust-lang/rust/pull/73684#issuecomment-649882503 Address merge conflict in MIR instrument_coverage test The MIR test output format changed for int types. moved debug messages out of block.rs This makes the block.rs calls to add coverage mapping data to the CodegenCx much more concise and readable. move coverage intrinsic handling into llvm impl I realized that having half of the coverage intrinsic handling in `rustc_codegen_ssa` and half in `rustc_codegen_llvm` meant that any non-llvm backend would be bound to the same decisions about how the coverage-related MIR terminators should be handled. To fix this, I moved the non-codegen portion of coverage intrinsic handling into its own trait, and implemented it in `rustc_codegen_llvm` alongside `codegen_intrinsic_call`. I also added the (required?) stubs for the new intrinsics to `IntrepretCx::emulate_intrinsic()`, to ensure calls to this function do not fail if called with these new but known intrinsics. address PR Feedback on 28 June 2020 2:48pm PDT
2020-06-26Show the values and computation that would overflow a const evaluation or ↵Oliver Scherer-1/+1
propagation
2020-06-21remove switch_ty reliance in codegenRalf Jung-0/+2
2020-06-19Rollup merge of #73011 - richkadel:llvm-count-from-mir-pass, r=tmandryRalf Jung-0/+1
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.](https://github.com/richkadel/rust/blob/cfa0b21d34ee64e4ebee226101bd2ef0c6757865/src/test/codegen/coverage-experiments/README-THIS-IS-TEMPORARY.md)***
2020-06-19Rollup merge of #72497 - RalfJung:tag-term, r=oli-obkRalf Jung-22/+22
tag/niche terminology cleanup The term "discriminant" was used in two ways throughout the compiler: * every enum variant has a corresponding discriminant, that can be given explicitly with `Variant = N`. * that discriminant is then encoded in memory to store which variant is active -- but this encoded form of the discriminant was also often called "discriminant", even though it is conceptually quite different (e.g., it can be smaller in size, or even use niche-filling). After discussion with @eddyb, this renames the second term to "tag". The way the tag is encoded can be either `TagEncoding::Direct` (formerly `DiscriminantKind::Tag`) or `TagEncoding::Niche` (formerly `DiscrimianntKind::Niche`). This finally resolves some long-standing confusion I had about the handling of variant indices and discriminants, which surfaced in https://github.com/rust-lang/rust/pull/72419. (There is also a `DiscriminantKind` type in libcore, it remains unaffected. I think this corresponds to the discriminant, not the tag, so that seems all right.) r? @eddyb
2020-06-16rename location field of Drop terminators to placeRalf Jung-2/+2
2020-06-16remove visit_terminator_kind from MIR visitorRalf Jung-3/+3
2020-06-15Add case for count_code_region() extern lang_itemRich Kadel-4/+1
As suggested in PR feedback: https://github.com/rust-lang/rust/pull/73011#discussion_r435728923 This allows count_code_region() to be handled like a normal intrinsic so the InstanceDef::InjectedCode variant is no longer needed.
2020-06-15[WIP] injects llvm intrinsic instrprof.increment for coverage reportsRich Kadel-1/+5
This initial version only injects counters at the top of each function. Rust Coverage will require injecting additional counters at each conditional code branch.
2020-06-12Rollup merge of #73033 - Amanieu:asm-tls, r=oli-obkDylan DPC-6/+2
Fix #[thread_local] statics as asm! sym operands The `asm!` RFC specifies that `#[thread_local]` statics may be used as `sym` operands for inline assembly. This also fixes a regression in the handling of `#[thread_local]` during monomorphization which caused link-time errors with multiple codegen units, most likely introduced by #71192. r? @oli-obk
2020-06-11Rollup merge of #73182 - Aaron1011:feature/call-fn-span, r=matthewjasperDylan DPC-2/+10
Track span of function in method calls, and use this in #[track_caller] Fixes #69977 When we parse a chain of method calls like `foo.a().b().c()`, each `MethodCallExpr` gets assigned a span that starts at the beginning of the call chain (`foo`). While this is useful for diagnostics, it means that `Location::caller` will return the same location for every call in a call chain. This PR makes us separately record the span of the function name and arguments for a method call (e.g. `b()` in `foo.a().b().c()`). This `Span` is passed through HIR lowering and MIR building to `TerminatorKind::Call`, where it is used in preference to `Terminator.source_info.span` when determining `Location::caller`. This new span is also useful for diagnostics where we want to emphasize a particular method call - for an example, see https://github.com/rust-lang/rust/pull/72389#discussion_r436035990
2020-06-10Track span of function in method calls, and use this in #[track_caller]Aaron Hill-2/+10
Fixes #69977 When we parse a chain of method calls like `foo.a().b().c()`, each `MethodCallExpr` gets assigned a span that starts at the beginning of the call chain (`foo`). While this is useful for diagnostics, it means that `Location::caller` will return the same location for every call in a call chain. This PR makes us separately record the span of the function name and arguments for a method call (e.g. `b()` in `foo.a().b().c()`). This `Span` is passed through HIR lowering and MIR building to `TerminatorKind::Call`, where it is used in preference to `Terminator.source_info.span` when determining `Location::caller`. This new span is also useful for diagnostics where we want to emphasize a particular method call - for an example, see https://github.com/rust-lang/rust/pull/72389#discussion_r436035990
2020-06-09Fix more clippy warningsMatthias Krüger-1/+1
Fixes more of: clippy::unused_unit clippy::op_ref clippy::useless_format clippy::needless_return clippy::useless_conversion clippy::bind_instead_of_map clippy::into_iter_on_ref clippy::redundant_clone clippy::nonminimal_bool clippy::redundant_closure clippy::option_as_ref_deref clippy::len_zero clippy::iter_cloned_collect clippy::filter_next
2020-06-07rename FalseEdges -> FalseEdgeRalf Jung-2/+2
2020-06-06Fix #[thread_local] statics as asm! sym operandsAmanieu d'Antras-6/+2
2020-06-01Auto merge of #71192 - oli-obk:eager_alloc_id_canonicalization, r=wesleywiserbors-0/+8
Make TLS accesses explicit in MIR r? @rust-lang/wg-mir-opt cc @RalfJung @vakaras for miri thread locals cc @bjorn3 for cranelift fixes #70685
2020-05-30Rollup merge of #72625 - Amanieu:asm-srcloc, r=petrochenkovRalf Jung-2/+10
Improve inline asm error diagnostics Previously we were just using the raw LLVM error output (with line, caret, etc) as the diagnostic message, which ends up looking rather out of place with our existing diagnostics. The new diagnostics properly format the diagnostics and also take advantage of LLVM's per-line `srcloc` attribute to map an error in inline assembly directly to the relevant line of source code. Incidentally also fixes #71639 by disabling `srcloc` metadata during LTO builds since we don't know what crate it might have come from. We can only resolve `srcloc`s from the currently crate since it indexes into the source map for the current crate. Fixes #72664 Fixes #71639 r? @petrochenkov ### Old style ```rust #![feature(llvm_asm)] fn main() { unsafe { let _x: i32; llvm_asm!( "mov $0, $1 invalid_instruction $0, $1 mov $0, $1" : "=&r" (_x) : "r" (0) :: "intel" ); } } ``` ``` error: <inline asm>:3:14: error: invalid instruction mnemonic 'invalid_instruction' invalid_instruction ecx, eax ^~~~~~~~~~~~~~~~~~~ --> src/main.rs:6:9 | 6 | / llvm_asm!( 7 | | "mov $0, $1 8 | | invalid_instruction $0, $1 9 | | mov $0, $1" ... | 12 | | :: "intel" 13 | | ); | |__________^ ``` ### New style ```rust #![feature(asm)] fn main() { unsafe { asm!( "mov {0}, {1} invalid_instruction {0}, {1} mov {0}, {1}", out(reg) _, in(reg) 0i64, ); } } ``` ``` error: invalid instruction mnemonic 'invalid_instruction' --> test.rs:7:14 | 7 | invalid_instruction {0}, {1} | ^ | note: instantiated into assembly here --> <inline asm>:3:14 | 3 | invalid_instruction rax, rcx | ^^^^^^^^^^^^^^^^^^^ ```
2020-05-30tag/niche terminology cleanupRalf Jung-22/+22
2020-05-30Rollup merge of #72521 - Amanieu:fix-72484, r=petrochenkovRalf Jung-2/+1
Properly handle InlineAsmOperand::SymFn when collecting monomorphized items Fixes #72484
2020-05-30Make TLS accesses explicit in MIROliver Scherer-0/+8
2020-05-29Improve inline asm error diagnosticsAmanieu d'Antras-2/+10
2020-05-28Auto merge of #72494 - lcnr:predicate-cleanup, r=nikomatsakisbors-9/+9
Pass more `Copy` types by value. There are a lot of locations where we pass `&T where T: Copy` by reference, which should both be slightly less performant and less readable IMO. This PR currently consists of three fairly self contained commits: - passes `ty::Predicate` by value and stops depending on `AsRef<ty::Predicate>`. - changes `<&List<_>>::into_iter` to iterate over the elements by value. This would break `List`s of non copy types. But as the only list constructor requires `T` to be copy anyways, I think the improved readability is worth this potential future restriction. - passes `mir::PlaceElem` by value. Mir currently has quite a few copy types which are passed by reference, e.g. `Local`. As I don't have a lot of experience working with MIR, I mostly did this to get some feedback from people who use MIR more frequently - tries to reuse `ty::Predicate` in case it did not change in some places, which should hopefully fix the regression caused by #72055 r? @nikomatsakis for the first commit, which continues the work of #72055 and makes adding `PredicateKind::ForAll` slightly more pleasant. Feel free to reassign though
2020-05-24Removed all instances of const_field.Rakshith Ravi-10/+6
2020-05-24Properly handle InlineAsmOperand::SymFn when collecting monomorphized itemsAmanieu d'Antras-2/+1
Fixes #72484
2020-05-23take mir::PlaceElem by valueBastian Kauschke-9/+9
2020-05-21Auto merge of #72205 - ecstatic-morse:nrvo, r=oli-obkbors-1/+2
Dumb NRVO This is a very simple version of an NRVO pass, which scans backwards from the `return` terminator to see if there is an an assignment like `_0 = _1`. If a basic block with two or more predecessors is encountered during this scan without first seeing an assignment to the return place, we bail out. This avoids running a full "reaching definitions" dataflow analysis. I wanted to see how much `rustc` would benefit from even a very limited version of this optimization. We should be able to use this as a point of comparison for more advanced versions that are based on live ranges. r? @ghost
2020-05-18Fix const handling and add tests for const operandsAmanieu d'Antras-91/+128
2020-05-18Minor fixesAmanieu d'Antras-1/+2
2020-05-18Implement asm! codegenAmanieu d'Antras-1/+95
2020-05-16Name return place in debuginfo if it is a user variableDylan MacKenzie-1/+2
2020-05-08Simplify the `tcx.alloc_map` APIOliver Scherer-1/+1
2020-05-06Define UB in float-to-int casts to saturateMark Rousskov-1/+1
- Round to zero, and representable values cast directly. - `NaN` goes to 0 - Values beyond the limits of the type are saturated to the "nearest value" (essentially rounding to zero, in some sense) in the integral type, so e.g. `f32::INFINITY` would go to `{u,i}N::MAX.`
2020-05-03Add `MutatingUseContext::Yield`Dylan MacKenzie-1/+2
...emulating `MutatingUseContext::Call`
2020-05-01Remove deadcode in eval_mir_constant_to_operandSantiago Pastorino-19/+3
2020-04-26Rollup merge of #71392 - ecstatic-morse:body-predecessor-cache-arc, ↵Dylan DPC-1/+1
r=nikomatsakis Don't hold the predecessor cache lock longer than necessary #71044 returns a `LockGuard` with the predecessor cache to callers of `Body::predecessors`. As a result, the lock around the predecessor cache could be held for an arbitrarily long time. This PR uses reference counting for ownership of the predecessor cache, meaning the lock is only ever held within `PredecessorCache::compute`. Checking this API for potential sources of deadlock is much easier now, since we no longer have to consider its consumers, only its internals. This required removing `predecessors_for`, since there is no equivalent to `LockGuard::map` for `Arc` and `Rc`. I believe this could be emulated with `owning_ref::{Arc,Rc}Ref`, but I don't think it's necessary. Also, we continue to return an opaque type from `Body::predecessors` with the lifetime of the `Body`, not `'static`. This depends on #71044. Only the last two commits are new. r? @nikomatsakis
2020-04-23Rename uneval_consts to required_constsSantiago Pastorino-1/+1
2020-04-23Evaluate unevaluated MIR constants in codegen_mirSantiago Pastorino-0/+14
2020-04-22Remove `predecessors_for`Dylan MacKenzie-1/+1
There is no `Arc::map` equivalent to `LockGuard::map`
2020-04-22Auto merge of #71044 - ecstatic-morse:body-predecessor-cache, r=oli-obkbors-15/+14
Remove `BodyAndCache` ...returning to the original approach using interior mutability within `Body`. This simplifies the API at the cost of some uncontended mutex locks when the parallel compiler is enabled. The current API requires you to either have a mutable reference to `Body` (`&mut BodyAndCache`), or to compute the predecessor graph ahead of time by creating a `ReadOnlyBodyAndCache`. This is not a good fit for, e.g., the dataflow framework, which 1. does not mutate the MIR 2. only sometimes needs the predecessor graph (for backward dataflow problems)
2020-04-22Use `Body` everywhereDylan MacKenzie-8/+7
2020-04-22Don't use `*` for deref-coercionDylan MacKenzie-7/+7
2020-04-22Rollup merge of #71401 - spastorino:remove-visit-place-base, r=wesleywiserDylan DPC-1/+1
visit_place_base is just visit_local r? @wesleywiser
2020-04-22Rollup merge of #70970 - eddyb:trait-vs-impl-mismatch, r=oli-obkDylan DPC-0/+1
Detect mistyped associated consts in `Instance::resolve`. *Based on #71049 to prevent redundant/misleading downstream errors.* Fixes #70942 by refusing to resolve an associated `const` if it doesn't have the same type in the `impl` that it does in the `trait` (which we assume had errored, and `delay_span_bug` guards against bugs).
2020-04-21visit_place_base is just visit_localSantiago Pastorino-1/+1
2020-04-19Dogfood more or_patterns in the compilerJosh Stone-20/+27
2020-04-18Detect mistyped associated consts in `Instance::resolve`.Eduard-Mihai Burtescu-0/+1
2020-04-17Rollup merge of #70467 - wesleywiser:invoke-vs-call, r=nagisaDylan DPC-1/+3
Use `call` instead of `invoke` for functions that cannot unwind The `FnAbi` now knows if the function is allowed to unwind. If a function isn't allowed to unwind, we can use a `call` instead of an `invoke`. This resolves an issue when calling LLVM intrinsics which cannot unwind LLVM will generate an error if you attempt to invoke them so we need to ignore cleanup blocks in codegen and generate a call instead. Fixes #69911 r? @eddyb cc @rust-lang/wg-ffi-unwind
2020-04-16mir/interpret: only use `ErrorHandled::Reported` for `ErrorReported`.Eduard-Mihai Burtescu-2/+5