mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-14 22:38:46 +00:00
Update skeleton
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
int main() {
|
||||
char a = -1;
|
||||
char a = 127;
|
||||
char b = a << 1;
|
||||
unsigned char c = (unsigned char)b >> 1;
|
||||
|
||||
|
||||
44
examples/gvn/gvn.input.ir
Normal file
44
examples/gvn/gvn.input.ir
Normal file
@@ -0,0 +1,44 @@
|
||||
fun unit @sink {
|
||||
init:
|
||||
bid: b0
|
||||
allocations:
|
||||
|
||||
block b0:
|
||||
%b0:p0:i32
|
||||
ret unit:unit
|
||||
}
|
||||
|
||||
fun i32 @gvn {
|
||||
init:
|
||||
bid: b0
|
||||
allocations:
|
||||
|
||||
block b0:
|
||||
%b0:p0:i32:a
|
||||
%b0:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
br undef:i1 b1() b2()
|
||||
|
||||
block b1:
|
||||
%b1:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
%b1:i1:i32:c = add %b1:i0:i32 2:i32
|
||||
|
||||
%b1:i2:unit = call @sink(%b1:i0:i32)
|
||||
|
||||
j b3()
|
||||
|
||||
block b2:
|
||||
%b2:i0:i32:c = add %b0:i0:i32 2:i32
|
||||
|
||||
%b2:i1:unit = call @sink(%b2:i0:i32)
|
||||
|
||||
j b3()
|
||||
|
||||
block b3:
|
||||
%b3:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
%b3:i1:i32:c = add %b3:i0:i32 2:i32
|
||||
|
||||
%b3:i2:unit = call @sink(%b3:i0:i32)
|
||||
%b3:i3:unit = call @sink(%b3:i1:i32)
|
||||
|
||||
ret 0:i32
|
||||
}
|
||||
46
examples/gvn/gvn.output.ir
Normal file
46
examples/gvn/gvn.output.ir
Normal file
@@ -0,0 +1,46 @@
|
||||
fun unit @sink {
|
||||
init:
|
||||
bid: b0
|
||||
allocations:
|
||||
|
||||
block b0:
|
||||
%b0:p0:i32
|
||||
ret unit:unit
|
||||
}
|
||||
|
||||
fun i32 @gvn {
|
||||
init:
|
||||
bid: b0
|
||||
allocations:
|
||||
|
||||
block b0:
|
||||
%b0:p0:i32:a
|
||||
%b0:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
br undef:i1 b1() b2()
|
||||
|
||||
block b1:
|
||||
%b1:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
%b1:i1:i32:c = add %b0:i0:i32 2:i32
|
||||
|
||||
%b1:i2:unit = call @sink(%b0:i0:i32)
|
||||
|
||||
j b3(%b1:i1:i32)
|
||||
|
||||
block b2:
|
||||
%b2:i0:i32:c = add %b0:i0:i32 2:i32
|
||||
|
||||
%b2:i1:unit = call @sink(%b2:i0:i32)
|
||||
|
||||
j b3(%b2:i0:i32)
|
||||
|
||||
block b3:
|
||||
%b3:p0:i32
|
||||
|
||||
%b3:i0:i32:b = add %b0:p0:i32 1:i32
|
||||
%b3:i1:i32:c = add %b0:i0:i32 2:i32
|
||||
|
||||
%b3:i2:unit = call @sink(%b0:i0:i32)
|
||||
%b3:i3:unit = call @sink(%b3:p0:i32)
|
||||
|
||||
ret 0:i32
|
||||
}
|
||||
@@ -45,17 +45,15 @@ block b0:
|
||||
%b0:i3:unit = nop
|
||||
%b0:i4:i32 = load %l0:*i32
|
||||
|
||||
j b1(37:i32)
|
||||
j b1()
|
||||
|
||||
block b1:
|
||||
%b1:p0:i32:x
|
||||
|
||||
%b1:i0:i32 = load %l0:*i32
|
||||
|
||||
%b1:i1:unit = call @sink(undef:i32)
|
||||
%b1:i2:unit = call @sink(42:i32)
|
||||
%b1:i3:unit = call @sink(37:i32)
|
||||
%b1:i4:unit = call @sink(%b1:p0:i32)
|
||||
%b1:i4:unit = call @sink(37:i32)
|
||||
|
||||
ret 0:i32
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use core::ops::{Deref, DerefMut};
|
||||
use hexf::{parse_hexf32, parse_hexf64};
|
||||
use lang_c::ast;
|
||||
use ordered_float::OrderedFloat;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
pub use dtype::{Dtype, DtypeError, HasDtype};
|
||||
@@ -18,7 +18,7 @@ pub use parse::Parse;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TranslationUnit {
|
||||
pub decls: HashMap<String, Declaration>,
|
||||
pub decls: BTreeMap<String, Declaration>,
|
||||
pub structs: HashMap<String, Option<Dtype>>,
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ pub struct FunctionDefinition {
|
||||
pub allocations: Vec<Named<Dtype>>,
|
||||
|
||||
/// Basic blocks.
|
||||
pub blocks: HashMap<BlockId, Block>,
|
||||
pub blocks: BTreeMap<BlockId, Block>,
|
||||
|
||||
/// The initial block id.
|
||||
pub bid_init: BlockId,
|
||||
|
||||
@@ -16,7 +16,7 @@ peg::parser! {
|
||||
|
||||
pub rule translation_unit() -> TranslationUnit
|
||||
= _ ds:(named_decl() ** __) _ {
|
||||
let mut decls = HashMap::new();
|
||||
let mut decls = BTreeMap::new();
|
||||
for decl in ds {
|
||||
let result = decls.insert(decl.name.unwrap(), decl.inner);
|
||||
assert!(result.is_none());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::opt::FunctionPass;
|
||||
use crate::*;
|
||||
|
||||
pub type Gvn = FunctionPass<Repeat<GvnInner>>;
|
||||
pub type Gvn = FunctionPass<GvnInner>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GvnInner {}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
//! Utilities for implementing optimizations.
|
||||
//!
|
||||
//! You can add here utilities commonly used in the implementation of multiple optimizations.
|
||||
|
||||
24
src/tests.rs
24
src/tests.rs
@@ -1,6 +1,6 @@
|
||||
use lang_c::ast::*;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{stderr, Write};
|
||||
use std::io::{stderr, Read, Write};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
use tempfile::tempdir;
|
||||
@@ -41,7 +41,14 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
||||
|
||||
// Compile c file: If fails, test is vacuously success
|
||||
if !Command::new("gcc")
|
||||
.args(&["-O1", &file_path, "-o", &bin_path])
|
||||
.args(&[
|
||||
"-fsanitize=undefined",
|
||||
"-fno-sanitize-recover=all",
|
||||
"-O1",
|
||||
&file_path,
|
||||
"-o",
|
||||
&bin_path,
|
||||
])
|
||||
.stderr(Stdio::null())
|
||||
.status()
|
||||
.unwrap()
|
||||
@@ -52,6 +59,7 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
||||
|
||||
// Execute compiled executable
|
||||
let mut child = Command::new(fs::canonicalize(bin_path.clone()).unwrap())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to execute the compiled executable");
|
||||
|
||||
@@ -71,6 +79,18 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
||||
::std::process::exit(SKIP_TEST);
|
||||
}
|
||||
);
|
||||
|
||||
if child
|
||||
.stderr
|
||||
.expect("`stderr` of `child` must be `Some`")
|
||||
.bytes()
|
||||
.next()
|
||||
.is_some()
|
||||
{
|
||||
println!("error occurs");
|
||||
::std::process::exit(SKIP_TEST);
|
||||
}
|
||||
|
||||
let status = some_or_exit!(status.code(), SKIP_TEST);
|
||||
|
||||
let ir = match Irgen::default().translate(unit) {
|
||||
|
||||
@@ -30,6 +30,7 @@ if
|
||||
grep 'too many arguments in call' out.txt ||\
|
||||
grep 'declaration does not declare anything' out.txt ||\
|
||||
grep 'not equal to a null pointer is always true' out.txt ||\
|
||||
grep 'empty struct is a GNU extension' out.txt ||\
|
||||
! gcc -Wall -Wextra -O2 test_reduced.c > outa.txt 2>&1 ||\
|
||||
grep 'uninitialized' outa.txt ||\
|
||||
grep 'without a cast' outa.txt ||\
|
||||
@@ -49,10 +50,16 @@ if
|
||||
grep 'excess elements in struct initializer' outa.txt ||\
|
||||
grep 'comparison between pointer and integer' outa.txt ||\
|
||||
! gcc -O1 test_reduced.c > cc_out1.txt 2>&1 ||\
|
||||
! gcc -O2 test_reduced.c > cc_out2.txt 2>&1)
|
||||
! gcc -O2 test_reduced.c > cc_out2.txt 2>&1 ||\
|
||||
! cargo run --manifest-path $PROJECT_DIR/Cargo.toml --release -- --parse test_reduced.c >/dev/null 2>&1)
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cargo run --manifest-path $PROJECT_DIR/Cargo.toml --release -- --parse test_reduced.c >/dev/null 2>&1 &&\
|
||||
! cargo run --manifest-path $PROJECT_DIR/Cargo.toml --release --bin fuzz -- $FUZZ_ARG test_reduced.c
|
||||
cargo run --manifest-path $PROJECT_DIR/Cargo.toml --release --bin fuzz -- $FUZZ_ARG test_reduced.c
|
||||
if [ "$?" = 101 ]
|
||||
then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -83,3 +83,12 @@ fn test_examples_mem2reg() {
|
||||
&mut Mem2reg::default(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_examples_gvn() {
|
||||
test_opt(
|
||||
&Path::new("examples/gvn/gvn.input.ir"),
|
||||
&Path::new("examples/gvn/gvn.output.ir"),
|
||||
&mut Gvn::default(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user