To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 3ef34581 authored by Yi Lin's avatar Yi Lin
Browse files

Merge branch 'issue82-inf-loop-in-peephole' into 'develop'

Issue82 inf loop in peephole

See merge request !27
parents 6d862159 54c92081
...@@ -155,12 +155,25 @@ impl PeepholeOptimization { ...@@ -155,12 +155,25 @@ impl PeepholeOptimization {
let orig_inst = inst; let orig_inst = inst;
// the destination we will rewrite the instruction to branch to // the destination we will rewrite the instruction to branch to
let final_dest: Option<MuName> = { let final_dest: Option<MuName> = {
use std::collections::HashSet;
let mut cur_inst = inst; let mut cur_inst = inst;
let mut last_dest = None; let mut last_dest = None;
let mut visited_labels = HashSet::new();
loop { loop {
let opt_dest = mc.is_jmp(cur_inst); let opt_dest = mc.is_jmp(cur_inst);
match opt_dest { match opt_dest {
Some(ref dest) => { Some(ref dest) => {
// if we have already visited this instruction
// this means we met an infinite loop, we need to break
if visited_labels.contains(dest) {
warn!("met an infinite loop in removing jump-to-jump");
warn!("we are not optimizing this case");
return;
}
// get the block for destination // get the block for destination
let first_inst = mc.get_block_range(dest).unwrap().start; let first_inst = mc.get_block_range(dest).unwrap().start;
debug_assert!( debug_assert!(
...@@ -179,6 +192,8 @@ impl PeepholeOptimization { ...@@ -179,6 +192,8 @@ impl PeepholeOptimization {
// its a jump-to-jump case // its a jump-to-jump case
cur_inst = first_inst; cur_inst = first_inst;
last_dest = Some(dest2.clone()); last_dest = Some(dest2.clone());
visited_labels.insert(dest2.clone());
debug!("visited {}", dest2);
} }
None => break None => break
} }
...@@ -190,19 +205,7 @@ impl PeepholeOptimization { ...@@ -190,19 +205,7 @@ impl PeepholeOptimization {
}; };
if let Some(dest) = final_dest { if let Some(dest) = final_dest {
let first_inst = { let first_inst = mc.get_block_range(&dest).unwrap().start;
let start = mc.get_block_range(&dest).unwrap().start;
match mc.get_next_inst(start) {
Some(i) => i,
None => {
panic!(
"we are jumping to a block {}\
that does not have instructions?",
dest
)
}
}
};
info!( info!(
"inst {} chain jumps to {}, rewrite as branching to {} (successor: {})", "inst {} chain jumps to {}, rewrite as branching to {} (successor: {})",
......
...@@ -405,7 +405,7 @@ macro_rules! inst { ...@@ -405,7 +405,7 @@ macro_rules! inst {
target: $dest.id(), target: $dest.id(),
args: { args: {
let mut i =0; let mut i =0;
vec![$($arg.clone()),*].iter().map(|_| { vec![$($arg.clone()),*].iter().map(|_: &Arc<TreeNode>| {
let ret = DestArg::Normal(i); i+=1; ret let ret = DestArg::Normal(i); i+=1; ret
}).collect() }).collect()
} }
......
...@@ -30,3 +30,4 @@ mod test_inline; ...@@ -30,3 +30,4 @@ mod test_inline;
mod test_convop; mod test_convop;
mod test_int128; mod test_int128;
mod test_misc; mod test_misc;
mod test_opt;
\ No newline at end of file
...@@ -8,6 +8,7 @@ use self::mu::ast::inst::*; ...@@ -8,6 +8,7 @@ use self::mu::ast::inst::*;
use self::mu::vm::*; use self::mu::vm::*;
use self::mu::linkutils; use self::mu::linkutils;
use self::mu::utils::LinkedHashMap; use self::mu::utils::LinkedHashMap;
use std::sync::Arc;
#[test] #[test]
fn test_mov_minus_one_to_int8() { fn test_mov_minus_one_to_int8() {
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate libloading;
use mu::ast::types::*;
use mu::ast::ir::*;
use mu::ast::ptr::*;
use mu::ast::inst::*;
use mu::ast::op::*;
use mu::vm::*;
use mu::compiler::*;
use std::sync::Arc;
use mu::linkutils;
use mu::linkutils::aot;
use mu::utils::LinkedHashMap;
#[test]
fn test_infinite_loop1() {
VM::start_logging_trace();
let vm = Arc::new(infinite_loop1());
let func_id = vm.id_of("infinite_loop1");
let func_handle = vm.handle_from_func(func_id);
let test_name = "test_infinite_loop1";
vm.make_boot_image(
vec![func_id],
Some(&func_handle),
None,
None,
vec![],
vec![],
vec![],
vec![],
test_name.to_string()
);
}
fn infinite_loop1() -> VM {
let vm = VM::new();
funcsig! ((vm) sig = () -> ());
funcdecl! ((vm) <sig> infinite_loop1);
funcdef! ((vm) <sig> infinite_loop1 VERSION infinite_loop1_v1);
// entry:
block! ((vm, infinite_loop1_v1) blk_entry);
block! ((vm, infinite_loop1_v1) blk_loop);
inst! ((vm, infinite_loop1_v1) blk_entry_branch:
BRANCH blk_loop ()
);
define_block!((vm, infinite_loop1_v1) blk_entry() {
blk_entry_branch
});
// loop
inst! ((vm, infinite_loop1_v1) blk_loop_branch:
BRANCH blk_loop ()
);
define_block!((vm, infinite_loop1_v1) blk_loop() {
blk_loop_branch
});
define_func_ver!((vm) infinite_loop1_v1 (entry: blk_entry) {
blk_entry, blk_loop
});
vm
}
#[test]
fn test_infinite_loop2() {
VM::start_logging_trace();
let vm = Arc::new(infinite_loop2());
let func_id = vm.id_of("infinite_loop2");
let func_handle = vm.handle_from_func(func_id);
let test_name = "test_infinite_loop2";
vm.make_boot_image(
vec![func_id],
Some(&func_handle),
None,
None,
vec![],
vec![],
vec![],
vec![],
test_name.to_string()
);
}
fn infinite_loop2() -> VM {
let vm = VM::new();
funcsig! ((vm) sig = () -> ());
funcdecl! ((vm) <sig> infinite_loop2);
funcdef! ((vm) <sig> infinite_loop2 VERSION infinite_loop2_v1);
// entry:
block! ((vm, infinite_loop2_v1) blk_entry);
block! ((vm, infinite_loop2_v1) blk_a);
block! ((vm, infinite_loop2_v1) blk_b);
inst! ((vm, infinite_loop2_v1) blk_entry_branch:
BRANCH blk_a ()
);
define_block!((vm, infinite_loop2_v1) blk_entry() {
blk_entry_branch
});
// blk a
inst! ((vm, infinite_loop2_v1) blk_a_branch:
BRANCH blk_b ()
);
define_block!((vm, infinite_loop2_v1) blk_a() {
blk_a_branch
});
// blk b
inst! ((vm, infinite_loop2_v1) blk_b_branch:
BRANCH blk_a ()
);
define_block!((vm, infinite_loop2_v1) blk_b() {
blk_b_branch
});
define_func_ver!((vm) infinite_loop2_v1 (entry: blk_entry) {
blk_entry, blk_a, blk_b
});
vm
}
\ No newline at end of file
...@@ -227,7 +227,6 @@ def test_newthread_swapstack(): ...@@ -227,7 +227,6 @@ def test_newthread_swapstack():
t = NEWTHREAD s PASS_VALUES<int<32>>(<int<32>> 2) t = NEWTHREAD s PASS_VALUES<int<32>>(<int<32>> 2)
BRANCH loop() BRANCH loop()
loop(): loop():
a = ADD <int<1>> <int<1>>0 <int<1>>0 // needed due to issue #82
BRANCH loop() BRANCH loop()
} }
.funcdef test_newthread_swapstack <main_sig> .funcdef test_newthread_swapstack <main_sig>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment