2022-11-06 10:09:24 -05:00
|
|
|
use crate::errors;
|
2018-10-03 13:49:57 +02:00
|
|
|
use crate::mir::operand::OperandRef;
|
|
|
|
|
use crate::traits::*;
|
2020-03-29 16:41:09 +02:00
|
|
|
use rustc_middle::mir;
|
|
|
|
|
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
2020-03-31 18:16:47 +02:00
|
|
|
use rustc_middle::ty::layout::HasTyCtxt;
|
2020-03-29 16:41:09 +02:00
|
|
|
use rustc_middle::ty::{self, Ty};
|
2020-01-01 19:25:28 +01:00
|
|
|
use rustc_span::source_map::Span;
|
2020-03-31 18:16:47 +02:00
|
|
|
use rustc_target::abi::Abi;
|
2015-11-16 19:57:57 +02:00
|
|
|
|
2018-01-16 10:16:38 +01:00
|
|
|
use super::FunctionCx;
|
2016-05-27 14:40:05 +03:00
|
|
|
|
2019-06-14 19:39:39 +03:00
|
|
|
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
2019-11-11 12:53:31 +01:00
|
|
|
pub fn eval_mir_constant_to_operand(
|
2020-05-30 15:02:32 -04:00
|
|
|
&self,
|
2019-11-11 12:53:31 +01:00
|
|
|
bx: &mut Bx,
|
|
|
|
|
constant: &mir::Constant<'tcx>,
|
|
|
|
|
) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
|
2020-05-01 09:30:46 -03:00
|
|
|
let val = self.eval_mir_constant(constant)?;
|
2021-03-08 14:14:11 +00:00
|
|
|
let ty = self.monomorphize(constant.ty());
|
2020-05-01 09:30:46 -03:00
|
|
|
Ok(OperandRef::from_const(bx, val, ty))
|
2019-11-11 12:53:31 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-14 10:19:31 +01:00
|
|
|
pub fn eval_mir_constant(
|
2020-05-30 15:02:32 -04:00
|
|
|
&self,
|
2019-03-14 10:19:31 +01:00
|
|
|
constant: &mir::Constant<'tcx>,
|
2020-02-15 12:57:46 +13:00
|
|
|
) -> Result<ConstValue<'tcx>, ErrorHandled> {
|
2021-03-08 16:18:03 +00:00
|
|
|
let ct = self.monomorphize(constant.literal);
|
2022-06-27 16:32:47 +02:00
|
|
|
let uv = match ct {
|
|
|
|
|
mir::ConstantKind::Ty(ct) => match ct.kind() {
|
|
|
|
|
ty::ConstKind::Unevaluated(uv) => uv.expand(),
|
|
|
|
|
ty::ConstKind::Value(val) => {
|
|
|
|
|
return Ok(self.cx.tcx().valtree_to_const_val((ct.ty(), val)));
|
|
|
|
|
}
|
|
|
|
|
err => span_bug!(
|
|
|
|
|
constant.span,
|
|
|
|
|
"encountered bad ConstKind after monomorphizing: {:?}",
|
|
|
|
|
err
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
mir::ConstantKind::Unevaluated(uv, _) => uv,
|
2021-03-15 11:23:44 +00:00
|
|
|
mir::ConstantKind::Val(val, _) => return Ok(val),
|
2021-03-08 16:18:03 +00:00
|
|
|
};
|
2022-06-27 16:32:47 +02:00
|
|
|
|
|
|
|
|
self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
|
2022-11-19 13:41:21 +01:00
|
|
|
match err {
|
|
|
|
|
ErrorHandled::Reported(_) => {
|
2022-11-06 10:09:24 -05:00
|
|
|
self.cx.tcx().sess.emit_err(errors::ErroneousConstant { span: constant.span });
|
2022-11-19 13:41:21 +01:00
|
|
|
}
|
|
|
|
|
ErrorHandled::TooGeneric => {
|
2022-11-23 01:07:36 -05:00
|
|
|
self.cx
|
|
|
|
|
.tcx()
|
|
|
|
|
.sess
|
|
|
|
|
.diagnostic()
|
|
|
|
|
.emit_bug(errors::PolymorphicConstantTooGeneric { span: constant.span });
|
2022-11-19 13:41:21 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-27 16:32:47 +02:00
|
|
|
err
|
|
|
|
|
})
|
2017-01-02 11:00:42 -07:00
|
|
|
}
|
|
|
|
|
|
2018-01-26 13:45:41 +01:00
|
|
|
/// process constant containing SIMD shuffle indices
|
|
|
|
|
pub fn simd_shuffle_indices(
|
|
|
|
|
&mut self,
|
2018-09-20 15:47:22 +02:00
|
|
|
bx: &Bx,
|
2018-07-22 01:01:07 +02:00
|
|
|
span: Span,
|
|
|
|
|
ty: Ty<'tcx>,
|
2023-06-16 16:02:11 +00:00
|
|
|
constant: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
|
2018-09-20 15:47:22 +02:00
|
|
|
) -> (Bx::Value, Ty<'tcx>) {
|
2023-06-16 16:02:11 +00:00
|
|
|
let val = constant
|
|
|
|
|
.ok()
|
|
|
|
|
.flatten()
|
2020-02-15 12:57:46 +13:00
|
|
|
.map(|val| {
|
|
|
|
|
let field_ty = ty.builtin_index().unwrap();
|
2023-06-16 16:02:11 +00:00
|
|
|
let values: Vec<_> = val
|
|
|
|
|
.unwrap_branch()
|
2020-06-09 15:57:08 +02:00
|
|
|
.iter()
|
2019-02-16 20:51:43 +01:00
|
|
|
.map(|field| {
|
2022-02-16 10:56:01 +01:00
|
|
|
if let Some(prim) = field.try_to_scalar() {
|
2018-11-27 19:00:25 +01:00
|
|
|
let layout = bx.layout_of(field_ty);
|
2022-02-19 00:48:49 +01:00
|
|
|
let Abi::Scalar(scalar) = layout.abi else {
|
|
|
|
|
bug!("from_const: invalid ByVal layout: {:#?}", layout);
|
2018-04-26 09:18:19 +02:00
|
|
|
};
|
2018-11-27 19:00:25 +01:00
|
|
|
bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
|
2018-04-26 09:18:19 +02:00
|
|
|
} else {
|
|
|
|
|
bug!("simd shuffle field {:?}", field)
|
2018-01-29 09:58:28 +01:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
2023-06-16 16:02:11 +00:00
|
|
|
bx.const_struct(&values, false)
|
2018-01-16 09:31:48 +01:00
|
|
|
})
|
2023-06-16 16:02:11 +00:00
|
|
|
.unwrap_or_else(|| {
|
2022-11-06 10:09:24 -05:00
|
|
|
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
|
2018-01-16 09:31:48 +01:00
|
|
|
// We've errored, so we don't have to produce working code.
|
2020-10-24 02:21:18 +02:00
|
|
|
let ty = self.monomorphize(ty);
|
2018-11-27 19:00:25 +01:00
|
|
|
let llty = bx.backend_type(bx.layout_of(ty));
|
2023-06-16 16:02:11 +00:00
|
|
|
bx.const_undef(llty)
|
|
|
|
|
});
|
|
|
|
|
(val, ty)
|
2017-01-02 11:00:42 -07:00
|
|
|
}
|
|
|
|
|
}
|