Skip to content

Commit

Permalink
Rollup merge of #83916 - Amanieu:asm_anonconst, r=petrochenkov
Browse files Browse the repository at this point in the history
Use AnonConst for asm! constants

This replaces the old system which used explicit promotion. See #83169 for more background.

The syntax for `const` operands is still the same as before: `const <expr>`.

Fixes #83169

Because the implementation is heavily based on inline consts, we suffer from the same issues:
- We lose the ability to use expressions derived from generics. See the deleted tests in `src/test/ui/asm/const.rs`.
- We are hitting the same ICEs as inline consts, for example #78174. It is unlikely that we will be able to stabilize this before inline consts are stabilized.
  • Loading branch information
Dylan-DPC authored Apr 7, 2021
2 parents 4d5bb1c + 32be124 commit b81c6cd
Show file tree
Hide file tree
Showing 37 changed files with 281 additions and 242 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1998,7 +1998,7 @@ pub enum InlineAsmOperand {
out_expr: Option<P<Expr>>,
},
Const {
expr: P<Expr>,
anon_const: AnonConst,
},
Sym {
expr: P<Expr>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,6 @@ pub fn noop_visit_expr<T: MutVisitor>(
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::InOut { expr, .. }
| InlineAsmOperand::Const { expr, .. }
| InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr),
InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
Expand All @@ -1265,6 +1264,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
vis.visit_expr(out_expr);
}
}
InlineAsmOperand::Const { anon_const, .. } => vis.visit_anon_const(anon_const),
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::InOut { expr, .. }
| InlineAsmOperand::Const { expr, .. }
| InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
Expand All @@ -848,6 +847,9 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
visitor.visit_expr(out_expr);
}
}
InlineAsmOperand::Const { anon_const, .. } => {
visitor.visit_anon_const(anon_const)
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,9 +1411,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
}
}
InlineAsmOperand::Const { ref expr } => {
hir::InlineAsmOperand::Const { expr: self.lower_expr_mut(expr) }
}
InlineAsmOperand::Const { ref anon_const } => hir::InlineAsmOperand::Const {
anon_const: self.lower_anon_const(anon_const),
},
InlineAsmOperand::Sym { ref expr } => {
hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2149,10 +2149,10 @@ impl<'a> State<'a> {
None => s.word("_"),
}
}
InlineAsmOperand::Const { expr } => {
InlineAsmOperand::Const { anon_const } => {
s.word("const");
s.space();
s.print_expr(expr);
s.print_expr(&anon_const.value);
}
InlineAsmOperand::Sym { expr } => {
s.word("sym");
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ fn parse_args<'a>(
ast::InlineAsmOperand::InOut { reg, expr, late: true }
}
} else if p.eat_keyword(kw::Const) {
let expr = p.parse_expr()?;
ast::InlineAsmOperand::Const { expr }
let anon_const = p.parse_anon_const_expr()?;
ast::InlineAsmOperand::Const { anon_const }
} else if p.eat_keyword(sym::sym) {
let expr = p.parse_expr()?;
match expr.kind {
Expand Down
64 changes: 30 additions & 34 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,41 +822,37 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
InlineAsmOperandRef::InOut { reg, late, in_value, out_place }
}
mir::InlineAsmOperand::Const { ref value } => {
if let mir::Operand::Constant(constant) = value {
let const_value = self
.eval_mir_constant(constant)
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
let ty = constant.ty();
let size = bx.layout_of(ty).size;
let scalar = match const_value {
ConstValue::Scalar(s) => s,
_ => span_bug!(
span,
"expected Scalar for promoted asm const, but got {:#?}",
const_value
),
};
let value = scalar.assert_bits(size);
let string = match ty.kind() {
ty::Uint(_) => value.to_string(),
ty::Int(int_ty) => {
match int_ty.normalize(bx.tcx().sess.target.pointer_width) {
ty::IntTy::I8 => (value as i8).to_string(),
ty::IntTy::I16 => (value as i16).to_string(),
ty::IntTy::I32 => (value as i32).to_string(),
ty::IntTy::I64 => (value as i64).to_string(),
ty::IntTy::I128 => (value as i128).to_string(),
ty::IntTy::Isize => unreachable!(),
}
let const_value = self
.eval_mir_constant(value)
.unwrap_or_else(|_| span_bug!(span, "asm const cannot be resolved"));
let ty = value.ty();
let size = bx.layout_of(ty).size;
let scalar = match const_value {
ConstValue::Scalar(s) => s,
_ => span_bug!(
span,
"expected Scalar for promoted asm const, but got {:#?}",
const_value
),
};
let value = scalar.assert_bits(size);
let string = match ty.kind() {
ty::Uint(_) => value.to_string(),
ty::Int(int_ty) => {
match int_ty.normalize(bx.tcx().sess.target.pointer_width) {
ty::IntTy::I8 => (value as i8).to_string(),
ty::IntTy::I16 => (value as i16).to_string(),
ty::IntTy::I32 => (value as i32).to_string(),
ty::IntTy::I64 => (value as i64).to_string(),
ty::IntTy::I128 => (value as i128).to_string(),
ty::IntTy::Isize => unreachable!(),
}
ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),
ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(),
_ => span_bug!(span, "asm const has bad type {}", ty),
};
InlineAsmOperandRef::Const { string }
} else {
span_bug!(span, "asm const is not a constant");
}
}
ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),
ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(),
_ => span_bug!(span, "asm const has bad type {}", ty),
};
InlineAsmOperandRef::Const { string }
}
mir::InlineAsmOperand::SymFn { ref value } => {
let literal = self.monomorphize(value.literal);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,7 @@ pub enum InlineAsmOperand<'hir> {
out_expr: Option<Expr<'hir>>,
},
Const {
expr: Expr<'hir>,
anon_const: AnonConst,
},
Sym {
expr: Expr<'hir>,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
match op {
InlineAsmOperand::In { expr, .. }
| InlineAsmOperand::InOut { expr, .. }
| InlineAsmOperand::Const { expr, .. }
| InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
InlineAsmOperand::Out { expr, .. } => {
if let Some(expr) = expr {
Expand All @@ -1202,6 +1201,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
visitor.visit_expr(out_expr);
}
}
InlineAsmOperand::Const { anon_const, .. } => {
visitor.visit_anon_const(anon_const)
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1570,10 +1570,10 @@ impl<'a> State<'a> {
None => s.word("_"),
}
}
hir::InlineAsmOperand::Const { expr } => {
hir::InlineAsmOperand::Const { anon_const } => {
s.word("const");
s.space();
s.print_expr(expr);
s.print_anon_const(anon_const);
}
hir::InlineAsmOperand::Sym { expr } => {
s.word("sym");
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ pub enum InlineAsmOperand<'tcx> {
out_place: Option<Place<'tcx>>,
},
Const {
value: Operand<'tcx>,
value: Box<Constant<'tcx>>,
},
SymFn {
value: Box<Constant<'tcx>>,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,7 @@ macro_rules! make_mir_visitor {
} => {
for op in operands {
match op {
InlineAsmOperand::In { value, .. }
| InlineAsmOperand::Const { value } => {
InlineAsmOperand::In { value, .. } => {
self.visit_operand(value, location);
}
InlineAsmOperand::Out { place, .. } => {
Expand All @@ -607,7 +606,8 @@ macro_rules! make_mir_visitor {
);
}
}
InlineAsmOperand::SymFn { value } => {
InlineAsmOperand::Const { value }
| InlineAsmOperand::SymFn { value } => {
self.visit_constant(value, location);
}
InlineAsmOperand::SymStatic { def_id: _ } => {}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir/src/borrow_check/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
} => {
for op in operands {
match *op {
InlineAsmOperand::In { reg: _, ref value }
| InlineAsmOperand::Const { ref value } => {
InlineAsmOperand::In { reg: _, ref value } => {
self.consume_operand(location, value);
}
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
Expand All @@ -219,7 +218,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
self.mutate_place(location, out_place, Shallow(None), JustWrite);
}
}
InlineAsmOperand::SymFn { value: _ }
InlineAsmOperand::Const { value: _ }
| InlineAsmOperand::SymFn { value: _ }
| InlineAsmOperand::SymStatic { def_id: _ } => {}
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir/src/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
} => {
for op in operands {
match *op {
InlineAsmOperand::In { reg: _, ref value }
| InlineAsmOperand::Const { ref value } => {
InlineAsmOperand::In { reg: _, ref value } => {
self.consume_operand(loc, (value, span), flow_state);
}
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
Expand All @@ -761,7 +760,8 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
);
}
}
InlineAsmOperand::SymFn { value: _ }
InlineAsmOperand::Const { value: _ }
| InlineAsmOperand::SymFn { value: _ }
| InlineAsmOperand::SymStatic { def_id: _ } => {}
}
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_mir/src/dataflow/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
for op in operands {
match *op {
InlineAsmOperand::In { reg: _, ref value }
| InlineAsmOperand::Const { ref value } => {
=> {
self.gather_operand(value);
}
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
Expand All @@ -441,7 +441,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
self.gather_init(out_place.as_ref(), InitKind::Deep);
}
}
InlineAsmOperand::SymFn { value: _ }
InlineAsmOperand::Const { value: _ }
| InlineAsmOperand::SymFn { value: _ }
| InlineAsmOperand::SymStatic { def_id: _ } => {}
}
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_mir/src/transform/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,9 +720,6 @@ impl Conflicts<'a> {
}
}
}
InlineAsmOperand::Const { value } => {
assert!(value.place().is_none());
}
InlineAsmOperand::InOut {
reg: _,
late: _,
Expand All @@ -731,6 +728,7 @@ impl Conflicts<'a> {
}
| InlineAsmOperand::In { reg: _, value: _ }
| InlineAsmOperand::Out { reg: _, late: _, place: None }
| InlineAsmOperand::Const { value: _ }
| InlineAsmOperand::SymFn { value: _ }
| InlineAsmOperand::SymStatic { def_id: _ } => {}
}
Expand Down
Loading

0 comments on commit b81c6cd

Please sign in to comment.