summaryrefslogtreecommitdiff
path: root/src/mir/from_hir.hpp
diff options
context:
space:
mode:
authorJohn Hodge (bugs) <tpg@mutabah.net>2017-05-14 12:01:45 +0800
committerJohn Hodge (bugs) <tpg@mutabah.net>2017-05-14 12:01:45 +0800
commit1d2fe7681219700998c8ecbdb8ed5acab66578df (patch)
tree0d38e8ab5fd80c890d3dec67a0596abfc7a4f0cd /src/mir/from_hir.hpp
parentc6fca061dd134068c831aefd88d9535a30f423ed (diff)
parentfde22b3f03d802231985b8ded567cba16cb5aa00 (diff)
downloadmrust-1d2fe7681219700998c8ecbdb8ed5acab66578df.tar.gz
Merge branch 'master' of https://github.com/thepowersgang/mrustc
# Conflicts: # src/common.hpp # src/hir/deserialise.cpp # src/hir_typeck/static.cpp # src/mir/from_hir.cpp # src/mir/from_hir.hpp # src/mir/from_hir_match.cpp # src/mir/helpers.hpp # src/mir/mir_builder.cpp
Diffstat (limited to 'src/mir/from_hir.hpp')
-rw-r--r--src/mir/from_hir.hpp61
1 files changed, 56 insertions, 5 deletions
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp
index 1b57a7f4..6b10d5bd 100644
--- a/src/mir/from_hir.hpp
+++ b/src/mir/from_hir.hpp
@@ -36,6 +36,11 @@ public:
ScopeHandle& operator=(const ScopeHandle& x) = delete;
ScopeHandle& operator=(ScopeHandle&& x) = delete;
~ScopeHandle();
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const ScopeHandle& x) {
+ os << x.idx;
+ return os;
+ }
};
// - Needs to handle future DerefMove (which can't use the Box hack)
@@ -48,11 +53,15 @@ enum class InvalidType {
TAGGED_UNION_EX(VarState, (), Invalid, (
// Currently invalid
(Invalid, InvalidType),
- // Partially valid (Map of field states, Box is assumed to have one field)
+ // Partially valid (Map of field states)
(Partial, struct {
::std::vector<VarState> inner_states;
unsigned int outer_flag; // If ~0u there's no condition on the outer
}),
+ (MovedOut, struct {
+ ::std::unique_ptr<VarState> inner_state;
+ unsigned int outer_flag;
+ }),
// Optionally valid (integer indicates the drop flag index)
(Optional, unsigned int),
// Fully valid
@@ -99,6 +108,14 @@ TAGGED_UNION(ScopeType, Variables,
})
);
+enum class VarGroup
+{
+ Return,
+ Argument,
+ Variable,
+ Temporary,
+};
+
/// Helper class to construct MIR
class MirBuilder
{
@@ -118,7 +135,8 @@ class MirBuilder
bool m_result_valid;
// TODO: Extra information.
- //::std::vector<VarState> m_arg_states;
+ VarState m_return_state;
+ ::std::vector<VarState> m_arg_states;
::std::vector<VarState> m_variable_states;
::std::vector<VarState> m_temporary_states;
@@ -142,6 +160,11 @@ class MirBuilder
::std::vector<ScopeDef> m_scopes;
::std::vector<unsigned int> m_scope_stack;
ScopeHandle m_fcn_scope;
+
+ // LValue used only for the condition of `if`
+ // - Using a fixed temporary simplifies parts of lowering (scope related) and reduces load on
+ // the optimiser.
+ ::MIR::LValue m_if_cond_lval;
public:
MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::Function::args_t& args, ::MIR::Function& output);
~MirBuilder();
@@ -169,6 +192,17 @@ public:
/// Obtains a result in a param (or a lvalue)
::MIR::Param get_result_in_param(const Span& sp, const ::HIR::TypeRef& ty, bool allow_missing_value=false);
+ ::MIR::LValue get_if_cond() const {
+ return m_if_cond_lval.clone();
+ }
+ ::MIR::LValue get_rval_in_if_cond(const Span& sp, ::MIR::RValue val) {
+ push_stmt_assign(sp, m_if_cond_lval.clone(), mv$(val));
+ return m_if_cond_lval.clone();
+ }
+ ::MIR::LValue get_result_in_if_cond(const Span& sp) {
+ return get_rval_in_if_cond(sp, get_result(sp));
+ }
+
// - Statements
// Push an assignment. NOTE: This also marks the rvalue as moved
void push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RValue val);
@@ -181,6 +215,9 @@ public:
// Push a setting/clearing of a drop flag
void push_stmt_set_dropflag_val(const Span& sp, unsigned int index, bool value);
void push_stmt_set_dropflag_other(const Span& sp, unsigned int index, unsigned int other);
+ void push_stmt_set_dropflag_default(const Span& sp, unsigned int index);
+
+ void push_stmt(const Span& sp, ::MIR::Statement stmt);
// - Block management
bool block_active() const {
@@ -190,12 +227,13 @@ public:
// Mark a value as initialised (used for Call, because it has to be done after the panic block is populated)
void mark_value_assigned(const Span& sp, const ::MIR::LValue& val);
- // Moves control of temporaries up to the next scope
- void raise_variables(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope);
- void raise_variables(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope);
+ // 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 set_cur_block(unsigned int new_block);
::MIR::BasicBlockId pause_cur_block();
+
void end_block(::MIR::Terminator term);
::MIR::BasicBlockId new_bb_linked();
@@ -210,9 +248,16 @@ public:
ScopeHandle new_scope_temp(const Span& sp);
ScopeHandle new_scope_split(const Span& sp);
ScopeHandle new_scope_loop(const Span& sp);
+
+ /// Raises every variable defined in the source scope into the target scope
+ void raise_all(const Span& sp, ScopeHandle src, const ScopeHandle& target);
+ /// Drop all defined values in the scope (emits the drops if `cleanup` is set)
void terminate_scope(const Span& sp, ScopeHandle , bool cleanup=true);
+ /// Terminates a scope early (e.g. via return/break/...)
void terminate_scope_early(const Span& sp, const ScopeHandle& , bool loop_exit=false);
+ /// Marks the end of a split arm (end match arm, if body, ...)
void end_split_arm(const Span& sp, const ScopeHandle& , bool reachable);
+ /// Terminates the current split early (TODO: What does this mean?)
void end_split_arm_early(const Span& sp);
const ScopeHandle& fcn_scope() const {
@@ -224,11 +269,17 @@ 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_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);
+
void terminate_loop_early(const Span& sp, ScopeType::Data_Loop& sd_loop);
void drop_value_from_state(const Span& sp, const VarState& vs, ::MIR::LValue lv);