From bec0f1fdcf458dc882be89cf9678f9461ac3980a Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Thu, 16 Jan 2025 11:15:37 -0800 Subject: [PATCH] Min and max operators for DCs --- hercules_cg/src/cpu.rs | 14 ++++++++++++++ hercules_cg/src/rt.rs | 14 ++++++++++++++ hercules_ir/src/ir.rs | 17 ++++++++++++++++- hercules_ir/src/typecheck.rs | 26 +++++++++++++++++++++++++- hercules_opt/src/utils.rs | 18 ++++++++++++++++++ 5 files changed, 87 insertions(+), 2 deletions(-) diff --git a/hercules_cg/src/cpu.rs b/hercules_cg/src/cpu.rs index 117e4f1d..8dfe06e7 100644 --- a/hercules_cg/src/cpu.rs +++ b/hercules_cg/src/cpu.rs @@ -602,6 +602,20 @@ impl<'a> CPUContext<'a> { left.idx(), right.idx() )?, + DynamicConstant::Min(left, right) => write!( + body, + " %dc{} = call @llvm.umin.i64(i64%dc{},i64%dc{})\n", + dc.idx(), + left.idx(), + right.idx() + )?, + DynamicConstant::Max(left, right) => write!( + body, + " %dc{} = call @llvm.umax.i64(i64%dc{},i64%dc{})\n", + dc.idx(), + left.idx(), + right.idx() + )?, } } Ok(()) diff --git a/hercules_cg/src/rt.rs b/hercules_cg/src/rt.rs index 13370c45..6e56ebc4 100644 --- a/hercules_cg/src/rt.rs +++ b/hercules_cg/src/rt.rs @@ -469,6 +469,20 @@ impl<'a> RTContext<'a> { self.codegen_dynamic_constant(right, w)?; write!(w, ")")?; } + DynamicConstant::Min(left, right) => { + write!(w, "::core::cmp::min(")?; + self.codegen_dynamic_constant(left, w)?; + write!(w, ",")?; + self.codegen_dynamic_constant(right, w)?; + write!(w, ")")?; + } + DynamicConstant::Max(left, right) => { + write!(w, "::core::cmp::max(")?; + self.codegen_dynamic_constant(left, w)?; + write!(w, ",")?; + self.codegen_dynamic_constant(right, w)?; + write!(w, ")")?; + } } Ok(()) } diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index 4fd0cf0b..ffa338b5 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -1,3 +1,4 @@ +use std::cmp::{max, min}; use std::fmt::Write; use std::ops::Coroutine; use std::ops::CoroutineState; @@ -121,6 +122,8 @@ pub enum DynamicConstant { Mul(DynamicConstantID, DynamicConstantID), Div(DynamicConstantID, DynamicConstantID), Rem(DynamicConstantID, DynamicConstantID), + Min(DynamicConstantID, DynamicConstantID), + Max(DynamicConstantID, DynamicConstantID), } /* @@ -445,13 +448,17 @@ impl Module { | DynamicConstant::Sub(x, y) | DynamicConstant::Mul(x, y) | DynamicConstant::Div(x, y) - | DynamicConstant::Rem(x, y) => { + | DynamicConstant::Rem(x, y) + | DynamicConstant::Min(x, y) + | DynamicConstant::Max(x, y) => { match &self.dynamic_constants[dc_id.idx()] { DynamicConstant::Add(_, _) => write!(w, "+")?, DynamicConstant::Sub(_, _) => write!(w, "-")?, DynamicConstant::Mul(_, _) => write!(w, "*")?, DynamicConstant::Div(_, _) => write!(w, "/")?, DynamicConstant::Rem(_, _) => write!(w, "%")?, + DynamicConstant::Min(_, _) => write!(w, "min")?, + DynamicConstant::Max(_, _) => write!(w, "max")?, _ => (), } write!(w, "(")?; @@ -1014,6 +1021,14 @@ pub fn evaluate_dynamic_constant( DynamicConstant::Rem(left, right) => { Some(evaluate_dynamic_constant(left, dcs)? % evaluate_dynamic_constant(right, dcs)?) } + DynamicConstant::Min(left, right) => Some(min( + evaluate_dynamic_constant(left, dcs)?, + evaluate_dynamic_constant(right, dcs)?, + )), + DynamicConstant::Max(left, right) => Some(max( + evaluate_dynamic_constant(left, dcs)?, + evaluate_dynamic_constant(right, dcs)?, + )), } } diff --git a/hercules_ir/src/typecheck.rs b/hercules_ir/src/typecheck.rs index d6862c35..5a64e577 100644 --- a/hercules_ir/src/typecheck.rs +++ b/hercules_ir/src/typecheck.rs @@ -193,7 +193,9 @@ fn typeflow( | DynamicConstant::Sub(x, y) | DynamicConstant::Mul(x, y) | DynamicConstant::Div(x, y) - | DynamicConstant::Rem(x, y) => { + | DynamicConstant::Rem(x, y) + | DynamicConstant::Min(x, y) + | DynamicConstant::Max(x, y) => { check_dynamic_constants(x, dynamic_constants, num_parameters) && check_dynamic_constants(y, dynamic_constants, num_parameters) } @@ -1328,5 +1330,27 @@ fn dyn_const_subst( reverse_dynamic_constant_map, ) } + DynamicConstant::Min(l, r) => { + let x = *l; + let y = *r; + let sx = dyn_const_subst(dynamic_constants, reverse_dynamic_constant_map, dc_args, x); + let sy = dyn_const_subst(dynamic_constants, reverse_dynamic_constant_map, dc_args, y); + intern_dyn_const( + DynamicConstant::Min(sx, sy), + dynamic_constants, + reverse_dynamic_constant_map, + ) + } + DynamicConstant::Max(l, r) => { + let x = *l; + let y = *r; + let sx = dyn_const_subst(dynamic_constants, reverse_dynamic_constant_map, dc_args, x); + let sy = dyn_const_subst(dynamic_constants, reverse_dynamic_constant_map, dc_args, y); + intern_dyn_const( + DynamicConstant::Max(sx, sy), + dynamic_constants, + reverse_dynamic_constant_map, + ) + } } } diff --git a/hercules_opt/src/utils.rs b/hercules_opt/src/utils.rs index 77fa1ff6..2a4fd94c 100644 --- a/hercules_opt/src/utils.rs +++ b/hercules_opt/src/utils.rs @@ -130,6 +130,24 @@ pub(crate) fn substitute_dynamic_constants( dc_c } } + DynamicConstant::Min(left, right) => { + let new_left = substitute_dynamic_constants(dc_a, dc_b, left, edit); + let new_right = substitute_dynamic_constants(dc_a, dc_b, right, edit); + if new_left != left || new_right != right { + edit.add_dynamic_constant(DynamicConstant::Min(new_left, new_right)) + } else { + dc_c + } + } + DynamicConstant::Max(left, right) => { + let new_left = substitute_dynamic_constants(dc_a, dc_b, left, edit); + let new_right = substitute_dynamic_constants(dc_a, dc_b, right, edit); + if new_left != left || new_right != right { + edit.add_dynamic_constant(DynamicConstant::Max(new_left, new_right)) + } else { + dc_c + } + } } } -- GitLab