Skip to content

Commit 6a3db03

Browse files
committed
Auto merge of #52597 - oli-obk:promotion_simplify, r=nagisa
Promoteds are statics and statics have a place, not just a value r? @eddyb This makes everything around promoteds a little simpler
2 parents a1e6bcb + cbd4274 commit 6a3db03

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+378
-587
lines changed

src/librustc/ich/impls_mir.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Place<'gcx> {
302302
mir::Place::Static(ref statik) => {
303303
statik.hash_stable(hcx, hasher);
304304
}
305+
mir::Place::Promoted(ref promoted) => {
306+
promoted.hash_stable(hcx, hasher);
307+
}
305308
mir::Place::Projection(ref place_projection) => {
306309
place_projection.hash_stable(hcx, hasher);
307310
}
@@ -527,22 +530,6 @@ impl_stable_hash_for!(enum mir::NullOp {
527530

528531
impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
529532

530-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Literal<'gcx> {
531-
fn hash_stable<W: StableHasherResult>(&self,
532-
hcx: &mut StableHashingContext<'a>,
533-
hasher: &mut StableHasher<W>) {
534-
mem::discriminant(self).hash_stable(hcx, hasher);
535-
match *self {
536-
mir::Literal::Value { ref value } => {
537-
value.hash_stable(hcx, hasher);
538-
}
539-
mir::Literal::Promoted { index } => {
540-
index.hash_stable(hcx, hasher);
541-
}
542-
}
543-
}
544-
}
545-
546533
impl_stable_hash_for!(struct mir::Location { block, statement_index });
547534

548535
impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {

src/librustc/mir/mod.rs

+8-46
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,9 @@ pub enum Place<'tcx> {
17011701
/// static or static mut variable
17021702
Static(Box<Static<'tcx>>),
17031703

1704+
/// Constant code promoted to an injected static
1705+
Promoted(Box<(Promoted, Ty<'tcx>)>),
1706+
17041707
/// projection out of a place (access a field, deref a pointer, etc)
17051708
Projection(Box<PlaceProjection<'tcx>>),
17061709
}
@@ -1810,6 +1813,7 @@ impl<'tcx> Debug for Place<'tcx> {
18101813
ty::tls::with(|tcx| tcx.item_path_str(def_id)),
18111814
ty
18121815
),
1816+
Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1),
18131817
Projection(ref data) => match data.elem {
18141818
ProjectionElem::Downcast(ref adt_def, index) => {
18151819
write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name)
@@ -1910,9 +1914,7 @@ impl<'tcx> Operand<'tcx> {
19101914
Operand::Constant(box Constant {
19111915
span,
19121916
ty,
1913-
literal: Literal::Value {
1914-
value: ty::Const::zero_sized(tcx, ty),
1915-
},
1917+
literal: ty::Const::zero_sized(tcx, ty),
19161918
})
19171919
}
19181920

@@ -2200,38 +2202,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
22002202
pub struct Constant<'tcx> {
22012203
pub span: Span,
22022204
pub ty: Ty<'tcx>,
2203-
pub literal: Literal<'tcx>,
2205+
pub literal: &'tcx ty::Const<'tcx>,
22042206
}
22052207

22062208
newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });
22072209

2208-
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
2209-
pub enum Literal<'tcx> {
2210-
Value {
2211-
value: &'tcx ty::Const<'tcx>,
2212-
},
2213-
Promoted {
2214-
// Index into the `promoted` vector of `Mir`.
2215-
index: Promoted,
2216-
},
2217-
}
2218-
22192210
impl<'tcx> Debug for Constant<'tcx> {
22202211
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2221-
write!(fmt, "{:?}", self.literal)
2222-
}
2223-
}
2224-
2225-
impl<'tcx> Debug for Literal<'tcx> {
2226-
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2227-
use self::Literal::*;
2228-
match *self {
2229-
Value { value } => {
2230-
write!(fmt, "const ")?;
2231-
fmt_const_val(fmt, value)
2232-
}
2233-
Promoted { index } => write!(fmt, "{:?}", index),
2234-
}
2212+
write!(fmt, "const ")?;
2213+
fmt_const_val(fmt, self.literal)
22352214
}
22362215
}
22372216

@@ -2918,20 +2897,3 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
29182897
self.ty.visit_with(visitor) || self.literal.visit_with(visitor)
29192898
}
29202899
}
2921-
2922-
impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
2923-
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
2924-
match *self {
2925-
Literal::Value { value } => Literal::Value {
2926-
value: value.fold_with(folder),
2927-
},
2928-
Literal::Promoted { index } => Literal::Promoted { index },
2929-
}
2930-
}
2931-
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
2932-
match *self {
2933-
Literal::Value { value } => value.visit_with(visitor),
2934-
Literal::Promoted { .. } => false,
2935-
}
2936-
}
2937-
}

src/librustc/mir/tcx.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ impl<'tcx> Place<'tcx> {
113113
match *self {
114114
Place::Local(index) =>
115115
PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
116+
Place::Promoted(ref data) => PlaceTy::Ty { ty: data.1 },
116117
Place::Static(ref data) =>
117118
PlaceTy::Ty { ty: data.ty },
118119
Place::Projection(ref proj) =>

src/librustc/mir/visit.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,6 @@ macro_rules! make_mir_visitor {
191191
self.super_constant(constant, location);
192192
}
193193

194-
fn visit_literal(&mut self,
195-
literal: & $($mutability)* Literal<'tcx>,
196-
location: Location) {
197-
self.super_literal(literal, location);
198-
}
199-
200194
fn visit_def_id(&mut self,
201195
def_id: & $($mutability)* DefId,
202196
_: Location) {
@@ -648,6 +642,9 @@ macro_rules! make_mir_visitor {
648642
Place::Static(ref $($mutability)* static_) => {
649643
self.visit_static(static_, context, location);
650644
}
645+
Place::Promoted(ref $($mutability)* promoted) => {
646+
self.visit_ty(& $($mutability)* promoted.1, TyContext::Location(location));
647+
},
651648
Place::Projection(ref $($mutability)* proj) => {
652649
self.visit_projection(proj, context, location);
653650
}
@@ -748,18 +745,7 @@ macro_rules! make_mir_visitor {
748745

749746
self.visit_span(span);
750747
self.visit_ty(ty, TyContext::Location(location));
751-
self.visit_literal(literal, location);
752-
}
753-
754-
fn super_literal(&mut self,
755-
literal: & $($mutability)* Literal<'tcx>,
756-
location: Location) {
757-
match *literal {
758-
Literal::Value { ref $($mutability)* value } => {
759-
self.visit_const(value, location);
760-
}
761-
Literal::Promoted { index: _ } => {}
762-
}
748+
self.visit_const(literal, location);
763749
}
764750

765751
fn super_def_id(&mut self, _def_id: & $($mutability)* DefId) {

src/librustc_codegen_llvm/consts.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,11 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
242242
g
243243
}
244244

245-
pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
246-
def_id: DefId,
247-
is_mutable: bool) {
245+
pub fn codegen_static<'a, 'tcx>(
246+
cx: &CodegenCx<'a, 'tcx>,
247+
def_id: DefId,
248+
is_mutable: bool,
249+
) {
248250
unsafe {
249251
let attrs = cx.tcx.codegen_fn_attrs(def_id);
250252

src/librustc_codegen_llvm/mir/block.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -507,14 +507,40 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
507507
// promotes any complex rvalues to constants.
508508
if i == 2 && intrinsic.unwrap().starts_with("simd_shuffle") {
509509
match *arg {
510+
// The shuffle array argument is usually not an explicit constant,
511+
// but specified directly in the code. This means it gets promoted
512+
// and we can then extract the value by evaluating the promoted.
513+
mir::Operand::Copy(mir::Place::Promoted(box(index, ty))) |
514+
mir::Operand::Move(mir::Place::Promoted(box(index, ty))) => {
515+
let param_env = ty::ParamEnv::reveal_all();
516+
let cid = mir::interpret::GlobalId {
517+
instance: self.instance,
518+
promoted: Some(index),
519+
};
520+
let c = bx.tcx().const_eval(param_env.and(cid));
521+
let (llval, ty) = self.simd_shuffle_indices(
522+
&bx,
523+
terminator.source_info.span,
524+
ty,
525+
c,
526+
);
527+
return OperandRef {
528+
val: Immediate(llval),
529+
layout: bx.cx.layout_of(ty),
530+
};
531+
532+
},
510533
mir::Operand::Copy(_) |
511534
mir::Operand::Move(_) => {
512535
span_bug!(span, "shuffle indices must be constant");
513536
}
514537
mir::Operand::Constant(ref constant) => {
538+
let c = self.eval_mir_constant(&bx, constant);
515539
let (llval, ty) = self.simd_shuffle_indices(
516540
&bx,
517-
constant,
541+
constant.span,
542+
constant.ty,
543+
c,
518544
);
519545
return OperandRef {
520546
val: Immediate(llval),

src/librustc_codegen_llvm/mir/constant.rs

+12-21
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use consts;
2525
use type_of::LayoutLlvmExt;
2626
use type_::Type;
2727
use syntax::ast::Mutability;
28+
use syntax::codemap::Span;
2829

2930
use super::super::callee;
3031
use super::FunctionCx;
@@ -117,13 +118,12 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
117118

118119
pub fn codegen_static_initializer<'a, 'tcx>(
119120
cx: &CodegenCx<'a, 'tcx>,
120-
def_id: DefId)
121-
-> Result<(ValueRef, &'tcx Allocation), Lrc<ConstEvalErr<'tcx>>>
122-
{
121+
def_id: DefId,
122+
) -> Result<(ValueRef, &'tcx Allocation), Lrc<ConstEvalErr<'tcx>>> {
123123
let instance = ty::Instance::mono(cx.tcx, def_id);
124124
let cid = GlobalId {
125125
instance,
126-
promoted: None
126+
promoted: None,
127127
};
128128
let param_env = ty::ParamEnv::reveal_all();
129129
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
@@ -161,28 +161,19 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
161161
bx: &Builder<'a, 'tcx>,
162162
constant: &mir::Constant<'tcx>,
163163
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
164-
match constant.literal {
165-
mir::Literal::Promoted { index } => {
166-
let param_env = ty::ParamEnv::reveal_all();
167-
let cid = mir::interpret::GlobalId {
168-
instance: self.instance,
169-
promoted: Some(index),
170-
};
171-
bx.tcx().const_eval(param_env.and(cid))
172-
}
173-
mir::Literal::Value { value } => {
174-
Ok(self.monomorphize(&value))
175-
}
176-
}.and_then(|c| self.fully_evaluate(bx, c))
164+
let c = self.monomorphize(&constant.literal);
165+
self.fully_evaluate(bx, c)
177166
}
178167

179168
/// process constant containing SIMD shuffle indices
180169
pub fn simd_shuffle_indices(
181170
&mut self,
182171
bx: &Builder<'a, 'tcx>,
183-
constant: &mir::Constant<'tcx>,
172+
span: Span,
173+
ty: Ty<'tcx>,
174+
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
184175
) -> (ValueRef, Ty<'tcx>) {
185-
self.eval_mir_constant(bx, constant)
176+
constant
186177
.and_then(|c| {
187178
let field_ty = c.ty.builtin_index().unwrap();
188179
let fields = match c.ty.sty {
@@ -217,11 +208,11 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
217208
})
218209
.unwrap_or_else(|e| {
219210
e.report_as_error(
220-
bx.tcx().at(constant.span),
211+
bx.tcx().at(span),
221212
"could not evaluate shuffle_indices at compile time",
222213
);
223214
// We've errored, so we don't have to produce working code.
224-
let ty = self.monomorphize(&constant.ty);
215+
let ty = self.monomorphize(&ty);
225216
let llty = bx.cx.layout_of(ty).llvm_type(bx.cx);
226217
(C_undef(llty), ty)
227218
})

src/librustc_codegen_llvm/mir/operand.rs

+9-28
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use llvm::{ValueRef, LLVMConstInBoundsGEP};
11+
use llvm::ValueRef;
1212
use rustc::mir::interpret::ConstEvalErr;
1313
use rustc::mir;
1414
use rustc::mir::interpret::ConstValue;
@@ -22,14 +22,12 @@ use common::{CodegenCx, C_undef, C_usize};
2222
use builder::{Builder, MemFlags};
2323
use value::Value;
2424
use type_of::LayoutLlvmExt;
25-
use type_::Type;
26-
use consts;
2725

2826
use std::fmt;
2927
use std::ptr;
3028

3129
use super::{FunctionCx, LocalRef};
32-
use super::constant::{scalar_to_llvm, const_alloc_to_llvm};
30+
use super::constant::scalar_to_llvm;
3331
use super::place::PlaceRef;
3432

3533
/// The representation of a Rust value. The enum variant is in fact
@@ -139,16 +137,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
139137
OperandValue::Pair(a_llval, b_llval)
140138
},
141139
ConstValue::ByRef(alloc, offset) => {
142-
let init = const_alloc_to_llvm(bx.cx, alloc);
143-
let base_addr = consts::addr_of(bx.cx, init, layout.align, "byte_str");
144-
145-
let llval = unsafe { LLVMConstInBoundsGEP(
146-
consts::bitcast(base_addr, Type::i8p(bx.cx)),
147-
&C_usize(bx.cx, offset.bytes()),
148-
1,
149-
)};
150-
let llval = consts::bitcast(llval, layout.llvm_type(bx.cx).ptr_to());
151-
return Ok(PlaceRef::new_sized(llval, layout, alloc.align).load(bx));
140+
return Ok(PlaceRef::from_const_alloc(bx, layout, alloc, offset).load(bx));
152141
},
153142
};
154143

@@ -409,20 +398,12 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
409398
self.eval_mir_constant(bx, constant)
410399
.and_then(|c| OperandRef::from_const(bx, c))
411400
.unwrap_or_else(|err| {
412-
match constant.literal {
413-
mir::Literal::Promoted { .. } => {
414-
// this is unreachable as long as runtime
415-
// and compile-time agree on values
416-
// With floats that won't always be true
417-
// so we generate an abort below
418-
},
419-
mir::Literal::Value { .. } => {
420-
err.report_as_error(
421-
bx.tcx().at(constant.span),
422-
"could not evaluate constant operand",
423-
);
424-
},
425-
}
401+
err.report_as_error(
402+
bx.tcx().at(constant.span),
403+
"could not evaluate constant operand",
404+
);
405+
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
406+
// the above error (or silence it under some conditions) will not cause UB
426407
let fnname = bx.cx.get_intrinsic(&("llvm.trap"));
427408
bx.call(fnname, &[], None);
428409
// We've errored, so we don't have to produce working code.

0 commit comments

Comments
 (0)