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() {
|
int main() {
|
||||||
char a = -1;
|
char a = 127;
|
||||||
char b = a << 1;
|
char b = a << 1;
|
||||||
unsigned char c = (unsigned char)b >> 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:i3:unit = nop
|
||||||
%b0:i4:i32 = load %l0:*i32
|
%b0:i4:i32 = load %l0:*i32
|
||||||
|
|
||||||
j b1(37:i32)
|
j b1()
|
||||||
|
|
||||||
block b1:
|
block b1:
|
||||||
%b1:p0:i32:x
|
|
||||||
|
|
||||||
%b1:i0:i32 = load %l0:*i32
|
%b1:i0:i32 = load %l0:*i32
|
||||||
|
|
||||||
%b1:i1:unit = call @sink(undef:i32)
|
%b1:i1:unit = call @sink(undef:i32)
|
||||||
%b1:i2:unit = call @sink(42:i32)
|
%b1:i2:unit = call @sink(42:i32)
|
||||||
%b1:i3:unit = call @sink(37: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
|
ret 0:i32
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use core::ops::{Deref, DerefMut};
|
|||||||
use hexf::{parse_hexf32, parse_hexf64};
|
use hexf::{parse_hexf32, parse_hexf64};
|
||||||
use lang_c::ast;
|
use lang_c::ast;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use std::collections::HashMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
pub use dtype::{Dtype, DtypeError, HasDtype};
|
pub use dtype::{Dtype, DtypeError, HasDtype};
|
||||||
@@ -18,7 +18,7 @@ pub use parse::Parse;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct TranslationUnit {
|
pub struct TranslationUnit {
|
||||||
pub decls: HashMap<String, Declaration>,
|
pub decls: BTreeMap<String, Declaration>,
|
||||||
pub structs: HashMap<String, Option<Dtype>>,
|
pub structs: HashMap<String, Option<Dtype>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ pub struct FunctionDefinition {
|
|||||||
pub allocations: Vec<Named<Dtype>>,
|
pub allocations: Vec<Named<Dtype>>,
|
||||||
|
|
||||||
/// Basic blocks.
|
/// Basic blocks.
|
||||||
pub blocks: HashMap<BlockId, Block>,
|
pub blocks: BTreeMap<BlockId, Block>,
|
||||||
|
|
||||||
/// The initial block id.
|
/// The initial block id.
|
||||||
pub bid_init: BlockId,
|
pub bid_init: BlockId,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ peg::parser! {
|
|||||||
|
|
||||||
pub rule translation_unit() -> TranslationUnit
|
pub rule translation_unit() -> TranslationUnit
|
||||||
= _ ds:(named_decl() ** __) _ {
|
= _ ds:(named_decl() ** __) _ {
|
||||||
let mut decls = HashMap::new();
|
let mut decls = BTreeMap::new();
|
||||||
for decl in ds {
|
for decl in ds {
|
||||||
let result = decls.insert(decl.name.unwrap(), decl.inner);
|
let result = decls.insert(decl.name.unwrap(), decl.inner);
|
||||||
assert!(result.is_none());
|
assert!(result.is_none());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::opt::FunctionPass;
|
use crate::opt::FunctionPass;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub type Gvn = FunctionPass<Repeat<GvnInner>>;
|
pub type Gvn = FunctionPass<GvnInner>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GvnInner {}
|
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 lang_c::ast::*;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{stderr, Write};
|
use std::io::{stderr, Read, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
@@ -41,7 +41,14 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
|||||||
|
|
||||||
// Compile c file: If fails, test is vacuously success
|
// Compile c file: If fails, test is vacuously success
|
||||||
if !Command::new("gcc")
|
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())
|
.stderr(Stdio::null())
|
||||||
.status()
|
.status()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -52,6 +59,7 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
|||||||
|
|
||||||
// Execute compiled executable
|
// Execute compiled executable
|
||||||
let mut child = Command::new(fs::canonicalize(bin_path.clone()).unwrap())
|
let mut child = Command::new(fs::canonicalize(bin_path.clone()).unwrap())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("failed to execute the compiled executable");
|
.expect("failed to execute the compiled executable");
|
||||||
|
|
||||||
@@ -71,6 +79,18 @@ pub fn test_irgen(unit: &TranslationUnit, path: &Path) {
|
|||||||
::std::process::exit(SKIP_TEST);
|
::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 status = some_or_exit!(status.code(), SKIP_TEST);
|
||||||
|
|
||||||
let ir = match Irgen::default().translate(unit) {
|
let ir = match Irgen::default().translate(unit) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ if
|
|||||||
grep 'too many arguments in call' out.txt ||\
|
grep 'too many arguments in call' out.txt ||\
|
||||||
grep 'declaration does not declare anything' out.txt ||\
|
grep 'declaration does not declare anything' out.txt ||\
|
||||||
grep 'not equal to a null pointer is always true' 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 ||\
|
! gcc -Wall -Wextra -O2 test_reduced.c > outa.txt 2>&1 ||\
|
||||||
grep 'uninitialized' outa.txt ||\
|
grep 'uninitialized' outa.txt ||\
|
||||||
grep 'without a cast' outa.txt ||\
|
grep 'without a cast' outa.txt ||\
|
||||||
@@ -49,10 +50,16 @@ if
|
|||||||
grep 'excess elements in struct initializer' outa.txt ||\
|
grep 'excess elements in struct initializer' outa.txt ||\
|
||||||
grep 'comparison between pointer and integer' outa.txt ||\
|
grep 'comparison between pointer and integer' outa.txt ||\
|
||||||
! gcc -O1 test_reduced.c > cc_out1.txt 2>&1 ||\
|
! 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
|
then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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(),
|
&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