More optimizations and snapshot integration tests
This commit is contained in:
175
rust_compiler/libs/integration_tests/src/lib.rs
Normal file
175
rust_compiler/libs/integration_tests/src/lib.rs
Normal file
@@ -0,0 +1,175 @@
|
||||
//! Integration tests for the Slang compiler with optimizer
|
||||
//!
|
||||
//! These tests compile Slang source code and verify both the compilation
|
||||
//! and optimization passes work correctly together using snapshot testing.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use compiler::Compiler;
|
||||
use indoc::indoc;
|
||||
use parser::Parser;
|
||||
use tokenizer::Tokenizer;
|
||||
|
||||
/// Compile Slang source code and return both unoptimized and optimized output
|
||||
fn compile_with_and_without_optimization(source: &str) -> String {
|
||||
// Compile for unoptimized output
|
||||
let tokenizer = Tokenizer::from(source);
|
||||
let parser = Parser::new(tokenizer);
|
||||
let compiler = Compiler::new(parser, None);
|
||||
let result = compiler.compile();
|
||||
|
||||
// Get unoptimized output
|
||||
let mut unoptimized_writer = std::io::BufWriter::new(Vec::new());
|
||||
result
|
||||
.instructions
|
||||
.write(&mut unoptimized_writer)
|
||||
.expect("Failed to write unoptimized output");
|
||||
let unoptimized_bytes = unoptimized_writer
|
||||
.into_inner()
|
||||
.expect("Failed to get bytes");
|
||||
let unoptimized = String::from_utf8(unoptimized_bytes).expect("Invalid UTF-8");
|
||||
|
||||
// Compile again for optimized output
|
||||
let tokenizer2 = Tokenizer::from(source);
|
||||
let parser2 = Parser::new(tokenizer2);
|
||||
let compiler2 = Compiler::new(parser2, None);
|
||||
let result2 = compiler2.compile();
|
||||
|
||||
// Apply optimizations
|
||||
let optimized_instructions = optimizer::optimize(result2.instructions);
|
||||
|
||||
// Get optimized output
|
||||
let mut optimized_writer = std::io::BufWriter::new(Vec::new());
|
||||
optimized_instructions
|
||||
.write(&mut optimized_writer)
|
||||
.expect("Failed to write optimized output");
|
||||
let optimized_bytes = optimized_writer.into_inner().expect("Failed to get bytes");
|
||||
let optimized = String::from_utf8(optimized_bytes).expect("Invalid UTF-8");
|
||||
|
||||
// Combine both outputs with clear separators
|
||||
format!(
|
||||
"## Unoptimized Output\n\n{}\n## Optimized Output\n\n{}",
|
||||
unoptimized, optimized
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple_leaf_function() {
|
||||
let source = "fn test() { let x = 10; }";
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_with_call() {
|
||||
let source = indoc! {"
|
||||
fn add(a, b) { return a + b; }
|
||||
fn main() { let x = add(5, 10); }
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_constant_folding() {
|
||||
let source = "let x = 5 + 10;";
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_algebraic_simplification() {
|
||||
let source = "let x = 5; let y = x * 1;";
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strength_reduction() {
|
||||
let source = "fn double(x) { return x * 2; }";
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dead_code_elimination() {
|
||||
let source = indoc! {"
|
||||
fn compute(x) {
|
||||
let unused = 20;
|
||||
return x + 1;
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peephole_comparison_fusion() {
|
||||
let source = indoc! {"
|
||||
fn compare(x, y) {
|
||||
if (x > y) {
|
||||
let z = 1;
|
||||
}
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_optimization() {
|
||||
let source = indoc! {"
|
||||
fn ternary(cond) {
|
||||
let result = 0;
|
||||
if (cond) {
|
||||
result = 10;
|
||||
} else {
|
||||
result = 20;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_leaf_function_no_stack_frame() {
|
||||
let source = indoc! {"
|
||||
fn increment(x) {
|
||||
x = x + 1;
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complex_arithmetic() {
|
||||
let source = indoc! {"
|
||||
fn compute(a, b, c) {
|
||||
let x = a * 2;
|
||||
let y = b + 0;
|
||||
let z = c * 1;
|
||||
return x + y + z;
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_function_calls() {
|
||||
let source = indoc! {"
|
||||
fn add(a, b) { return a + b; }
|
||||
fn multiply(x, y) { return x * 2; }
|
||||
fn complex(a, b) {
|
||||
let sum = add(a, b);
|
||||
let doubled = multiply(sum, 2);
|
||||
return doubled;
|
||||
}
|
||||
"};
|
||||
let output = compile_with_and_without_optimization(source);
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
main:
|
||||
move r8 5
|
||||
mul r1 r8 1
|
||||
move r9 r1
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j 1
|
||||
move r8 5
|
||||
move r1 5
|
||||
move r9 5
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
compute:
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
push sp
|
||||
push ra
|
||||
mul r1 r10 2
|
||||
move r11 r1
|
||||
add r2 r9 0
|
||||
move r12 r2
|
||||
mul r3 r8 1
|
||||
move r13 r3
|
||||
add r4 r11 r12
|
||||
add r5 r4 r13
|
||||
move r15 r5
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
pop r9
|
||||
pop r10
|
||||
push sp
|
||||
push ra
|
||||
add r1 r10 r10
|
||||
move r11 r1
|
||||
move r2 r9
|
||||
move r12 r2
|
||||
move r3 r8
|
||||
move r13 r3
|
||||
add r4 r11 r12
|
||||
add r5 r4 r13
|
||||
move r15 r5
|
||||
j 16
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
main:
|
||||
move r8 15
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j 1
|
||||
move r8 15
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
compute:
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
move r9 20
|
||||
add r1 r8 1
|
||||
move r15 r1
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
move r9 20
|
||||
add r1 r8 1
|
||||
move r15 r1
|
||||
j 8
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
add:
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
add r1 r9 r8
|
||||
move r15 r1
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
main:
|
||||
push sp
|
||||
push ra
|
||||
push 5
|
||||
push 10
|
||||
jal add
|
||||
move r8 r15
|
||||
__internal_L2:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j 11
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
add r1 r9 r8
|
||||
move r15 r1
|
||||
j 8
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
push sp
|
||||
push ra
|
||||
push 5
|
||||
push 10
|
||||
jal 1
|
||||
move r8 r15
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
increment:
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
add r1 r8 1
|
||||
move r8 r1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
j main
|
||||
pop r8
|
||||
add r1 r8 1
|
||||
move r8 r1
|
||||
j ra
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
add:
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
add r1 r9 r8
|
||||
move r15 r1
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
multiply:
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
mul r1 r9 2
|
||||
move r15 r1
|
||||
j __internal_L2
|
||||
__internal_L2:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
complex:
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
push r8
|
||||
push r9
|
||||
push r9
|
||||
push r8
|
||||
jal add
|
||||
pop r9
|
||||
pop r8
|
||||
move r10 r15
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r10
|
||||
push 2
|
||||
jal multiply
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
move r11 r15
|
||||
move r15 r11
|
||||
j __internal_L3
|
||||
__internal_L3:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
add r1 r9 r8
|
||||
move r15 r1
|
||||
j 8
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
add r1 r9 r9
|
||||
move r15 r1
|
||||
j 18
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
push r8
|
||||
push r9
|
||||
push r9
|
||||
push r8
|
||||
jal 1
|
||||
pop r9
|
||||
pop r8
|
||||
move r10 r15
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r10
|
||||
push 2
|
||||
jal 11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
move r11 r15
|
||||
move r15 r11
|
||||
j 45
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
compare:
|
||||
pop r8
|
||||
pop r9
|
||||
push sp
|
||||
push ra
|
||||
sgt r1 r9 r8
|
||||
beqz r1 __internal_L2
|
||||
move r10 1
|
||||
__internal_L2:
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
pop r9
|
||||
j main
|
||||
pop r8
|
||||
pop r9
|
||||
ble r9 r8 8
|
||||
move r10 1
|
||||
j ra
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
ternary:
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
move r9 0
|
||||
beqz r8 __internal_L3
|
||||
move r9 10
|
||||
j __internal_L2
|
||||
__internal_L3:
|
||||
move r9 20
|
||||
__internal_L2:
|
||||
move r15 r9
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
select r9 r8 10 20
|
||||
move r15 r9
|
||||
j 7
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
test:
|
||||
push sp
|
||||
push ra
|
||||
move r8 10
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
j main
|
||||
move r8 10
|
||||
j ra
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
source: libs/integration_tests/src/lib.rs
|
||||
expression: output
|
||||
---
|
||||
## Unoptimized Output
|
||||
|
||||
j main
|
||||
double:
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
mul r1 r8 2
|
||||
move r15 r1
|
||||
j __internal_L1
|
||||
__internal_L1:
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
|
||||
## Optimized Output
|
||||
|
||||
j main
|
||||
pop r8
|
||||
push sp
|
||||
push ra
|
||||
add r1 r8 r8
|
||||
move r15 r1
|
||||
j 7
|
||||
pop ra
|
||||
pop sp
|
||||
j ra
|
||||
Reference in New Issue
Block a user