Commit e2de3cc2 authored by Paul's avatar Paul
Browse files

Fix issue with DCE, and add more tests

parent c7ad413e
...@@ -11,19 +11,24 @@ void dead_code_elimination::apply(program& p) const ...@@ -11,19 +11,24 @@ void dead_code_elimination::apply(program& p) const
auto last = std::prev(p.end()); auto last = std::prev(p.end());
for(auto ins : iterator_for(p)) for(auto ins : iterator_for(p))
{ {
// Skip the first instruction, since we always process the previous
// instruction
if(ins == p.begin())
continue;
// Skip the last instruction // Skip the last instruction
if(ins == last) if(std::prev(ins) == last)
break; break;
fix([&](auto self, auto leaf) { fix([&](auto self, auto leaf) {
assert(p.has_instruction(leaf)); assert(p.has_instruction(leaf));
if(leaf->output.empty()) if(leaf->output.empty())
{ {
auto args = leaf->arguments; auto args = leaf->arguments;
leaf->clear_arguments();
p.move_instruction(leaf, p.end()); p.move_instruction(leaf, p.end());
for(auto arg : args) for(auto arg : args)
self(arg); self(arg);
} }
})(ins); })(std::prev(ins));
} }
p.remove_instructions(std::next(last), p.end()); p.remove_instructions(std::next(last), p.end());
} }
......
...@@ -54,6 +54,7 @@ struct instruction ...@@ -54,6 +54,7 @@ struct instruction
{ {
migraph::erase(arg->output, *this); migraph::erase(arg->output, *this);
} }
arguments.clear();
} }
friend bool operator==(const instruction& i, instruction_ref ref) friend bool operator==(const instruction& i, instruction_ref ref)
......
...@@ -62,8 +62,9 @@ instruction_ref program::remove_instruction(instruction_ref ins) ...@@ -62,8 +62,9 @@ instruction_ref program::remove_instruction(instruction_ref ins)
instruction_ref program::remove_instructions(instruction_ref first, instruction_ref last) instruction_ref program::remove_instructions(instruction_ref first, instruction_ref last)
{ {
if(first == last) return first;
// TODO: Check every element
assert(has_instruction(first)); assert(has_instruction(first));
assert(has_instruction(last));
std::for_each(first, last, [&](instruction& ins) { ins.clear_arguments(); }); std::for_each(first, last, [&](instruction& ins) { ins.clear_arguments(); });
assert(std::all_of(first, last, [&](instruction& ins) { return ins.output.empty(); })); assert(std::all_of(first, last, [&](instruction& ins) { return ins.output.empty(); }));
return impl->instructions.erase(first, last); return impl->instructions.erase(first, last);
......
...@@ -60,9 +60,29 @@ void duplicate_test2() ...@@ -60,9 +60,29 @@ void duplicate_test2()
EXPECT(result != migraph::literal{4}); EXPECT(result != migraph::literal{4});
} }
void depth_test()
{
migraph::program p;
auto one = p.add_literal(1);
auto two = p.add_literal(2);
auto x1 = p.add_instruction(sum_op{}, one, two);
auto x2 = p.add_instruction(sum_op{}, one, two);
p.add_instruction(minus_op{}, x1, x2);
p.add_instruction(minus_op{}, x1, x2);
p.add_instruction(sum_op{}, one, two);
auto count = std::distance(p.begin(), p.end());
p.compile(dce_target{});
EXPECT(std::distance(p.begin(), p.end()) == (count - 4));
auto result = p.eval({});
EXPECT(result == migraph::literal{3});
EXPECT(result != migraph::literal{4});
}
int main() int main()
{ {
simple_test(); simple_test();
duplicate_test1(); duplicate_test1();
duplicate_test2(); duplicate_test2();
depth_test();
} }
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