reducing repeating patters

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-16 23:47:31 +01:00
parent e65c72e19f
commit 127fdb3cc5
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143

View file

@ -3071,11 +3071,10 @@ impl<'a> Codegen<'a> {
} }
Expr::Return { pos, val } => { Expr::Return { pos, val } => {
let mut value = if let Some(val) = val { let mut value = if let Some(val) = val {
self.raw_expr_ctx(val, Ctx { ty: self.ci.ret })? self.ptr_expr_ctx(val, Ctx { ty: self.ci.ret })?
} else { } else {
Value { ty: ty::Id::VOID, ..Default::default() } Value { ty: ty::Id::VOID, ..Default::default() }
}; };
self.strip_var(&mut value);
let expected = *self.ci.ret.get_or_insert(value.ty); let expected = *self.ci.ret.get_or_insert(value.ty);
self.assert_ty(pos, &mut value, expected, "return value"); self.assert_ty(pos, &mut value, expected, "return value");
@ -3190,8 +3189,7 @@ impl<'a> Codegen<'a> {
Expr::UnOp { op: TokenKind::Band, val, pos } => { Expr::UnOp { op: TokenKind::Band, val, pos } => {
let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) }; let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) };
let mut val = self.raw_expr_ctx(val, ctx)?; let mut val = self.ptr_expr_ctx(val, ctx)?;
self.strip_var(&mut val);
if val.ptr { if val.ptr {
val.ptr = false; val.ptr = false;
@ -3316,8 +3314,7 @@ impl<'a> Codegen<'a> {
right: Expr::Null { .. }, right: Expr::Null { .. },
.. ..
} => { } => {
let mut cmped = self.raw_expr(left)?; let cmped = self.ptr_expr(left)?;
self.strip_var(&mut cmped);
let Some(ty) = self.tys.inner_of(cmped.ty) else { let Some(ty) = self.tys.inner_of(cmped.ty) else {
return self.error( return self.error(
@ -3331,8 +3328,7 @@ impl<'a> Codegen<'a> {
Expr::BinOp { left, pos, op, right } Expr::BinOp { left, pos, op, right }
if !matches!(op, TokenKind::Assign | TokenKind::Decl) => if !matches!(op, TokenKind::Assign | TokenKind::Decl) =>
{ {
let mut lhs = self.raw_expr_ctx(left, ctx)?; let mut lhs = self.ptr_expr_ctx(left, ctx)?;
self.strip_var(&mut lhs);
self.implicit_unwrap(left.pos(), &mut lhs); self.implicit_unwrap(left.pos(), &mut lhs);
match lhs.ty.expand() { match lhs.ty.expand() {
@ -3348,7 +3344,6 @@ impl<'a> Codegen<'a> {
let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty)); let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id); self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?; let mut rhs = rhs?;
self.strip_var(&mut rhs);
self.implicit_unwrap(right.pos(), &mut rhs); self.implicit_unwrap(right.pos(), &mut rhs);
let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op); let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
if op.is_compatison() { if op.is_compatison() {
@ -3378,10 +3373,9 @@ impl<'a> Codegen<'a> {
ty::Kind::Struct(s) if op.is_homogenous() => { ty::Kind::Struct(s) if op.is_homogenous() => {
debug_assert!(lhs.ptr); debug_assert!(lhs.ptr);
self.ci.nodes.lock(lhs.id); self.ci.nodes.lock(lhs.id);
let rhs = self.raw_expr_ctx(right, Ctx::default().with_ty(lhs.ty)); let rhs = self.ptr_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id); self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?; let mut rhs = rhs?;
self.strip_var(&mut rhs);
debug_assert!(rhs.ptr); debug_assert!(rhs.ptr);
self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand"); self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand");
let dst = self.new_stack(pos, lhs.ty); let dst = self.new_stack(pos, lhs.ty);
@ -3395,10 +3389,9 @@ impl<'a> Codegen<'a> {
}; };
self.ci.nodes.lock(lhs.id); self.ci.nodes.lock(lhs.id);
let rhs = self.raw_expr_ctx(right, Ctx::default().with_ty(lhs.ty)); let rhs = self.ptr_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id); self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?; let mut rhs = rhs?;
self.strip_var(&mut rhs);
self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand"); self.assert_ty(pos, &mut rhs, lhs.ty, "struct operand");
self.struct_fold_op(left.pos(), op, binding_op, s, lhs.id, rhs.id) self.struct_fold_op(left.pos(), op, binding_op, s, lhs.id, rhs.id)
@ -3409,8 +3402,7 @@ impl<'a> Codegen<'a> {
} }
} }
Expr::Index { base, index } => { Expr::Index { base, index } => {
let mut bs = self.raw_expr(base)?; let mut bs = self.ptr_expr(base)?;
self.strip_var(&mut bs);
if let Some(base) = self.tys.base_of(bs.ty) { if let Some(base) = self.tys.base_of(bs.ty) {
bs.ptr = true; bs.ptr = true;
@ -3508,8 +3500,7 @@ impl<'a> Codegen<'a> {
self.gen_inferred_const(ctx, ty::Id::DINT, len) self.gen_inferred_const(ctx, ty::Id::DINT, len)
} }
Expr::Directive { name: "bitcast", args: [val], pos } => { Expr::Directive { name: "bitcast", args: [val], pos } => {
let mut val = self.raw_expr(val)?; let mut val = self.ptr_expr(val)?;
self.strip_var(&mut val);
inference!(ty, ctx, self, pos, "type", "@as(<ty>, @bitcast(<expr>))"); inference!(ty, ctx, self, pos, "type", "@as(<ty>, @bitcast(<expr>))");
@ -3541,8 +3532,7 @@ impl<'a> Codegen<'a> {
Some(val) Some(val)
} }
Expr::Directive { name: "unwrap", args: [expr], .. } => { Expr::Directive { name: "unwrap", args: [expr], .. } => {
let mut val = self.raw_expr(expr)?; let mut val = self.ptr_expr(expr)?;
self.strip_var(&mut val);
if !val.ty.is_optional() { if !val.ty.is_optional() {
return self.error( return self.error(
@ -3661,7 +3651,7 @@ impl<'a> Codegen<'a> {
} }
Expr::Directive { name: "as", args: [ty, expr], pos } => { Expr::Directive { name: "as", args: [ty, expr], pos } => {
let ty = self.ty(ty); let ty = self.ty(ty);
let mut val = self.raw_expr_ctx(expr, Ctx::default().with_ty(ty))?; let mut val = self.ptr_expr_ctx(expr, Ctx::default().with_ty(ty))?;
if let Some(ity) = ctx.ty if let Some(ity) = ctx.ty
&& ity.try_upcast(ty) == Some(ty) && ity.try_upcast(ty) == Some(ty)
@ -3669,7 +3659,6 @@ impl<'a> Codegen<'a> {
{ {
self.error(pos, "the type is known at this point, remove the hint"); self.error(pos, "the type is known at this point, remove the hint");
} }
self.strip_var(&mut val);
self.assert_ty(expr.pos(), &mut val, ty, "hinted expr"); self.assert_ty(expr.pos(), &mut val, ty, "hinted expr");
Some(val) Some(val)
} }
@ -4381,8 +4370,7 @@ impl<'a> Codegen<'a> {
expected_ty: ty::Id, expected_ty: ty::Id,
hint: impl Display, hint: impl Display,
) -> Option<Value> { ) -> Option<Value> {
let mut value = self.raw_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?; let mut value = self.ptr_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?;
self.strip_var(&mut value);
self.assert_ty(expr.pos(), &mut value, expected_ty, hint); self.assert_ty(expr.pos(), &mut value, expected_ty, hint);
self.strip_ptr(&mut value); self.strip_ptr(&mut value);
Some(value) Some(value)
@ -4395,8 +4383,7 @@ impl<'a> Codegen<'a> {
pos: Pos, pos: Pos,
name: &str, name: &str,
) -> Option<Result<Value, (ty::Id, Value)>> { ) -> Option<Result<Value, (ty::Id, Value)>> {
let mut vtarget = self.raw_expr(target)?; let mut vtarget = self.ptr_expr(target)?;
self.strip_var(&mut vtarget);
self.implicit_unwrap(pos, &mut vtarget); self.implicit_unwrap(pos, &mut vtarget);
let tty = vtarget.ty; let tty = vtarget.ty;
@ -4658,8 +4645,7 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
), ),
Arg::Value(ty) => { Arg::Value(ty) => {
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.ptr_expr_ctx(arg, Ctx::default().with_ty(ty))?;
self.strip_var(&mut value);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
debug_assert_ne!(value.id, 0); debug_assert_ne!(value.id, 0);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name)); self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
@ -4761,11 +4747,8 @@ impl<'a> Codegen<'a> {
let carg = cargs.next().unwrap(); let carg = cargs.next().unwrap();
let Arg::Value(ty) = ty else { continue }; let Arg::Value(ty) = ty else { continue };
let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?; let value = self.checked_expr(arg, ty, fa!("argument {}", carg.name))?;
self.strip_var(&mut value);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
self.strip_ptr(&mut value);
self.add_clobbers(value, &mut clobbered_aliases); self.add_clobbers(value, &mut clobbered_aliases);
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
@ -4814,13 +4797,12 @@ impl<'a> Codegen<'a> {
let f = &self.files[c.file]; let f = &self.files[c.file];
let Expr::BinOp { left, right, .. } = c.ast.get(f) else { unreachable!() }; let Expr::BinOp { left, right, .. } = c.ast.get(f) else { unreachable!() };
let mut value = left let value = left
.find_pattern_path(c.name, right, |expr, is_ct| { .find_pattern_path(c.name, right, |expr, is_ct| {
debug_assert!(is_ct); debug_assert!(is_ct);
self.raw_expr_ctx(expr, ctx) self.ptr_expr_ctx(expr, ctx)
}) })
.unwrap_or_else(|_| unreachable!())?; .unwrap_or_else(|_| unreachable!())?;
self.strip_var(&mut value);
self.ci.file = prev_file; self.ci.file = prev_file;
self.ci.parent = prev_parent; self.ci.parent = prev_parent;
Some(value) Some(value)
@ -5079,13 +5061,26 @@ impl<'a> Codegen<'a> {
} }
} }
fn expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> { fn ptr_expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
let mut n = self.raw_expr_ctx(expr, ctx)?; let mut n = self.raw_expr_ctx(expr, ctx)?;
self.strip_var(&mut n); if mem::take(&mut n.var) {
let id = (u16::MAX - n.id) as usize;
n.ptr = self.ci.scope.vars[id].ptr;
n.id = self.ci.scope.vars[id].value();
}
Some(n)
}
fn expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
let mut n = self.ptr_expr_ctx(expr, ctx)?;
self.strip_ptr(&mut n); self.strip_ptr(&mut n);
Some(n) Some(n)
} }
fn ptr_expr(&mut self, expr: &Expr) -> Option<Value> {
self.ptr_expr_ctx(expr, Default::default())
}
fn expr(&mut self, expr: &Expr) -> Option<Value> { fn expr(&mut self, expr: &Expr) -> Option<Value> {
self.expr_ctx(expr, Default::default()) self.expr_ctx(expr, Default::default())
} }
@ -5110,14 +5105,6 @@ impl<'a> Codegen<'a> {
seted seted
} }
fn strip_var(&mut self, n: &mut Value) {
if mem::take(&mut n.var) {
let id = (u16::MAX - n.id) as usize;
n.ptr = self.ci.scope.vars[id].ptr;
n.id = self.ci.scope.vars[id].value();
}
}
fn gen_defers(&mut self, base: usize) -> Option<()> { fn gen_defers(&mut self, base: usize) -> Option<()> {
let defers = mem::take(&mut self.ci.defers); let defers = mem::take(&mut self.ci.defers);
for &(_, defer) in defers.iter().skip(base).rev() { for &(_, defer) in defers.iter().skip(base).rev() {
@ -5444,7 +5431,6 @@ impl<'a> Codegen<'a> {
fn wrap_in_opt(&mut self, pos: Pos, val: &mut Value) { fn wrap_in_opt(&mut self, pos: Pos, val: &mut Value) {
debug_assert!(!val.var); debug_assert!(!val.var);
let was_ptr = val.ptr;
let oty = self.tys.make_opt(val.ty); let oty = self.tys.make_opt(val.ty);
if let Some((uninit, ..)) = self.tys.nieche_of(val.ty) { if let Some((uninit, ..)) = self.tys.nieche_of(val.ty) {
@ -5456,9 +5442,9 @@ impl<'a> Codegen<'a> {
let OptLayout { flag_ty, flag_offset, payload_offset } = self.tys.opt_layout(val.ty); let OptLayout { flag_ty, flag_offset, payload_offset } = self.tys.opt_layout(val.ty);
self.strip_ptr(val);
match oty.loc(self.tys) { match oty.loc(self.tys) {
Loc::Reg => { Loc::Reg => {
self.strip_ptr(val);
// registers have inverted offsets so that accessing the inner type is a noop // registers have inverted offsets so that accessing the inner type is a noop
let flag_offset = self.tys.size_of(oty) * 8 - flag_offset * 8 - 1; let flag_offset = self.tys.size_of(oty) * 8 - flag_offset * 8 - 1;
let fill = self.ci.nodes.new_const(oty, 1i64 << flag_offset); let fill = self.ci.nodes.new_const(oty, 1i64 << flag_offset);
@ -5471,7 +5457,6 @@ impl<'a> Codegen<'a> {
val.ty = oty; val.ty = oty;
} }
Loc::Stack => { Loc::Stack => {
self.strip_ptr(val);
let stack = self.new_stack(pos, oty); let stack = self.new_stack(pos, oty);
let fill = self.ci.nodes.new_const(flag_ty, 1); let fill = self.ci.nodes.new_const(flag_ty, 1);
self.store_mem(stack, flag_ty, fill); self.store_mem(stack, flag_ty, fill);
@ -5482,10 +5467,6 @@ impl<'a> Codegen<'a> {
val.ty = oty; val.ty = oty;
} }
} }
if !was_ptr {
self.strip_ptr(val);
}
} }
fn implicit_unwrap(&mut self, pos: Pos, opt: &mut Value) { fn implicit_unwrap(&mut self, pos: Pos, opt: &mut Value) {