From 041393fa72d9f4caf15daf953fd759be717a20bc Mon Sep 17 00:00:00 2001 From: itycodes Date: Mon, 10 Mar 2025 12:36:24 +0100 Subject: [PATCH] Temporary frontend with backend changes Broken: Order of constant ops generated by functions. OpConstant belongs before OpFunction. --- src/compiler/backend/mod.rs | 43 ++++++++++++++++------------- src/compiler/backend/tests.rs | 18 +++++++------ src/main.rs | 51 +++++++++++++++++++++++++++++++---- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/src/compiler/backend/mod.rs b/src/compiler/backend/mod.rs index 88cc01a..c9c2a97 100644 --- a/src/compiler/backend/mod.rs +++ b/src/compiler/backend/mod.rs @@ -3,7 +3,6 @@ mod tests; use crate::compiler::{Instruction, Module}; use std::fmt; -use std::fmt::Write; use super::StorageClass; @@ -149,7 +148,7 @@ fn fix_name(name: &String) -> String { ) } -fn has_id(name: String, ops: &Vec<(Option, Vec)>) -> bool { +fn has_id(name: String, ops: &Vec<(Option, T)>) -> bool { for op in ops { if op.0.is_some() && op.0.clone().unwrap() == name { return true; @@ -158,8 +157,7 @@ fn has_id(name: String, ops: &Vec<(Option, Vec)>) -> bool { false } -pub fn spirv_meta(module: Module) -> String { - let mut spirv_asm = String::new(); +pub fn spirv_meta(module: &mut Module) -> Vec<(Option, Vec)> { let mut ops: Vec<(Option, Vec)> = Vec::new(); let capabilities: Vec = module @@ -192,7 +190,7 @@ pub fn spirv_meta(module: Module) -> String { ], )); - for entry in module.entry_points { + for entry in module.entry_points.clone() { let exec_model = match entry.execution_model { crate::compiler::ExecutionModel::Fragment => "Fragment", crate::compiler::ExecutionModel::Vertex => "Vertex", @@ -226,7 +224,7 @@ pub fn spirv_meta(module: Module) -> String { )); } - for global in module.globals { + for global in module.globals.clone() { let name = fix_name(&global.name); let _typ = global.typ; let storage_class = match global.storage_class { @@ -265,8 +263,8 @@ pub fn spirv_meta(module: Module) -> String { } } - for fun in module.functions { - let name = fix_name(&fun.name); + for fun in module.functions.clone() { + let name = fix_name(&format!("l_{}", fun.name)); let return_type = fix_name(&fun.return_type); let mut type_ops = Vec::new(); emit_type(parse_type(&fun.return_type), &mut type_ops); @@ -283,16 +281,17 @@ pub fn spirv_meta(module: Module) -> String { )); } - for op in ops { - if op.0.is_some() { - write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap(); - } - for arg in op.1 { - write!(spirv_asm, "{} ", arg).unwrap(); - } - writeln!(spirv_asm).unwrap(); - } - spirv_asm + // for op in ops { + // if op.0.is_some() { + // write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap(); + // } + // for arg in op.1 { + // write!(spirv_asm, "{} ", arg).unwrap(); + // } + // writeln!(spirv_asm).unwrap(); + // } + // spirv_asm + ops } enum Number { @@ -475,7 +474,7 @@ pub fn compile_ast_ssa( } } -pub fn compile_fun_ssa(module: &mut Module) { +pub fn compile_fun_ssa(module: &mut Module, ops: &Vec<(Option, String)>) { for fun in module.functions.iter_mut() { assert!(fun.ast.is_some()); let ast = fun.ast.as_mut().unwrap(); @@ -501,6 +500,12 @@ pub fn compile_fun_ssa(module: &mut Module) { let mut out_pre = vec![]; for t in &types { let typ = parse_type(t); + if has_id(fix_name(&typ.to_string()), ops) { + continue; + } + if has_id(fix_name(&typ.to_string()), &out_pre) { + continue; + } let mut type_ops = vec![]; emit_type(typ, &mut type_ops); for type_op in type_ops { diff --git a/src/compiler/backend/tests.rs b/src/compiler/backend/tests.rs index 36d5734..acbc86a 100644 --- a/src/compiler/backend/tests.rs +++ b/src/compiler/backend/tests.rs @@ -19,9 +19,10 @@ fn test_emit() { 1.0))) "; let ast = parse(tokenize(src)); - let module = meta_compile(ast.unwrap()).unwrap(); - let res = spirv_meta(module); - println!("{}", res); + let mut module = meta_compile(ast.unwrap()).unwrap(); + let res = spirv_meta(&mut module); + println!("{:#?}", res); + // TODO add an assert } #[test] @@ -58,8 +59,8 @@ fn test_block_ssa() { let src = " (module Shader Logical GLSL450) (import :std GLSL.std.450) -(bind (out-color:*f32) (Location 0)) -(dec out-color:*f32 Output) +(bind (out-color:*f32o) (Location 0)) +(dec out-color:*f32o Output) (entry main Fragment OriginUpperLeft (:out-color)) (fun (main) :<> (store-ptr out-color (/ 1.0 (+ 1.0 1.0)))) @@ -112,15 +113,16 @@ fn test_fun_ssa() { let src = " (module Shader Logical GLSL450) (import :std GLSL.std.450) - (bind (out-color:*f32) (Location 0)) - (dec out-color:*f32 Output) + (bind (out-color:*f32o) (Location 0)) + (dec out-color:*f32o Output) (entry main Fragment OriginUpperLeft (:out-color)) (fun (main) :<> (store-ptr out-color (/ 1.0 (+ 1.0 1.0)))) "; let ast = parse(tokenize(src)); let mut module = meta_compile(ast.unwrap()).unwrap(); - compile_fun_ssa(&mut module); + let ops = vec![]; + compile_fun_ssa(&mut module, &ops); let res = module.functions.pop().unwrap(); let res = res.body.unwrap(); println!("{:#?}", res); diff --git a/src/main.rs b/src/main.rs index ef9d46d..d746ffe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ -use compiler::{backend::spirv_meta, meta_compile}; +use compiler::{ + backend::{compile_fun_ssa, spirv_meta}, + meta_compile, +}; use error::print_error; use std::{env, fs, path::PathBuf, process::ExitCode}; @@ -34,7 +37,7 @@ fn main() -> ExitCode { return ExitCode::FAILURE; }; - let output = args.output.unwrap_or(PathBuf::from("./out.spv")); + let output = args.output.unwrap_or(PathBuf::from("./out.spvas")); let src = match fs::read_to_string(input) { Ok(i) => i, @@ -52,7 +55,7 @@ fn main() -> ExitCode { } }; - let module = match meta_compile(ast) { + let mut module = match meta_compile(ast) { Ok(m) => m, Err(e) => { print_error(e, Some(&src)); @@ -60,7 +63,45 @@ fn main() -> ExitCode { } }; - let res = spirv_meta(module); + use std::fmt::Write; + + let ops_split_params = spirv_meta(&mut module); + let mut ops_merged_param = vec![]; + for op in ops_split_params.clone() { + ops_merged_param.push((op.0, op.1.join(" "))); + } + compile_fun_ssa(&mut module, &ops_merged_param); + + let mut res = String::new(); + + for op in ops_split_params { + if op.0.is_some() { + write!(res, "{} = ", op.0.unwrap()).unwrap(); + } + for arg in op.1 { + write!(res, "{} ", arg).unwrap(); + } + writeln!(res).unwrap(); + } + + let mut counter: u32 = 0; + for fun in module.functions.iter() { + // TODO non-void type + // TODO this should NOT be in the frontend + writeln!(res, "%{} = OpFunction %void None %l_{}", fun.name, fun.name).unwrap(); + writeln!(res, "%n_{} = OpLabel", counter.to_string()).unwrap(); + for inst in fun.body.clone().unwrap().iter() { + if let Some(id) = inst.result_id.as_ref() { + write!(res, "{} = ", id).unwrap(); + } + write!(res, "{}", inst.op).unwrap(); + for op in inst.operands.iter() { + write!(res, " {}", op).unwrap(); + } + writeln!(res).unwrap(); + counter += 1; + } + } fs::write(output, res).unwrap(); @@ -203,7 +244,7 @@ fn print_help() { println!("\t\tThe shader to be parsed and compiled, manadory argument"); println!(); println!("\t-o --output:"); - println!("\t\tWhere to output the compiled spirv assembly to, default: out.spv"); + println!("\t\tWhere to output the compiled spirv assembly to, default: out.spvas"); println!(); println!("\t-h --help:"); println!("\t\tPrint this and exit");