]>
Commit | Line | Data |
---|---|---|
dfeec247 XL |
1 | use crate::mir::operand::OperandRef; |
2 | use crate::traits::*; | |
ba9703b0 XL |
3 | use rustc_middle::mir; |
4 | use rustc_middle::mir::interpret::{ConstValue, ErrorHandled}; | |
5 | use rustc_middle::ty::layout::HasTyCtxt; | |
6 | use rustc_middle::ty::{self, Ty}; | |
dfeec247 | 7 | use rustc_span::source_map::Span; |
ba9703b0 | 8 | use rustc_target::abi::Abi; |
a1dfa0c6 XL |
9 | |
10 | use super::FunctionCx; | |
11 | ||
dc9dc135 | 12 | impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { |
60c5eb7d | 13 | pub fn eval_mir_constant_to_operand( |
fc512014 | 14 | &self, |
60c5eb7d XL |
15 | bx: &mut Bx, |
16 | constant: &mir::Constant<'tcx>, | |
17 | ) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> { | |
f9f354fc | 18 | let val = self.eval_mir_constant(constant)?; |
6a06907d | 19 | let ty = self.monomorphize(constant.ty()); |
f9f354fc | 20 | Ok(OperandRef::from_const(bx, val, ty)) |
60c5eb7d XL |
21 | } |
22 | ||
532ac7d7 | 23 | pub fn eval_mir_constant( |
fc512014 | 24 | &self, |
532ac7d7 | 25 | constant: &mir::Constant<'tcx>, |
74b04a01 | 26 | ) -> Result<ConstValue<'tcx>, ErrorHandled> { |
6a06907d XL |
27 | let ct = self.monomorphize(constant.literal); |
28 | let ct = match ct { | |
29 | mir::ConstantKind::Ty(ct) => ct, | |
30 | mir::ConstantKind::Val(val, _) => return Ok(val), | |
31 | }; | |
5099ac24 | 32 | match ct.val() { |
cdc7bbd5 | 33 | ty::ConstKind::Unevaluated(ct) => self |
ba9703b0 XL |
34 | .cx |
35 | .tcx() | |
cdc7bbd5 | 36 | .const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None) |
ba9703b0 | 37 | .map_err(|err| { |
5869c6ff | 38 | self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); |
ba9703b0 XL |
39 | err |
40 | }), | |
74b04a01 | 41 | ty::ConstKind::Value(value) => Ok(value), |
ba9703b0 XL |
42 | err => span_bug!( |
43 | constant.span, | |
44 | "encountered bad ConstKind after monomorphizing: {:?}", | |
45 | err | |
46 | ), | |
a1dfa0c6 XL |
47 | } |
48 | } | |
49 | ||
a1dfa0c6 XL |
50 | /// process constant containing SIMD shuffle indices |
51 | pub fn simd_shuffle_indices( | |
52 | &mut self, | |
53 | bx: &Bx, | |
54 | span: Span, | |
55 | ty: Ty<'tcx>, | |
74b04a01 | 56 | constant: Result<ConstValue<'tcx>, ErrorHandled>, |
a1dfa0c6 XL |
57 | ) -> (Bx::Value, Ty<'tcx>) { |
58 | constant | |
74b04a01 XL |
59 | .map(|val| { |
60 | let field_ty = ty.builtin_index().unwrap(); | |
74b04a01 | 61 | let c = ty::Const::from_value(bx.tcx(), val, ty); |
f9f354fc XL |
62 | let values: Vec<_> = bx |
63 | .tcx() | |
5099ac24 | 64 | .destructure_const(ty::ParamEnv::reveal_all().and(c)) |
f9f354fc | 65 | .fields |
f035d41b | 66 | .iter() |
dfeec247 | 67 | .map(|field| { |
5099ac24 | 68 | if let Some(prim) = field.val().try_to_scalar() { |
dfeec247 | 69 | let layout = bx.layout_of(field_ty); |
5e7ed085 FG |
70 | let Abi::Scalar(scalar) = layout.abi else { |
71 | bug!("from_const: invalid ByVal layout: {:#?}", layout); | |
dfeec247 XL |
72 | }; |
73 | bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) | |
74 | } else { | |
75 | bug!("simd shuffle field {:?}", field) | |
76 | } | |
77 | }) | |
78 | .collect(); | |
532ac7d7 | 79 | let llval = bx.const_struct(&values, false); |
5099ac24 | 80 | (llval, c.ty()) |
a1dfa0c6 XL |
81 | }) |
82 | .unwrap_or_else(|_| { | |
dfeec247 | 83 | bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time"); |
a1dfa0c6 | 84 | // We've errored, so we don't have to produce working code. |
fc512014 | 85 | let ty = self.monomorphize(ty); |
a1dfa0c6 XL |
86 | let llty = bx.backend_type(bx.layout_of(ty)); |
87 | (bx.const_undef(llty), ty) | |
88 | }) | |
89 | } | |
90 | } |