summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-06-16 10:35:30 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-06-16 10:35:30 +0800
commitbbb7023bee036f87b45ba0555e60ce33837460b0 (patch)
treea1e1210bee4a1da459a3be90fb67dc586e400bb5 /src
parent94015a6835ae0d050a83dee1622e1d1b6851f556 (diff)
downloadmrust-bbb7023bee036f87b45ba0555e60ce33837460b0.tar.gz
MIR - Unify temporaries and variables
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp12
-rw-r--r--src/hir/serialise.cpp18
-rw-r--r--src/hir_conv/bind.cpp10
-rw-r--r--src/hir_conv/constant_evaluation.cpp25
-rw-r--r--src/hir_expand/const_eval_full.cpp32
-rw-r--r--src/mir/check.cpp81
-rw-r--r--src/mir/check_full.cpp130
-rw-r--r--src/mir/cleanup.cpp12
-rw-r--r--src/mir/dump.cpp27
-rw-r--r--src/mir/from_hir.cpp26
-rw-r--r--src/mir/from_hir.hpp41
-rw-r--r--src/mir/from_hir_match.cpp2
-rw-r--r--src/mir/helpers.cpp65
-rw-r--r--src/mir/helpers.hpp10
-rw-r--r--src/mir/mir.cpp50
-rw-r--r--src/mir/mir.hpp28
-rw-r--r--src/mir/mir_builder.cpp543
-rw-r--r--src/mir/optimise.cpp272
-rw-r--r--src/trans/codegen_c.cpp33
-rw-r--r--src/trans/enumerate.cpp29
-rw-r--r--src/trans/monomorphise.cpp19
21 files changed, 521 insertions, 944 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index f4dfdf19..3cb58a2e 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -338,11 +338,10 @@ namespace {
switch(auto tag = m_in.read_tag())
{
#define _(x, ...) case ::MIR::LValue::TAG_##x: return ::MIR::LValue::make_##x( __VA_ARGS__ );
- _(Variable, static_cast<unsigned int>(m_in.read_count()) )
- _(Temporary, { static_cast<unsigned int>(m_in.read_count()) } )
- _(Argument, { static_cast<unsigned int>(m_in.read_count()) } )
- _(Static, deserialise_path() )
_(Return, {})
+ _(Argument, { static_cast<unsigned int>(m_in.read_count()) } )
+ _(Local, static_cast<unsigned int>(m_in.read_count()) )
+ _(Static, deserialise_path() )
_(Field, {
box$( deserialise_mir_lvalue() ),
static_cast<unsigned int>(m_in.read_count())
@@ -962,8 +961,8 @@ namespace {
::MIR::Function rv;
- rv.named_variables = deserialise_vec< ::HIR::TypeRef>( );
- rv.temporaries = deserialise_vec< ::HIR::TypeRef>( );
+ rv.locals = deserialise_vec< ::HIR::TypeRef>( );
+ //rv.local_names = deserialise_vec< ::std::string>( );
rv.drop_flags = deserialise_vec<bool>();
rv.blocks = deserialise_vec< ::MIR::BasicBlock>( );
@@ -1012,7 +1011,6 @@ namespace {
}
case 4:
return ::MIR::Statement::make_ScopeEnd({
- deserialise_vec<unsigned int>(),
deserialise_vec<unsigned int>()
});
default:
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 77e17dba..cddbf0b8 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -457,8 +457,8 @@ namespace {
void serialise(const ::MIR::Function& mir)
{
// Write out MIR.
- serialise_vec( mir.named_variables );
- serialise_vec( mir.temporaries );
+ serialise_vec( mir.locals );
+ //serialise_vec( mir.slot_names );
serialise_vec( mir.drop_flags );
serialise_vec( mir.blocks );
}
@@ -498,8 +498,7 @@ namespace {
),
(ScopeEnd,
m_out.write_tag(4);
- serialise_vec(e.vars);
- serialise_vec(e.tmps);
+ serialise_vec(e.slots);
)
)
}
@@ -571,20 +570,17 @@ namespace {
TRACE_FUNCTION_F("LValue = "<<lv);
m_out.write_tag( static_cast<int>(lv.tag()) );
TU_MATCHA( (lv), (e),
- (Variable,
- m_out.write_count(e);
- ),
- (Temporary,
- m_out.write_count(e.idx);
+ (Return,
),
(Argument,
m_out.write_count(e.idx);
),
+ (Local,
+ m_out.write_count(e);
+ ),
(Static,
serialise_path(e);
),
- (Return,
- ),
(Field,
serialise(e.val);
m_out.write_count(e.field_index);
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index cf443eb6..1b0f61b6 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -480,14 +480,12 @@ namespace {
static void visit_lvalue(Visitor& upper_visitor, ::MIR::LValue& lv)
{
TU_MATCHA( (lv), (e),
- (Variable,
+ (Return,
),
- (Temporary,
+ (Local,
),
(Argument,
),
- (Return,
- ),
(Static,
upper_visitor.visit_path(e, ::HIR::Visitor::PathContext::VALUE);
),
@@ -529,9 +527,7 @@ namespace {
)
}
};
- for(auto& ty : expr.m_mir->named_variables)
- this->visit_type(ty);
- for(auto& ty : expr.m_mir->temporaries)
+ for(auto& ty : expr.m_mir->locals)
this->visit_type(ty);
for(auto& block : expr.m_mir->blocks)
{
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index a950a3dd..e8138169 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -1026,32 +1026,25 @@ namespace {
::MIR::TypeResolve state { sp, resolve, FMT_CB(,), exp, {}, fcn };
::HIR::Literal retval;
- ::std::vector< ::HIR::Literal> locals;
- ::std::vector< ::HIR::Literal> temps;
- locals.resize( fcn.named_variables.size() );
- temps.resize( fcn.temporaries.size() );
+ ::std::vector< ::HIR::Literal> locals( fcn.locals.size() );
auto get_lval = [&](const ::MIR::LValue& lv) -> ::HIR::Literal& {
TU_MATCHA( (lv), (e),
- (Variable,
- if( e >= locals.size() )
- BUG(sp, "Local index out of range - " << e << " >= " << locals.size());
- return locals[e];
- ),
- (Temporary,
- if( e.idx >= temps.size() )
- BUG(sp, "Temp index out of range - " << e.idx << " >= " << temps.size());
- return temps[e.idx];
+ (Return,
+ return retval;
),
(Argument,
+ ASSERT_BUG(sp, e.idx < args.size(), "Argument index out of range - " << e.idx << " >= " << args.size());
return args[e.idx];
),
+ (Local,
+ if( e >= locals.size() )
+ BUG(sp, "Local index out of range - " << e << " >= " << locals.size());
+ return locals[e];
+ ),
(Static,
TODO(sp, "LValue::Static");
),
- (Return,
- return retval;
- ),
(Field,
TODO(sp, "LValue::Field");
),
diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp
index 538693f4..04575a6e 100644
--- a/src/hir_expand/const_eval_full.cpp
+++ b/src/hir_expand/const_eval_full.cpp
@@ -292,49 +292,41 @@ namespace {
::MIR::TypeResolve state { sp, resolve, name, ::HIR::TypeRef(), {}, fcn };
::HIR::Literal retval;
- ::std::vector< ::HIR::Literal> locals;
- ::std::vector< ::HIR::Literal> temps;
- locals.resize( fcn.named_variables.size() );
- temps.resize( fcn.temporaries.size() );
+ ::std::vector< ::HIR::Literal> locals( fcn.locals.size() );
struct LocalState {
typedef ::std::vector< ::HIR::Literal> t_vec_lit;
::MIR::TypeResolve& state;
::HIR::Literal& retval;
- ::std::vector< ::HIR::Literal>& locals;
- ::std::vector< ::HIR::Literal>& temps;
::std::vector< ::HIR::Literal>& args;
+ ::std::vector< ::HIR::Literal>& locals;
- LocalState(::MIR::TypeResolve& state, ::HIR::Literal& retval, t_vec_lit& locals, t_vec_lit& temps, t_vec_lit& args):
+ LocalState(::MIR::TypeResolve& state, ::HIR::Literal& retval, t_vec_lit& args, t_vec_lit& locals):
state(state),
retval(retval),
- locals(locals),
- temps(temps),
- args(args)
+ args(args),
+ locals(locals)
{}
::HIR::Literal& get_lval(const ::MIR::LValue& lv)
{
TU_MATCHA( (lv), (e),
- (Variable,
+ (Return,
+ return retval;
+ ),
+ (Local,
if( e >= locals.size() )
MIR_BUG(state, "Local index out of range - " << e << " >= " << locals.size());
return locals[e];
),
- (Temporary,
- if( e.idx >= temps.size() )
- MIR_BUG(state, "Temp index out of range - " << e.idx << " >= " << temps.size());
- return temps[e.idx];
- ),
(Argument,
+ if( e.idx >= args.size() )
+ MIR_BUG(state, "Local index out of range - " << e.idx << " >= " << args.size());
return args[e.idx];
),
(Static,
MIR_TODO(state, "LValue::Static - " << e);
),
- (Return,
- return retval;
- ),
(Field,
auto& val = get_lval(*e.val);
MIR_ASSERT(state, val.is_List(), "LValue::Field on non-list literal - " << val.tag_str() << " - " << lv);
@@ -362,7 +354,7 @@ namespace {
throw "";
}
};
- LocalState local_state( state, retval, locals, temps, args );
+ LocalState local_state( state, retval, args, locals );
auto get_lval = [&](const ::MIR::LValue& lv) -> ::HIR::Literal& { return local_state.get_lval(lv); };
auto read_lval = [&](const ::MIR::LValue& lv) -> ::HIR::Literal {
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index f669623a..58bcaf55 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -105,15 +105,13 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
Valid,
};
State ret_state = State::Invalid;
- ::std::vector<State> arguments;
- ::std::vector<State> temporaries;
- ::std::vector<State> variables;
+ ::std::vector<State> args;
+ ::std::vector<State> locals;
ValStates() {}
- ValStates(size_t n_args, size_t n_temps, size_t n_vars):
- arguments(n_args, State::Valid),
- temporaries(n_temps),
- variables(n_vars)
+ ValStates(size_t n_args, size_t n_locals):
+ args(n_args, State::Valid),
+ locals(n_locals)
{
}
@@ -144,22 +142,20 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
}
}
};
- fmt_val_range("arg", this->arguments);
- fmt_val_range("tmp", this->temporaries);
- fmt_val_range("var", this->variables);
+ fmt_val_range("arg", this->args);
+ fmt_val_range("_", this->locals);
os << "}";
}
bool operator==(const ValStates& x) const {
- if( ret_state != x.ret_state ) return false;
- if( arguments != x.arguments ) return false;
- if( temporaries != x.temporaries ) return false;
- if( variables != x.variables ) return false;
+ if( ret_state != x.ret_state ) return false;
+ if( args != x.args ) return false;
+ if( locals != x.locals ) return false;
return true;
}
bool empty() const {
- return arguments.empty() && temporaries.empty() && variables.empty();
+ return locals.empty() && args.empty();
}
bool merge(unsigned bb_idx, ValStates& other)
@@ -178,9 +174,8 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
{
bool rv = false;
rv |= ValStates::merge_state(this->ret_state, other.ret_state);
- rv |= ValStates::merge_lists(this->arguments , other.arguments);
- rv |= ValStates::merge_lists(this->temporaries, other.temporaries);
- rv |= ValStates::merge_lists(this->variables , other.variables);
+ rv |= ValStates::merge_lists(this->args , other.args );
+ rv |= ValStates::merge_lists(this->locals, other.locals);
return rv;
}
}
@@ -194,42 +189,32 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
ret_state = is_valid ? State::Valid : State::Invalid;
),
(Argument,
- MIR_ASSERT(state, e.idx < this->arguments.size(), "");
- DEBUG("arg" << e.idx << " = " << (is_valid ? "Valid" : "Invalid"));
- this->arguments[e.idx] = is_valid ? State::Valid : State::Invalid;
+ MIR_ASSERT(state, e.idx < this->args.size(), "Argument index out of range");
+ DEBUG("arg$" << e.idx << " = " << (is_valid ? "Valid" : "Invalid"));
+ this->args[e.idx] = is_valid ? State::Valid : State::Invalid;
),
- (Variable,
- MIR_ASSERT(state, e < this->variables.size(), "");
- DEBUG("var" << e << " = " << (is_valid ? "Valid" : "Invalid"));
- this->variables[e] = is_valid ? State::Valid : State::Invalid;
- ),
- (Temporary,
- MIR_ASSERT(state, e.idx < this->temporaries.size(), "");
- DEBUG("tmp" << e.idx << " = " << (is_valid ? "Valid" : "Invalid"));
- this->temporaries[e.idx] = is_valid ? State::Valid : State::Invalid;
+ (Local,
+ MIR_ASSERT(state, e < this->locals.size(), "Local index out of range");
+ DEBUG("_" << e << " = " << (is_valid ? "Valid" : "Invalid"));
+ this->locals[e] = is_valid ? State::Valid : State::Invalid;
)
)
}
void ensure_valid(const ::MIR::TypeResolve& state, const ::MIR::LValue& lv)
{
TU_MATCH( ::MIR::LValue, (lv), (e),
- (Variable,
- MIR_ASSERT(state, e < this->variables.size(), "");
- if( this->variables[e] != State::Valid )
- MIR_BUG(state, "Use of non-valid variable - " << lv);
- ),
- (Temporary,
- MIR_ASSERT(state, e.idx < this->temporaries.size(), "");
- if( this->temporaries[e.idx] != State::Valid )
- MIR_BUG(state, "Use of non-valid temporary - " << lv);
+ (Return,
+ if( this->ret_state != State::Valid )
+ MIR_BUG(state, "Use of non-valid lvalue - " << lv);
),
(Argument,
- MIR_ASSERT(state, e.idx < this->arguments.size(), "");
- if( this->arguments[e.idx] != State::Valid )
- MIR_BUG(state, "Use of non-valid argument - " << lv);
+ MIR_ASSERT(state, e.idx < this->args.size(), "Arg index out of range");
+ if( this->args[e.idx] != State::Valid )
+ MIR_BUG(state, "Use of non-valid lvalue - " << lv);
),
- (Return,
- if( this->ret_state != State::Valid )
+ (Local,
+ MIR_ASSERT(state, e < this->locals.size(), "Local index out of range");
+ if( this->locals[e] != State::Valid )
MIR_BUG(state, "Use of non-valid lvalue - " << lv);
),
(Static,
@@ -309,7 +294,7 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
src_path.push_back(idx);
to_visit_blocks.push_back( ToVisit { idx, mv$(src_path), mv$(vs) } );
};
- add_to_visit( 0, {}, ValStates { state.m_args.size(), fcn.temporaries.size(), fcn.named_variables.size() } );
+ add_to_visit( 0, {}, ValStates { state.m_args.size(), fcn.locals.size() } );
while( to_visit_blocks.size() > 0 )
{
auto block = to_visit_blocks.back().bb;
@@ -430,12 +415,12 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
// Check if the return value has been set
val_state.ensure_valid( state, ::MIR::LValue::make_Return({}) );
// Ensure that no other non-Copy values are valid
- for(unsigned int i = 0; i < val_state.variables.size(); i ++)
+ for(unsigned int i = 0; i < val_state.locals.size(); i ++)
{
- if( val_state.variables[i] == ValStates::State::Invalid )
+ if( val_state.locals[i] == ValStates::State::Invalid )
{
}
- else if( state.m_resolve.type_is_copy(state.sp, fcn.named_variables[i]) )
+ else if( state.m_resolve.type_is_copy(state.sp, fcn.locals[i]) )
{
}
else
diff --git a/src/mir/check_full.cpp b/src/mir/check_full.cpp
index f49598da..a153aca7 100644
--- a/src/mir/check_full.cpp
+++ b/src/mir/check_full.cpp
@@ -67,10 +67,9 @@ namespace
{
struct ValueStates
{
- ::std::vector<State> vars;
- ::std::vector<State> temporaries;
- ::std::vector<State> arguments;
State return_value;
+ ::std::vector<State> args;
+ ::std::vector<State> locals;
::std::vector<bool> drop_flags;
::std::vector< ::std::vector<State> > inner_states;
@@ -89,10 +88,9 @@ namespace
}
};
ValueStates rv;
- rv.vars = H::clone_state_list(this->vars);
- rv.temporaries = H::clone_state_list(this->temporaries);
- rv.arguments = H::clone_state_list(this->arguments);
rv.return_value = State(this->return_value);
+ rv.args = H::clone_state_list(this->args);
+ rv.locals = H::clone_state_list(this->locals);
rv.drop_flags = this->drop_flags;
rv.inner_states.reserve( this->inner_states.size() );
for(const auto& isl : this->inner_states)
@@ -139,22 +137,18 @@ namespace
return false;
if( ! H::equal(*this, return_value, x, x.return_value) )
return false;
- assert(vars.size() == x.vars.size());
- for(size_t i = 0; i < vars.size(); i ++)
- {
- if( ! H::equal(*this, vars[i], x, x.vars[i]) )
- return false;
- }
- assert(temporaries.size() == x.temporaries.size());
- for(size_t i = 0; i < temporaries.size(); i ++)
+
+ assert(args.size() == x.args.size());
+ for(size_t i = 0; i < args.size(); i ++)
{
- if( ! H::equal(*this, temporaries[i], x, x.temporaries[i]) )
+ if( ! H::equal(*this, args[i], x, x.args[i]) )
return false;
}
- assert(arguments.size() == x.arguments.size());
- for(size_t i = 0; i < arguments.size(); i ++)
+
+ assert(locals.size() == x.locals.size());
+ for(size_t i = 0; i < locals.size(); i ++)
{
- if( ! H::equal(*this, arguments[i], x, x.arguments[i]) )
+ if( ! H::equal(*this, locals[i], x, x.locals[i]) )
return false;
}
return true;
@@ -397,13 +391,11 @@ namespace
Marker m;
m.used.resize(this->inner_states.size(), false);
- for(const auto& s : this->vars)
- m.mark_from_state(*this, s);
- for(const auto& s : this->temporaries)
+ m.mark_from_state(*this, this->return_value);
+ for(const auto& s : this->args)
m.mark_from_state(*this, s);
- for(const auto& s : this->arguments)
+ for(const auto& s : this->locals)
m.mark_from_state(*this, s);
- m.mark_from_state(*this, this->return_value);
}
private:
::std::vector<State>& allocate_composite_int(State& out_state)
@@ -455,22 +447,19 @@ namespace
const State& get_lvalue_state(const ::MIR::TypeResolve& mir_res, const ::MIR::LValue& lv) const
{
TU_MATCHA( (lv), (e),
- (Variable,
- return vars.at(e);
- ),
- (Temporary,
- return temporaries.at(e.idx);
+ (Return,
+ return return_value;
),
(Argument,
- return arguments.at(e.idx);
+ return args.at(e.idx);
+ ),
+ (Local,
+ return locals.at(e);
),
(Static,
static State state_of_static(true);
return state_of_static;
),
- (Return,
- return return_value;
- ),
(Field,
const auto& vs = get_lvalue_state(mir_res, *e.val);
if( vs.is_composite() )
@@ -520,7 +509,7 @@ namespace
)
throw "";
}
-
+
void clear_state(const ::MIR::TypeResolve& mir_res, State& s) {
if(s.is_composite()) {
auto& sub_states = this->get_composite(mir_res, s);
@@ -529,33 +518,28 @@ namespace
sub_states.clear();
}
}
-
+
void set_lvalue_state(const ::MIR::TypeResolve& mir_res, const ::MIR::LValue& lv, State new_vs)
{
TRACE_FUNCTION_F(lv << " = " << StateFmt(*this, new_vs) << " (from " << StateFmt(*this, get_lvalue_state(mir_res, lv)) << ")");
TU_MATCHA( (lv), (e),
- (Variable,
- auto& slot = vars.at(e);
- this->clear_state(mir_res, slot);
- slot = mv$(new_vs);
+ (Return,
+ this->clear_state(mir_res, return_value);
+ return_value = mv$(new_vs);
),
- (Temporary,
- auto& slot = temporaries.at(e.idx);
+ (Argument,
+ auto& slot = args.at(e.idx);
this->clear_state(mir_res, slot);
slot = mv$(new_vs);
),
- (Argument,
- auto& slot = arguments.at(e.idx);
+ (Local,
+ auto& slot = locals.at(e);
this->clear_state(mir_res, slot);
slot = mv$(new_vs);
),
(Static,
// Ignore.
),
- (Return,
- this->clear_state(mir_res, return_value);
- return_value = mv$(new_vs);
- ),
(Field,
const auto& cur_vs = get_lvalue_state(mir_res, *e.val);
if( !cur_vs.is_composite() && cur_vs == new_vs )
@@ -736,12 +720,10 @@ namespace std {
os << "ValueStates(path=[" << x.bb_path << "]";
print_val(",rv", x.return_value);
- for(unsigned int i = 0; i < x.arguments.size(); i ++)
- print_val(FMT_CB(ss, ss << ",a" << i;), x.arguments[i]);
- for(unsigned int i = 0; i < x.vars.size(); i ++)
- print_val(FMT_CB(ss, ss << ",_" << i;), x.vars[i]);
- for(unsigned int i = 0; i < x.temporaries.size(); i ++)
- print_val(FMT_CB(ss, ss << ",t" << i;), x.temporaries[i]);
+ for(unsigned int i = 0; i < x.args.size(); i ++)
+ print_val(FMT_CB(ss, ss << ",a" << i;), x.args[i]);
+ for(unsigned int i = 0; i < x.locals.size(); i ++)
+ print_val(FMT_CB(ss, ss << ",_" << i;), x.locals[i]);
for(unsigned int i = 0; i < x.drop_flags.size(); i++)
if(x.drop_flags[i])
os << ",df" << i;
@@ -774,9 +756,8 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
return rv;
}
};
- state.arguments = H::make_list(mir_res.m_args.size(), true);
- state.vars = H::make_list(fcn.named_variables.size(), false);
- state.temporaries = H::make_list(fcn.temporaries.size(), false);
+ state.args = H::make_list(mir_res.m_args.size(), true);
+ state.locals = H::make_list(fcn.locals.size(), false);
state.drop_flags = fcn.drop_flags;
::std::vector< ::std::pair<unsigned int, ValueStates> > todo_queue;
@@ -789,46 +770,25 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
// Mask off any values which aren't valid in the first statement of this block
{
- for(unsigned i = 0; i < state.vars.size(); i ++)
- {
- /*if( !variables_copy[i] )
- {
- // Not Copy, don't apply masking
- }
- else*/ if( ! state.vars[i].is_valid() )
- {
- // Already invalid
- }
- else if( lifetimes.var_valid(i, cur_block, 0) )
- {
- // Expected to be valid in this block, leave as-is
- }
- else
- {
- // Copy value not used at/after this block, mask to false
- DEBUG("BB" << cur_block << " - var$" << i << " - Outside lifetime, discard");
- state.vars[i] = State(false);
- }
- }
- for(unsigned i = 0; i < state.temporaries.size(); i ++)
+ for(unsigned i = 0; i < state.locals.size(); i ++)
{
/*if( !variables_copy[i] )
{
// Not Copy, don't apply masking
}
- else*/ if( ! state.temporaries[i].is_valid() )
+ else*/ if( ! state.locals[i].is_valid() )
{
// Already invalid
}
- else if( lifetimes.tmp_valid(i, cur_block, 0) )
+ else if( lifetimes.slot_valid(i, cur_block, 0) )
{
// Expected to be valid in this block, leave as-is
}
else
{
// Copy value not used at/after this block, mask to false
- DEBUG("BB" << cur_block << " - tmp$" << i << " - Outside lifetime, discard");
- state.temporaries[i] = State(false);
+ DEBUG("BB" << cur_block << " - _" << i << " - Outside lifetime, discard");
+ state.locals[i] = State(false);
}
}
}
@@ -1007,11 +967,11 @@ void MIR_Validate_FullValState(::MIR::TypeResolve& mir_res, const ::MIR::Functio
}
}
};
- for(unsigned i = 0; i < state.arguments.size(); i ++ ) {
- ensure_dropped(state.arguments[i], ::MIR::LValue::make_Argument({i}));
+ for(unsigned i = 0; i < state.locals.size(); i ++ ) {
+ ensure_dropped(state.locals[i], ::MIR::LValue::make_Local(i));
}
- for(unsigned i = 0; i < state.vars.size(); i ++ ) {
- ensure_dropped(state.vars[i], ::MIR::LValue::make_Variable(i));
+ for(unsigned i = 0; i < state.args.size(); i ++ ) {
+ ensure_dropped(state.args[i], ::MIR::LValue::make_Argument({i}));
}
}
),
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index 17dca948..3dda81dc 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -32,8 +32,8 @@ struct MirMutator
::MIR::LValue new_temporary(::HIR::TypeRef ty)
{
- auto rv = ::MIR::LValue::make_Temporary({ static_cast<unsigned int>(m_fcn.temporaries.size()) });
- m_fcn.temporaries.push_back( mv$(ty) );
+ auto rv = ::MIR::LValue::make_Local( static_cast<unsigned int>(m_fcn.locals.size()) );
+ m_fcn.locals.push_back( mv$(ty) );
return rv;
}
@@ -831,15 +831,13 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
void MIR_Cleanup_LValue(const ::MIR::TypeResolve& state, MirMutator& mutator, ::MIR::LValue& lval)
{
TU_MATCHA( (lval), (le),
- (Variable,
- ),
- (Temporary,
+ (Return,
),
(Argument,
),
- (Static,
+ (Local,
),
- (Return,
+ (Static,
),
(Field,
MIR_Cleanup_LValue(state, mutator, *le.val);
diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp
index b4177295..4e53cf5b 100644
--- a/src/mir/dump.cpp
+++ b/src/mir/dump.cpp
@@ -25,13 +25,9 @@ namespace {
void dump_mir(const ::MIR::Function& fcn)
{
- for(unsigned int i = 0; i < fcn.named_variables.size(); i ++)
+ for(size_t i = 0; i < fcn.locals.size(); i ++)
{
- m_os << indent() << "let _#" << i << ": " << fcn.named_variables[i] << ";\n";
- }
- for(unsigned int i = 0; i < fcn.temporaries.size(); i ++)
- {
- m_os << indent() << "let tmp$" << i << ": " << fcn.temporaries[i] << ";\n";
+ m_os << indent() << "let _$" << i << ": " << fcn.locals[i] << ";\n";
}
for(unsigned int i = 0; i < fcn.drop_flags.size(); i ++)
{
@@ -102,10 +98,8 @@ namespace {
),
(ScopeEnd,
m_os << "// Scope End: ";
- for(auto idx : e.vars)
- m_os << "var$" << idx << ",";
- for(auto idx : e.tmps)
- m_os << "tmp$" << idx << ",";
+ for(auto idx : e.slots)
+ m_os << "_$" << idx << ",";
m_os << "\n";
)
)
@@ -165,21 +159,18 @@ namespace {
}
void fmt_val(::std::ostream& os, const ::MIR::LValue& lval) {
TU_MATCHA( (lval), (e),
- (Variable,
- os << "_#" << e;
- ),
- (Temporary,
- os << "tmp$" << e.idx;
+ (Return,
+ os << "RETURN";
),
(Argument,
os << "arg$" << e.idx;
),
+ (Local,
+ os << "_$" << e;
+ ),
(Static,
os << e;
),
- (Return,
- os << "RETURN";
- ),
(Field,
os << "(";
fmt_val(os, *e.val);
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index d9796aed..149d53ea 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -175,16 +175,16 @@ namespace {
switch( pat.m_binding.m_type )
{
case ::HIR::PatternBinding::Type::Move:
- m_builder.push_stmt_assign( sp, ::MIR::LValue::make_Variable(pat.m_binding.m_slot), mv$(lval) );
+ m_builder.push_stmt_assign( sp, m_builder.get_variable(sp, pat.m_binding.m_slot), mv$(lval) );
break;
case ::HIR::PatternBinding::Type::Ref:
if(m_borrow_raise_target)
{
DEBUG("- Raising destructure borrow of " << lval << " to scope " << *m_borrow_raise_target);
- m_builder.raise_variables(sp, lval, *m_borrow_raise_target);
+ m_builder.raise_temporaries(sp, lval, *m_borrow_raise_target);
}
- m_builder.push_stmt_assign( sp, ::MIR::LValue::make_Variable(pat.m_binding.m_slot), ::MIR::RValue::make_Borrow({
+ m_builder.push_stmt_assign( sp, m_builder.get_variable(sp, pat.m_binding.m_slot), ::MIR::RValue::make_Borrow({
0, ::HIR::BorrowType::Shared, mv$(lval)
}) );
break;
@@ -192,9 +192,9 @@ namespace {
if(m_borrow_raise_target)
{
DEBUG("- Raising destructure borrow of " << lval << " to scope " << *m_borrow_raise_target);
- m_builder.raise_variables(sp, lval, *m_borrow_raise_target);
+ m_builder.raise_temporaries(sp, lval, *m_borrow_raise_target);
}
- m_builder.push_stmt_assign( sp, ::MIR::LValue::make_Variable(pat.m_binding.m_slot), ::MIR::RValue::make_Borrow({
+ m_builder.push_stmt_assign( sp, m_builder.get_variable(sp, pat.m_binding.m_slot), ::MIR::RValue::make_Borrow({
0, ::HIR::BorrowType::Unique, mv$(lval)
}) );
break;
@@ -390,7 +390,7 @@ namespace {
);
// Construct fat pointer
- m_builder.push_stmt_assign( sp, ::MIR::LValue::make_Variable(e.extra_bind.m_slot), ::MIR::RValue::make_MakeDst({ mv$(ptr_val), mv$(len_val) }) );
+ m_builder.push_stmt_assign( sp, m_builder.get_variable(sp, e.extra_bind.m_slot), ::MIR::RValue::make_MakeDst({ mv$(ptr_val), mv$(len_val) }) );
}
if( e.trailing.size() > 0 )
{
@@ -536,7 +536,7 @@ namespace {
if( node.m_pattern.m_binding.is_valid() && node.m_pattern.m_data.is_Any() && node.m_pattern.m_binding.m_type == ::HIR::PatternBinding::Type::Move )
{
- m_builder.push_stmt_assign( node.span(), ::MIR::LValue::make_Variable(node.m_pattern.m_binding.m_slot), mv$(res) );
+ m_builder.push_stmt_assign( node.span(), m_builder.get_variable(node.span(), node.m_pattern.m_binding.m_slot), mv$(res) );
}
else
{
@@ -663,7 +663,7 @@ namespace {
if( m_builder.block_active() ) {
auto res = m_builder.get_result(arm.m_code->span());
- m_builder.raise_variables( arm.m_code->span(), res, scope, /*to_above=*/true);
+ m_builder.raise_temporaries( arm.m_code->span(), res, scope, /*to_above=*/true);
m_builder.set_result(arm.m_code->span(), mv$(res));
m_builder.terminate_scope( node.span(), mv$(tmp_scope) );
@@ -1157,7 +1157,7 @@ namespace {
if( m_borrow_raise_target )
{
DEBUG("- Raising borrow to scope " << *m_borrow_raise_target);
- m_builder.raise_variables(node.span(), val, *m_borrow_raise_target);
+ m_builder.raise_temporaries(node.span(), val, *m_borrow_raise_target);
}
m_builder.set_result( node.span(), ::MIR::RValue::make_Borrow({ 0, node.m_type, mv$(val) }) );
@@ -1438,7 +1438,7 @@ namespace {
if( m_borrow_raise_target && m_in_borrow )
{
DEBUG("- Raising deref in borrow to scope " << *m_borrow_raise_target);
- m_builder.raise_variables(node.span(), val, *m_borrow_raise_target);
+ m_builder.raise_temporaries(node.span(), val, *m_borrow_raise_target);
}
@@ -2057,7 +2057,7 @@ namespace {
void visit(::HIR::ExprNode_Variable& node) override
{
TRACE_FUNCTION_F("_Variable - " << node.m_name << " #" << node.m_slot);
- m_builder.set_result( node.span(), ::MIR::LValue::make_Variable(node.m_slot) );
+ m_builder.set_result( node.span(), m_builder.get_variable(node.span(), node.m_slot) );
}
void visit(::HIR::ExprNode_StructLiteral& node) override
@@ -2239,9 +2239,9 @@ namespace {
TRACE_FUNCTION;
::MIR::Function fcn;
- fcn.named_variables.reserve(ptr.m_bindings.size());
+ fcn.locals.reserve(ptr.m_bindings.size());
for(const auto& t : ptr.m_bindings)
- fcn.named_variables.push_back( t.clone() );
+ fcn.locals.push_back( t.clone() );
// Scope ensures that builder cleanup happens before `fcn` is moved
{
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp
index 6b10d5bd..2730631f 100644
--- a/src/mir/from_hir.hpp
+++ b/src/mir/from_hir.hpp
@@ -79,20 +79,16 @@ extern ::std::ostream& operator<<(::std::ostream& os, const VarState& x);
struct SplitArm {
bool has_early_terminated = false;
bool always_early_terminated = false; // Populated on completion
- ::std::map<unsigned int, VarState> var_states;
- ::std::map<unsigned int, VarState> tmp_states;
+ ::std::map<unsigned int, VarState> states;
};
struct SplitEnd {
- ::std::map<unsigned int, VarState> var_states;
- ::std::map<unsigned int, VarState> tmp_states;
+ ::std::map<unsigned int, VarState> states;
};
-TAGGED_UNION(ScopeType, Variables,
- (Variables, struct {
- ::std::vector<unsigned int> vars; // List of owned variables
- }),
- (Temporaries, struct {
- ::std::vector<unsigned int> temporaries; // Controlled temporaries
+TAGGED_UNION(ScopeType, Owning,
+ (Owning, struct {
+ bool is_temporary;
+ ::std::vector<unsigned int> slots; // List of owned variables
}),
(Split, struct {
bool end_state_valid = false;
@@ -101,8 +97,7 @@ TAGGED_UNION(ScopeType, Variables,
}),
(Loop, struct {
// NOTE: This contains the original state for variables changed after `exit_state_valid` is true
- ::std::map<unsigned int,VarState> changed_vars;
- ::std::map<unsigned int,VarState> changed_tmps;
+ ::std::map<unsigned int,VarState> changed_slots;
bool exit_state_valid;
SplitEnd exit_state;
})
@@ -134,11 +129,11 @@ class MirBuilder
::MIR::RValue m_result;
bool m_result_valid;
- // TODO: Extra information.
+ // TODO: Extra information (e.g. mutability)
VarState m_return_state;
::std::vector<VarState> m_arg_states;
- ::std::vector<VarState> m_variable_states;
- ::std::vector<VarState> m_temporary_states;
+ ::std::vector<VarState> m_slot_states;
+ size_t m_first_temp_idx;
struct ScopeDef
{
@@ -177,6 +172,9 @@ public:
const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const;
// - Values
+ ::MIR::LValue get_variable(const Span& sp, unsigned idx) const {
+ return ::MIR::LValue::make_Local( idx );
+ }
::MIR::LValue new_temporary(const ::HIR::TypeRef& ty);
::MIR::LValue lvalue_or_temp(const Span& sp, const ::HIR::TypeRef& ty, ::MIR::RValue val);
@@ -228,8 +226,8 @@ public:
void mark_value_assigned(const Span& sp, const ::MIR::LValue& val);
// Moves control of temporaries up to the specified scope (or to above it)
- void raise_variables(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above=false);
- void raise_variables(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above=false);
+ void raise_temporaries(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above=false);
+ void raise_temporaries(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above=false);
void set_cur_block(unsigned int new_block);
::MIR::BasicBlockId pause_cur_block();
@@ -269,13 +267,8 @@ public:
// Helper - Marks a variable/... as moved (and checks if the move is valid)
void moved_lvalue(const Span& sp, const ::MIR::LValue& lv);
private:
- const VarState& get_slot_state(const Span& sp, VarGroup ty, unsigned int idx, unsigned int skip_count=0) const;
- VarState& get_slot_state_mut(const Span& sp, VarGroup ty, unsigned int idx);
-
- const VarState& get_variable_state(const Span& sp, unsigned int idx, unsigned int skip_count=0) const;
- VarState& get_variable_state_mut(const Span& sp, unsigned int idx);
- const VarState& get_temp_state(const Span& sp, unsigned int idx, unsigned int skip_count=0) const;
- VarState& get_temp_state_mut(const Span& sp, unsigned int idx);
+ const VarState& get_slot_state(const Span& sp, unsigned int idx, unsigned int skip_count=0) const;
+ VarState& get_slot_state_mut(const Span& sp, unsigned int idx);
const VarState& get_val_state(const Span& sp, const ::MIR::LValue& lv, unsigned int skip_count=0);
VarState& get_val_state_mut(const Span& sp, const ::MIR::LValue& lv);
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp
index a68fd1bf..6e00e2e4 100644
--- a/src/mir/from_hir_match.cpp
+++ b/src/mir/from_hir_match.cpp
@@ -219,7 +219,7 @@ void MIR_LowerHIR_Match( MirBuilder& builder, MirConverter& conv, ::HIR::ExprNod
{
if( pat.m_binding.m_type != ::HIR::PatternBinding::Type::Move)
return false;
- return !builder.lvalue_is_copy( sp, ::MIR::LValue::make_Variable( pat.m_binding.m_slot) );
+ return !builder.lvalue_is_copy( sp, builder.get_variable(sp, pat.m_binding.m_slot) );
}
TU_MATCHA( (pat.m_data), (e),
(Any,
diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp
index c38e73e9..31b50246 100644
--- a/src/mir/helpers.cpp
+++ b/src/mir/helpers.cpp
@@ -70,24 +70,20 @@ const ::HIR::TypeRef& ::MIR::TypeResolve::get_static_type(::HIR::TypeRef& tmp, c
const ::HIR::TypeRef& ::MIR::TypeResolve::get_lvalue_type(::HIR::TypeRef& tmp, const ::MIR::LValue& val) const
{
TU_MATCH(::MIR::LValue, (val), (e),
- (Variable,
- MIR_ASSERT(*this, e < m_fcn.named_variables.size(), val << " out of range (" << m_fcn.named_variables.size() << ")");
- return m_fcn.named_variables.at(e);
- ),
- (Temporary,
- MIR_ASSERT(*this, e.idx < m_fcn.temporaries.size(), val << " out of range (" << m_fcn.temporaries.size() << ")");
- return m_fcn.temporaries.at(e.idx);
+ (Return,
+ return m_ret_type;
),
(Argument,
- MIR_ASSERT(*this, e.idx < m_args.size(), val << " out of range (" << m_args.size() << ")");
+ MIR_ASSERT(*this, e.idx < m_args.size(), "Argument " << val << " out of range (" << m_args.size() << ")");
return m_args.at(e.idx).second;
),
+ (Local,
+ MIR_ASSERT(*this, e < m_fcn.locals.size(), "Local " << val << " out of range (" << m_fcn.locals.size() << ")");
+ return m_fcn.locals.at(e);
+ ),
(Static,
return get_static_type(tmp, e);
),
- (Return,
- return m_ret_type;
- ),
(Field,
const auto& ty = this->get_lvalue_type(tmp, *e.val);
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te),
@@ -314,16 +310,14 @@ namespace visit {
if( cb(lv, u) )
return true;
TU_MATCHA( (lv), (e),
- (Variable,
+ (Return,
),
(Argument,
),
- (Temporary,
+ (Local,
),
(Static,
),
- (Return,
- ),
(Field,
return visit_mir_lvalue(*e.val, u, cb);
),
@@ -547,27 +541,21 @@ void MIR_Helper_GetLifetimes_DetermineValueLifetime(::MIR::TypeResolve& state, c
}
block_offsets.push_back(statement_count); // Store the final limit for later code to use.
- ::std::vector<ValueLifetime> temporary_lifetimes( fcn.temporaries.size(), ValueLifetime(statement_count) );
- ::std::vector<ValueLifetime> variable_lifetimes( fcn.named_variables.size(), ValueLifetime(statement_count) );
-
+ ::std::vector<ValueLifetime> slot_lifetimes( fcn.locals.size(), ValueLifetime(statement_count) );
// Enumerate direct assignments of variables (linear iteration of BB list)
for(size_t bb_idx = 0; bb_idx < fcn.blocks.size(); bb_idx ++)
{
auto assigned_lvalue = [&](size_t bb_idx, size_t stmt_idx, const ::MIR::LValue& lv) {
// NOTE: Fills the first statement after running, just to ensure that any assigned value has _a_ lifetime
- if( const auto* de = lv.opt_Variable() )
- {
- MIR_Helper_GetLifetimes_DetermineValueLifetime(state, fcn, bb_idx, stmt_idx, lv, block_offsets, variable_lifetimes[*de]);
- variable_lifetimes[*de].fill(block_offsets, bb_idx, stmt_idx, stmt_idx);
- }
- else if( const auto* de = lv.opt_Temporary() )
+ if( const auto* de = lv.opt_Local() )
{
- MIR_Helper_GetLifetimes_DetermineValueLifetime(state, fcn, bb_idx, stmt_idx, lv, block_offsets, temporary_lifetimes[de->idx]);
- temporary_lifetimes[de->idx].fill(block_offsets, bb_idx, stmt_idx, stmt_idx);
+ MIR_Helper_GetLifetimes_DetermineValueLifetime(state, fcn, bb_idx, stmt_idx, lv, block_offsets, slot_lifetimes[*de]);
+ slot_lifetimes[*de].fill(block_offsets, bb_idx, stmt_idx, stmt_idx);
}
else
{
+ // TODO: Can Argument(_) be assigned?
// Not a direct assignment of a slot
}
};
@@ -589,6 +577,14 @@ void MIR_Helper_GetLifetimes_DetermineValueLifetime(::MIR::TypeResolve& state, c
assigned_lvalue(bb_idx, stmt_idx+1, e.second);
}
}
+ else if( const auto* se = stmt.opt_Drop() )
+ {
+ // HACK: Mark values as valid wherever there's a drop (prevents confusion by simple validator)
+ if( const auto* de = se->slot.opt_Local() )
+ {
+ slot_lifetimes[*de].fill(block_offsets, bb_idx, stmt_idx,stmt_idx);
+ }
+ }
}
state.set_cur_stmt_term(bb_idx);
@@ -601,25 +597,18 @@ void MIR_Helper_GetLifetimes_DetermineValueLifetime(::MIR::TypeResolve& state, c
// Dump out variable lifetimes.
if( dump_debug )
{
- for(unsigned int i = 0; i < temporary_lifetimes.size(); i ++)
+ for(size_t i = 0; i < slot_lifetimes.size(); i ++)
{
- temporary_lifetimes[i].dump_debug("tmp", i, block_offsets);
- }
- for(unsigned int i = 0; i < variable_lifetimes.size(); i ++)
- {
- variable_lifetimes[i].dump_debug("var", i, block_offsets);
+ slot_lifetimes[i].dump_debug("_", i, block_offsets);
}
}
::MIR::ValueLifetimes rv;
rv.m_block_offsets = mv$(block_offsets);
- rv.m_temporaries.reserve( temporary_lifetimes.size() );
- for(auto& lft : temporary_lifetimes)
- rv.m_temporaries.push_back( ::MIR::ValueLifetime(mv$(lft.stmt_bitmap)) );
- rv.m_variables.reserve( variable_lifetimes.size() );
- for(auto& lft : variable_lifetimes)
- rv.m_variables.push_back( ::MIR::ValueLifetime(mv$(lft.stmt_bitmap)) );
+ rv.m_slots.reserve( slot_lifetimes.size() );
+ for(auto& lft : slot_lifetimes)
+ rv.m_slots.push_back( ::MIR::ValueLifetime(mv$(lft.stmt_bitmap)) );
return rv;
}
void MIR_Helper_GetLifetimes_DetermineValueLifetime(
diff --git a/src/mir/helpers.hpp b/src/mir/helpers.hpp
index 802ce88f..091a669f 100644
--- a/src/mir/helpers.hpp
+++ b/src/mir/helpers.hpp
@@ -158,14 +158,10 @@ public:
struct ValueLifetimes
{
::std::vector<size_t> m_block_offsets;
- ::std::vector<ValueLifetime> m_temporaries;
- ::std::vector<ValueLifetime> m_variables;
+ ::std::vector<ValueLifetime> m_slots;
- bool var_valid(unsigned var_idx, unsigned bb_idx, unsigned stmt_idx) const {
- return m_variables.at(var_idx).valid_at( m_block_offsets[bb_idx] + stmt_idx );
- }
- bool tmp_valid(unsigned tmp_idx, unsigned bb_idx, unsigned stmt_idx) const {
- return m_temporaries.at(tmp_idx).valid_at( m_block_offsets[bb_idx] + stmt_idx );
+ bool slot_valid(unsigned idx, unsigned bb_idx, unsigned stmt_idx) const {
+ return m_slots.at(idx).valid_at( m_block_offsets[bb_idx] + stmt_idx );
}
};
diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp
index 9edc925b..3f7057ff 100644
--- a/src/mir/mir.cpp
+++ b/src/mir/mir.cpp
@@ -92,21 +92,18 @@ namespace MIR {
::std::ostream& operator<<(::std::ostream& os, const LValue& x)
{
TU_MATCHA( (x), (e),
- (Variable,
- os << "Variable(" << e << ")";
- ),
- (Temporary,
- os << "Temporary(" << e.idx << ")";
+ (Return,
+ os << "Return";
),
(Argument,
os << "Argument(" << e.idx << ")";
),
+ (Local,
+ os << "Local(" << e << ")";
+ ),
(Static,
os << "Static(" << e << ")";
),
- (Return,
- os << "Return";
- ),
(Field,
os << "Field(" << e.field_index << ", " << *e.val << ")";
),
@@ -127,20 +124,17 @@ namespace MIR {
if( a.tag() != b.tag() )
return a.tag() < b.tag();
TU_MATCHA( (a, b), (ea, eb),
- (Variable,
- return ea < eb;
- ),
- (Temporary,
- return ea.idx < eb.idx;
+ (Return,
+ return false;
),
(Argument,
return ea.idx < eb.idx;
),
- (Static,
+ (Local,
return ea < eb;
),
- (Return,
- return false;
+ (Static,
+ return ea < eb;
),
(Field,
if( *ea.val != *eb.val )
@@ -170,20 +164,17 @@ namespace MIR {
if( a.tag() != b.tag() )
return false;
TU_MATCHA( (a, b), (ea, eb),
- (Variable,
- return ea == eb;
- ),
- (Temporary,
- return ea.idx == eb.idx;
+ (Return,
+ return true;
),
(Argument,
return ea.idx == eb.idx;
),
- (Static,
+ (Local,
return ea == eb;
),
- (Return,
- return true;
+ (Static,
+ return ea == eb;
),
(Field,
if( *ea.val != *eb.val )
@@ -486,10 +477,8 @@ namespace MIR {
),
(ScopeEnd,
os << "ScopeEnd(";
- for(auto idx : e.vars)
- os << "var$" << idx << ",";
- for(auto idx : e.tmps)
- os << "tmp$" << idx << ",";
+ for(auto idx : e.slots)
+ os << "_$" << idx << ",";
os << ")";
)
)
@@ -500,11 +489,10 @@ namespace MIR {
::MIR::LValue MIR::LValue::clone() const
{
TU_MATCHA( (*this), (e),
- (Variable, return LValue(e); ),
- (Temporary, return LValue(e); ),
+ (Return, return LValue(e); ),
(Argument, return LValue(e); ),
+ (Local, return LValue(e); ),
(Static, return LValue(e.clone()); ),
- (Return, return LValue(e); ),
(Field, return LValue::make_Field({
box$( e.val->clone() ),
e.field_index
diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp
index c22f8d5d..6254bf42 100644
--- a/src/mir/mir.hpp
+++ b/src/mir/mir.hpp
@@ -17,21 +17,15 @@ typedef unsigned int RegionId;
typedef unsigned int BasicBlockId;
// "LVALUE" - Assignable values
-TAGGED_UNION_EX(LValue, (), Variable, (
- // User-named variable
- (Variable, unsigned int),
- // Temporary with no user-defined name
- (Temporary, struct {
- unsigned int idx;
- }),
- // Function argument (matters for destructuring)
- (Argument, struct {
- unsigned int idx;
- }),
- // `static` or `static mut`
- (Static, ::HIR::Path),
+TAGGED_UNION_EX(LValue, (), Return, (
// Function return
(Return, struct{}),
+ // Function argument (input)
+ (Argument, struct { unsigned int idx; }),
+ // Variable/Temporary
+ (Local, unsigned int),
+ // `static` or `static mut`
+ (Static, ::HIR::Path),
// Field access (tuple, struct, tuple struct, enum field, ...)
// NOTE: Also used to index an array/slice by a compile-time known index (e.g. in destructuring)
(Field, struct {
@@ -274,8 +268,7 @@ TAGGED_UNION(Statement, Assign,
unsigned int flag_idx; // Valid if != ~0u
}),
(ScopeEnd, struct {
- ::std::vector<unsigned> vars;
- ::std::vector<unsigned> tmps;
+ ::std::vector<unsigned> slots;
})
);
extern ::std::ostream& operator<<(::std::ostream& os, const Statement& x);
@@ -290,9 +283,8 @@ struct BasicBlock
class Function
{
public:
- // TODO: Unify Variables, Temporaries, and Arguments
- ::std::vector< ::HIR::TypeRef> named_variables;
- ::std::vector< ::HIR::TypeRef> temporaries;
+ ::std::vector< ::HIR::TypeRef> locals;
+ //::std::vector< ::std::string> local_names;
::std::vector<bool> drop_flags;
::std::vector<BasicBlock> blocks;
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index f03dc40f..5ace0bb0 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -26,21 +26,20 @@ MirBuilder::MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const
}
set_cur_block( new_bb_unlinked() );
- m_scopes.push_back( ScopeDef { sp } );
+ m_scopes.push_back( ScopeDef { sp, ScopeType::make_Owning({ false, {} }) } );
m_scope_stack.push_back( 0 );
- m_scopes.push_back( ScopeDef { sp, ScopeType::make_Temporaries({}) } );
+ m_scopes.push_back( ScopeDef { sp, ScopeType::make_Owning({ true, {} }) } );
m_scope_stack.push_back( 1 );
-
- m_if_cond_lval = this->new_temporary(::HIR::CoreType::Bool);
-
m_arg_states.reserve( args.size() );
- for(size_t i = 0; i < args.size(); i ++ )
+ for(size_t i = 0; i < args.size(); i ++)
m_arg_states.push_back( VarState::make_Valid({}) );
- m_variable_states.reserve( output.named_variables.size() );
- for(size_t i = 0; i < output.named_variables.size(); i ++ )
- m_variable_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
+ m_slot_states.resize( output.locals.size() );
+ m_first_temp_idx = output.locals.size();
+ DEBUG("First temporary will be " << m_first_temp_idx);
+
+ m_if_cond_lval = this->new_temporary(::HIR::CoreType::Bool);
}
MirBuilder::~MirBuilder()
{
@@ -85,18 +84,21 @@ const ::HIR::TypeRef* MirBuilder::is_type_owned_box(const ::HIR::TypeRef& ty) co
void MirBuilder::define_variable(unsigned int idx)
{
- DEBUG("DEFINE var" << idx << ": " << m_output.named_variables.at(idx));
+ DEBUG("DEFINE (var) _" << idx << ": " << m_output.locals.at(idx));
for( auto scope_idx : ::reverse(m_scope_stack) )
{
auto& scope_def = m_scopes.at(scope_idx);
TU_MATCH_DEF( ScopeType, (scope_def.data), (e),
(
),
- (Variables,
- auto it = ::std::find(e.vars.begin(), e.vars.end(), idx);
- assert(it == e.vars.end());
- e.vars.push_back( idx );
- return ;
+ (Owning,
+ if( !e.is_temporary )
+ {
+ auto it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ assert(it == e.slots.end());
+ e.slots.push_back( idx );
+ return ;
+ }
),
(Split,
BUG(Span(), "Variable " << idx << " introduced within a Split");
@@ -107,20 +109,24 @@ void MirBuilder::define_variable(unsigned int idx)
}
::MIR::LValue MirBuilder::new_temporary(const ::HIR::TypeRef& ty)
{
- unsigned int rv = m_output.temporaries.size();
- DEBUG("DEFINE tmp" << rv << ": " << ty);
+ unsigned int rv = m_output.locals.size();
+ DEBUG("DEFINE (temp) _" << rv << ": " << ty);
- m_output.temporaries.push_back( ty.clone() );
- m_temporary_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
- assert(m_output.temporaries.size() == m_temporary_states.size());
+ assert(m_output.locals.size() == m_slot_states.size());
+ m_output.locals.push_back( ty.clone() );
+ m_slot_states.push_back( VarState::make_Invalid(InvalidType::Uninit) );
+ assert(m_output.locals.size() == m_slot_states.size());
ScopeDef* top_scope = nullptr;
for(unsigned int i = m_scope_stack.size(); i --; )
{
auto idx = m_scope_stack[i];
- if( m_scopes.at( idx ).data.is_Temporaries() ) {
- top_scope = &m_scopes.at(idx);
- break ;
+ if( const auto* e = m_scopes.at( idx ).data.opt_Owning() ) {
+ if( e->is_temporary )
+ {
+ top_scope = &m_scopes.at(idx);
+ break ;
+ }
}
else if( m_scopes.at(idx).data.is_Loop() )
{
@@ -140,9 +146,10 @@ void MirBuilder::define_variable(unsigned int idx)
}
}
assert( top_scope );
- auto& tmp_scope = top_scope->data.as_Temporaries();
- tmp_scope.temporaries.push_back( rv );
- return ::MIR::LValue::make_Temporary({rv});
+ auto& tmp_scope = top_scope->data.as_Owning();
+ assert(tmp_scope.is_temporary);
+ tmp_scope.slots.push_back( rv );
+ return ::MIR::LValue::make_Local(rv);
}
::MIR::LValue MirBuilder::lvalue_or_temp(const Span& sp, const ::HIR::TypeRef& ty, ::MIR::RValue val)
{
@@ -151,7 +158,7 @@ void MirBuilder::define_variable(unsigned int idx)
)
else {
auto temp = new_temporary(ty);
- push_stmt_assign( sp, ::MIR::LValue(temp.as_Temporary()), mv$(val) );
+ push_stmt_assign( sp, temp.clone(), mv$(val) );
return temp;
}
}
@@ -378,26 +385,12 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst)
TU_MATCH_DEF(::MIR::LValue, (dst), (e),
(
),
- (Temporary,
- state_p = &get_temp_state_mut(sp, e.idx);
- if( const auto* se = state_p->opt_Invalid() )
- {
- if( *se != InvalidType::Uninit ) {
- BUG(sp, "Reassigning temporary " << e.idx << " - " << *state_p);
- }
- }
- else {
- // TODO: This should be a bug, but some of the match code ends up reassigning so..
- //BUG(sp, "Reassigning temporary " << e.idx << " - " << *state_p);
- }
- ),
(Return,
// Don't drop.
// No state tracking for the return value
),
- (Variable,
- // TODO: Ensure that slot is mutable (information is lost, assume true)
- state_p = &get_variable_state_mut(sp, e);
+ (Local,
+ state_p = &get_slot_state_mut(sp, e);
)
)
@@ -411,7 +404,7 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst)
}
}
-void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above/*=false*/)
+void MirBuilder::raise_temporaries(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above/*=false*/)
{
TRACE_FUNCTION_F(val);
TU_MATCH_DEF(::MIR::LValue, (val), (e),
@@ -422,29 +415,32 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
// TODO: This may not be correct, because it can change the drop points and ordering
// HACK: Working around cases where values are dropped while the result is not yet used.
(Index,
- raise_variables(sp, *e.val, scope, to_above);
- raise_variables(sp, *e.idx, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.idx, scope, to_above);
return ;
),
(Deref,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
(Field,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
(Downcast,
- raise_variables(sp, *e.val, scope, to_above);
+ raise_temporaries(sp, *e.val, scope, to_above);
return ;
),
// Actual value types
- (Variable,
- ),
- (Temporary,
+ (Local,
)
)
- ASSERT_BUG(sp, val.is_Variable() || val.is_Temporary(), "Hit value raising code with non-variable value - " << val);
+ ASSERT_BUG(sp, val.is_Local(), "Hit value raising code with non-variable value - " << val);
+ const auto idx = val.as_Local();
+ bool is_temp = (idx < m_first_temp_idx);
+ if( idx < m_first_temp_idx ) {
+ return ;
+ }
// Find controlling scope
auto scope_it = m_scope_stack.rbegin();
@@ -457,30 +453,20 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
DEBUG(val << " defined in or above target (scope " << scope << ")");
}
- TU_IFLET( ScopeType, scope_def.data, Variables, e,
- if( const auto* ve = val.opt_Variable() )
+ TU_IFLET( ScopeType, scope_def.data, Owning, e,
+ if( e.is_temporary == is_temp )
{
- auto idx = *ve;
- auto tmp_it = ::std::find( e.vars.begin(), e.vars.end(), idx );
- if( tmp_it != e.vars.end() )
+ auto tmp_it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ if( tmp_it != e.slots.end() )
{
- e.vars.erase( tmp_it );
- DEBUG("Raise variable " << idx << " from " << *scope_it);
+ e.slots.erase( tmp_it );
+ DEBUG("Raise slot " << idx << " from " << *scope_it);
break ;
}
}
- )
- else TU_IFLET( ScopeType, scope_def.data, Temporaries, e,
- if( const auto* ve = val.opt_Temporary() )
+ else
{
- auto idx = ve->idx;
- auto tmp_it = ::std::find( e.temporaries.begin(), e.temporaries.end(), idx );
- if( tmp_it != e.temporaries.end() )
- {
- e.temporaries.erase( tmp_it );
- DEBUG("Raise temporary " << idx << " from " << *scope_it);
- break ;
- }
+ // TODO: Should this care about variables?
}
)
else
@@ -536,26 +522,12 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
target_seen = true;
}
- TU_IFLET( ScopeType, scope_def.data, Variables, e,
- if( target_seen )
- {
- if( const auto* ve = val.opt_Variable() )
- {
- e.vars.push_back( *ve );
- DEBUG("- to " << *scope_it);
- return ;
- }
- }
- )
- else TU_IFLET( ScopeType, scope_def.data, Temporaries, e,
- if( target_seen )
+ TU_IFLET( ScopeType, scope_def.data, Owning, e,
+ if( target_seen && e.is_temporary == is_temp )
{
- if( const auto* ve = val.opt_Temporary() )
- {
- e.temporaries.push_back( ve->idx );
- DEBUG("- to " << *scope_it);
- return ;
- }
+ e.slots.push_back( idx );
+ DEBUG("- to " << *scope_it);
+ return ;
}
)
else if( auto* sd_loop = scope_def.data.opt_Loop() )
@@ -566,19 +538,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
if( sd_loop->exit_state_valid )
{
DEBUG("Adding " << val << " as unset to loop exit state");
- if( const auto* ve = val.opt_Variable() )
- {
- auto v = sd_loop->exit_state.var_states.insert( ::std::make_pair(*ve, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- auto v = sd_loop->exit_state.tmp_states.insert( ::std::make_pair(ve->idx, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else {
- BUG(sp, "Impossible raise value");
- }
+ auto v = sd_loop->exit_state.states.insert( ::std::make_pair(idx, VarState(InvalidType::Uninit)) );
+ ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
}
else
{
@@ -592,19 +553,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
if( sd_split->end_state_valid )
{
DEBUG("Adding " << val << " as unset to loop exit state");
- if( const auto* ve = val.opt_Variable() )
- {
- auto v = sd_split->end_state.var_states.insert( ::std::make_pair(*ve, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- auto v = sd_split->end_state.tmp_states.insert( ::std::make_pair(ve->idx, VarState(InvalidType::Uninit)) );
- ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
- }
- else {
- BUG(sp, "Impossible raise value");
- }
+ auto v = sd_split->end_state.states.insert( ::std::make_pair(idx, VarState(InvalidType::Uninit)) );
+ ASSERT_BUG(sp, v.second, "Raising " << val << " which already had a state entry");
}
else
{
@@ -613,20 +563,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
// TODO: This should update the outer state to unset.
auto& arm = sd_split->arms.back();
- if( const auto* ve = val.opt_Variable() )
- {
- arm.var_states.insert(::std::make_pair( *ve, get_variable_state(sp, *ve).clone() ));
- m_variable_states.at(*ve) = VarState(InvalidType::Uninit);
- }
- else if( const auto* ve = val.opt_Temporary() )
- {
- arm.tmp_states.insert(::std::make_pair( ve->idx, get_temp_state(sp, ve->idx).clone() ));
- m_temporary_states.at(ve->idx) = VarState(InvalidType::Uninit);
- }
- else
- {
- BUG(sp, "Impossible raise value");
- }
+ arm.states.insert(::std::make_pair( idx, get_slot_state(sp, idx).clone() ));
+ m_slot_states.at(idx) = VarState(InvalidType::Uninit);
}
else
{
@@ -635,15 +573,15 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
}
BUG(sp, "Couldn't find a scope to raise " << val << " into");
}
-void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above/*=false*/)
+void MirBuilder::raise_temporaries(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope, bool to_above/*=false*/)
{
auto raise_vars = [&](const ::MIR::Param& p) {
if( const auto* e = p.opt_LValue() )
- this->raise_variables(sp, *e, scope, to_above);
+ this->raise_temporaries(sp, *e, scope, to_above);
};
TU_MATCHA( (rval), (e),
(Use,
- this->raise_variables(sp, e, scope, to_above);
+ this->raise_temporaries(sp, e, scope, to_above);
),
(Constant,
),
@@ -652,23 +590,23 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, cons
),
(Borrow,
// TODO: Wait, is this valid?
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(Cast,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(BinOp,
raise_vars(e.val_l);
raise_vars(e.val_r);
),
(UniOp,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(DstMeta,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(DstPtr,
- this->raise_variables(sp, e.val, scope, to_above);
+ this->raise_temporaries(sp, e.val, scope, to_above);
),
(MakeDst,
raise_vars(e.ptr_val);
@@ -760,7 +698,7 @@ bool MirBuilder::get_drop_flag_default(const Span& sp, unsigned int idx)
ScopeHandle MirBuilder::new_scope_var(const Span& sp)
{
unsigned int idx = m_scopes.size();
- m_scopes.push_back( ScopeDef {sp, ScopeType::make_Variables({})} );
+ m_scopes.push_back( ScopeDef {sp, ScopeType::make_Owning({ false, {} })} );
m_scope_stack.push_back( idx );
DEBUG("START (var) scope " << idx);
return ScopeHandle { *this, idx };
@@ -768,7 +706,8 @@ ScopeHandle MirBuilder::new_scope_var(const Span& sp)
ScopeHandle MirBuilder::new_scope_temp(const Span& sp)
{
unsigned int idx = m_scopes.size();
- m_scopes.push_back( ScopeDef {sp, ScopeType::make_Temporaries({})} );
+
+ m_scopes.push_back( ScopeDef {sp, ScopeType::make_Owning({ true, {} })} );
m_scope_stack.push_back( idx );
DEBUG("START (temp) scope " << idx);
return ScopeHandle { *this, idx };
@@ -852,11 +791,13 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
auto& src_scope_def = m_scopes.at(source.idx);
#if 1
- ASSERT_BUG(sp, src_scope_def.data.is_Temporaries(), "Rasising scopes can only be done on temporaries (source)");
- auto& src_list = src_scope_def.data.as_Temporaries().temporaries;
+ ASSERT_BUG(sp, src_scope_def.data.is_Owning(), "Rasising scopes can only be done on temporaries (source)");
+ ASSERT_BUG(sp, src_scope_def.data.as_Owning().is_temporary, "Rasising scopes can only be done on temporaries (source)");
+ auto& src_list = src_scope_def.data.as_Owning().slots;
for(auto idx : src_list)
{
- DEBUG("> Raising " << ::MIR::LValue::make_Temporary({ idx }));
+ DEBUG("> Raising " << ::MIR::LValue::make_Local(idx));
+ assert(idx >= m_first_temp_idx);
}
// Seek up stack until the target scope is seen
@@ -873,7 +814,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
// Insert these values as Invalid, both in the existing exit state, and in the changed list
for(auto idx : src_list)
{
- auto v = sd_loop->exit_state.tmp_states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v = sd_loop->exit_state.states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v.second, "");
}
}
@@ -884,7 +825,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
for(auto idx : src_list)
{
- auto v2 = sd_loop->changed_tmps.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v2 = sd_loop->changed_slots.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v2.second, "");
}
}
@@ -896,7 +837,7 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
// Insert these indexes as Invalid
for(auto idx : src_list)
{
- auto v = sd_split->end_state.tmp_states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
+ auto v = sd_split->end_state.states.insert(::std::make_pair( idx, VarState(InvalidType::Uninit) ));
ASSERT_BUG(sp, v.second, "");
}
}
@@ -910,8 +851,8 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
auto& arm = sd_split->arms.back();
for(auto idx : src_list)
{
- arm.tmp_states.insert(::std::make_pair( idx, mv$(m_temporary_states.at(idx)) ));
- m_temporary_states.at(idx) = VarState(InvalidType::Uninit);
+ arm.states.insert(::std::make_pair( idx, mv$(m_slot_states.at(idx)) ));
+ m_slot_states.at(idx) = VarState(InvalidType::Uninit);
}
}
}
@@ -920,16 +861,17 @@ void MirBuilder::raise_all(const Span& sp, ScopeHandle source, const ScopeHandle
BUG(sp, "Moving values to a scope not on the stack - scope " << target.idx);
}
auto& tgt_scope_def = m_scopes.at(target.idx);
- ASSERT_BUG(sp, tgt_scope_def.data.is_Temporaries(), "Rasising scopes can only be done on temporaries (target)");
+ ASSERT_BUG(sp, tgt_scope_def.data.is_Owning(), "Rasising scopes can only be done on temporaries (target)");
+ ASSERT_BUG(sp, tgt_scope_def.data.as_Owning().is_temporary, "Rasising scopes can only be done on temporaries (target)");
// Move all defined variables from one to the other
- auto& tgt_list = tgt_scope_def.data.as_Temporaries().temporaries;
+ auto& tgt_list = tgt_scope_def.data.as_Owning().slots;
tgt_list.insert( tgt_list.end(), src_list.begin(), src_list.end() );
#else
auto list = src_scope_def.data.as_Temporaries().temporaries;
for(auto idx : list)
{
- this->raise_variables(sp, ::MIR::LValue::make_Temporary({ idx }), target);
+ this->raise_temporaries(sp, ::MIR::LValue::make_Temporary({ idx }), target);
}
#endif
@@ -1388,39 +1330,24 @@ void MirBuilder::terminate_loop_early(const Span& sp, ScopeType::Data_Loop& sd_l
{
// Insert copies of parent state for newly changed values
// and Merge all changed values
- for(const auto& ent : sd_loop.changed_vars)
- {
- auto idx = ent.first;
- if( sd_loop.exit_state.var_states.count(idx) == 0 ) {
- sd_loop.exit_state.var_states.insert(::std::make_pair( idx, ent.second.clone() ));
- }
- auto& old_state = sd_loop.exit_state.var_states.at(idx);
- merge_state(sp, *this, ::MIR::LValue::make_Variable(idx), old_state, get_variable_state(sp, idx));
- }
- for(const auto& ent : sd_loop.changed_tmps)
+ for(const auto& ent : sd_loop.changed_slots)
{
auto idx = ent.first;
- if( sd_loop.exit_state.tmp_states.count(idx) == 0 ) {
- sd_loop.exit_state.tmp_states.insert(::std::make_pair( idx, ent.second.clone() ));
+ if( sd_loop.exit_state.states.count(idx) == 0 ) {
+ sd_loop.exit_state.states.insert(::std::make_pair( idx, ent.second.clone() ));
}
- auto& old_state = sd_loop.exit_state.tmp_states.at(idx);
- merge_state(sp, *this, ::MIR::LValue::make_Temporary({idx}), old_state, get_temp_state(sp, idx));
+ auto& old_state = sd_loop.exit_state.states.at(idx);
+ merge_state(sp, *this, ::MIR::LValue::make_Local(idx), old_state, get_slot_state(sp, idx));
}
}
else
{
// Obtain states of changed variables/temporaries
- for(const auto& ent : sd_loop.changed_vars)
+ for(const auto& ent : sd_loop.changed_slots)
{
- DEBUG("Variable(" << ent.first << ") = " << ent.second);
+ DEBUG("Slot(" << ent.first << ") = " << ent.second);
auto idx = ent.first;
- sd_loop.exit_state.var_states.insert(::std::make_pair( idx, get_variable_state(sp, idx).clone() ));
- }
- for(const auto& ent : sd_loop.changed_tmps)
- {
- DEBUG("Temporary(" << ent.first << ") = " << ent.second);
- auto idx = ent.first;
- sd_loop.exit_state.tmp_states.insert(::std::make_pair( idx, get_temp_state(sp, idx).clone() ));
+ sd_loop.exit_state.states.insert(::std::make_pair( idx, get_slot_state(sp, idx).clone() ));
}
sd_loop.exit_state_valid = true;
}
@@ -1446,39 +1373,23 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
if( reachable )
{
// Insert copies of the parent state
- for(const auto& ent : this_arm_state.var_states) {
- if( sd_split.end_state.var_states.count(ent.first) == 0 ) {
- sd_split.end_state.var_states.insert(::std::make_pair( ent.first, get_variable_state(sp, ent.first, 1).clone() ));
- }
- }
- for(const auto& ent : this_arm_state.tmp_states) {
- if( sd_split.end_state.tmp_states.count(ent.first) == 0 ) {
- sd_split.end_state.tmp_states.insert(::std::make_pair( ent.first, get_temp_state(sp, ent.first, 1).clone() ));
+ for(const auto& ent : this_arm_state.states) {
+ if( sd_split.end_state.states.count(ent.first) == 0 ) {
+ sd_split.end_state.states.insert(::std::make_pair( ent.first, get_slot_state(sp, ent.first, 1).clone() ));
}
}
// Merge state
- for(auto& ent : sd_split.end_state.var_states)
- {
- auto idx = ent.first;
- auto& out_state = ent.second;
-
- // Merge the states
- auto it = this_arm_state.var_states.find(idx);
- const auto& src_state = (it != this_arm_state.var_states.end() ? it->second : get_variable_state(sp, idx, 1));
-
- merge_state(sp, *this, ::MIR::LValue::make_Variable(idx), out_state, src_state);
- }
- for(auto& ent : sd_split.end_state.tmp_states)
+ for(auto& ent : sd_split.end_state.states)
{
auto idx = ent.first;
auto& out_state = ent.second;
// Merge the states
- auto it = this_arm_state.tmp_states.find(idx);
- const auto& src_state = (it != this_arm_state.tmp_states.end() ? it->second : get_temp_state(sp, idx, 1));
+ auto it = this_arm_state.states.find(idx);
+ const auto& src_state = (it != this_arm_state.states.end() ? it->second : get_slot_state(sp, idx, 1));
- merge_state(sp, *this, ::MIR::LValue::make_Temporary({idx}), out_state, src_state);
+ merge_state(sp, *this, ::MIR::LValue::make_Local(idx), out_state, src_state);
}
}
else
@@ -1489,15 +1400,10 @@ void MirBuilder::end_split_arm(const Span& sp, const ScopeHandle& handle, bool r
else
{
// Clone this arm's state
- for(auto& ent : this_arm_state.var_states)
- {
- DEBUG("Variable(" << ent.first << ") = " << ent.second);
- sd_split.end_state.var_states.insert(::std::make_pair( ent.first, ent.second.clone() ));
- }
- for(auto& ent : this_arm_state.tmp_states)
+ for(auto& ent : this_arm_state.states)
{
- DEBUG("Temporary(" << ent.first << ") = " << ent.second);
- sd_split.end_state.tmp_states.insert(::std::make_pair( ent.first, ent.second.clone() ));
+ DEBUG("Slot(" << ent.first << ") = " << ent.second);
+ sd_split.end_state.states.insert(::std::make_pair( ent.first, ent.second.clone() ));
}
sd_split.end_state_valid = true;
}
@@ -1536,11 +1442,8 @@ void MirBuilder::complete_scope(ScopeDef& sd)
sd.complete = true;
TU_MATCHA( (sd.data), (e),
- (Temporaries,
- DEBUG("Temporaries - " << e.temporaries);
- ),
- (Variables,
- DEBUG("Variables - " << e.vars);
+ (Owning,
+ DEBUG("Owning (" << (e.is_temporary ? "temps" : "vars") << ") - " << e.slots);
),
(Loop,
DEBUG("Loop");
@@ -1552,21 +1455,12 @@ void MirBuilder::complete_scope(ScopeDef& sd)
struct H {
static void apply_end_state(const Span& sp, MirBuilder& builder, SplitEnd& end_state)
{
- for(auto& ent : end_state.var_states)
+ for(auto& ent : end_state.states)
{
- auto& vs = builder.get_variable_state_mut(sp, ent.first);
+ auto& vs = builder.get_slot_state_mut(sp, ent.first);
if( vs != ent.second )
{
- DEBUG(::MIR::LValue::make_Variable(ent.first) << " " << vs << " => " << ent.second);
- vs = ::std::move(ent.second);
- }
- }
- for(auto& ent : end_state.tmp_states)
- {
- auto& vs = builder.get_temp_state_mut(sp, ent.first);
- if( vs != ent.second )
- {
- DEBUG(::MIR::LValue::make_Temporary({ent.first}) << " " << vs << " => " << ent.second);
+ DEBUG(::MIR::LValue::make_Local(ent.first) << " " << vs << " => " << ent.second);
vs = ::std::move(ent.second);
}
}
@@ -1596,16 +1490,15 @@ void MirBuilder::complete_scope(ScopeDef& sd)
void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::function<void(const ::HIR::TypeRef&)> cb) const
{
TU_MATCH(::MIR::LValue, (val), (e),
- (Variable,
- cb( m_output.named_variables.at(e) );
- ),
- (Temporary,
- cb( m_output.temporaries.at(e.idx) );
+ (Return,
+ TODO(sp, "Return");
),
(Argument,
- ASSERT_BUG(sp, e.idx < m_args.size(), "Argument number out of range");
cb( m_args.at(e.idx).second );
),
+ (Local,
+ cb( m_output.locals.at(e) );
+ ),
(Static,
TU_MATCHA( (e.m_data), (pe),
(Generic,
@@ -1624,9 +1517,6 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::
)
)
),
- (Return,
- TODO(sp, "Return");
- ),
(Field,
with_val_type(sp, *e.val, [&](const auto& ty){
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty.m_data), (te),
@@ -1821,7 +1711,7 @@ bool MirBuilder::lvalue_is_copy(const Span& sp, const ::MIR::LValue& val) const
return rv == 2;
}
-const VarState& MirBuilder::get_slot_state(const Span& sp, VarGroup ty, unsigned int idx, unsigned int skip_count/*=0*/) const
+const VarState& MirBuilder::get_slot_state(const Span& sp, unsigned int idx, unsigned int skip_count/*=0*/) const
{
// 1. Find an applicable Split scope
for( auto scope_idx : ::reverse(m_scope_stack) )
@@ -1830,92 +1720,46 @@ const VarState& MirBuilder::get_slot_state(const Span& sp, VarGroup ty, unsigned
TU_MATCH_DEF( ScopeType, (scope_def.data), (e),
(
),
- (Temporaries,
- if( ty == VarGroup::Temporary )
- {
- auto it = ::std::find(e.temporaries.begin(), e.temporaries.end(), idx);
- if( it != e.temporaries.end() ) {
- break ;
- }
- }
- ),
- (Variables,
- if( ty == VarGroup::Variable )
- {
- auto it = ::std::find(e.vars.begin(), e.vars.end(), idx);
- if( it != e.vars.end() ) {
- // If controlled by this block, exit early (won't find it elsewhere)
- break ;
- }
+ (Owning,
+ auto it = ::std::find(e.slots.begin(), e.slots.end(), idx);
+ if( it != e.slots.end() ) {
+ break ;
}
),
(Split,
const auto& cur_arm = e.arms.back();
- if( ty == VarGroup::Variable )
- {
- auto it = cur_arm.var_states.find(idx);
- if( it != cur_arm.var_states.end() )
- {
- if( ! skip_count -- )
- {
- return it->second;
- }
- }
- }
- else if( ty == VarGroup::Temporary )
+ auto it = cur_arm.states.find(idx);
+ if( it != cur_arm.states.end() )
{
- auto it = cur_arm.tmp_states.find(idx);
- if( it != cur_arm.tmp_states.end() )
+ if( ! skip_count -- )
{
- if( ! skip_count -- )
- {
- return it->second;
- }
+ return it->second;
}
}
)
)
}
- switch(ty)
+ if( idx == ~0u )
{
- case VarGroup::Return:
return m_return_state;
- case VarGroup::Argument:
- ASSERT_BUG(sp, idx < m_arg_states.size(), "Argument " << idx << " out of range for state table");
- return m_arg_states.at(idx);
- case VarGroup::Variable:
- ASSERT_BUG(sp, idx < m_variable_states.size(), "Variable " << idx << " out of range for state table");
- return m_variable_states[idx];
- case VarGroup::Temporary:
- ASSERT_BUG(sp, idx < m_temporary_states.size(), "Temporary " << idx << " out of range for state table");
- return m_temporary_states[idx];
}
- BUG(sp, "Fell off the end of get_slot_state");
+ else
+ {
+ ASSERT_BUG(sp, idx < m_slot_states.size(), "Slot " << idx << " out of range for state table");
+ return m_slot_states.at(idx);
+ }
}
-VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned int idx)
+VarState& MirBuilder::get_slot_state_mut(const Span& sp, unsigned int idx)
{
VarState* ret = nullptr;
for( auto scope_idx : ::reverse(m_scope_stack) )
{
auto& scope_def = m_scopes.at(scope_idx);
- if( const auto* e = scope_def.data.opt_Variables() )
- {
- if( ty == VarGroup::Variable )
- {
- auto it = ::std::find(e->vars.begin(), e->vars.end(), idx);
- if( it != e->vars.end() ) {
- break ;
- }
- }
- }
- else if( const auto* e = scope_def.data.opt_Temporaries() )
+ if( const auto* e = scope_def.data.opt_Owning() )
{
- if( ty == VarGroup::Temporary )
- {
- auto it = ::std::find(e->temporaries.begin(), e->temporaries.end(), idx);
- if( it != e->temporaries.end() ) {
- break ;
- }
+ auto it = ::std::find(e->slots.begin(), e->slots.end(), idx);
+ if( it != e->slots.end() ) {
+ break ;
}
}
else if( scope_def.data.is_Split() )
@@ -1924,28 +1768,21 @@ VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned i
auto& cur_arm = e.arms.back();
if( ! ret )
{
- ::std::map<unsigned int, VarState>* states;
- switch(ty)
- {
- case VarGroup::Return: states = nullptr; break;
- case VarGroup::Argument: BUG(sp, "Mutating state of argument"); break;
- case VarGroup::Variable: states = &cur_arm.var_states; break;
- case VarGroup::Temporary: states = &cur_arm.tmp_states; break;
+ if( idx == ~0u ) {
}
-
- if( states )
- {
+ else {
+ auto* states = &cur_arm.states;
auto it = states->find(idx);
if( it == states->end() )
{
DEBUG("Split new (scope " << scope_idx << ")");
- ret = &( (*states)[idx] = get_slot_state(sp, ty, idx).clone() );
+ it = states->insert(::std::make_pair( idx, get_slot_state(sp, idx).clone() )).first;
}
else
{
DEBUG("Split existing (scope " << scope_idx << ")");
- ret = &it->second;
}
+ ret = &it->second;
}
}
}
@@ -1953,19 +1790,15 @@ VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned i
{
auto& e = scope_def.data.as_Loop();
::std::map<unsigned int, VarState>* states = nullptr;
- switch(ty)
+ if( idx == ~0u )
{
- case VarGroup::Return: states = nullptr; break;
- case VarGroup::Argument: BUG(sp, "Mutating state of argument"); break;
- case VarGroup::Variable: states = &e.changed_vars; break;
- case VarGroup::Temporary: states = &e.changed_tmps; break;
}
-
- if( states )
+ else
{
+ states = &e.changed_slots;
if( states->count(idx) == 0 )
{
- auto state = e.exit_state_valid ? get_slot_state(sp, ty, idx).clone() : VarState::make_Valid({});
+ auto state = e.exit_state_valid ? get_slot_state(sp, idx).clone() : VarState::make_Valid({});
states->insert(::std::make_pair( idx, mv$(state) ));
}
}
@@ -1980,39 +1813,16 @@ VarState& MirBuilder::get_slot_state_mut(const Span& sp, VarGroup ty, unsigned i
}
else
{
- switch(ty)
+ if( idx == ~0u )
{
- case VarGroup::Return:
return m_return_state;
- case VarGroup::Argument:
- ASSERT_BUG(sp, idx < m_arg_states.size(), "Argument " << idx << " out of range for state table");
- return m_arg_states.at(idx);
- case VarGroup::Variable:
- ASSERT_BUG(sp, idx < m_variable_states.size(), "Variable " << idx << " out of range for state table");
- return m_variable_states[idx];
- case VarGroup::Temporary:
- ASSERT_BUG(sp, idx < m_temporary_states.size(), "Temporary " << idx << " out of range for state table");
- return m_temporary_states[idx];
}
- BUG(sp, "Fell off the end of get_slot_state_mut");
+ else
+ {
+ return m_slot_states.at(idx);
+ }
}
}
-const VarState& MirBuilder::get_variable_state(const Span& sp, unsigned int idx, unsigned int skip_count) const
-{
- return get_slot_state(sp, VarGroup::Variable, idx, skip_count);
-}
-VarState& MirBuilder::get_variable_state_mut(const Span& sp, unsigned int idx)
-{
- return get_slot_state_mut(sp, VarGroup::Variable, idx);
-}
-const VarState& MirBuilder::get_temp_state(const Span& sp, unsigned int idx, unsigned int skip_count) const
-{
- return get_slot_state(sp, VarGroup::Temporary, idx, skip_count);
-}
-VarState& MirBuilder::get_temp_state_mut(const Span& sp, unsigned int idx)
-{
- return get_slot_state_mut(sp, VarGroup::Temporary, idx);
-}
const VarState& MirBuilder::get_val_state(const Span& sp, const ::MIR::LValue& lv, unsigned int skip_count)
{
@@ -2022,22 +1832,20 @@ VarState& MirBuilder::get_val_state_mut(const Span& sp, const ::MIR::LValue& lv)
{
TRACE_FUNCTION_F(lv);
TU_MATCHA( (lv), (e),
- (Variable,
- return get_slot_state_mut(sp, VarGroup::Variable, e);
- ),
- (Temporary,
- return get_slot_state_mut(sp, VarGroup::Temporary, e.idx);
+ (Return,
+ BUG(sp, "Move of return value");
+ return get_slot_state_mut(sp, ~0u);
),
(Argument,
- return get_slot_state_mut(sp, VarGroup::Argument, e.idx);
+ // NOTE: Only valid outside of split scopes (should only happen at the start)
+ return m_arg_states.at(e.idx);
+ ),
+ (Local,
+ return get_slot_state_mut(sp, e);
),
(Static,
BUG(sp, "Attempting to mutate state of a static");
),
- (Return,
- BUG(sp, "Move of return value");
- return get_slot_state_mut(sp, VarGroup::Return, 0);
- ),
(Field,
auto& ivs = get_val_state_mut(sp, *e.val);
VarState tpl;
@@ -2117,13 +1925,10 @@ VarState& MirBuilder::get_val_state_mut(const Span& sp, const ::MIR::LValue& lv)
this->push_stmt_assign(sp, inner_lv.clone(), ::MIR::RValue( mv$(*e.val) ));
*e.val = inner_lv.clone();
),
- (Variable,
+ (Argument,
inner_lv = ::MIR::LValue(ei);
),
- (Temporary,
- inner_lv = ::MIR::LValue(ei);
- ),
- (Argument,
+ (Local,
inner_lv = ::MIR::LValue(ei);
)
)
@@ -2252,20 +2057,12 @@ void MirBuilder::drop_value_from_state(const Span& sp, const VarState& vs, ::MIR
void MirBuilder::drop_scope_values(const ScopeDef& sd)
{
TU_MATCHA( (sd.data), (e),
- (Temporaries,
- for(auto tmp_idx : ::reverse(e.temporaries))
- {
- const auto& vs = get_temp_state(sd.span, tmp_idx);
- DEBUG("tmp" << tmp_idx << " - " << vs);
- drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Temporary({ tmp_idx }) );
- }
- ),
- (Variables,
- for(auto var_idx : ::reverse(e.vars))
+ (Owning,
+ for(auto idx : ::reverse(e.slots))
{
- const auto& vs = get_variable_state(sd.span, var_idx);
- DEBUG("var" << var_idx << " - " << vs);
- drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Variable(var_idx) );
+ const auto& vs = get_slot_state(sd.span, idx);
+ DEBUG("slot" << idx << " - " << vs);
+ drop_value_from_state( sd.span, vs, ::MIR::LValue::make_Local(idx) );
}
),
(Split,
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index 8e350c45..6837eab6 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -20,6 +20,7 @@
#define DUMP_BEFORE_ALL 0
#define DUMP_BEFORE_CONSTPROPAGATE 0
#define CHECK_AFTER_PASS 0
+#define CHECK_AFTER_ALL 0
#define DUMP_AFTER_DONE 0
#define CHECK_AFTER_DONE 1
@@ -59,16 +60,14 @@ namespace {
if( cb(lv, u) )
return true;
TU_MATCHA( (lv), (e),
- (Variable,
+ (Return,
),
(Argument,
),
- (Temporary,
+ (Local,
),
(Static,
),
- (Return,
- ),
(Field,
return visit_mir_lvalue_mut(*e.val, u, cb);
),
@@ -473,6 +472,9 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
// >> Apply known constants
change_happened |= MIR_Optimise_ConstPropagte(state, fcn);
+ #if CHECK_AFTER_ALL
+ MIR_Validate(resolve, path, fcn, args, ret_type);
+ #endif
// >> Inline short functions
bool inline_happened = MIR_Optimise_Inlining(state, fcn);
@@ -483,18 +485,27 @@ void MIR_Optimise(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
//MIR_Dump_Fcn(::std::cout, fcn);
change_happened = true;
}
+ #if CHECK_AFTER_ALL
+ MIR_Validate(resolve, path, fcn, args, ret_type);
+ #endif
// TODO: Convert `&mut *mut_foo` into `mut_foo` if the source is movable and not used afterwards
// >> Propagate/remove dead assignments
while( MIR_Optimise_PropagateSingleAssignments(state, fcn) )
change_happened = true;
+ #if CHECK_AFTER_ALL
+ MIR_Validate(resolve, path, fcn, args, ret_type);
+ #endif
change_happened |= MIR_Optimise_UnifyBlocks(state, fcn);
// >> Unify duplicate temporaries
// If two temporaries don't overlap in lifetime (blocks in which they're valid), unify the two
change_happened |= MIR_Optimise_UnifyTemporaries(state, fcn);
+ #if CHECK_AFTER_ALL
+ MIR_Validate(resolve, path, fcn, args, ret_type);
+ #endif
// >> Combine Duplicate Blocks
change_happened |= MIR_Optimise_UnifyBlocks(state, fcn);
@@ -553,12 +564,9 @@ bool MIR_Optimise_BlockSimplify(::MIR::TypeResolve& state, ::MIR::Function& fcn)
auto& dst = (it-1)->as_ScopeEnd();
const auto& src = it->as_ScopeEnd();
DEBUG("Unify " << *(it-1) << " and " << *it);
- for(auto v : src.vars)
- dst.vars.push_back(v);
- for(auto v : src.tmps)
- dst.tmps.push_back(v);
- ::std::sort(dst.vars.begin(), dst.vars.end());
- ::std::sort(dst.tmps.begin(), dst.tmps.end());
+ for(auto v : src.slots)
+ dst.slots.push_back(v);
+ ::std::sort(dst.slots.begin(), dst.slots.end());
it = block.statements.erase(it);
}
else
@@ -824,12 +832,9 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
),
(ScopeEnd,
::MIR::Statement::Data_ScopeEnd new_se;
- new_se.vars.reserve(se.vars.size());
- for(auto idx : se.vars)
- new_se.vars.push_back(this->var_base + idx);
- new_se.tmps.reserve(se.tmps.size());
- for(auto idx : se.tmps)
- new_se.tmps.push_back(this->tmp_base + idx);
+ new_se.slots.reserve(se.slots.size());
+ for(auto idx : se.slots)
+ new_se.slots.push_back(this->var_base + idx);
rv.statements.push_back(::MIR::Statement( mv$(new_se) ));
)
)
@@ -922,23 +927,24 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
::MIR::LValue clone_lval(const ::MIR::LValue& src) const
{
TU_MATCHA( (src), (se),
- (Variable,
- return ::MIR::LValue::make_Variable(se + this->var_base);
- ),
- (Temporary,
- return ::MIR::LValue::make_Temporary({se.idx + this->tmp_base});
+ (Return,
+ return this->te.ret_val.clone();
),
(Argument,
const auto& arg = this->te.args.at(se.idx);
- if( const auto* e = arg.opt_Constant() ) {
- auto tmp = ::MIR::LValue::make_Temporary({ static_cast<unsigned>(this->tmp_end + this->const_assignments.size()) });
+ if( const auto* e = arg.opt_Constant() )
+ {
+ auto tmp = ::MIR::LValue::make_Local( static_cast<unsigned>(this->tmp_end + this->const_assignments.size()) );
this->const_assignments.push_back( e->clone() );
return tmp;
}
- return arg.as_LValue().clone();
+ else
+ {
+ return arg.as_LValue().clone();
+ }
),
- (Return,
- return this->te.ret_val.clone();
+ (Local,
+ return ::MIR::LValue::make_Local(this->var_base + se);
),
(Static,
return this->monomorph( se );
@@ -983,8 +989,8 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
TU_MATCHA( (src), (se),
(LValue,
- if( se.is_Argument() )
- return this->te.args.at(se.as_Argument().idx).clone();
+ if( const auto* ae = se.opt_Argument() )
+ return this->te.args.at(ae->idx).clone();
return clone_lval(se);
),
(Constant, return clone_constant(se); )
@@ -995,8 +1001,8 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
TU_MATCHA( (src), (se),
(Use,
- if( se.is_Argument() )
- if( const auto* e = this->te.args.at(se.as_Argument().idx).opt_Constant() )
+ if( const auto* ae = se.opt_Argument() )
+ if( const auto* e = this->te.args.at(ae->idx).opt_Constant() )
return e->clone();
return ::MIR::RValue( this->clone_lval(se) );
),
@@ -1072,13 +1078,10 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
TRACE_FUNCTION_F("Inline " << path);
// Monomorph values and append
- cloner.var_base = fcn.named_variables.size();
- for(const auto& ty : called_mir->named_variables)
- fcn.named_variables.push_back( cloner.monomorph(ty) );
- cloner.tmp_base = fcn.temporaries.size();
- for(const auto& ty : called_mir->temporaries)
- fcn.temporaries.push_back( cloner.monomorph(ty) );
- cloner.tmp_end = fcn.temporaries.size();
+ cloner.var_base = fcn.locals.size();
+ for(const auto& ty : called_mir->locals)
+ fcn.locals.push_back( cloner.monomorph(ty) );
+ cloner.tmp_end = fcn.locals.size();
cloner.df_base = fcn.drop_flags.size();
fcn.drop_flags.insert( fcn.drop_flags.end(), called_mir->drop_flags.begin(), called_mir->drop_flags.end() );
cloner.bb_base = fcn.blocks.size();
@@ -1094,8 +1097,8 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
for(auto& val : cloner.const_assignments)
{
auto ty = state.get_const_type(val);
- auto lv = ::MIR::LValue::make_Temporary({ static_cast<unsigned>(fcn.temporaries.size()) });
- fcn.temporaries.push_back( mv$(ty) );
+ auto lv = ::MIR::LValue::make_Local( static_cast<unsigned>(fcn.locals.size()) );
+ fcn.locals.push_back( mv$(ty) );
new_blocks[0].statements.insert( new_blocks[0].statements.begin(), ::MIR::Statement::make_Assign({ mv$(lv), mv$(val) }) );
}
cloner.const_assignments.clear();
@@ -1120,19 +1123,19 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
TRACE_FUNCTION;
- ::std::vector<bool> replacable( fcn.temporaries.size() );
+ ::std::vector<bool> replacable( fcn.locals.size() );
// 1. Enumerate which (if any) temporaries share the same type
{
unsigned int n_found = 0;
- for(unsigned int tmpidx = 0; tmpidx < fcn.temporaries.size(); tmpidx ++)
+ for(unsigned int tmpidx = 0; tmpidx < fcn.locals.size(); tmpidx ++)
{
if( replacable[tmpidx] )
continue ;
- for(unsigned int i = tmpidx+1; i < fcn.temporaries.size(); i ++ )
+ for(unsigned int i = tmpidx+1; i < fcn.locals.size(); i ++ )
{
if( replacable[i] )
continue ;
- if( fcn.temporaries[i] == fcn.temporaries[tmpidx] )
+ if( fcn.locals[i] == fcn.locals[tmpidx] )
{
replacable[i] = true;
replacable[tmpidx] = true;
@@ -1145,34 +1148,33 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f
}
auto lifetimes = MIR_Helper_GetLifetimes(state, fcn, /*dump_debug=*/true);
- //::std::vector<::MIR::ValueLifetime> var_lifetimes = mv$(lifetimes.m_variables);
- ::std::vector<::MIR::ValueLifetime> tmp_lifetimes = mv$(lifetimes.m_temporaries);
+ ::std::vector<::MIR::ValueLifetime> slot_lifetimes = mv$(lifetimes.m_slots);
// 2. Unify variables of the same type with distinct non-overlapping lifetimes
::std::map<unsigned int, unsigned int> replacements;
- ::std::vector<bool> visited( fcn.temporaries.size() );
+ ::std::vector<bool> visited( fcn.locals.size() );
bool replacement_needed = false;
- for(unsigned int tmpidx = 0; tmpidx < fcn.temporaries.size(); tmpidx ++)
+ for(unsigned int local_idx = 0; local_idx < fcn.locals.size(); local_idx ++)
{
- if( ! replacable[tmpidx] ) continue ;
- if( visited[tmpidx] ) continue ;
- if( ! tmp_lifetimes[tmpidx].is_used() ) continue ;
- visited[tmpidx] = true;
+ if( ! replacable[local_idx] ) continue ;
+ if( visited[local_idx] ) continue ;
+ if( ! slot_lifetimes[local_idx].is_used() ) continue ;
+ visited[local_idx] = true;
- for(unsigned int i = tmpidx+1; i < fcn.temporaries.size(); i ++)
+ for(unsigned int i = local_idx+1; i < fcn.locals.size(); i ++)
{
if( !replacable[i] )
continue ;
- if( fcn.temporaries[i] != fcn.temporaries[tmpidx] )
+ if( fcn.locals[i] != fcn.locals[local_idx] )
continue ;
- if( ! tmp_lifetimes[i].is_used() )
+ if( ! slot_lifetimes[i].is_used() )
continue ;
// Variables are of the same type, check if they overlap
- if( tmp_lifetimes[tmpidx].overlaps( tmp_lifetimes[i] ) )
+ if( slot_lifetimes[local_idx].overlaps( slot_lifetimes[i] ) )
continue ;
// They don't overlap, unify
- tmp_lifetimes[tmpidx].unify( tmp_lifetimes[i] );
- replacements[i] = tmpidx;
+ slot_lifetimes[local_idx].unify( slot_lifetimes[i] );
+ replacements[i] = local_idx;
replacement_needed = true;
visited[i] = true;
}
@@ -1182,12 +1184,12 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f
{
DEBUG("Replacing temporaries using {" << replacements << "}");
visit_mir_lvalues_mut(state, fcn, [&](auto& lv, auto ) {
- if( auto* ve = lv.opt_Temporary() ) {
- auto it = replacements.find(ve->idx);
+ if( auto* ve = lv.opt_Local() ) {
+ auto it = replacements.find(*ve);
if( it != replacements.end() )
{
- MIR_DEBUG(state, lv << " => Temporary(" << it->second << ")");
- ve->idx = it->second;
+ MIR_DEBUG(state, lv << " => Local(" << it->second << ")");
+ *ve = it->second;
return true;
}
}
@@ -1249,9 +1251,7 @@ bool MIR_Optimise_UnifyBlocks(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return false;
),
(ScopeEnd,
- if( ae.vars != be.vars )
- return false;
- if( ae.tmps == be.tmps )
+ if( ae.slots != be.slots )
return false;
)
)
@@ -1721,7 +1721,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
// - Locate `temp = SOME_CONST` and record value
if( const auto* e = stmt.opt_Assign() )
{
- if( e->dst.is_Temporary() || e->dst.is_Variable() )
+ if( e->dst.is_Local() )
{
if( const auto* ce = e->src.opt_Constant() )
{
@@ -1743,9 +1743,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
const auto& te = bb.terminator.as_If();
// Restrict condition to being a temporary/variable
- if( te.cond.is_Temporary() )
- ;
- else if( te.cond.is_Argument() )
+ if( te.cond.is_Local() )
;
else
continue;
@@ -1813,24 +1811,16 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
unsigned int borrow = 0;
};
struct {
- ::std::vector<ValUse> var_uses;
- ::std::vector<ValUse> tmp_uses;
+ ::std::vector<ValUse> local_uses;
void use_lvalue(const ::MIR::LValue& lv, ValUsage ut) {
TU_MATCHA( (lv), (e),
- (Variable,
- auto& vu = var_uses[e];
- switch(ut)
- {
- case ValUsage::Read: vu.read += 1; break;
- case ValUsage::Write: vu.write += 1; break;
- case ValUsage::Borrow: vu.borrow += 1; break;
- }
+ (Return,
),
(Argument,
),
- (Temporary,
- auto& vu = tmp_uses[e.idx];
+ (Local,
+ auto& vu = local_uses[e];
switch(ut)
{
case ValUsage::Read: vu.read += 1; break;
@@ -1840,8 +1830,6 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
),
(Static,
),
- (Return,
- ),
(Field,
use_lvalue(*e.val, ut);
),
@@ -1858,8 +1846,7 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
)
}
} val_uses = {
- ::std::vector<ValUse>(fcn.named_variables.size()),
- ::std::vector<ValUse>(fcn.temporaries.size())
+ ::std::vector<ValUse>(fcn.locals.size())
};
visit_mir_lvalues(state, fcn, [&](const auto& lv, auto ut){ val_uses.use_lvalue(lv, ut); return false; });
@@ -1886,19 +1873,10 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
continue ;
const auto& e = stmt.as_Assign();
// > Of a temporary from with a RValue::Use
- if( const auto* de = e.dst.opt_Temporary() )
+ if( const auto* de = e.dst.opt_Local() )
{
- const auto& vu = val_uses.tmp_uses[de->idx];
- DEBUG(e.dst << " - VU " << e.dst << " R:" << vu.read << " W:" << vu.write);
- // TODO: Allow write many?
- // > Where the temporary is written once and read once
- if( !( vu.read == 1 && vu.write == 1 && vu.borrow == 0 ) )
- continue ;
- }
- else if( const auto* de = e.dst.opt_Variable() )
- {
- const auto& vu = val_uses.var_uses[*de];
- DEBUG(e.dst << " - VU " << e.dst << " R:" << vu.read << " W:" << vu.write);
+ const auto& vu = val_uses.local_uses[*de];
+ DEBUG(e.dst << " - VU " << e.dst << " R:" << vu.read << " W:" << vu.write << " B:" << vu.borrow);
// TODO: Allow write many?
// > Where the variable is written once and read once
if( !( vu.read == 1 && vu.write == 1 && vu.borrow == 0 ) )
@@ -1915,7 +1893,7 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
const auto* srcp = &e.src.as_Use();
while( srcp->is_Field() )
srcp = &*srcp->as_Field().val;
- if( !( srcp->is_Temporary() || srcp->is_Variable() || srcp->is_Argument() ) )
+ if( !srcp->is_Local() )
continue ;
if( replacements.find(*srcp) != replacements.end() )
@@ -2030,6 +2008,7 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
} // for(stmt : block.statements)
}
+ // Apply replacements within replacements
for(;;)
{
unsigned int inner_replaced_count = 0;
@@ -2131,9 +2110,9 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
if( it->as_Assign().src.tag() == ::MIR::RValue::TAGDEAD )
continue ;
auto& to_replace_lval = it->as_Assign().dst;
- if( const auto* e = to_replace_lval.opt_Temporary() ) {
- const auto& vu = val_uses.tmp_uses[e->idx];
- if( !( vu.read == 1 && vu.write == 1 ) )
+ if( const auto* e = to_replace_lval.opt_Local() ) {
+ const auto& vu = val_uses.local_uses[*e];
+ if( !( vu.read == 1 && vu.write == 1 && vu.borrow == 0 ) )
continue ;
}
else {
@@ -2201,10 +2180,9 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
{
// TODO: What if the destination located here is a 1:1 and its usage is listed to be replaced by the return value.
auto& e = block.terminator.as_Call();
- // TODO: Support variables too?
- if( !e.ret_val.is_Temporary() )
+ if( !e.ret_val.is_Local() )
continue ;
- const auto& vu = val_uses.tmp_uses[e.ret_val.as_Temporary().idx];
+ const auto& vu = val_uses.local_uses[e.ret_val.as_Local()];
if( !( vu.read == 1 && vu.write == 1 && vu.borrow == 0 ) )
continue ;
@@ -2261,19 +2239,12 @@ bool MIR_Optimise_PropagateSingleAssignments(::MIR::TypeResolve& state, ::MIR::F
TU_MATCH_DEF( ::MIR::LValue, (se->dst), (de),
(
),
- (Variable,
- const auto& vu = val_uses.var_uses[de];
+ (Local,
+ const auto& vu = val_uses.local_uses[de];
if( vu.write == 1 && vu.read == 0 && vu.borrow == 0 ) {
DEBUG(se->dst << " only written, removing write");
it = block.statements.erase(it)-1;
}
- ),
- (Temporary,
- const auto& vu = val_uses.tmp_uses[de.idx];
- if( vu.write == 1 && vu.read == 0 && vu.borrow == 0 ) {
- DEBUG(se->dst << " only written, removing write with " << se->src);
- it = block.statements.erase(it)-1;
- }
)
)
}
@@ -2355,8 +2326,7 @@ bool MIR_Optimise_GarbageCollect_Partial(::MIR::TypeResolve& state, ::MIR::Funct
// --------------------------------------------------------------------
bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
- ::std::vector<bool> used_temps( fcn.temporaries.size() );
- ::std::vector<bool> used_vars( fcn.named_variables.size() );
+ ::std::vector<bool> used_locals( fcn.locals.size() );
::std::vector<bool> used_dfs( fcn.drop_flags.size() );
::std::vector<bool> visited( fcn.blocks.size() );
@@ -2364,10 +2334,8 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn
visited[bb] = true;
auto assigned_lval = [&](const ::MIR::LValue& lv) {
- if(const auto* le = lv.opt_Temporary() )
- used_temps[le->idx] = true;
- if(const auto* le = lv.opt_Variable() )
- used_vars[*le] = true;
+ if(const auto* le = lv.opt_Local() )
+ used_locals[*le] = true;
};
for(const auto& stmt : block.statements)
@@ -2404,42 +2372,28 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn
{
block_rewrite_table.push_back( visited[i] ? j ++ : ~0u );
}
- ::std::vector<unsigned int> temp_rewrite_table;
- unsigned int n_temp = fcn.temporaries.size();
- for(unsigned int i = 0, j = 0; i < n_temp; i ++)
+ ::std::vector<unsigned int> local_rewrite_table;
+ unsigned int n_locals = fcn.locals.size();
+ for(unsigned int i = 0, j = 0; i < n_locals; i ++)
{
- if( !used_temps[i] )
+ if( !used_locals[i] )
{
- fcn.temporaries.erase(fcn.temporaries.begin() + j);
+ fcn.locals.erase(fcn.locals.begin() + j);
}
else {
- DEBUG("tmp$" << i << " => tmp$" << j);
+ DEBUG("_" << i << " => _" << j);
}
- temp_rewrite_table.push_back( used_temps[i] ? j ++ : ~0u );
+ local_rewrite_table.push_back( used_locals[i] ? j ++ : ~0u );
}
- DEBUG("Deleted Temporaries:" << FMT_CB(ss,
- for(auto run : runs(used_temps))
- if( !used_temps[run.first] )
+ DEBUG("Deleted Locals:" << FMT_CB(ss,
+ for(auto run : runs(used_locals))
+ if( !used_locals[run.first] )
{
ss << " " << run.first;
if(run.second != run.first)
ss << "-" << run.second;
}
));
- ::std::vector<unsigned int> var_rewrite_table;
- unsigned int n_var = fcn.named_variables.size();
- for(unsigned int i = 0, j = 0; i < n_var; i ++)
- {
- if( !used_vars[i] )
- {
- DEBUG("GC Variable(" << i << ")");
- fcn.named_variables.erase(fcn.named_variables.begin() + j);
- }
- else {
- DEBUG("var$" << i << " => var$" << j);
- }
- var_rewrite_table.push_back( used_vars[i] ? j ++ : ~0u );
- }
::std::vector<unsigned int> df_rewrite_table;
unsigned int n_df = fcn.drop_flags.size();
for(unsigned int i = 0, j = 0; i < n_df; i ++)
@@ -2464,17 +2418,11 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn
else
{
auto lvalue_cb = [&](auto& lv, auto ) {
- if(auto* e = lv.opt_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);
- }
- if(auto* e = lv.opt_Variable() ) {
- MIR_ASSERT(state, *e < var_rewrite_table.size(), "Variable out of range - " << lv);
+ if(auto* e = lv.opt_Local() ) {
+ MIR_ASSERT(state, *e < local_rewrite_table.size(), "Variable out of range - " << lv);
// If the table entry for this variable is !0, it wasn't marked as used
- MIR_ASSERT(state, var_rewrite_table.at(*e) != ~0u, "LValue " << lv << " incorrectly marked as unused");
- *e = var_rewrite_table.at(*e);
+ MIR_ASSERT(state, local_rewrite_table.at(*e) != ~0u, "LValue " << lv << " incorrectly marked as unused");
+ *e = local_rewrite_table.at(*e);
}
return false;
};
@@ -2520,28 +2468,18 @@ bool MIR_Optimise_GarbageCollect(::MIR::TypeResolve& state, ::MIR::Function& fcn
}
else if( auto* se = stmt.opt_ScopeEnd() )
{
- for(auto it = se->vars.begin(); it != se->vars.end(); )
- {
- if( var_rewrite_table.at(*it) == ~0u ) {
- it = se->vars.erase(it);
- }
- else {
- *it = var_rewrite_table.at(*it);
- ++ it;
- }
- }
- for(auto it = se->tmps.begin(); it != se->tmps.end(); )
+ for(auto it = se->slots.begin(); it != se->slots.end(); )
{
- if( temp_rewrite_table.at(*it) == ~0u ) {
- it = se->tmps.erase(it);
+ if( local_rewrite_table.at(*it) == ~0u ) {
+ it = se->slots.erase(it);
}
else {
- *it = temp_rewrite_table.at(*it);
+ *it = local_rewrite_table.at(*it);
++ it;
}
}
- if( se->vars.empty() && se->tmps.empty() ) {
+ if( se->slots.empty() ) {
DEBUG(state << "Delete ScopeEnd (now empty)");
to_remove_statements[stmt_idx] = true;
continue ;
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 878a55d4..2841db10 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -1303,16 +1303,10 @@ namespace {
m_of << "{\n";
// Variables
m_of << "\t"; emit_ctype(ret_type, FMT_CB(ss, ss << "rv";)); m_of << ";\n";
- for(unsigned int i = 0; i < code->named_variables.size(); i ++) {
- DEBUG("var" << i << " : " << code->named_variables[i]);
- m_of << "\t"; emit_ctype(code->named_variables[i], FMT_CB(ss, ss << "var" << i;)); m_of << ";";
- m_of << "\t// " << code->named_variables[i];
- m_of << "\n";
- }
- for(unsigned int i = 0; i < code->temporaries.size(); i ++) {
- DEBUG("tmp" << i << " : " << code->temporaries[i]);
- m_of << "\t"; emit_ctype(code->temporaries[i], FMT_CB(ss, ss << " tmp" << i;)); m_of << ";";
- m_of << "\t// " << code->temporaries[i];
+ for(unsigned int i = 0; i < code->locals.size(); i ++) {
+ DEBUG("var" << i << " : " << code->locals[i]);
+ m_of << "\t"; emit_ctype(code->locals[i], FMT_CB(ss, ss << "var" << i;)); m_of << ";";
+ m_of << "\t// " << code->locals[i];
m_of << "\n";
}
for(unsigned int i = 0; i < code->drop_flags.size(); i ++) {
@@ -2612,7 +2606,7 @@ namespace {
// Call destructor on all entries
m_of << "for(unsigned i = 0; i < "; emit_lvalue(*lvp->as_Deref().val); m_of << ".META; i++) {";
m_of << "\t\t";
- emit_destructor_call(::MIR::LValue::make_Index({ box$(slot.clone()), box$(::MIR::LValue::make_Temporary({~0u})) }), *te.inner, false);
+ emit_destructor_call(::MIR::LValue::make_Index({ box$(slot.clone()), box$(::MIR::LValue::make_Local(~0u)) }), *te.inner, false);
m_of << "\n\t}";
)
)
@@ -2814,20 +2808,17 @@ namespace {
void emit_lvalue(const ::MIR::LValue& val) {
TU_MATCHA( (val), (e),
- (Variable,
- m_of << "var" << e;
- ),
- (Temporary,
- if( e.idx == ~0u )
- m_of << "i";
- else
- m_of << "tmp" << e.idx;
+ (Return,
+ m_of << "rv";
),
(Argument,
m_of << "arg" << e.idx;
),
- (Return,
- m_of << "rv";
+ (Local,
+ if( e == ~0u )
+ m_of << "i";
+ else
+ m_of << "var" << e;
),
(Static,
m_of << Trans_Mangle(e);
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 02116d18..fb577959 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -623,9 +623,7 @@ void Trans_Enumerate_Types(EnumState& state)
if( fcn.m_code.m_mir )
{
const auto& mir = *fcn.m_code.m_mir;
- for(const auto& ty : mir.named_variables)
- tv.visit_type(monomorph(ty));
- for(const auto& ty : mir.temporaries)
+ for(const auto& ty : mir.locals)
tv.visit_type(monomorph(ty));
// TODO: Find all LValue::Deref instances and get the result type
@@ -646,19 +644,19 @@ void Trans_Enumerate_Types(EnumState& state)
};
// Recurse, if Deref get the type and add it to the visitor
TU_MATCHA( (lv), (e),
- (Variable,
+ (Return,
if( tmp_ty_ptr ) {
- return monomorph_outer(fcn.m_code.m_mir->named_variables[e]);
+ TODO(Span(), "Get return type for MIR type enumeration");
}
),
- (Temporary,
+ (Argument,
if( tmp_ty_ptr ) {
- return monomorph_outer(fcn.m_code.m_mir->temporaries[e.idx]);
+ return monomorph_outer(fcn.m_args[e.idx].second);
}
),
- (Argument,
+ (Local,
if( tmp_ty_ptr ) {
- return monomorph_outer(fcn.m_args[e.idx].second);
+ return monomorph_outer(fcn.m_code.m_mir->locals[e]);
}
),
(Static,
@@ -682,11 +680,6 @@ void Trans_Enumerate_Types(EnumState& state)
)
}
),
- (Return,
- if( tmp_ty_ptr ) {
- TODO(Span(), "Get return type for MIR type enumeration");
- }
- ),
(Field,
const auto& ity = visit_lvalue(tv,pp,fcn, *e.val, tmp_ty_ptr);
if( tmp_ty_ptr )
@@ -1344,17 +1337,15 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co
void Trans_Enumerate_FillFrom_MIR_LValue(EnumState& state, const ::MIR::LValue& lv, const Trans_Params& pp)
{
TU_MATCHA( (lv), (e),
- (Variable,
- ),
- (Temporary,
+ (Return,
),
(Argument,
),
+ (Local,
+ ),
(Static,
Trans_Enumerate_FillFrom_Path(state, e, pp);
),
- (Return,
- ),
(Field,
Trans_Enumerate_FillFrom_MIR_LValue(state, *e.val, pp);
),
diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp
index 3ac2ee09..f708060d 100644
--- a/src/trans/monomorphise.cpp
+++ b/src/trans/monomorphise.cpp
@@ -13,10 +13,9 @@ namespace {
::MIR::LValue monomorph_LValue(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::MIR::LValue& tpl)
{
TU_MATCHA( (tpl), (e),
- (Variable, return e; ),
- (Temporary, return e; ),
- (Argument, return e; ),
(Return, return e; ),
+ (Argument, return e; ),
+ (Local, return e; ),
(Static,
return params.monomorph(resolve, e);
),
@@ -120,17 +119,11 @@ namespace {
::MIR::Function output;
// 1. Monomorphise locals and temporaries
- output.named_variables.reserve( tpl->named_variables.size() );
- for(const auto& var : tpl->named_variables)
- {
- DEBUG("- var" << output.named_variables.size());
- output.named_variables.push_back( params.monomorph(resolve, var) );
- }
- output.temporaries.reserve( tpl->temporaries.size() );
- for(const auto& ty : tpl->temporaries)
+ output.locals.reserve( tpl->locals.size() );
+ for(const auto& var : tpl->locals)
{
- DEBUG("- tmp" << output.temporaries.size());
- output.temporaries.push_back( params.monomorph(resolve, ty) );
+ DEBUG("- _" << output.locals.size());
+ output.locals.push_back( params.monomorph(resolve, var) );
}
output.drop_flags = tpl->drop_flags;