about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa/traits/builder.rs
AgeCommit message (Collapse)AuthorLines
2020-08-30mv compiler to compiler/mark-286/+0
2020-08-18Moved coverage counter injection from BasicBlock to Statement.Rich Kadel-1/+1
2020-07-28rustc: Improving safe wasm float->int castsAlex Crichton-0/+1
This commit improves code generation for WebAssembly targets when translating floating to integer casts. This improvement is only relevant when the `nontrapping-fptoint` feature is not enabled, but the feature is not enabled by default right now. Additionally this improvement only affects safe casts since unchecked casts were improved in #74659. Some more background for this issue is present on #73591, but the general gist of the issue is that in LLVM the `fptosi` and `fptoui` instructions are defined to return an `undef` value if they execute on out-of-bounds values; they notably do not trap. To implement these instructions for WebAssembly the LLVM backend must therefore generate quite a few instructions before executing `i32.trunc_f32_s` (for example) because this WebAssembly instruction traps on out-of-bounds values. This codegen into wasm instructions happens very late in the code generator, so what ends up happening is that rustc inserts its own codegen to implement Rust's saturating semantics, and then LLVM also inserts its own codegen to make sure that the `fptosi` instruction doesn't trap. Overall this means that a function like this: #[no_mangle] pub unsafe extern "C" fn cast(x: f64) -> u32 { x as u32 } will generate this WebAssembly today: (func $cast (type 0) (param f64) (result i32) (local i32 i32) local.get 0 f64.const 0x1.fffffffep+31 (;=4.29497e+09;) f64.gt local.set 1 block ;; label = @1 block ;; label = @2 local.get 0 f64.const 0x0p+0 (;=0;) local.get 0 f64.const 0x0p+0 (;=0;) f64.gt select local.tee 0 f64.const 0x1p+32 (;=4.29497e+09;) f64.lt local.get 0 f64.const 0x0p+0 (;=0;) f64.ge i32.and i32.eqz br_if 0 (;@2;) local.get 0 i32.trunc_f64_u local.set 2 br 1 (;@1;) end i32.const 0 local.set 2 end i32.const -1 local.get 2 local.get 1 select) This PR improves the situation by updating the code generation for float-to-int conversions in rustc, specifically only for WebAssembly targets and only for some situations (float-to-u8 still has not great codegen). The fix here is to use basic blocks and control flow to avoid speculatively executing `fptosi`, and instead LLVM's raw intrinsic for the WebAssembly instruction is used instead. This effectively extends the support added in #74659 to checked casts. After this commit the codegen for the above Rust function looks like: (func $cast (type 0) (param f64) (result i32) (local i32) block ;; label = @1 local.get 0 f64.const 0x0p+0 (;=0;) f64.ge local.tee 1 i32.const 1 i32.xor br_if 0 (;@1;) local.get 0 f64.const 0x1.fffffffep+31 (;=4.29497e+09;) f64.le i32.eqz br_if 0 (;@1;) local.get 0 i32.trunc_f64_u return end i32.const -1 i32.const 0 local.get 1 select) For reference, in Rust 1.44, which did not have saturating float-to-integer casts, the codegen LLVM would emit is: (func $cast (type 0) (param f64) (result i32) block ;; label = @1 local.get 0 f64.const 0x1p+32 (;=4.29497e+09;) f64.lt local.get 0 f64.const 0x0p+0 (;=0;) f64.ge i32.and i32.eqz br_if 0 (;@1;) local.get 0 i32.trunc_f64_u return end i32.const 0) So we're relatively close to the original codegen, although it's slightly different because the semantics of the function changed where we're emulating the `i32.trunc_sat_f32_s` instruction rather than always replacing out-of-bounds values with zero. There is still work that could be done to improve casts such as `f32` to `u8`. That form of cast still uses the `fptosi` instruction which generates lots of branch-y code. This seems less important to tackle now though. In the meantime this should take care of most use cases of floating-point conversion and as a result I'm going to speculate that this... Closes #73591
2020-07-02Rollup merge of #73724 - CryZe:wasm-saturating-casts, r=alexcrichtonManish Goregaokar-0/+2
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-0/+2
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-0/+2
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-15[WIP] injects llvm intrinsic instrprof.increment for coverage reportsRich Kadel-0/+8
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-04-02nix rustc_target::abi::* reexport in ty::layoutMazdak Farrokhzad-1/+2
2020-03-30rustc -> rustc_middle part 2Mazdak Farrokhzad-2/+2
2020-02-03rustc_codegen_ssa: split declare_local into create_dbg_var and dbg_var_addr.Eduard-Mihai Burtescu-1/+1
2019-12-22Format the worldMark Rousskov-13/+8
2019-11-21Aggregation of drive-by cosmetic changes.Alexander Regueiro-1/+4
2019-11-03rustc_codegen_ssa: rename ArgTypeMethods to ArgAbiMethods.Eduard-Mihai Burtescu-2/+2
2019-10-13s/FuncId/Functionbjorn3-1/+1
2019-10-13Introduce FuncId backend typebjorn3-1/+1
2019-09-12codegen: be more explicit about setting giving names to allocas.Eduard-Mihai Burtescu-3/+2
2019-07-03Remove needless lifetimesJeremy Stucki-1/+1
2019-06-18rustc: remove 'x: 'y bounds (except from comments/strings).Eduard-Mihai Burtescu-1/+1
2019-06-11rustc_codegen_*: deny(unused_lifetimes).Eduard-Mihai Burtescu-1/+1
2019-06-03add support for unchecked mathlcnr/Bastian Kauschke-0/+6
2019-05-14removes `AbiMethods`Saleem Jaffer-0/+2
2019-05-04adding HasParamEnv traitSaleem Jaffer-1/+3
2019-03-29Use ExactSizeIterator + TrustedLen instead of num_cases arg for switchbjorn3-2/+2
2019-03-29Add a method for emiting a switch.bjorn3-2/+3
2019-03-29Remove inline_asm_call from cg_ssabjorn3-14/+0
`count_insn` is no longer called for inline asm, because it is private to builder.rs
2019-03-29Remove type_variadic_func and typ_array from cg_ssabjorn3-7/+8
2019-03-29Move get_param and set_value_namebjorn3-2/+1
2019-03-29Remove a lot of methods from BuilderMethodsbjorn3-47/+0
2019-02-25librustc_codegen_ssa: deny(elided_lifetimes_in_paths)Mazdak Farrokhzad-1/+1
2019-02-09librustc_codegen_ssa => 2018Taiki Endo-4/+5
2018-12-25Remove licensesMark Rousskov-10/+0
2018-11-29Move get_static from CodegenCx to Builderbjorn3-1/+2
2018-11-29Move IntrinsicCallMethods::call_overflow_intrinsics to ↵bjorn3-0/+16
BuilderMethods::checked_binop
2018-11-29Remove call_lifetime_intrinsic from cg_ssabjorn3-10/+4
2018-11-22rustc_target: avoid using AbiAndPrefAlign where possible.Eduard-Mihai Burtescu-13/+12
2018-11-22rustc_target: rename abi::Align to AbiAndPrefAlign.Eduard-Mihai Burtescu-13/+14
2018-11-16[eddyb] rustc_codegen_ssa: rename `interfaces` to `traits`.Eduard-Mihai Burtescu-0/+323