Temporary frontend with backend changes

Broken: Order of constant ops generated by functions. OpConstant belongs
before OpFunction.
master
itycodes 2 weeks ago
parent 7382e9185f
commit 041393fa72

@ -3,7 +3,6 @@ mod tests;
use crate::compiler::{Instruction, Module}; use crate::compiler::{Instruction, Module};
use std::fmt; use std::fmt;
use std::fmt::Write;
use super::StorageClass; use super::StorageClass;
@ -149,7 +148,7 @@ fn fix_name(name: &String) -> String {
) )
} }
fn has_id(name: String, ops: &Vec<(Option<String>, Vec<String>)>) -> bool { fn has_id<T>(name: String, ops: &Vec<(Option<String>, T)>) -> bool {
for op in ops { for op in ops {
if op.0.is_some() && op.0.clone().unwrap() == name { if op.0.is_some() && op.0.clone().unwrap() == name {
return true; return true;
@ -158,8 +157,7 @@ fn has_id(name: String, ops: &Vec<(Option<String>, Vec<String>)>) -> bool {
false false
} }
pub fn spirv_meta(module: Module) -> String { pub fn spirv_meta(module: &mut Module) -> Vec<(Option<String>, Vec<String>)> {
let mut spirv_asm = String::new();
let mut ops: Vec<(Option<String>, Vec<String>)> = Vec::new(); let mut ops: Vec<(Option<String>, Vec<String>)> = Vec::new();
let capabilities: Vec<String> = module let capabilities: Vec<String> = 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 { let exec_model = match entry.execution_model {
crate::compiler::ExecutionModel::Fragment => "Fragment", crate::compiler::ExecutionModel::Fragment => "Fragment",
crate::compiler::ExecutionModel::Vertex => "Vertex", 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 name = fix_name(&global.name);
let _typ = global.typ; let _typ = global.typ;
let storage_class = match global.storage_class { let storage_class = match global.storage_class {
@ -265,8 +263,8 @@ pub fn spirv_meta(module: Module) -> String {
} }
} }
for fun in module.functions { for fun in module.functions.clone() {
let name = fix_name(&fun.name); let name = fix_name(&format!("l_{}", fun.name));
let return_type = fix_name(&fun.return_type); let return_type = fix_name(&fun.return_type);
let mut type_ops = Vec::new(); let mut type_ops = Vec::new();
emit_type(parse_type(&fun.return_type), &mut type_ops); 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 { // for op in ops {
if op.0.is_some() { // if op.0.is_some() {
write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap(); // write!(spirv_asm, "{} = ", op.0.unwrap()).unwrap();
} // }
for arg in op.1 { // for arg in op.1 {
write!(spirv_asm, "{} ", arg).unwrap(); // write!(spirv_asm, "{} ", arg).unwrap();
} // }
writeln!(spirv_asm).unwrap(); // writeln!(spirv_asm).unwrap();
} // }
spirv_asm // spirv_asm
ops
} }
enum Number { 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>, String)>) {
for fun in module.functions.iter_mut() { for fun in module.functions.iter_mut() {
assert!(fun.ast.is_some()); assert!(fun.ast.is_some());
let ast = fun.ast.as_mut().unwrap(); let ast = fun.ast.as_mut().unwrap();
@ -501,6 +500,12 @@ pub fn compile_fun_ssa(module: &mut Module) {
let mut out_pre = vec![]; let mut out_pre = vec![];
for t in &types { for t in &types {
let typ = parse_type(t); 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![]; let mut type_ops = vec![];
emit_type(typ, &mut type_ops); emit_type(typ, &mut type_ops);
for type_op in type_ops { for type_op in type_ops {

@ -19,9 +19,10 @@ fn test_emit() {
1.0))) 1.0)))
"; ";
let ast = parse(tokenize(src)); let ast = parse(tokenize(src));
let module = meta_compile(ast.unwrap()).unwrap(); let mut module = meta_compile(ast.unwrap()).unwrap();
let res = spirv_meta(module); let res = spirv_meta(&mut module);
println!("{}", res); println!("{:#?}", res);
// TODO add an assert
} }
#[test] #[test]
@ -58,8 +59,8 @@ fn test_block_ssa() {
let src = " let src = "
(module Shader Logical GLSL450) (module Shader Logical GLSL450)
(import :std GLSL.std.450) (import :std GLSL.std.450)
(bind (out-color:*f32) (Location 0)) (bind (out-color:*f32o) (Location 0))
(dec out-color:*f32 Output) (dec out-color:*f32o Output)
(entry main Fragment OriginUpperLeft (:out-color)) (entry main Fragment OriginUpperLeft (:out-color))
(fun (main) :<> (fun (main) :<>
(store-ptr out-color (/ 1.0 (+ 1.0 1.0)))) (store-ptr out-color (/ 1.0 (+ 1.0 1.0))))
@ -112,15 +113,16 @@ fn test_fun_ssa() {
let src = " let src = "
(module Shader Logical GLSL450) (module Shader Logical GLSL450)
(import :std GLSL.std.450) (import :std GLSL.std.450)
(bind (out-color:*f32) (Location 0)) (bind (out-color:*f32o) (Location 0))
(dec out-color:*f32 Output) (dec out-color:*f32o Output)
(entry main Fragment OriginUpperLeft (:out-color)) (entry main Fragment OriginUpperLeft (:out-color))
(fun (main) :<> (fun (main) :<>
(store-ptr out-color (/ 1.0 (+ 1.0 1.0)))) (store-ptr out-color (/ 1.0 (+ 1.0 1.0))))
"; ";
let ast = parse(tokenize(src)); let ast = parse(tokenize(src));
let mut module = meta_compile(ast.unwrap()).unwrap(); 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 = module.functions.pop().unwrap();
let res = res.body.unwrap(); let res = res.body.unwrap();
println!("{:#?}", res); println!("{:#?}", res);

@ -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 error::print_error;
use std::{env, fs, path::PathBuf, process::ExitCode}; use std::{env, fs, path::PathBuf, process::ExitCode};
@ -34,7 +37,7 @@ fn main() -> ExitCode {
return ExitCode::FAILURE; 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) { let src = match fs::read_to_string(input) {
Ok(i) => i, 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, Ok(m) => m,
Err(e) => { Err(e) => {
print_error(e, Some(&src)); 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(); fs::write(output, res).unwrap();
@ -203,7 +244,7 @@ fn print_help() {
println!("\t\tThe shader to be parsed and compiled, manadory argument"); println!("\t\tThe shader to be parsed and compiled, manadory argument");
println!(); println!();
println!("\t-o --output:"); 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!();
println!("\t-h --help:"); println!("\t-h --help:");
println!("\t\tPrint this and exit"); println!("\t\tPrint this and exit");

Loading…
Cancel
Save