From 2c1427c56db66622e47367bbbf223286d9a0adc5 Mon Sep 17 00:00:00 2001 From: rarbore2 <rarbore2@illinois.edu> Date: Mon, 23 Dec 2024 23:59:46 -0600 Subject: [PATCH] Misc. fixes to make cava compile --- hercules_cg/src/cpu.rs | 32 ++++- hercules_cg/src/device.rs | 24 ++++ hercules_cg/src/lib.rs | 2 + hercules_cg/src/rt.rs | 183 +++++++++++++++++----------- hercules_ir/src/ir.rs | 25 +++- hercules_ir/src/typecheck.rs | 8 +- hercules_opt/src/ccp.rs | 109 ++++++++++++++++- hercules_opt/src/inline.rs | 5 +- hercules_opt/src/pass.rs | 36 +++--- hercules_samples/call/src/main.rs | 2 +- hercules_samples/ccp/src/main.rs | 2 +- juno_frontend/src/intrinsics.rs | 10 ++ juno_frontend/src/lib.rs | 4 +- juno_samples/cava.jn | 14 +-- juno_samples/nested_ccp/src/main.rs | 2 +- 15 files changed, 340 insertions(+), 118 deletions(-) create mode 100644 hercules_cg/src/device.rs diff --git a/hercules_cg/src/cpu.rs b/hercules_cg/src/cpu.rs index eba161bb..080c195a 100644 --- a/hercules_cg/src/cpu.rs +++ b/hercules_cg/src/cpu.rs @@ -114,8 +114,8 @@ impl<'a> CPUContext<'a> { .map(|idx| (NodeID::new(idx), LLVMBlock::default())) .collect(); - // Emit calculation of dynamic constants into the start block. Just - // calculate every dynamic constant, and let LLVM clean them up. + // Emit calculation of dynamic constants into the start block. Calculate + // every valid dynamic constant, and let LLVM clean them up. self.codegen_dynamic_constants( blocks.get_mut(&NodeID::new(0)).unwrap(), self.function.num_dynamic_constants, @@ -212,7 +212,11 @@ impl<'a> CPUContext<'a> { let term = &mut blocks.get_mut(&id).unwrap().term; write!(term, " ret {}\n", self.get_value(data, true))? } - _ => panic!("PANIC: Can't lower {:?}.", self.function.nodes[id.idx()]), + _ => panic!( + "PANIC: Can't lower {:?} in {}.", + self.function.nodes[id.idx()], + self.function.name + ), } Ok(()) } @@ -866,6 +870,28 @@ fn convert_intrinsic(intrinsic: &Intrinsic, ty: &Type) -> String { Intrinsic::Ln => "log", Intrinsic::Log10 => "log10", Intrinsic::Log2 => "log2", + Intrinsic::Max => { + if ty.is_float() { + "max" + } else if ty.is_unsigned() { + "umax" + } else if ty.is_signed() { + "smax" + } else { + panic!() + } + } + Intrinsic::Min => { + if ty.is_float() { + "min" + } else if ty.is_unsigned() { + "umin" + } else if ty.is_signed() { + "smin" + } else { + panic!() + } + } Intrinsic::Pow => "pow", Intrinsic::Powf => "pow", Intrinsic::Powi => "powi", diff --git a/hercules_cg/src/device.rs b/hercules_cg/src/device.rs new file mode 100644 index 00000000..7dbeeeda --- /dev/null +++ b/hercules_cg/src/device.rs @@ -0,0 +1,24 @@ +extern crate hercules_ir; + +use self::hercules_ir::*; + +/* + * Top level function to definitively place functions onto devices. A function + * may store a device placement, but only optionally - this function assigns + * devices to the rest of the functions. + */ +pub fn device_placement(functions: &Vec<Function>, callgraph: &CallGraph) -> Vec<Device> { + let mut devices = vec![]; + + for (idx, function) in functions.into_iter().enumerate() { + if let Some(device) = function.device { + devices.push(device); + } else if function.entry || callgraph.num_callees(FunctionID::new(idx)) != 0 { + devices.push(Device::AsyncRust); + } else { + devices.push(Device::LLVM); + } + } + + devices +} diff --git a/hercules_cg/src/lib.rs b/hercules_cg/src/lib.rs index 9013eff7..952ce368 100644 --- a/hercules_cg/src/lib.rs +++ b/hercules_cg/src/lib.rs @@ -1,9 +1,11 @@ #![feature(if_let_guard, let_chains)] pub mod cpu; +pub mod device; pub mod mem; pub mod rt; pub use crate::cpu::*; +pub use crate::device::*; pub use crate::mem::*; pub use crate::rt::*; diff --git a/hercules_cg/src/rt.rs b/hercules_cg/src/rt.rs index ddbc8f53..305ecf9b 100644 --- a/hercules_cg/src/rt.rs +++ b/hercules_cg/src/rt.rs @@ -24,6 +24,7 @@ pub fn rt_codegen<W: Write>( control_subgraph: &Subgraph, bbs: &Vec<NodeID>, callgraph: &CallGraph, + devices: &Vec<Device>, memory_objects: &Vec<MemoryObjects>, memory_objects_mutability: &MemoryObjectsMutability, w: &mut W, @@ -36,6 +37,7 @@ pub fn rt_codegen<W: Write>( control_subgraph, bbs, callgraph, + devices, memory_objects, _memory_objects_mutability: memory_objects_mutability, }; @@ -50,6 +52,7 @@ struct RTContext<'a> { control_subgraph: &'a Subgraph, bbs: &'a Vec<NodeID>, callgraph: &'a CallGraph, + devices: &'a Vec<Device>, memory_objects: &'a Vec<MemoryObjects>, // TODO: use once memory objects are passed in a custom type where this // actually matters. @@ -157,6 +160,9 @@ impl<'a> RTContext<'a> { // Dump signatures for called CPU functions. write!(w, " extern \"C\" {{\n")?; for callee in self.callgraph.get_callees(self.func_id) { + if self.devices[callee.idx()] != Device::LLVM { + continue; + } let callee = &self.module.functions[callee.idx()]; write!(w, " fn {}(", callee.name)?; let mut first_param = true; @@ -376,86 +382,119 @@ impl<'a> RTContext<'a> { ref dynamic_constants, ref args, } => { - let block = &mut blocks.get_mut(&self.bbs[id.idx()]).unwrap(); - write!( - block, - " {} = unsafe {{ {}(", - self.get_value(id), - self.module.functions[callee_id.idx()].name - )?; - for dc in dynamic_constants { - self.codegen_dynamic_constant(*dc, block)?; - write!(block, ", ")?; - } - for arg in args { - write!(block, "{}, ", self.get_value(*arg))?; - } - write!(block, ") }};\n")?; - - // When a CPU function is called that returns a memory object, - // that memory object must have come from one of its parameters. - // Dynamically figure out which one it came from, so that we can - // move it to the slot of the output memory object. - let call_memory_objects = - self.memory_objects[self.func_id.idx()].memory_objects(id); - if !call_memory_objects.is_empty() { - assert_eq!(call_memory_objects.len(), 1); - let call_memory_object = call_memory_objects[0]; - - let callee_returned_memory_objects = - self.memory_objects[callee_id.idx()].returned_memory_objects(); - let possible_params: Vec<_> = (0..self.module.functions[callee_id.idx()] - .param_types - .len()) - .filter(|idx| { - let memory_object_of_param = self.memory_objects[callee_id.idx()] - .memory_object_of_parameter(*idx); - // Look at parameters that could be the source of - // the memory object returned by the function. - memory_object_of_param - .map(|memory_object_of_param| { - callee_returned_memory_objects.contains(&memory_object_of_param) - }) - .unwrap_or(false) - }) - .collect(); - let arg_memory_objects = args - .into_iter() - .enumerate() - .filter(|(idx, _)| possible_params.contains(idx)) - .map(|(_, arg)| { - self.memory_objects[self.func_id.idx()] - .memory_objects(*arg) + match self.devices[callee_id.idx()] { + Device::LLVM => { + let block = &mut blocks.get_mut(&self.bbs[id.idx()]).unwrap(); + write!( + block, + " {} = unsafe {{ {}(", + self.get_value(id), + self.module.functions[callee_id.idx()].name + )?; + for dc in dynamic_constants { + self.codegen_dynamic_constant(*dc, block)?; + write!(block, ", ")?; + } + for arg in args { + write!(block, "{}, ", self.get_value(*arg))?; + } + write!(block, ") }};\n")?; + + // When a CPU function is called that returns a memory + // object, that memory object must have come from one of + // its parameters. Dynamically figure out which one it + // came from, so that we can move it to the slot of the + // output memory object. + let call_memory_objects = + self.memory_objects[self.func_id.idx()].memory_objects(id); + if !call_memory_objects.is_empty() { + assert_eq!(call_memory_objects.len(), 1); + let call_memory_object = call_memory_objects[0]; + + let callee_returned_memory_objects = + self.memory_objects[callee_id.idx()].returned_memory_objects(); + let possible_params: Vec<_> = + (0..self.module.functions[callee_id.idx()].param_types.len()) + .filter(|idx| { + let memory_object_of_param = self.memory_objects + [callee_id.idx()] + .memory_object_of_parameter(*idx); + // Look at parameters that could be the + // source of the memory object returned + // by the function. + memory_object_of_param + .map(|memory_object_of_param| { + callee_returned_memory_objects + .contains(&memory_object_of_param) + }) + .unwrap_or(false) + }) + .collect(); + let arg_memory_objects = args .into_iter() - }) - .flatten(); - - // Dynamically check which of the memory objects - // corresponding to arguments to the call was returned by - // the call. Move that memory object into the memory object - // of the call. - let mut first_obj = true; - for arg_memory_object in arg_memory_objects { - write!(block, " ")?; - if first_obj { - first_obj = false; - } else { - write!(block, "else ")?; + .enumerate() + .filter(|(idx, _)| possible_params.contains(idx)) + .map(|(_, arg)| { + self.memory_objects[self.func_id.idx()] + .memory_objects(*arg) + .into_iter() + }) + .flatten(); + + // Dynamically check which of the memory objects + // corresponding to arguments to the call was + // returned by the call. Move that memory object + // into the memory object of the call. + let mut first_obj = true; + for arg_memory_object in arg_memory_objects { + write!(block, " ")?; + if first_obj { + first_obj = false; + } else { + write!(block, "else ")?; + } + write!(block, "if let Some(mem_obj) = mem_obj{}.as_mut() && ::std::boxed::Box::as_mut_ptr(mem_obj) as *mut u8 == {} {{\n", arg_memory_object, self.get_value(id))?; + write!( + block, + " mem_obj{} = mem_obj{}.take();\n", + call_memory_object, arg_memory_object + )?; + write!(block, " }}\n")?; + } + write!(block, " else {{\n")?; + write!(block, " panic!(\"HERCULES PANIC: Pointer returned from called function doesn't match any known memory objects.\");\n")?; + write!(block, " }}\n")?; } - write!(block, "if let Some(mem_obj) = mem_obj{}.as_mut() && ::std::boxed::Box::as_mut_ptr(mem_obj) as *mut u8 == {} {{\n", arg_memory_object, self.get_value(id))?; + } + Device::AsyncRust => { + let block = &mut blocks.get_mut(&self.bbs[id.idx()]).unwrap(); write!( block, - " mem_obj{} = mem_obj{}.take();\n", - call_memory_object, arg_memory_object + " {} = {}(", + self.get_value(id), + self.module.functions[callee_id.idx()].name )?; - write!(block, " }}\n")?; + for dc in dynamic_constants { + self.codegen_dynamic_constant(*dc, block)?; + write!(block, ", ")?; + } + for arg in args { + if self.module.types[self.typing[arg.idx()].idx()].is_primitive() { + write!(block, "{}, ", self.get_value(*arg))?; + } else { + write!(block, "{}.take(), ", self.get_value(*arg))?; + } + } + write!(block, ").await;\n")?; } - write!(block, " else {{\n")?; - write!(block, " panic!(\"HERCULES PANIC: Pointer returned from called function doesn't match any known memory objects.\");\n")?; - write!(block, " }}\n")?; + _ => todo!(), } } - _ => panic!("PANIC: Can't lower {:?}.", func.nodes[id.idx()]), + _ => panic!( + "PANIC: Can't lower {:?} in {}.", + func.nodes[id.idx()], + func.name + ), } Ok(()) } diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index d4eed8e2..b46e2dda 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -289,6 +289,8 @@ pub enum Intrinsic { Log, Log10, Log2, + Max, + Min, Pow, Powf, Powi, @@ -327,13 +329,12 @@ pub enum Schedule { * The authoritative enumeration of supported backends. Multiple backends may * correspond to the same kind of hardware. */ -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum Device { LLVM, NVVM, - // Internal nodes in the call graph are lowered to async Rust code that - // calls device functions (leaf nodes in the call graph), possibly - // concurrently. + // Entry functions are lowered to async Rust code that calls device + // functions (leaf nodes in the call graph), possibly concurrently. AsyncRust, } @@ -594,7 +595,10 @@ pub fn constants_bottom_up(constants: &Vec<Constant>) -> impl Iterator<Item = Co /* * Create an iterator that traverses all the dynamic constants in the module * bottom up. This uses a coroutine to make iteratively traversing the dynamic - * constant DAGs easier. + * constant DAGs easier. This bottom-up visitor will ignore dynamic constants + * that reference non-sensical IDs. These are artifacts left over by the process + * of subsituting dynamic constants during some transformation passes, and + * shouldn't be used by any nodes. */ pub fn dynamic_constants_bottom_up( dynamic_constants: &Vec<DynamicConstant>, @@ -619,6 +623,11 @@ pub fn dynamic_constants_bottom_up( // We have to yield the children of this node before // this node itself. We keep track of which nodes have // yielded using visited. + if left.idx() >= visited.len() || right.idx() >= visited.len() { + // This is an invalid dynamic constant and should be + // skipped. + continue; + } let can_yield = visited[left.idx()] && visited[right.idx()]; if can_yield { visited.set(id.idx(), true); @@ -1565,6 +1574,8 @@ impl Intrinsic { "log" => Some(Intrinsic::Log), "log10" => Some(Intrinsic::Log10), "log2" => Some(Intrinsic::Log2), + "max" => Some(Intrinsic::Max), + "min" => Some(Intrinsic::Min), "pow" => Some(Intrinsic::Pow), "powf" => Some(Intrinsic::Powf), "powi" => Some(Intrinsic::Powi), @@ -1601,6 +1612,8 @@ impl Intrinsic { Intrinsic::Log => "Log", Intrinsic::Log10 => "Log10", Intrinsic::Log2 => "Log2", + Intrinsic::Max => "Max", + Intrinsic::Min => "Min", Intrinsic::Pow => "Pow", Intrinsic::Powf => "Powf", Intrinsic::Powi => "Powi", @@ -1636,6 +1649,8 @@ impl Intrinsic { Intrinsic::Log => "log", Intrinsic::Log10 => "log10", Intrinsic::Log2 => "log2", + Intrinsic::Max => "max", + Intrinsic::Min => "min", Intrinsic::Pow => "pow", Intrinsic::Powf => "powf", Intrinsic::Powi => "powi", diff --git a/hercules_ir/src/typecheck.rs b/hercules_ir/src/typecheck.rs index 46a0a9f2..c657d598 100644 --- a/hercules_ir/src/typecheck.rs +++ b/hercules_ir/src/typecheck.rs @@ -790,6 +790,8 @@ fn typeflow( | Intrinsic::Tanh => 1, Intrinsic::ATan2 | Intrinsic::Log + | Intrinsic::Max + | Intrinsic::Min | Intrinsic::Pow | Intrinsic::Powf | Intrinsic::Powi => 2, @@ -844,6 +846,8 @@ fn typeflow( | Intrinsic::Ln1P | Intrinsic::Log10 | Intrinsic::Log2 + | Intrinsic::Max + | Intrinsic::Min | Intrinsic::Round | Intrinsic::Sin | Intrinsic::Sinh @@ -1062,9 +1066,7 @@ fn typeflow( // Type is the type of the _if node inputs[0].clone() } - Node::Undef { ty } => { - TypeSemilattice::Concrete(*ty) - } + Node::Undef { ty } => TypeSemilattice::Concrete(*ty), } } diff --git a/hercules_opt/src/ccp.rs b/hercules_opt/src/ccp.rs index 28215366..a66bf633 100644 --- a/hercules_opt/src/ccp.rs +++ b/hercules_opt/src/ccp.rs @@ -1,11 +1,12 @@ extern crate hercules_ir; +use std::cmp::{max, min}; use std::collections::HashSet; use std::iter::zip; use self::hercules_ir::dataflow::*; -use self::hercules_ir::ir::*; use self::hercules_ir::def_use::get_uses; +use self::hercules_ir::ir::*; use crate::*; @@ -833,6 +834,112 @@ fn ccp_flow_function( Intrinsic::Log => binary_float_intrinsic!(intrinsic, constants, log), Intrinsic::Log10 => unary_float_intrinsic!(intrinsic, constants, log10), Intrinsic::Log2 => unary_float_intrinsic!(intrinsic, constants, log2), + Intrinsic::Max => { + if let (Constant::Integer8(i), Constant::Integer8(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer8(max(*i, *j))) + } else if let (Constant::Integer16(i), Constant::Integer16(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer16(max(*i, *j))) + } else if let (Constant::Integer32(i), Constant::Integer32(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer32(max(*i, *j))) + } else if let (Constant::Integer64(i), Constant::Integer64(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer64(max(*i, *j))) + } else if let ( + Constant::UnsignedInteger8(i), + Constant::UnsignedInteger8(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger8(max(*i, *j))) + } else if let ( + Constant::UnsignedInteger16(i), + Constant::UnsignedInteger16(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger16(max(*i, *j))) + } else if let ( + Constant::UnsignedInteger32(i), + Constant::UnsignedInteger32(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger32(max(*i, *j))) + } else if let ( + Constant::UnsignedInteger64(i), + Constant::UnsignedInteger64(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger64(max(*i, *j))) + } else if let (Constant::Float32(i), Constant::Float32(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Float32(*i.max(j))) + } else if let (Constant::Float64(i), Constant::Float64(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Float64(*i.max(j))) + } else { + panic!("Unsupported combination of intrinsic abs and constant value. Did typechecking succeed?") + } + } + Intrinsic::Min => { + if let (Constant::Integer8(i), Constant::Integer8(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer8(min(*i, *j))) + } else if let (Constant::Integer16(i), Constant::Integer16(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer16(min(*i, *j))) + } else if let (Constant::Integer32(i), Constant::Integer32(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer32(min(*i, *j))) + } else if let (Constant::Integer64(i), Constant::Integer64(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Integer64(min(*i, *j))) + } else if let ( + Constant::UnsignedInteger8(i), + Constant::UnsignedInteger8(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger8(min(*i, *j))) + } else if let ( + Constant::UnsignedInteger16(i), + Constant::UnsignedInteger16(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger16(min(*i, *j))) + } else if let ( + Constant::UnsignedInteger32(i), + Constant::UnsignedInteger32(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger32(min(*i, *j))) + } else if let ( + Constant::UnsignedInteger64(i), + Constant::UnsignedInteger64(j), + ) = (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::UnsignedInteger64(min(*i, *j))) + } else if let (Constant::Float32(i), Constant::Float32(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Float32(*i.min(j))) + } else if let (Constant::Float64(i), Constant::Float64(j)) = + (constants[0], constants[1]) + { + ConstantLattice::Constant(Constant::Float64(*i.min(j))) + } else { + panic!("Unsupported combination of intrinsic abs and constant value. Did typechecking succeed?") + } + } Intrinsic::Pow => { if let Constant::UnsignedInteger32(p) = constants[1] { if let Constant::Integer8(i) = constants[0] { diff --git a/hercules_opt/src/inline.rs b/hercules_opt/src/inline.rs index 1c485ecc..9ab15874 100644 --- a/hercules_opt/src/inline.rs +++ b/hercules_opt/src/inline.rs @@ -45,6 +45,9 @@ pub fn inline(editors: &mut [FunctionEditor], callgraph: &CallGraph) { // Step 4: run inlining on each function individually. Iterate the functions // in topological order. for to_inline_id in topo { + if editors[to_inline_id.idx()].func().entry { + continue; + } // Since Rust cannot analyze the accesses into an array of mutable // references, we need to do some weirdness here to simultaneously get: // 1. A mutable reference to the function we're modifying. @@ -181,7 +184,7 @@ fn inline_func( // as the new references we just made in the first step. We // actually want to institute all the updates // *simultaneously*, hence the two step maneuver. - let first_dc = edit.num_dynamic_constants() + 1; + let first_dc = edit.num_dynamic_constants() + 100; for (dc_a, dc_n) in zip(dcs_a, first_dc..) { substitute_dynamic_constants_in_node( *dc_a, diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs index 58251c42..24ed0e4e 100644 --- a/hercules_opt/src/pass.rs +++ b/hercules_opt/src/pass.rs @@ -864,11 +864,25 @@ impl PassManager { let memory_objects_mutable = memory_objects_mutability(&self.module, &callgraph, &memory_objects); + let devices = device_placement(&self.module.functions, &callgraph); + let mut rust_rt = String::new(); let mut llvm_ir = String::new(); for idx in 0..self.module.functions.len() { - if self.module.functions[idx].entry { - rt_codegen( + match devices[idx] { + Device::LLVM => cpu_codegen( + &self.module.functions[idx], + &self.module.types, + &self.module.constants, + &self.module.dynamic_constants, + &reverse_postorders[idx], + &typing[idx], + &control_subgraphs[idx], + &bbs[idx], + &mut llvm_ir, + ) + .unwrap(), + Device::AsyncRust => rt_codegen( FunctionID::new(idx), &self.module, &reverse_postorders[idx], @@ -876,25 +890,13 @@ impl PassManager { &control_subgraphs[idx], &bbs[idx], &callgraph, + &devices, &memory_objects, &memory_objects_mutable, &mut rust_rt, ) - .unwrap(); - } else { - // TODO: determine which backend to use for function. - cpu_codegen( - &self.module.functions[idx], - &self.module.types, - &self.module.constants, - &self.module.dynamic_constants, - &reverse_postorders[idx], - &typing[idx], - &control_subgraphs[idx], - &bbs[idx], - &mut llvm_ir, - ) - .unwrap(); + .unwrap(), + _ => todo!(), } } println!("{}", llvm_ir); diff --git a/hercules_samples/call/src/main.rs b/hercules_samples/call/src/main.rs index 3bbb634c..b5c999fd 100644 --- a/hercules_samples/call/src/main.rs +++ b/hercules_samples/call/src/main.rs @@ -14,6 +14,6 @@ fn main() { } #[test] -fn dot_test() { +fn call_test() { main(); } diff --git a/hercules_samples/ccp/src/main.rs b/hercules_samples/ccp/src/main.rs index 5fc78ab5..9e2aced9 100644 --- a/hercules_samples/ccp/src/main.rs +++ b/hercules_samples/ccp/src/main.rs @@ -13,6 +13,6 @@ fn main() { } #[test] -fn dot_test() { +fn ccp_test() { main(); } diff --git a/juno_frontend/src/intrinsics.rs b/juno_frontend/src/intrinsics.rs index e0c2d2c3..e307f7f0 100644 --- a/juno_frontend/src/intrinsics.rs +++ b/juno_frontend/src/intrinsics.rs @@ -148,6 +148,16 @@ static INTRINSICS: phf::Map<&'static str, IntrinsicInfo> = phf_map! { kinds : &[parser::Kind::Float], typ : var_type, }, + "max" => IntrinsicInfo { + id : hercules_ir::ir::Intrinsic::Max, + kinds : &[parser::Kind::Number], + typ : var2_type, + }, + "min" => IntrinsicInfo { + id : hercules_ir::ir::Intrinsic::Min, + kinds : &[parser::Kind::Number], + typ : var2_type, + }, "pow" => IntrinsicInfo { id : hercules_ir::ir::Intrinsic::Pow, kinds : &[parser::Kind::Integer], diff --git a/juno_frontend/src/lib.rs b/juno_frontend/src/lib.rs index 4ff5d9fc..b18b2979 100644 --- a/juno_frontend/src/lib.rs +++ b/juno_frontend/src/lib.rs @@ -184,8 +184,8 @@ pub fn compile_ir( if x_dot { pm.add_pass(hercules_opt::pass::Pass::Xdot(true)); } - add_pass!(pm, verify, Forkify); - add_pass!(pm, verify, ForkGuardElim); + //add_pass!(pm, verify, Forkify); + //add_pass!(pm, verify, ForkGuardElim); add_verified_pass!(pm, verify, DCE); add_pass!(pm, verify, Outline); add_pass!(pm, verify, InterproceduralSROA); diff --git a/juno_samples/cava.jn b/juno_samples/cava.jn index 977e2e02..9d398db1 100644 --- a/juno_samples/cava.jn +++ b/juno_samples/cava.jn @@ -1,11 +1,3 @@ -fn max<a : number>(x : a, y : a) -> a { - return if x >= y then x else y; -} - -fn min<a : number>(x : a, y : a) -> a { - return if x < y then x else y; -} - fn medianMatrix<a : number, rows, cols : usize>(m : a[rows, cols]) -> a { const n : usize = rows * cols; @@ -52,7 +44,7 @@ fn descale<row : usize, col : usize>(input : f32[CHAN, row, col]) -> u8[CHAN, ro for chan = 0 to CHAN { for r = 0 to row { for c = 0 to col { - res[chan, r, c] = min::<f32>(max::<f32>(input[chan, r, c] * 255, 0), 255) as u8; + res[chan, r, c] = min!::<f32>(max!::<f32>(input[chan, r, c] * 255, 0), 255) as u8; } } } @@ -144,7 +136,7 @@ fn transform<row : usize, col : usize> for chan = 0 to CHAN { for r = 0 to row { for c = 0 to col { - result[chan, r, c] = max::<f32>( + result[chan, r, c] = max!::<f32>( input[0, r, c] * tstw_trans[0, chan] + input[1, r, c] * tstw_trans[1, chan] + input[2, r, c] * tstw_trans[2, chan] @@ -181,7 +173,7 @@ fn gamut<row : usize, col : usize> chan_val += coefs[0, chan] + coefs[1, chan] * input[0, r, c] + coefs[2, chan] * input[1, r, c] + coefs[3, chan] * input[2, r, c]; - result[chan, row, col] = max::<f32>(chan_val, 0); + result[chan, row, col] = max!::<f32>(chan_val, 0); } } } diff --git a/juno_samples/nested_ccp/src/main.rs b/juno_samples/nested_ccp/src/main.rs index 9b38476e..83132aca 100644 --- a/juno_samples/nested_ccp/src/main.rs +++ b/juno_samples/nested_ccp/src/main.rs @@ -35,6 +35,6 @@ fn main() { } #[test] -fn nested_ccp() { +fn nested_ccp_test() { main(); } -- GitLab