]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_ssa/src/mir/constant.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / compiler / rustc_codegen_ssa / src / mir / constant.rs
CommitLineData
dfeec247
XL
1use crate::mir::operand::OperandRef;
2use crate::traits::*;
ba9703b0
XL
3use rustc_middle::mir;
4use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
5use rustc_middle::ty::layout::HasTyCtxt;
6use rustc_middle::ty::{self, Ty};
dfeec247 7use rustc_span::source_map::Span;
ba9703b0 8use rustc_target::abi::Abi;
a1dfa0c6
XL
9
10use super::FunctionCx;
11
dc9dc135 12impl<'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}