diff --git a/hercules_cg/src/top.rs b/hercules_cg/src/top.rs index adcc0c613d61d23857d98c1bf1803cedf74aba05..4e029ccfd2de5180969b68235281660d5b7ac664 100644 --- a/hercules_cg/src/top.rs +++ b/hercules_cg/src/top.rs @@ -65,6 +65,16 @@ pub fn codegen<W: Write>( Ok(ModuleManifest { functions: manifests, types: module.types.clone(), + type_sizes_aligns: (0..module.types.len()) + .map(|idx| { + if module.types[idx].is_control() { + (None, 0) + } else { + type_size_and_alignment(module, TypeID::new(idx)) + } + }) + .collect(), + dynamic_constants: module.dynamic_constants.clone(), // Get the types of all of the constants. This requires collecting over // all of the functions, since the calculated types of constants may be // distributed over many functions. This may contain duplicate mappings, diff --git a/hercules_ir/src/ir.rs b/hercules_ir/src/ir.rs index d231b186f64679019f5f7ec5696ee458c7ede66b..e721026115983118805f338e51cf19edba4005f7 100644 --- a/hercules_ir/src/ir.rs +++ b/hercules_ir/src/ir.rs @@ -113,7 +113,7 @@ pub enum Constant { * allocation - by providing dynamic constants to the conductor API, the * conductor can allocate memory as necessary. */ -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum DynamicConstant { Constant(usize), Parameter(usize), diff --git a/hercules_ir/src/manifest.rs b/hercules_ir/src/manifest.rs index 24ec610e0fe9194b810adb3af3b628d796d473fa..8b2914c89e235cc3122c967589124b581c3a41e9 100644 --- a/hercules_ir/src/manifest.rs +++ b/hercules_ir/src/manifest.rs @@ -17,6 +17,10 @@ pub struct ModuleManifest { pub functions: Vec<FunctionManifest>, // All of the types used in the module. pub types: Vec<Type>, + // All of the sizes and alignments for types in the module. + pub type_sizes_aligns: Vec<(Option<usize>, usize)>, + // All of the dynamic constants used in the module. + pub dynamic_constants: Vec<DynamicConstant>, // Store the types of constants. pub constant_types: Vec<(ConstantID, TypeID)>, // The only constants that aren't baked into the generated code are array diff --git a/hercules_rt_proc/src/lib.rs b/hercules_rt_proc/src/lib.rs index a1869b548c5c199822069bad18e6ba707fad51bb..1e600cb7f32636377d98d797e023dee6731971a5 100644 --- a/hercules_rt_proc/src/lib.rs +++ b/hercules_rt_proc/src/lib.rs @@ -53,11 +53,35 @@ fn generate_type_string(ty: &Type, rust_types: &Vec<String>) -> String { } /* - * Emit dynamic constant math to calculate the runtime size of an array, in - * number of bytes. + * Emit a dynamic constant, which isn't necessarily just a dynamic constant + * parameter. */ -fn emit_array_size_expression(ty: TypeID, manifest: &ModuleManifest) -> String { - "16".to_string() +fn emit_dynamic_constant(dc: DynamicConstantID, manifest: &ModuleManifest) -> String { + match manifest.dynamic_constants[dc.idx()] { + DynamicConstant::Constant(val) => format!("{}", val), + DynamicConstant::Parameter(idx) => format!("dyn_cons_{}", idx), + } +} + +/* + * Emit dynamic constant math to calculate the runtime size of a type, in number + * of bytes. + */ +fn emit_type_size_expression(ty: TypeID, manifest: &ModuleManifest) -> String { + match manifest.types[ty.idx()] { + Type::Array(elem, ref dcs) => { + dcs.iter().fold( + "(".to_string() + &emit_type_size_expression(elem, manifest), + |acc, dc| acc + " * " + &emit_dynamic_constant(*dc, manifest), + ) + ")" + } + _ => format!( + "{}", + manifest.type_sizes_aligns[ty.idx()] + .0 + .expect("PANIC: Size of non-array type is unknown at compile-time.") + ), + } } /* @@ -188,7 +212,7 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro )?; } - // Declare all of the array constant memories. We declare them as Boxes + // Declare all of the array constant memories. We declare them as Vecs // to allocate the memories. We emit multiplications of the dynamic // constant dimensions to allocate the whole memory as one contiguous // range. TODO: emit only the array constants actually used in this @@ -203,9 +227,9 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro .1; write!( rust_code, - "let mut arr_cons_{}_vec = vec![0u8; {}];let mut arr_cons_{} = arr_cons_{}_vec.as_mut_ptr();arr_cons_{}_vec.leak();", + "let mut arr_cons_{}_vec = vec![0u8; {} as usize];let mut arr_cons_{} = arr_cons_{}_vec.as_mut_ptr();arr_cons_{}_vec.leak();", arr_cons_num, - emit_array_size_expression(arr_ty_id, manifest), + emit_type_size_expression(arr_ty_id, manifest), arr_cons_num, arr_cons_num, arr_cons_num,