Skip to content

Commit abe0fef

Browse files
Deploying to gh-pages from @ 598682c 🚀
1 parent 7acca41 commit abe0fef

6 files changed

Lines changed: 555 additions & 71 deletions

File tree

api/src/rustc_codegen_spirv/builder/builder_methods.rs.html

Lines changed: 223 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,7 +3641,111 @@
36413641
<a href="#3640" id="3640">3640</a>
36423642
<a href="#3641" id="3641">3641</a>
36433643
<a href="#3642" id="3642">3642</a>
3644-
<a href="#3643" id="3643">3643</a></pre></div><pre class="rust"><code><span class="comment">// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
3644+
<a href="#3643" id="3643">3643</a>
3645+
<a href="#3644" id="3644">3644</a>
3646+
<a href="#3645" id="3645">3645</a>
3647+
<a href="#3646" id="3646">3646</a>
3648+
<a href="#3647" id="3647">3647</a>
3649+
<a href="#3648" id="3648">3648</a>
3650+
<a href="#3649" id="3649">3649</a>
3651+
<a href="#3650" id="3650">3650</a>
3652+
<a href="#3651" id="3651">3651</a>
3653+
<a href="#3652" id="3652">3652</a>
3654+
<a href="#3653" id="3653">3653</a>
3655+
<a href="#3654" id="3654">3654</a>
3656+
<a href="#3655" id="3655">3655</a>
3657+
<a href="#3656" id="3656">3656</a>
3658+
<a href="#3657" id="3657">3657</a>
3659+
<a href="#3658" id="3658">3658</a>
3660+
<a href="#3659" id="3659">3659</a>
3661+
<a href="#3660" id="3660">3660</a>
3662+
<a href="#3661" id="3661">3661</a>
3663+
<a href="#3662" id="3662">3662</a>
3664+
<a href="#3663" id="3663">3663</a>
3665+
<a href="#3664" id="3664">3664</a>
3666+
<a href="#3665" id="3665">3665</a>
3667+
<a href="#3666" id="3666">3666</a>
3668+
<a href="#3667" id="3667">3667</a>
3669+
<a href="#3668" id="3668">3668</a>
3670+
<a href="#3669" id="3669">3669</a>
3671+
<a href="#3670" id="3670">3670</a>
3672+
<a href="#3671" id="3671">3671</a>
3673+
<a href="#3672" id="3672">3672</a>
3674+
<a href="#3673" id="3673">3673</a>
3675+
<a href="#3674" id="3674">3674</a>
3676+
<a href="#3675" id="3675">3675</a>
3677+
<a href="#3676" id="3676">3676</a>
3678+
<a href="#3677" id="3677">3677</a>
3679+
<a href="#3678" id="3678">3678</a>
3680+
<a href="#3679" id="3679">3679</a>
3681+
<a href="#3680" id="3680">3680</a>
3682+
<a href="#3681" id="3681">3681</a>
3683+
<a href="#3682" id="3682">3682</a>
3684+
<a href="#3683" id="3683">3683</a>
3685+
<a href="#3684" id="3684">3684</a>
3686+
<a href="#3685" id="3685">3685</a>
3687+
<a href="#3686" id="3686">3686</a>
3688+
<a href="#3687" id="3687">3687</a>
3689+
<a href="#3688" id="3688">3688</a>
3690+
<a href="#3689" id="3689">3689</a>
3691+
<a href="#3690" id="3690">3690</a>
3692+
<a href="#3691" id="3691">3691</a>
3693+
<a href="#3692" id="3692">3692</a>
3694+
<a href="#3693" id="3693">3693</a>
3695+
<a href="#3694" id="3694">3694</a>
3696+
<a href="#3695" id="3695">3695</a>
3697+
<a href="#3696" id="3696">3696</a>
3698+
<a href="#3697" id="3697">3697</a>
3699+
<a href="#3698" id="3698">3698</a>
3700+
<a href="#3699" id="3699">3699</a>
3701+
<a href="#3700" id="3700">3700</a>
3702+
<a href="#3701" id="3701">3701</a>
3703+
<a href="#3702" id="3702">3702</a>
3704+
<a href="#3703" id="3703">3703</a>
3705+
<a href="#3704" id="3704">3704</a>
3706+
<a href="#3705" id="3705">3705</a>
3707+
<a href="#3706" id="3706">3706</a>
3708+
<a href="#3707" id="3707">3707</a>
3709+
<a href="#3708" id="3708">3708</a>
3710+
<a href="#3709" id="3709">3709</a>
3711+
<a href="#3710" id="3710">3710</a>
3712+
<a href="#3711" id="3711">3711</a>
3713+
<a href="#3712" id="3712">3712</a>
3714+
<a href="#3713" id="3713">3713</a>
3715+
<a href="#3714" id="3714">3714</a>
3716+
<a href="#3715" id="3715">3715</a>
3717+
<a href="#3716" id="3716">3716</a>
3718+
<a href="#3717" id="3717">3717</a>
3719+
<a href="#3718" id="3718">3718</a>
3720+
<a href="#3719" id="3719">3719</a>
3721+
<a href="#3720" id="3720">3720</a>
3722+
<a href="#3721" id="3721">3721</a>
3723+
<a href="#3722" id="3722">3722</a>
3724+
<a href="#3723" id="3723">3723</a>
3725+
<a href="#3724" id="3724">3724</a>
3726+
<a href="#3725" id="3725">3725</a>
3727+
<a href="#3726" id="3726">3726</a>
3728+
<a href="#3727" id="3727">3727</a>
3729+
<a href="#3728" id="3728">3728</a>
3730+
<a href="#3729" id="3729">3729</a>
3731+
<a href="#3730" id="3730">3730</a>
3732+
<a href="#3731" id="3731">3731</a>
3733+
<a href="#3732" id="3732">3732</a>
3734+
<a href="#3733" id="3733">3733</a>
3735+
<a href="#3734" id="3734">3734</a>
3736+
<a href="#3735" id="3735">3735</a>
3737+
<a href="#3736" id="3736">3736</a>
3738+
<a href="#3737" id="3737">3737</a>
3739+
<a href="#3738" id="3738">3738</a>
3740+
<a href="#3739" id="3739">3739</a>
3741+
<a href="#3740" id="3740">3740</a>
3742+
<a href="#3741" id="3741">3741</a>
3743+
<a href="#3742" id="3742">3742</a>
3744+
<a href="#3743" id="3743">3743</a>
3745+
<a href="#3744" id="3744">3744</a>
3746+
<a href="#3745" id="3745">3745</a>
3747+
<a href="#3746" id="3746">3746</a>
3748+
<a href="#3747" id="3747">3747</a></pre></div><pre class="rust"><code><span class="comment">// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
36453749
</span><span class="kw">use </span><span class="kw">crate</span>::maybe_pqp_cg_ssa <span class="kw">as </span>rustc_codegen_ssa;
36463750

36473751
<span class="kw">use </span><span class="kw">super</span>::Builder;
@@ -5676,7 +5780,32 @@
56765780
<span class="kw">if </span>val.ty == dest_ty {
56775781
val
56785782
} <span class="kw">else </span>{
5679-
<span class="self">self</span>.emit()
5783+
<span class="comment">// If casting a constant, directly create a constant of the target type.
5784+
// This avoids creating intermediate types that might require additional
5785+
// capabilities. For example, casting a f16 constant to f32 will directly
5786+
// create a f32 constant, avoiding the need for Float16 capability if it is
5787+
// not used elsewhere.
5788+
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(const_val) = <span class="self">self</span>.builder.lookup_const_scalar(val) {
5789+
<span class="kw">if let </span>(SpirvType::Float(src_width), SpirvType::Float(dst_width)) =
5790+
(<span class="self">self</span>.lookup_type(val.ty), <span class="self">self</span>.lookup_type(dest_ty))
5791+
{
5792+
<span class="kw">if </span>src_width &lt; dst_width {
5793+
<span class="comment">// Convert the bit representation to the actual float value
5794+
</span><span class="kw">let </span>float_val = <span class="kw">match </span>src_width {
5795+
<span class="number">32 </span>=&gt; <span class="prelude-val">Some</span>(f32::from_bits(const_val <span class="kw">as </span>u32) <span class="kw">as </span>f64),
5796+
<span class="number">64 </span>=&gt; <span class="prelude-val">Some</span>(f64::from_bits(const_val <span class="kw">as </span>u64)),
5797+
<span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
5798+
};
5799+
5800+
<span class="kw">if let </span><span class="prelude-val">Some</span>(val) = float_val {
5801+
<span class="kw">return </span><span class="self">self</span>.constant_float(dest_ty, val);
5802+
}
5803+
}
5804+
}
5805+
}
5806+
5807+
<span class="comment">// Regular conversion
5808+
</span><span class="self">self</span>.emit()
56805809
.f_convert(dest_ty, <span class="prelude-val">None</span>, val.def(<span class="self">self</span>))
56815810
.unwrap()
56825811
.with_type(dest_ty)
@@ -5841,6 +5970,46 @@
58415970
<span class="comment">// I guess?
58425971
</span><span class="kw">return </span>val;
58435972
}
5973+
5974+
<span class="comment">// If casting a constant, directly create a constant of the target type. This
5975+
// avoids creating intermediate types that might require additional
5976+
// capabilities. For example, casting a u8 constant to u32 will directly create
5977+
// a u32 constant, avoiding the need for Int8 capability if it is not used
5978+
// elsewhere.
5979+
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(const_val) = <span class="self">self</span>.builder.lookup_const_scalar(val) {
5980+
<span class="kw">let </span>src_ty = <span class="self">self</span>.lookup_type(val.ty);
5981+
<span class="kw">let </span>dst_ty_spv = <span class="self">self</span>.lookup_type(dest_ty);
5982+
5983+
<span class="comment">// Try to optimize the constant cast
5984+
</span><span class="kw">let </span>optimized_result = <span class="kw">match </span>(src_ty, dst_ty_spv) {
5985+
<span class="comment">// Integer to integer cast
5986+
</span>(SpirvType::Integer(src_width, <span class="kw">_</span>), SpirvType::Integer(dst_width, <span class="kw">_</span>)) =&gt; {
5987+
<span class="comment">// Only optimize if we're widening. This avoids creating the source
5988+
// type when it's safe to do so. For narrowing casts (e.g., u32 as
5989+
// u8), we need the proper truncation behavior that the regular cast
5990+
// provides.
5991+
</span><span class="kw">if </span>src_width &lt; dst_width {
5992+
<span class="prelude-val">Some</span>(<span class="self">self</span>.constant_int(dest_ty, const_val))
5993+
} <span class="kw">else </span>{
5994+
<span class="prelude-val">None
5995+
</span>}
5996+
}
5997+
<span class="comment">// Bool to integer cast - const_val will be 0 or 1
5998+
</span>(SpirvType::Bool, SpirvType::Integer(<span class="kw">_</span>, <span class="kw">_</span>)) =&gt; {
5999+
<span class="prelude-val">Some</span>(<span class="self">self</span>.constant_int(dest_ty, const_val))
6000+
}
6001+
<span class="comment">// Integer to bool cast - compare with zero
6002+
</span>(SpirvType::Integer(<span class="kw">_</span>, <span class="kw">_</span>), SpirvType::Bool) =&gt; {
6003+
<span class="prelude-val">Some</span>(<span class="self">self</span>.constant_bool(<span class="self">self</span>.span(), const_val != <span class="number">0</span>))
6004+
}
6005+
<span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
6006+
};
6007+
6008+
<span class="kw">if let </span><span class="prelude-val">Some</span>(result) = optimized_result {
6009+
<span class="kw">return </span>result;
6010+
}
6011+
}
6012+
58446013
<span class="kw">match </span>(<span class="self">self</span>.lookup_type(val.ty), <span class="self">self</span>.lookup_type(dest_ty)) {
58456014
<span class="comment">// sign change
58466015
</span>(
@@ -6771,6 +6940,8 @@
67716940
.and_then(|def_id| <span class="self">self</span>.buffer_store_intrinsics.borrow().get(<span class="kw-2">&amp;</span>def_id).copied());
67726941
<span class="kw">let </span>is_panic_entry_point = instance_def_id
67736942
.is_some_and(|def_id| <span class="self">self</span>.panic_entry_points.borrow().contains(<span class="kw-2">&amp;</span>def_id));
6943+
<span class="kw">let </span>from_trait_impl =
6944+
instance_def_id.and_then(|def_id| <span class="self">self</span>.from_trait_impls.borrow().get(<span class="kw-2">&amp;</span>def_id).copied());
67746945

67756946
<span class="kw">if let </span><span class="prelude-val">Some</span>(libm_intrinsic) = libm_intrinsic {
67766947
<span class="kw">let </span>result = <span class="self">self</span>.call_libm_intrinsic(libm_intrinsic, result_type, args);
@@ -6782,8 +6953,10 @@
67826953
<span class="self">self</span>.debug_type(result.ty),
67836954
);
67846955
}
6785-
result
6786-
} <span class="kw">else if </span>is_panic_entry_point {
6956+
<span class="kw">return </span>result;
6957+
}
6958+
6959+
<span class="kw">if </span>is_panic_entry_point {
67876960
<span class="comment">// HACK(eddyb) Rust 2021 `panic!` always uses `format_args!`, even
67886961
// in the simple case that used to pass a `&amp;str` constant, which
67896962
// would not remain reachable in the SPIR-V - but `format_args!` is
@@ -7256,24 +7429,59 @@
72567429
<span class="comment">// HACK(eddyb) redirect any possible panic call to an abort, to avoid
72577430
// needing to materialize `&amp;core::panic::Location` or `format_args!`.
72587431
</span><span class="self">self</span>.abort_with_kind_and_message_debug_printf(<span class="string">"panic"</span>, message, debug_printf_args);
7259-
<span class="self">self</span>.undef(result_type)
7260-
} <span class="kw">else if let </span><span class="prelude-val">Some</span>(mode) = buffer_load_intrinsic {
7261-
<span class="self">self</span>.codegen_buffer_load_intrinsic(result_type, args, mode)
7262-
} <span class="kw">else if let </span><span class="prelude-val">Some</span>(mode) = buffer_store_intrinsic {
7432+
<span class="kw">return </span><span class="self">self</span>.undef(result_type);
7433+
}
7434+
7435+
<span class="kw">if let </span><span class="prelude-val">Some</span>(mode) = buffer_load_intrinsic {
7436+
<span class="kw">return </span><span class="self">self</span>.codegen_buffer_load_intrinsic(result_type, args, mode);
7437+
}
7438+
7439+
<span class="kw">if let </span><span class="prelude-val">Some</span>(mode) = buffer_store_intrinsic {
72637440
<span class="self">self</span>.codegen_buffer_store_intrinsic(args, mode);
72647441

72657442
<span class="kw">let </span>void_ty = SpirvType::Void.def(rustc_span::DUMMY_SP, <span class="self">self</span>);
7266-
SpirvValue {
7443+
<span class="kw">return </span>SpirvValue {
72677444
kind: SpirvValueKind::IllegalTypeUsed(void_ty),
72687445
ty: void_ty,
7446+
};
7447+
}
7448+
7449+
<span class="kw">if let </span><span class="prelude-val">Some</span>((source_ty, target_ty)) = from_trait_impl {
7450+
<span class="comment">// Optimize From::from calls with constant arguments to avoid creating intermediate types.
7451+
// Since From is only implemented for safe conversions (widening conversions that preserve
7452+
// the numeric value), we can directly create a constant of the target type for primitive
7453+
// numeric types.
7454+
</span><span class="kw">if let </span>[arg] = args {
7455+
<span class="kw">if let </span><span class="prelude-val">Some</span>(const_val) = <span class="self">self</span>.builder.lookup_const_scalar(<span class="kw-2">*</span>arg) {
7456+
<span class="kw">use </span>rustc_middle::ty::FloatTy;
7457+
<span class="kw">let </span>optimized_result = <span class="kw">match </span>(source_ty.kind(), target_ty.kind()) {
7458+
<span class="comment">// Integer widening conversions
7459+
</span>(ty::Uint(<span class="kw">_</span>), ty::Uint(<span class="kw">_</span>)) | (ty::Int(<span class="kw">_</span>), ty::Int(<span class="kw">_</span>)) =&gt; {
7460+
<span class="prelude-val">Some</span>(<span class="self">self</span>.constant_int(result_type, const_val))
7461+
}
7462+
<span class="comment">// Float widening conversions
7463+
// TODO(@LegNeato): Handle more float types
7464+
</span>(ty::Float(FloatTy::F32), ty::Float(FloatTy::F64)) =&gt; {
7465+
<span class="kw">let </span>float_val = f32::from_bits(const_val <span class="kw">as </span>u32) <span class="kw">as </span>f64;
7466+
<span class="prelude-val">Some</span>(<span class="self">self</span>.constant_float(result_type, float_val))
7467+
}
7468+
<span class="comment">// No optimization for narrowing conversions or unsupported types
7469+
</span><span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
7470+
};
7471+
7472+
<span class="kw">if let </span><span class="prelude-val">Some</span>(result) = optimized_result {
7473+
<span class="kw">return </span>result;
7474+
}
7475+
}
72697476
}
7270-
} <span class="kw">else </span>{
7271-
<span class="kw">let </span>args = args.iter().map(|arg| arg.def(<span class="self">self</span>)).collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;();
7272-
<span class="self">self</span>.emit()
7273-
.function_call(result_type, <span class="prelude-val">None</span>, callee_val, args)
7274-
.unwrap()
7275-
.with_type(result_type)
72767477
}
7478+
7479+
<span class="comment">// Default: emit a regular function call
7480+
</span><span class="kw">let </span>args = args.iter().map(|arg| arg.def(<span class="self">self</span>)).collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;();
7481+
<span class="self">self</span>.emit()
7482+
.function_call(result_type, <span class="prelude-val">None</span>, callee_val, args)
7483+
.unwrap()
7484+
.with_type(result_type)
72777485
}
72787486

72797487
<span class="kw">fn </span>zext(<span class="kw-2">&amp;mut </span><span class="self">self</span>, val: <span class="self">Self</span>::Value, dest_ty: <span class="self">Self</span>::Type) -&gt; <span class="self">Self</span>::Value {

api/src/rustc_codegen_spirv/codegen_cx/declare.rs.html

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,31 @@
373373
<a href="#372" id="372">372</a>
374374
<a href="#373" id="373">373</a>
375375
<a href="#374" id="374">374</a>
376-
<a href="#375" id="375">375</a></pre></div><pre class="rust"><code><span class="comment">// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
376+
<a href="#375" id="375">375</a>
377+
<a href="#376" id="376">376</a>
378+
<a href="#377" id="377">377</a>
379+
<a href="#378" id="378">378</a>
380+
<a href="#379" id="379">379</a>
381+
<a href="#380" id="380">380</a>
382+
<a href="#381" id="381">381</a>
383+
<a href="#382" id="382">382</a>
384+
<a href="#383" id="383">383</a>
385+
<a href="#384" id="384">384</a>
386+
<a href="#385" id="385">385</a>
387+
<a href="#386" id="386">386</a>
388+
<a href="#387" id="387">387</a>
389+
<a href="#388" id="388">388</a>
390+
<a href="#389" id="389">389</a>
391+
<a href="#390" id="390">390</a>
392+
<a href="#391" id="391">391</a>
393+
<a href="#392" id="392">392</a>
394+
<a href="#393" id="393">393</a>
395+
<a href="#394" id="394">394</a>
396+
<a href="#395" id="395">395</a>
397+
<a href="#396" id="396">396</a>
398+
<a href="#397" id="397">397</a>
399+
<a href="#398" id="398">398</a>
400+
<a href="#399" id="399">399</a></pre></div><pre class="rust"><code><span class="comment">// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
377401
</span><span class="kw">use </span><span class="kw">crate</span>::maybe_pqp_cg_ssa <span class="kw">as </span>rustc_codegen_ssa;
378402

379403
<span class="kw">use </span><span class="kw">super</span>::CodegenCx;
@@ -547,6 +571,30 @@
547571
}
548572
}
549573

574+
<span class="comment">// Check if this is a From trait implementation
575+
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(impl_def_id) = <span class="self">self</span>.tcx.impl_of_method(def_id) {
576+
<span class="kw">if let </span><span class="prelude-val">Some</span>(trait_ref) = <span class="self">self</span>.tcx.impl_trait_ref(impl_def_id) {
577+
<span class="kw">let </span>trait_def_id = trait_ref.skip_binder().def_id;
578+
579+
<span class="comment">// Check if this is the From trait.
580+
</span><span class="kw">let </span>trait_path = <span class="self">self</span>.tcx.def_path_str(trait_def_id);
581+
<span class="kw">if </span><span class="macro">matches!</span>(
582+
trait_path.as_str(),
583+
<span class="string">"core::convert::From" </span>| <span class="string">"std::convert::From"
584+
</span>) {
585+
<span class="comment">// Extract the source and target types from the trait substitutions
586+
</span><span class="kw">let </span>trait_args = trait_ref.skip_binder().args;
587+
<span class="kw">if let </span>(<span class="prelude-val">Some</span>(target_ty), <span class="prelude-val">Some</span>(source_ty)) =
588+
(trait_args.types().nth(<span class="number">0</span>), trait_args.types().nth(<span class="number">1</span>))
589+
{
590+
<span class="self">self</span>.from_trait_impls
591+
.borrow_mut()
592+
.insert(def_id, (source_ty, target_ty));
593+
}
594+
}
595+
}
596+
}
597+
550598
<span class="kw">if </span>[
551599
<span class="self">self</span>.tcx.lang_items().panic_fn(),
552600
<span class="self">self</span>.tcx.lang_items().panic_fmt(),

0 commit comments

Comments
 (0)