diff options
author | John Hodge <tpg@mutabah.net> | 2017-01-22 12:14:01 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-01-22 12:14:01 +0800 |
commit | 726e32afac634e89495baca4c8c0ad04e95cec68 (patch) | |
tree | 225d49dc2e94527ebef16e141e2cf074bd247e1c | |
parent | 4776f2c628c7c421e71ff89e732ae8aa7dae321f (diff) | |
download | mrust-726e32afac634e89495baca4c8c0ad04e95cec68.tar.gz |
MIR Optimise - Fixed replacement of unified temporaries
-rw-r--r-- | src/mir/helpers.cpp | 11 | ||||
-rw-r--r-- | src/mir/helpers.hpp | 3 | ||||
-rw-r--r-- | src/mir/mir.cpp | 2 | ||||
-rw-r--r-- | src/mir/optimise.cpp | 17 |
4 files changed, 21 insertions, 12 deletions
diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp index e731fae7..9750b978 100644 --- a/src/mir/helpers.cpp +++ b/src/mir/helpers.cpp @@ -11,10 +11,9 @@ #include <hir/type.hpp> #include <mir/mir.hpp> -void ::MIR::TypeResolve::print_msg(const char* tag, ::std::function<void(::std::ostream& os)> cb) const +void ::MIR::TypeResolve::fmt_pos(::std::ostream& os) const { - auto& os = ::std::cerr; - os << "MIR " << tag << ": " << this->m_path << " BB" << this->bb_idx << "/"; + os << this->m_path << " BB" << this->bb_idx << "/"; if( this->stmt_idx == STMT_TERM ) { os << "TERM"; } @@ -22,6 +21,12 @@ void ::MIR::TypeResolve::print_msg(const char* tag, ::std::function<void(::std:: os << this->stmt_idx; } os << ": "; +} +void ::MIR::TypeResolve::print_msg(const char* tag, ::std::function<void(::std::ostream& os)> cb) const +{ + auto& os = ::std::cerr; + os << "MIR " << tag << ": "; + fmt_pos(os); cb(os); os << ::std::endl; abort(); diff --git a/src/mir/helpers.hpp b/src/mir/helpers.hpp index 40dbd4a3..cc0766ec 100644 --- a/src/mir/helpers.hpp +++ b/src/mir/helpers.hpp @@ -33,6 +33,7 @@ struct CheckFailure: #define MIR_BUG(state, ...) do { (state).print_bug( [&](auto& _os){_os << __VA_ARGS__; } ); throw ""; } while(0) #define MIR_ASSERT(state, cnd, ...) do { if( !(cnd) ) (state).print_bug( [&](auto& _os){_os << "ASSERT " #cnd " failed - " << __VA_ARGS__; } ); } while(0) #define MIR_TODO(state, ...) do { (state).print_todo( [&](auto& _os){_os << __VA_ARGS__; } ); throw ""; } while(0) +#define MIR_DEBUG(state, ...) do { DEBUG(FMT_CB(_ss, (state).fmt_pos(_ss);) << __VA_ARGS__); } while(0) class TypeResolve { @@ -79,6 +80,7 @@ public: this->stmt_idx = STMT_TERM; } + void fmt_pos(::std::ostream& os) const; void print_bug(::std::function<void(::std::ostream& os)> cb) const { print_msg("ERROR", cb); } @@ -95,5 +97,4 @@ public: const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const; }; - } // namespace MIR diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 8daeef39..157071c7 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -108,7 +108,7 @@ namespace MIR { os << "Deref(" << *e.val << ")"; ), (Index, - os << "Deref(" << *e.val << ", " << *e.idx << ")"; + os << "Index(" << *e.val << ", " << *e.idx << ")"; ), (Downcast, os << "Downcast(" << e.variant_index << ", " << *e.val << ")"; diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index 7e5243fb..a0b42e0d 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -60,9 +60,10 @@ namespace { return visit_mir_lvalue_mut(*e.val, is_write, cb); ), (Index, - if( visit_mir_lvalue_mut(*e.val, is_write, cb) ) - return true; - return visit_mir_lvalue_mut(*e.idx, false, cb); + bool rv = false; + rv |= visit_mir_lvalue_mut(*e.val, is_write, cb); + rv |= visit_mir_lvalue_mut(*e.idx, false, cb); + return rv; ), (Downcast, return visit_mir_lvalue_mut(*e.val, is_write, cb); @@ -196,13 +197,13 @@ namespace { for(unsigned int block_idx = 0; block_idx < fcn.blocks.size(); block_idx ++) { auto& block = fcn.blocks[block_idx]; - if( block.terminator.tag() == ::MIR::Terminator::TAGDEAD ) - continue ; for(auto& stmt : block.statements) { state.set_cur_stmt(block_idx, (&stmt - &block.statements.front())); visit_mir_lvalues_mut(stmt, cb); } + if( block.terminator.tag() == ::MIR::Terminator::TAGDEAD ) + continue ; state.set_cur_stmt_term(block_idx); visit_mir_lvalues_mut(block.terminator, cb); } @@ -606,7 +607,7 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f // Variables are of the same type, check if they overlap if( tmp_lifetimes[tmpidx].overlaps( tmp_lifetimes[i] ) ) continue ; - // They overlap, unify + // They overlap, unify tmp_lifetimes[tmpidx].unify( tmp_lifetimes[i] ); replacements[i] = tmpidx; replacement_needed = true; @@ -622,9 +623,10 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f auto it = replacements.find(ve->idx); if( it != replacements.end() ) { + MIR_DEBUG(state, lv << " => Temporary(" << it->second << ")"); ve->idx = it->second; + return true; } - return true; } return false; }); @@ -1342,6 +1344,7 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn if( lv.is_Temporary() ) { auto& e = lv.as_Temporary(); MIR_ASSERT(state, e.idx < temp_rewrite_table.size(), "Temporary out of range - " << lv); + // If the table entry for this temporary is !0, it wasn't marked as used MIR_ASSERT(state, temp_rewrite_table.at(e.idx) != ~0u, "LValue " << lv << " incorrectly marked as unused"); e.idx = temp_rewrite_table.at(e.idx); } |