summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-02-22 13:27:28 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-02-22 13:27:28 +0800
commite4d8415f346e7067c3f060649c577b947a249e51 (patch)
tree8af7cd07650aaac7a53cd5d560134c0990d82ba0 /src
parenta4ec506e3f3c23c7818c3ce2d020b25966c420d8 (diff)
downloadmrust-e4d8415f346e7067c3f060649c577b947a249e51.tar.gz
MIR - add Param type for places where a lvalue is read
Diffstat (limited to 'src')
-rw-r--r--src/hir/deserialise.cpp29
-rw-r--r--src/hir/serialise.cpp9
-rw-r--r--src/hir_conv/bind.cpp40
-rw-r--r--src/hir_conv/constant_evaluation.cpp87
-rw-r--r--src/hir_expand/const_eval_full.cpp105
-rw-r--r--src/mir/check.cpp9
-rw-r--r--src/mir/cleanup.cpp47
-rw-r--r--src/mir/dump.cpp65
-rw-r--r--src/mir/from_hir.cpp45
-rw-r--r--src/mir/mir.cpp77
-rw-r--r--src/mir/mir.hpp54
-rw-r--r--src/mir/mir_builder.cpp41
-rw-r--r--src/mir/optimise.cpp104
-rw-r--r--src/trans/codegen_c.cpp508
-rw-r--r--src/trans/enumerate.cpp86
-rw-r--r--src/trans/monomorphise.cpp113
16 files changed, 851 insertions, 568 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index 19786eb1..fd6cbbf2 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -317,6 +317,16 @@ namespace {
::MIR::Terminator deserialise_mir_terminator();
::MIR::CallTarget deserialise_mir_calltarget();
+ ::MIR::Param deserialise_mir_param()
+ {
+ switch(auto tag = m_in.read_tag())
+ {
+ case ::MIR::Param::TAG_LValue: return deserialise_mir_lvalue();
+ case ::MIR::Param::TAG_Constant: return deserialise_mir_constant();
+ default:
+ throw ::std::runtime_error(FMT("Invalid MIR LValue tag - " << tag));
+ }
+ }
::MIR::LValue deserialise_mir_lvalue() {
::MIR::LValue rv;
TRACE_FUNCTION_FR("", rv);
@@ -361,7 +371,7 @@ namespace {
_(Use, deserialise_mir_lvalue() )
_(Constant, deserialise_mir_constant() )
_(SizedArray, {
- deserialise_mir_lvalue(),
+ deserialise_mir_param(),
static_cast<unsigned int>(m_in.read_u64c())
})
_(Borrow, {
@@ -374,9 +384,9 @@ namespace {
deserialise_type()
})
_(BinOp, {
- deserialise_mir_lvalue(),
+ deserialise_mir_param(),
static_cast< ::MIR::eBinOp>( m_in.read_tag() ),
- deserialise_mir_lvalue()
+ deserialise_mir_param()
})
_(UniOp, {
deserialise_mir_lvalue(),
@@ -390,23 +400,23 @@ namespace {
})
_(MakeDst, {
deserialise_mir_lvalue(),
- deserialise_mir_lvalue()
+ deserialise_mir_param()
})
_(Tuple, {
- deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); })
+ deserialise_vec< ::MIR::Param>()
})
_(Array, {
- deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); })
+ deserialise_vec< ::MIR::Param>()
})
_(Variant, {
deserialise_genericpath(),
static_cast<unsigned int>( m_in.read_count() ),
- deserialise_mir_lvalue()
+ deserialise_mir_param()
})
_(Struct, {
deserialise_genericpath(),
static_cast<unsigned int>( m_in.read_count() ),
- deserialise_vec_c< ::MIR::LValue>([&](){ return deserialise_mir_lvalue(); })
+ deserialise_vec< ::MIR::Param>()
})
#undef _
default:
@@ -642,6 +652,7 @@ namespace {
template<> DEF_D( ::HIR::AssociatedType, return d.deserialise_associatedtype(); )
template<> DEF_D( ::HIR::TraitValueItem, return d.deserialise_traitvalueitem(); )
+ template<> DEF_D( ::MIR::Param, return d.deserialise_mir_param(); )
template<> DEF_D( ::MIR::LValue, return d.deserialise_mir_lvalue(); )
template<> DEF_D( ::MIR::Statement, return d.deserialise_mir_statement(); )
template<> DEF_D( ::MIR::BasicBlock, return d.deserialise_mir_basicblock(); )
@@ -1017,7 +1028,7 @@ namespace {
static_cast<unsigned int>(m_in.read_count()),
deserialise_mir_lvalue(),
deserialise_mir_calltarget(),
- deserialise_vec< ::MIR::LValue>()
+ deserialise_vec< ::MIR::Param>()
})
#undef _
default:
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index dede23a4..5a74e798 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -552,6 +552,15 @@ namespace {
)
)
}
+ void serialise(const ::MIR::Param& p)
+ {
+ TRACE_FUNCTION_F("Param = "<<p);
+ m_out.write_tag( static_cast<int>(p.tag()) );
+ TU_MATCHA( (p), (e),
+ (LValue, serialise(e);),
+ (Constant, serialise(e);)
+ )
+ }
void serialise(const ::MIR::LValue& lv)
{
TRACE_FUNCTION_F("LValue = "<<lv);
diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp
index 686c71d2..53d97fb0 100644
--- a/src/hir_conv/bind.cpp
+++ b/src/hir_conv/bind.cpp
@@ -499,6 +499,28 @@ namespace {
)
)
}
+ static void visit_param(Visitor& upper_visitor, ::MIR::Param& p)
+ {
+ TU_MATCHA( (p), (e),
+ (LValue, H::visit_lvalue(upper_visitor, e);),
+ (Constant,
+ TU_MATCHA( (e), (ce),
+ (Int, ),
+ (Uint,),
+ (Float, ),
+ (Bool, ),
+ (Bytes, ),
+ (StaticString, ), // String
+ (Const,
+ // TODO: Should this trigger anything?
+ ),
+ (ItemAddr,
+ upper_visitor.visit_path(ce, ::HIR::Visitor::PathContext::VALUE);
+ )
+ )
+ )
+ )
+ }
};
for(auto& ty : expr.m_mir->named_variables)
this->visit_type(ty);
@@ -531,7 +553,7 @@ namespace {
)
),
(SizedArray,
- H::visit_lvalue(*this, e.val);
+ H::visit_param(*this, e.val);
),
(Borrow,
H::visit_lvalue(*this, e.val);
@@ -541,8 +563,8 @@ namespace {
this->visit_type(e.type);
),
(BinOp,
- H::visit_lvalue(*this, e.val_l);
- H::visit_lvalue(*this, e.val_r);
+ H::visit_param(*this, e.val_l);
+ H::visit_param(*this, e.val_r);
),
(UniOp,
H::visit_lvalue(*this, e.val);
@@ -554,23 +576,23 @@ namespace {
H::visit_lvalue(*this, e.val);
),
(MakeDst,
- H::visit_lvalue(*this, e.meta_val);
H::visit_lvalue(*this, e.ptr_val);
+ H::visit_param(*this, e.meta_val);
),
(Tuple,
for(auto& val : e.vals)
- H::visit_lvalue(*this, val);
+ H::visit_param(*this, val);
),
(Array,
for(auto& val : e.vals)
- H::visit_lvalue(*this, val);
+ H::visit_param(*this, val);
),
(Variant,
- H::visit_lvalue(*this, e.val);
+ H::visit_param(*this, e.val);
),
(Struct,
for(auto& val : e.vals)
- H::visit_lvalue(*this, val);
+ H::visit_param(*this, val);
)
)
)
@@ -606,7 +628,7 @@ namespace {
)
)
for(auto& arg : te.args)
- H::visit_lvalue(*this, arg);
+ H::visit_param(*this, arg);
)
)
}
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index 1baa48ac..b604b510 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -1083,6 +1083,48 @@ namespace {
)
)
};
+ auto const_to_lit = [&](const ::MIR::Constant& c)->::HIR::Literal {
+ TU_MATCH(::MIR::Constant, (c), (e2),
+ (Int,
+ return ::HIR::Literal(static_cast<uint64_t>(e2));
+ ),
+ (Uint,
+ return ::HIR::Literal(e2);
+ ),
+ (Float,
+ return ::HIR::Literal(e2);
+ ),
+ (Bool,
+ return ::HIR::Literal(static_cast<uint64_t>(e2));
+ ),
+ (Bytes,
+ return ::HIR::Literal::make_String({e2.begin(), e2.end()});
+ ),
+ (StaticString,
+ return ::HIR::Literal(e2);
+ ),
+ (Const,
+ auto ent = get_ent_fullpath(sp, crate, e2.p, EntNS::Value);
+ ASSERT_BUG(sp, ent.is_Constant(), "MIR Constant::Const("<<e2.p<<") didn't point to a Constant - " << ent.tag_str());
+ return clone_literal( ent.as_Constant()->m_value_res );
+ ),
+ (ItemAddr,
+ return ::HIR::Literal::make_BorrowOf( e2.clone() );
+ )
+ )
+ throw "";
+ };
+ auto read_param = [&](const ::MIR::Param& p) ->::HIR::Literal {
+ TU_MATCH(::MIR::Param, (p), (e),
+ (LValue,
+ return read_lval(e);
+ ),
+ (Constant,
+ return const_to_lit(e);
+ )
+ )
+ throw "";
+ };
unsigned int cur_block = 0;
for(;;)
@@ -1105,41 +1147,14 @@ namespace {
val = read_lval(e);
),
(Constant,
- TU_MATCH(::MIR::Constant, (e), (e2),
- (Int,
- val = ::HIR::Literal(static_cast<uint64_t>(e2));
- ),
- (Uint,
- val = ::HIR::Literal(e2);
- ),
- (Float,
- val = ::HIR::Literal(e2);
- ),
- (Bool,
- val = ::HIR::Literal(static_cast<uint64_t>(e2));
- ),
- (Bytes,
- val = ::HIR::Literal::make_String({e2.begin(), e2.end()});
- ),
- (StaticString,
- val = ::HIR::Literal(e2);
- ),
- (Const,
- auto ent = get_ent_fullpath(sp, crate, e2.p, EntNS::Value);
- ASSERT_BUG(sp, ent.is_Constant(), "MIR Constant::Const("<<e2.p<<") didn't point to a Constant - " << ent.tag_str());
- val = clone_literal( ent.as_Constant()->m_value_res );
- ),
- (ItemAddr,
- val = ::HIR::Literal::make_BorrowOf( e2.clone() );
- )
- )
+ val = const_to_lit(e);
),
(SizedArray,
::std::vector< ::HIR::Literal> vals;
if( e.count > 0 )
{
vals.reserve( e.count );
- val = read_lval(e.val);
+ val = read_param(e.val);
for(unsigned int i = 1; i < e.count; i++)
vals.push_back( clone_literal(val) );
vals.push_back( mv$(val) );
@@ -1235,8 +1250,8 @@ namespace {
)
),
(BinOp,
- auto inval_l = read_lval(e.val_l);
- auto inval_r = read_lval(e.val_r);
+ auto inval_l = read_param(e.val_l);
+ auto inval_r = read_param(e.val_r);
ASSERT_BUG(sp, inval_l.tag() == inval_r.tag(), "Mismatched literal types in binop - " << inval_l << " and " << inval_r);
TU_MATCH_DEF( ::HIR::Literal, (inval_l, inval_r), (l, r),
(
@@ -1337,7 +1352,7 @@ namespace {
),
(MakeDst,
auto ptr = read_lval(e.ptr_val);
- auto meta = read_lval(e.meta_val);
+ auto meta = read_param(e.meta_val);
if( ! meta.is_Integer() ) {
TODO(sp, "RValue::MakeDst - (non-integral meta) " << ptr << " , " << meta);
}
@@ -1349,14 +1364,14 @@ namespace {
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
val = ::HIR::Literal::make_List( mv$(vals) );
),
(Array,
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
val = ::HIR::Literal::make_List( mv$(vals) );
),
(Variant,
@@ -1366,7 +1381,7 @@ namespace {
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
val = ::HIR::Literal::make_List( mv$(vals) );
)
)
@@ -1436,7 +1451,7 @@ namespace {
::std::vector< ::HIR::Literal> call_args;
call_args.reserve( e.args.size() );
for(const auto& a : e.args)
- call_args.push_back( read_lval(a) );
+ call_args.push_back( read_param(a) );
// TODO: Set m_const during parse and check here
// Call by invoking evaluate_constant on the function
diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp
index 35ddcb66..4a6fec21 100644
--- a/src/hir_expand/const_eval_full.cpp
+++ b/src/hir_expand/const_eval_full.cpp
@@ -4,6 +4,9 @@
*
* hir_expand/const_eval_full.cpp
* - More-complete constant evaluation
+ *
+ * NOTE: This is run _after_ MIR lowering (not before, as the rest of this
+ * folder is)
*/
#include "main_bindings.hpp"
#include <hir/hir.hpp>
@@ -382,6 +385,56 @@ namespace {
)
)
};
+ auto const_to_lit = [&](const ::MIR::Constant& c)->::HIR::Literal {
+ TU_MATCH(::MIR::Constant, (c), (e2),
+ (Int,
+ return ::HIR::Literal(static_cast<uint64_t>(e2));
+ ),
+ (Uint,
+ return ::HIR::Literal(e2);
+ ),
+ (Float,
+ return ::HIR::Literal(e2);
+ ),
+ (Bool,
+ return ::HIR::Literal(static_cast<uint64_t>(e2));
+ ),
+ (Bytes,
+ return ::HIR::Literal::make_String({e2.begin(), e2.end()});
+ ),
+ (StaticString,
+ return ::HIR::Literal(e2);
+ ),
+ (Const,
+ MonomorphState const_ms;
+ // TODO: Monomorph the path? (Not needed... yet)
+ auto ent = get_ent_fullpath(sp, resolve.m_crate, e2.p, EntNS::Value, const_ms);
+ ASSERT_BUG(sp, ent.is_Constant(), "MIR Constant::Const("<<e2.p<<") didn't point to a Constant - " << ent.tag_str());
+ auto val = clone_literal( ent.as_Constant()->m_value_res );
+ if( val.is_Invalid() ) {
+ return evaluate_constant(sp, resolve, newval_state, FMT_CB(ss, ss << e2.p;), ent.as_Constant()->m_value, {}, {});
+ }
+ // Monomorphise the value according to `const_ms`
+ monomorph_literal_inplace(sp, val, const_ms);
+ return val;
+ ),
+ (ItemAddr,
+ return ::HIR::Literal::make_BorrowOf( ms.monomorph(sp, e2) );
+ )
+ )
+ throw "";
+ };
+ auto read_param = [&](const ::MIR::Param& p) ->::HIR::Literal {
+ TU_MATCH(::MIR::Param, (p), (e),
+ (LValue,
+ return read_lval(e);
+ ),
+ (Constant,
+ return const_to_lit(e);
+ )
+ )
+ throw "";
+ };
unsigned int cur_block = 0;
for(;;)
@@ -405,48 +458,14 @@ namespace {
val = read_lval(e);
),
(Constant,
- TU_MATCH(::MIR::Constant, (e), (e2),
- (Int,
- val = ::HIR::Literal(static_cast<uint64_t>(e2));
- ),
- (Uint,
- val = ::HIR::Literal(e2);
- ),
- (Float,
- val = ::HIR::Literal(e2);
- ),
- (Bool,
- val = ::HIR::Literal(static_cast<uint64_t>(e2));
- ),
- (Bytes,
- val = ::HIR::Literal::make_String({e2.begin(), e2.end()});
- ),
- (StaticString,
- val = ::HIR::Literal(e2);
- ),
- (Const,
- MonomorphState const_ms;
- // TODO: Monomorph the path? (Not needed... yet)
- auto ent = get_ent_fullpath(sp, resolve.m_crate, e2.p, EntNS::Value, const_ms);
- ASSERT_BUG(sp, ent.is_Constant(), "MIR Constant::Const("<<e2.p<<") didn't point to a Constant - " << ent.tag_str());
- val = clone_literal( ent.as_Constant()->m_value_res );
- if( val.is_Invalid() ) {
- val = evaluate_constant(sp, resolve, newval_state, FMT_CB(ss, ss << e2.p;), ent.as_Constant()->m_value, {}, {});
- }
- // Monomorphise the value according to `const_ms`
- monomorph_literal_inplace(sp, val, const_ms);
- ),
- (ItemAddr,
- val = ::HIR::Literal::make_BorrowOf( ms.monomorph(sp, e2) );
- )
- )
+ val = const_to_lit(e);
),
(SizedArray,
::std::vector< ::HIR::Literal> vals;
if( e.count > 0 )
{
vals.reserve( e.count );
- val = read_lval(e.val);
+ val = read_param(e.val);
for(unsigned int i = 1; i < e.count; i++)
vals.push_back( clone_literal(val) );
vals.push_back( mv$(val) );
@@ -557,8 +576,8 @@ namespace {
)
),
(BinOp,
- auto inval_l = read_lval(e.val_l);
- auto inval_r = read_lval(e.val_r);
+ auto inval_l = read_param(e.val_l);
+ auto inval_r = read_param(e.val_r);
ASSERT_BUG(sp, inval_l.tag() == inval_r.tag(), "Mismatched literal types in binop - " << inval_l << " and " << inval_r);
TU_MATCH_DEF( ::HIR::Literal, (inval_l, inval_r), (l, r),
(
@@ -659,7 +678,7 @@ namespace {
),
(MakeDst,
auto ptr = read_lval(e.ptr_val);
- auto meta = read_lval(e.meta_val);
+ auto meta = read_param(e.meta_val);
if( ! meta.is_Integer() ) {
TODO(sp, "RValue::MakeDst - (non-integral meta) " << ptr << " , " << meta);
}
@@ -671,14 +690,14 @@ namespace {
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
val = ::HIR::Literal::make_List( mv$(vals) );
),
(Array,
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
val = ::HIR::Literal::make_List( mv$(vals) );
),
(Variant,
@@ -688,7 +707,7 @@ namespace {
::std::vector< ::HIR::Literal> vals;
vals.reserve( e.vals.size() );
for(const auto& v : e.vals)
- vals.push_back( read_lval(v) );
+ vals.push_back( read_param(v) );
if( e.variant_idx == ~0u )
val = ::HIR::Literal::make_List( mv$(vals) );
else
@@ -725,7 +744,7 @@ namespace {
::std::vector< ::HIR::Literal> call_args;
call_args.reserve( e.args.size() );
for(const auto& a : e.args)
- call_args.push_back( read_lval(a) );
+ call_args.push_back( read_param(a) );
// TODO: Set m_const during parse and check here
// Call by invoking evaluate_constant on the function
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index ae2887e0..62e06d51 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -301,6 +301,13 @@ void MIR_Validate_ValState(::MIR::TypeResolve& state, const ::MIR::Function& fcn
mark_validity(state, lv, false);
}
}
+ void move_val(const ::MIR::TypeResolve& state, const ::MIR::Param& p)
+ {
+ if( const auto* e = p.opt_LValue() )
+ {
+ move_val(state, *e);
+ }
+ }
private:
static bool merge_state(State& a, State& b)
{
@@ -720,6 +727,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
// TODO: Check suitability of source type (COMPLEX)
),
(BinOp,
+ #if 0
::HIR::TypeRef tmp_l, tmp_r;
const auto& ty_l = state.get_lvalue_type(tmp_l, e.val_l);
const auto& ty_r = state.get_lvalue_type(tmp_r, e.val_r);
@@ -734,6 +742,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
if( ty_l != ty_r )
MIR_BUG(state, "Type mismatch in binop, " << ty_l << " != " << ty_r);
}
+ #endif
// TODO: Check return type
),
(UniOp,
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index 53d1c17b..c9dba9bd 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -207,7 +207,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
const auto& vals = lit.as_List();
MIR_ASSERT(state, vals.size() == te.size(), "Literal size mismatched with tuple size");
- ::std::vector< ::MIR::LValue> lvals;
+ ::std::vector< ::MIR::Param> lvals;
lvals.reserve( vals.size() );
for(unsigned int i = 0; i < vals.size(); i ++)
@@ -245,7 +245,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
}
else
{
- ::std::vector< ::MIR::LValue> lvals;
+ ::std::vector< ::MIR::Param> lvals;
lvals.reserve( vals.size() );
for(const auto& val: vals)
@@ -265,7 +265,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
auto monomorph = [&](const auto& tpl) { return monomorphise_type(state.sp, str.m_params, te.path.m_data.as_Generic().m_params, tpl); };
- ::std::vector< ::MIR::LValue> lvals;
+ ::std::vector< ::MIR::Param> lvals;
TU_MATCHA( (str.m_data), (se),
(Unit,
MIR_ASSERT(state, vals.size() == 0, "Values passed for unit struct");
@@ -298,7 +298,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
auto monomorph = [&](const auto& tpl) { return monomorphise_type(state.sp, enm.m_params, te.path.m_data.as_Generic().m_params, tpl); };
- ::std::vector< ::MIR::LValue> lvals;
+ ::std::vector< ::MIR::Param> lvals;
MIR_ASSERT(state, lit_var.idx < enm.m_variants.size(), "Variant index out of range");
TU_MATCHA( (enm.m_variants[lit_var.idx].second), (ve),
(Unit,
@@ -487,7 +487,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
const auto& str = *te.binding.as_Struct();
::HIR::TypeRef tmp;
auto monomorph = [&](const auto& t) { return monomorphise_type(Span(), str.m_params, ty_path.m_params, t); };
- ::std::vector< ::MIR::LValue> vals;
+ ::std::vector< ::MIR::Param> vals;
TU_MATCHA( (str.m_data), (se),
(Unit,
),
@@ -732,7 +732,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
auto monomorph_cb_s = monomorphise_type_get_cb(state.sp, nullptr, &ste.path.m_data.as_Generic().m_params, nullptr);
// - Destructure and restrucure with the unsized fields
- ::std::vector<::MIR::LValue> ents;
+ ::std::vector<::MIR::Param> ents;
TU_MATCHA( (str.m_data), (se),
(Unit,
MIR_BUG(state, "Unit-like struct CoerceUnsized is impossible - " << src_ty);
@@ -904,6 +904,17 @@ void MIR_Cleanup_LValue(const ::MIR::TypeResolve& state, MirMutator& mutator, ::
}
}
}
+void MIR_Cleanup_Param(const ::MIR::TypeResolve& state, MirMutator& mutator, ::MIR::Param& p)
+{
+ TU_MATCHA( (p), (e),
+ (LValue,
+ MIR_Cleanup_LValue(state, mutator, e);
+ ),
+ (Constant,
+ // NOTE: No cleanup
+ )
+ )
+}
void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type)
{
@@ -941,7 +952,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
(Constant,
),
(SizedArray,
- MIR_Cleanup_LValue(state, mutator, re.val);
+ MIR_Cleanup_Param(state, mutator, re.val);
),
(Borrow,
MIR_Cleanup_LValue(state, mutator, re.val);
@@ -950,8 +961,8 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
MIR_Cleanup_LValue(state, mutator, re.val);
),
(BinOp,
- MIR_Cleanup_LValue(state, mutator, re.val_l);
- MIR_Cleanup_LValue(state, mutator, re.val_r);
+ MIR_Cleanup_Param(state, mutator, re.val_l);
+ MIR_Cleanup_Param(state, mutator, re.val_r);
),
(UniOp,
MIR_Cleanup_LValue(state, mutator, re.val);
@@ -987,22 +998,22 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
),
(MakeDst,
MIR_Cleanup_LValue(state, mutator, re.ptr_val);
- MIR_Cleanup_LValue(state, mutator, re.meta_val);
+ MIR_Cleanup_Param(state, mutator, re.meta_val);
),
(Tuple,
for(auto& lv : re.vals)
- MIR_Cleanup_LValue(state, mutator, lv);
+ MIR_Cleanup_Param(state, mutator, lv);
),
(Array,
for(auto& lv : re.vals)
- MIR_Cleanup_LValue(state, mutator, lv);
+ MIR_Cleanup_Param(state, mutator, lv);
),
(Variant,
- MIR_Cleanup_LValue(state, mutator, re.val);
+ MIR_Cleanup_Param(state, mutator, re.val);
),
(Struct,
for(auto& lv : re.vals)
- MIR_Cleanup_LValue(state, mutator, lv);
+ MIR_Cleanup_Param(state, mutator, lv);
)
)
)
@@ -1103,7 +1114,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
MIR_Cleanup_LValue(state, mutator, e.fcn.as_Value());
}
for(auto& lv : e.args)
- MIR_Cleanup_LValue(state, mutator, lv);
+ MIR_Cleanup_Param(state, mutator, lv);
)
)
@@ -1125,7 +1136,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
)
)
{
- auto tgt_lvalue = MIR_Cleanup_Virtualize(sp, state, mutator, e.args.front(), te, pe);
+ auto tgt_lvalue = MIR_Cleanup_Virtualize(sp, state, mutator, e.args.front().as_LValue(), te, pe);
e.fcn = mv$(tgt_lvalue);
}
}
@@ -1137,8 +1148,8 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
if( pe.trait.m_path == resolve.m_lang_Fn || pe.trait.m_path == resolve.m_lang_FnMut || pe.trait.m_path == resolve.m_lang_FnOnce )
{
MIR_ASSERT(state, e.args.size() == 2, "Fn* call requires two arguments");
- auto fcn_lvalue = mv$(e.args[0]);
- auto args_lvalue = mv$(e.args[1]);
+ auto fcn_lvalue = mv$(e.args[0].as_LValue());
+ auto args_lvalue = mv$(e.args[1].as_LValue());
DEBUG("Convert function pointer call");
diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp
index bbacbbf3..1342e086 100644
--- a/src/mir/dump.cpp
+++ b/src/mir/dump.cpp
@@ -193,38 +193,51 @@ namespace {
)
)
}
+ void fmt_val(::std::ostream& os, const ::MIR::Constant& e) {
+ TU_MATCHA( (e), (ce),
+ (Int,
+ os << ce;
+ ),
+ (Uint,
+ os << "0x" << ::std::hex << ce << ::std::dec;
+ ),
+ (Float,
+ os << ce;
+ ),
+ (Bool,
+ os << (ce ? "true" : "false");
+ ),
+ (Bytes,
+ os << "b\"" << ce << "\"";
+ ),
+ (StaticString,
+ os << "\"" << ce << "\"";
+ ),
+ (Const,
+ os << ce.p;
+ ),
+ (ItemAddr,
+ os << "addr " << ce;
+ )
+ )
+ }
+ void fmt_val(::std::ostream& os, const ::MIR::Param& param) {
+ TU_MATCHA( (param), (e),
+ (LValue,
+ fmt_val(os, e);
+ ),
+ (Constant,
+ fmt_val(os, e);
+ )
+ )
+ }
void fmt_val(::std::ostream& os, const ::MIR::RValue& rval) {
TU_MATCHA( (rval), (e),
(Use,
fmt_val(os, e);
),
(Constant,
- TU_MATCHA( (e), (ce),
- (Int,
- os << ce;
- ),
- (Uint,
- os << "0x" << ::std::hex << ce << ::std::dec;
- ),
- (Float,
- os << ce;
- ),
- (Bool,
- os << (ce ? "true" : "false");
- ),
- (Bytes,
- os << "b\"" << ce << "\"";
- ),
- (StaticString,
- os << "\"" << ce << "\"";
- ),
- (Const,
- os << ce.p;
- ),
- (ItemAddr,
- os << "addr " << ce;
- )
- )
+ fmt_val(os, e);
),
(SizedArray,
os << "[";
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 40e43f3b..36d3adc4 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1434,7 +1434,7 @@ namespace {
m_builder.end_block(::MIR::Terminator::make_Call({
place_raw__ok, place_raw__panic,
place_raw.clone(), mv$(fcn_path),
- ::make_vec1( mv$(place_refmut) )
+ ::make_vec1( ::MIR::Param(mv$(place_refmut)) )
}));
}
@@ -1471,7 +1471,7 @@ namespace {
m_builder.end_block(::MIR::Terminator::make_Call({
res__ok, res__panic,
res.clone(), mv$(finalize_path),
- ::make_vec1( mv$(place) )
+ ::make_vec1( ::MIR::Param(mv$(place)) )
}));
// TODO: Proper panic handling, including scope destruction
@@ -1488,7 +1488,7 @@ namespace {
{
const Span& sp = node.span();
TRACE_FUNCTION_F("_TupleVariant");
- ::std::vector< ::MIR::LValue> values;
+ ::std::vector< ::MIR::Param> values;
values.reserve( node.m_args.size() );
for(auto& arg : node.m_args)
{
@@ -1517,16 +1517,15 @@ namespace {
}) );
}
- void visit(::HIR::ExprNode_CallPath& node) override
+ ::std::vector< ::MIR::Param> get_args(/*const*/ ::std::vector<::HIR::ExprNodeP>& args)
{
- TRACE_FUNCTION_F("_CallPath " << node.m_path);
- ::std::vector< ::MIR::LValue> values;
- values.reserve( node.m_args.size() );
- for(auto& arg : node.m_args)
+ ::std::vector< ::MIR::Param> values;
+ values.reserve( args.size() );
+ for(auto& arg : args)
{
this->visit_node_ptr(arg);
- if( node.m_args.size() == 1 )
+ if( args.size() == 1 )
{
values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type, /*allow_missing_value=*/true) );
}
@@ -1541,9 +1540,18 @@ namespace {
values.push_back( mv$(tmp) );
}
- m_builder.moved_lvalue( arg->span(), values.back() );
+ if(const auto* e = values.back().opt_LValue() )
+ {
+ m_builder.moved_lvalue( arg->span(), *e );
+ }
}
+ return values;
+ }
+ void visit(::HIR::ExprNode_CallPath& node) override
+ {
+ TRACE_FUNCTION_F("_CallPath " << node.m_path);
+ auto values = get_args(node.m_args);
auto panic_block = m_builder.new_bb_unlinked();
auto next_block = m_builder.new_bb_unlinked();
@@ -1616,14 +1624,7 @@ namespace {
this->visit_node_ptr(node.m_value);
auto fcn_val = m_builder.get_result_in_lvalue( node.m_value->span(), node.m_value->m_res_type );
- ::std::vector< ::MIR::LValue> values;
- values.reserve( node.m_args.size() );
- for(auto& arg : node.m_args)
- {
- this->visit_node_ptr(arg);
- values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type) );
- m_builder.moved_lvalue( arg->span(), values.back() );
- }
+ auto values = get_args(node.m_args);
auto panic_block = m_builder.new_bb_unlinked();
@@ -1924,7 +1925,7 @@ namespace {
const ::HIR::t_struct_fields& fields = *fields_ptr;
::std::vector<bool> values_set;
- ::std::vector< ::MIR::LValue> values;
+ ::std::vector< ::MIR::Param> values;
values.resize( fields.size() );
values_set.resize( fields.size() );
@@ -1982,7 +1983,7 @@ namespace {
void visit(::HIR::ExprNode_Tuple& node) override
{
TRACE_FUNCTION_F("_Tuple");
- ::std::vector< ::MIR::LValue> values;
+ ::std::vector< ::MIR::Param> values;
values.reserve( node.m_vals.size() );
for(auto& arg : node.m_vals)
{
@@ -1998,7 +1999,7 @@ namespace {
void visit(::HIR::ExprNode_ArrayList& node) override
{
TRACE_FUNCTION_F("_ArrayList");
- ::std::vector< ::MIR::LValue> values;
+ ::std::vector< ::MIR::Param> values;
values.reserve( node.m_vals.size() );
for(auto& arg : node.m_vals)
{
@@ -2027,7 +2028,7 @@ namespace {
{
TRACE_FUNCTION_F("_Closure - " << node.m_obj_path);
- ::std::vector< ::MIR::LValue> vals;
+ ::std::vector< ::MIR::Param> vals;
vals.reserve( node.m_captures.size() );
for(auto& arg : node.m_captures)
{
diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp
index 157071c7..aab0c53f 100644
--- a/src/mir/mir.cpp
+++ b/src/mir/mir.cpp
@@ -50,11 +50,11 @@ namespace MIR {
)
return os;
}
- bool operator==(const Constant& a, const Constant& b)
+ bool Constant::operator==(const Constant& b) const
{
- if( a.tag() != b.tag() )
+ if( this->tag() != b.tag() )
return false;
- TU_MATCHA( (a,b), (ae,be),
+ TU_MATCHA( (*this,b), (ae,be),
(Int,
return ae == be;
),
@@ -207,6 +207,33 @@ namespace MIR {
throw "";
}
+ ::std::ostream& operator<<(::std::ostream& os, const Param& x)
+ {
+ TU_MATCHA( (x), (e),
+ (LValue,
+ os << e;
+ ),
+ (Constant,
+ os << e;
+ )
+ )
+ return os;
+ }
+ bool Param::operator==(const Param& x) const
+ {
+ if( this->tag() != x.tag() )
+ return false;
+ TU_MATCHA( (*this, x), (ea, eb),
+ (LValue,
+ return ea == eb;
+ ),
+ (Constant,
+ return ea == eb;
+ )
+ )
+ throw "";
+ }
+
::std::ostream& operator<<(::std::ostream& os, const RValue& x)
{
TU_MATCHA( (x), (e),
@@ -445,6 +472,33 @@ namespace MIR {
)
throw "";
}
+::MIR::Constant MIR::Constant::clone() const
+{
+ TU_MATCHA( (*this), (e2),
+ (Int, return ::MIR::Constant(e2); ),
+ (Uint, return ::MIR::Constant(e2); ),
+ (Float, return ::MIR::Constant(e2); ),
+ (Bool, return ::MIR::Constant(e2); ),
+ (Bytes, return ::MIR::Constant(e2); ),
+ (StaticString, return ::MIR::Constant(e2); ),
+ (Const, return ::MIR::Constant::make_Const({e2.p.clone()}); ),
+ (ItemAddr, return ::MIR::Constant(e2.clone()); )
+ )
+ throw "";
+}
+
+::MIR::Param MIR::Param::clone() const
+{
+ TU_MATCHA( (*this), (e),
+ (LValue,
+ return e.clone();
+ ),
+ (Constant,
+ return e.clone();
+ )
+ )
+ throw "";
+}
::MIR::RValue MIR::RValue::clone() const
{
@@ -453,16 +507,7 @@ namespace MIR {
return ::MIR::RValue(e.clone());
),
(Constant,
- TU_MATCHA( (e), (e2),
- (Int, return ::MIR::Constant(e2); ),
- (Uint, return ::MIR::Constant(e2); ),
- (Float, return ::MIR::Constant(e2); ),
- (Bool, return ::MIR::Constant(e2); ),
- (Bytes, return ::MIR::Constant(e2); ),
- (StaticString, return ::MIR::Constant(e2); ),
- (Const, return ::MIR::Constant::make_Const({e2.p.clone()}); ),
- (ItemAddr, return ::MIR::Constant(e2.clone()); )
- )
+ return e.clone();
),
(SizedArray,
return ::MIR::RValue::make_SizedArray({ e.val.clone(), e.count });
@@ -490,7 +535,7 @@ namespace MIR {
return ::MIR::RValue::make_MakeDst({ e.ptr_val.clone(), e.meta_val.clone() });
),
(Tuple,
- ::std::vector<::MIR::LValue> ret;
+ decltype(e.vals) ret;
ret.reserve(e.vals.size());
for(const auto& v : e.vals)
ret.push_back( v.clone() );
@@ -498,7 +543,7 @@ namespace MIR {
),
// Array literal
(Array,
- ::std::vector<::MIR::LValue> ret;
+ decltype(e.vals) ret;
ret.reserve(e.vals.size());
for(const auto& v : e.vals)
ret.push_back( v.clone() );
@@ -510,7 +555,7 @@ namespace MIR {
),
// Create a new instance of a struct (or enum)
(Struct,
- ::std::vector<::MIR::LValue> ret;
+ decltype(e.vals) ret;
ret.reserve(e.vals.size());
for(const auto& v : e.vals)
ret.push_back( v.clone() );
diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp
index 00cfcf8f..94eaa973 100644
--- a/src/mir/mir.hpp
+++ b/src/mir/mir.hpp
@@ -90,7 +90,7 @@ enum class eUniOp
};
// Compile-time known values
-TAGGED_UNION(Constant, Int,
+TAGGED_UNION_EX(Constant, (), Int, (
(Int, ::std::int64_t),
(Uint, ::std::uint64_t),
(Float, double),
@@ -99,18 +99,36 @@ TAGGED_UNION(Constant, Int,
(StaticString, ::std::string), // String
(Const, struct { ::HIR::Path p; }), // `const`
(ItemAddr, ::HIR::Path) // address of a value
- );
-extern ::std::ostream& operator<<(::std::ostream& os, const Constant& v);
-extern bool operator==(const Constant& a, const Constant& b);
-static inline bool operator!=(const Constant& a, const Constant& b) {
- return !(a == b);
-}
+ ), (), (), (
+ friend ::std::ostream& operator<<(::std::ostream& os, const Constant& v);
+ bool operator==(const Constant& b) const;
+ inline bool operator!=(const Constant& b) const {
+ return !(*this == b);
+ }
+ Constant clone() const;
+ )
+);
+
+/// Parameter - A value used when a rvalue just reads (doesn't require a lvalue)
+/// Can be either a lvalue (memory address), or a constant
+TAGGED_UNION_EX(Param, (), LValue, (
+ (LValue, LValue),
+ (Constant, Constant)
+ ), (), (), (
+ Param clone() const;
+ friend ::std::ostream& operator<<(::std::ostream& os, const Param& v);
+ bool operator==(const Param& b) const;
+ inline bool operator!=(const Param& b) const {
+ return !(*this == b);
+ }
+ )
+);
TAGGED_UNION_EX(RValue, (), Use, (
(Use, LValue),
(Constant, Constant),
(SizedArray, struct {
- LValue val;
+ Param val;
unsigned int count;
}),
(Borrow, struct {
@@ -125,13 +143,13 @@ TAGGED_UNION_EX(RValue, (), Use, (
}),
// Binary operation on primitives
(BinOp, struct {
- LValue val_l;
+ Param val_l;
eBinOp op;
- LValue val_r;
+ Param val_r;
}),
// Unary operation on primitives
(UniOp, struct {
- LValue val;
+ LValue val; // NOTE: Not a param, because UniOps can be const propagated
eUniOp op;
}),
// Extract the metadata from a DST pointer
@@ -145,27 +163,27 @@ TAGGED_UNION_EX(RValue, (), Use, (
}),
// Construct a DST pointer from a thin pointer and metadata
(MakeDst, struct {
- LValue ptr_val;
- LValue meta_val;
+ LValue ptr_val; // NOTE: Not a Param, becuase the pointer is a borrow
+ Param meta_val;
}),
(Tuple, struct {
- ::std::vector<LValue> vals;
+ ::std::vector<Param> vals;
}),
// Array literal
(Array, struct {
- ::std::vector<LValue> vals;
+ ::std::vector<Param> vals;
}),
// Create a new instance of a union (and eventually enum)
(Variant, struct {
::HIR::GenericPath path;
unsigned int index;
- LValue val;
+ Param val;
}),
// Create a new instance of a struct (or enum)
(Struct, struct {
::HIR::GenericPath path;
unsigned int variant_idx; // if ~0, it's a struct
- ::std::vector<LValue> vals;
+ ::std::vector<Param> vals;
})
), (),(), (
RValue clone() const;
@@ -206,7 +224,7 @@ TAGGED_UNION(Terminator, Incomplete,
BasicBlockId panic_block;
LValue ret_val;
CallTarget fcn;
- ::std::vector<LValue> args;
+ ::std::vector<Param> args;
})
);
extern ::std::ostream& operator<<(::std::ostream& os, const Terminator& x);
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 16b0fd80..110d87e3 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -186,6 +186,11 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal
ASSERT_BUG(sp, dst.tag() != ::MIR::LValue::TAGDEAD, "");
ASSERT_BUG(sp, val.tag() != ::MIR::RValue::TAGDEAD, "");
+ auto moved_param = [&](const ::MIR::Param& p) {
+ if(const auto* e = p.opt_LValue()) {
+ this->moved_lvalue(sp, *e);
+ }
+ };
TU_MATCHA( (val), (e),
(Use,
this->moved_lvalue(sp, e);
@@ -193,7 +198,7 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal
(Constant,
),
(SizedArray,
- this->moved_lvalue(sp, e.val);
+ moved_param(e.val);
),
(Borrow,
if( e.type == ::HIR::BorrowType::Owned ) {
@@ -220,8 +225,8 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal
// Takes an implicit borrow... and only works on copy, so why is this block here?
break;
default:
- this->moved_lvalue(sp, e.val_l);
- this->moved_lvalue(sp, e.val_r);
+ moved_param(e.val_l);
+ moved_param(e.val_r);
break;
}
),
@@ -236,22 +241,22 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal
),
(MakeDst,
// Doesn't move ptr_val
- this->moved_lvalue(sp, e.meta_val);
+ moved_param(e.meta_val);
),
(Tuple,
for(const auto& val : e.vals)
- this->moved_lvalue(sp, val);
+ moved_param(val);
),
(Array,
for(const auto& val : e.vals)
- this->moved_lvalue(sp, val);
+ moved_param(val);
),
(Variant,
- this->moved_lvalue(sp, e.val);
+ moved_param(e.val);
),
(Struct,
for(const auto& val : e.vals)
- this->moved_lvalue(sp, val);
+ moved_param(val);
)
)
@@ -453,6 +458,10 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::LValue& val, const
}
void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, const ScopeHandle& scope)
{
+ auto raise_vars = [&](const ::MIR::Param& p) {
+ if( const auto* e = p.opt_LValue() )
+ this->raise_variables(sp, *e, scope);
+ };
TU_MATCHA( (rval), (e),
(Use,
this->raise_variables(sp, e, scope);
@@ -460,7 +469,7 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, cons
(Constant,
),
(SizedArray,
- this->raise_variables(sp, e.val, scope);
+ raise_vars(e.val);
),
(Borrow,
// TODO: Wait, is this valid?
@@ -470,8 +479,8 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, cons
this->raise_variables(sp, e.val, scope);
),
(BinOp,
- this->raise_variables(sp, e.val_l, scope);
- this->raise_variables(sp, e.val_r, scope);
+ raise_vars(e.val_l);
+ raise_vars(e.val_r);
),
(UniOp,
this->raise_variables(sp, e.val, scope);
@@ -484,22 +493,22 @@ void MirBuilder::raise_variables(const Span& sp, const ::MIR::RValue& rval, cons
),
(MakeDst,
this->raise_variables(sp, e.ptr_val, scope);
- this->raise_variables(sp, e.meta_val, scope);
+ raise_vars(e.meta_val);
),
(Tuple,
for(const auto& val : e.vals)
- this->raise_variables(sp, val, scope);
+ raise_vars(val);
),
(Array,
for(const auto& val : e.vals)
- this->raise_variables(sp, val, scope);
+ raise_vars(val);
),
(Variant,
- this->raise_variables(sp, e.val, scope);
+ raise_vars(e.val);
),
(Struct,
for(const auto& val : e.vals)
- this->raise_variables(sp, val, scope);
+ raise_vars(val);
)
)
}
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index a60d2e32..c7c4e6d7 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -82,6 +82,29 @@ namespace {
return visit_mir_lvalue_mut( const_cast<::MIR::LValue&>(lv), u, [&](auto& v, auto u) { return cb(v,u); } );
}
+ bool visit_mir_lvalue_mut(::MIR::Param& p, ValUsage u, ::std::function<bool(::MIR::LValue& , ValUsage)> cb)
+ {
+ if( auto* e = p.opt_LValue() )
+ {
+ return visit_mir_lvalue_mut(*e, u, cb);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ bool visit_mir_lvalue(const ::MIR::Param& p, ValUsage u, ::std::function<bool(const ::MIR::LValue& , ValUsage)> cb)
+ {
+ if( const auto* e = p.opt_LValue() )
+ {
+ return visit_mir_lvalue(*e, u, cb);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
bool visit_mir_lvalues_mut(::MIR::RValue& rval, ::std::function<bool(::MIR::LValue& , ValUsage)> cb)
{
bool rv = false;
@@ -751,7 +774,7 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
this->bb_base + se.panic_block,
this->clone_lval(se.ret_val),
mv$(tgt),
- this->clone_lval_vec(se.args)
+ this->clone_param_vec(se.args)
});
)
)
@@ -773,6 +796,14 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
rv.push_back( this->clone_lval(lv) );
return rv;
}
+ ::std::vector<::MIR::Param> clone_param_vec(const ::std::vector<::MIR::Param>& src) const
+ {
+ ::std::vector<::MIR::Param> rv;
+ rv.reserve(src.size());
+ for(const auto& lv : src)
+ rv.push_back( this->clone_param(lv) );
+ return rv;
+ }
::MIR::LValue clone_lval(const ::MIR::LValue& src) const
{
TU_MATCHA( (src), (se),
@@ -783,7 +814,9 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return ::MIR::LValue::make_Temporary({se.idx + this->tmp_base});
),
(Argument,
- return this->te.args.at(se.idx).clone();
+ // TODO: If this argument is a literal, need to allocate a
+ // tmep for it
+ return this->te.args.at(se.idx).as_LValue().clone();
),
(Return,
return this->te.ret_val.clone();
@@ -791,7 +824,6 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
(Static,
return this->monomorph( se );
),
-
(Deref,
return ::MIR::LValue::make_Deref({ box$(this->clone_lval(*se.val)) });
),
@@ -810,6 +842,32 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
)
throw "";
}
+ ::MIR::Constant clone_constant(const ::MIR::Constant& src) const
+ {
+ TU_MATCHA( (src), (ce),
+ (Int , return ::MIR::Constant(ce);),
+ (Uint , return ::MIR::Constant(ce);),
+ (Float, return ::MIR::Constant(ce);),
+ (Bool , return ::MIR::Constant(ce);),
+ (Bytes, return ::MIR::Constant(ce);),
+ (StaticString, return ::MIR::Constant(ce);),
+ (Const,
+ return ::MIR::Constant::make_Const({ this->monomorph(ce.p) });
+ ),
+ (ItemAddr,
+ return ::MIR::Constant::make_ItemAddr(this->monomorph(ce));
+ )
+ )
+ throw "";
+ }
+ ::MIR::Param clone_param(const ::MIR::Param& src) const
+ {
+ TU_MATCHA( (src), (se),
+ (LValue, return clone_lval(se);),
+ (Constant, return clone_constant(se); )
+ )
+ throw "";
+ }
::MIR::RValue clone_rval(const ::MIR::RValue& src) const
{
TU_MATCHA( (src), (se),
@@ -817,23 +875,10 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return ::MIR::RValue( this->clone_lval(se) );
),
(Constant,
- TU_MATCHA( (se), (ce),
- (Int , return ::MIR::Constant(ce);),
- (Uint , return ::MIR::Constant(ce);),
- (Float, return ::MIR::Constant(ce);),
- (Bool , return ::MIR::Constant(ce);),
- (Bytes, return ::MIR::Constant(ce);),
- (StaticString, return ::MIR::Constant(ce);),
- (Const,
- return ::MIR::Constant::make_Const({ this->monomorph(ce.p) });
- ),
- (ItemAddr,
- return ::MIR::Constant::make_ItemAddr(this->monomorph(ce));
- )
- )
+ return this->clone_constant(se);
),
(SizedArray,
- return ::MIR::RValue::make_SizedArray({ this->clone_lval(se.val), se.count });
+ return ::MIR::RValue::make_SizedArray({ this->clone_param(se.val), se.count });
),
(Borrow,
// TODO: Region IDs
@@ -843,7 +888,7 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return ::MIR::RValue::make_Cast({ this->clone_lval(se.val), this->monomorph(se.type) });
),
(BinOp,
- return ::MIR::RValue::make_BinOp({ this->clone_lval(se.val_l), se.op, this->clone_lval(se.val_r) });
+ return ::MIR::RValue::make_BinOp({ this->clone_param(se.val_l), se.op, this->clone_param(se.val_r) });
),
(UniOp,
return ::MIR::RValue::make_UniOp({ this->clone_lval(se.val), se.op });
@@ -855,19 +900,19 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return ::MIR::RValue::make_DstPtr({ this->clone_lval(se.val) });
),
(MakeDst,
- return ::MIR::RValue::make_MakeDst({ this->clone_lval(se.ptr_val), this->clone_lval(se.meta_val) });
+ return ::MIR::RValue::make_MakeDst({ this->clone_lval(se.ptr_val), this->clone_param(se.meta_val) });
),
(Tuple,
- return ::MIR::RValue::make_Tuple({ this->clone_lval_vec(se.vals) });
+ return ::MIR::RValue::make_Tuple({ this->clone_param_vec(se.vals) });
),
(Array,
- return ::MIR::RValue::make_Array({ this->clone_lval_vec(se.vals) });
+ return ::MIR::RValue::make_Array({ this->clone_param_vec(se.vals) });
),
(Variant,
- return ::MIR::RValue::make_Variant({ this->monomorph(se.path), se.index, this->clone_lval(se.val) });
+ return ::MIR::RValue::make_Variant({ this->monomorph(se.path), se.index, this->clone_param(se.val) });
),
(Struct,
- return ::MIR::RValue::make_Struct({ this->monomorph(se.path), se.variant_idx, this->clone_lval_vec(se.vals) });
+ return ::MIR::RValue::make_Struct({ this->monomorph(se.path), se.variant_idx, this->clone_param_vec(se.vals) });
)
)
throw "";
@@ -1055,6 +1100,12 @@ bool MIR_Optimise_UnifyTemporaries(::MIR::TypeResolve& state, ::MIR::Function& f
mark_validity(mir_res, lv, false);
}
}
+ void move_val(const ::MIR::TypeResolve& mir_res, const ::MIR::Param& p) {
+ if(const auto* e = p.opt_LValue())
+ {
+ move_val(mir_res, *e);
+ }
+ }
};
::std::vector<State> block_states( fcn.blocks.size() );
::std::vector< ::std::pair<unsigned int, State> > to_visit;
@@ -1486,7 +1537,10 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
else if( tef.name == "bswap" && tef.params.m_types.at(0) == ::HIR::CoreType::U8 )
{
DEBUG("bswap<u8> is a no-op");
- bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), mv$(te.args.at(0)) }));
+ if( auto* e = te.args.at(0).opt_LValue() )
+ bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), mv$(*e) }));
+ else
+ bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), mv$(te.args.at(0).as_Constant()) }));
bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block);
changed = true;
}
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 3ae69ba7..4b7d6a72 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -1398,178 +1398,28 @@ namespace {
emit_lvalue(ve);
),
(Constant,
- TU_MATCHA( (ve), (c),
- (Int,
- emit_lvalue(e.dst);
- m_of << " = ";
- if( c == INT64_MIN )
- m_of << "INT64_MIN";
- else
- m_of << c;
- ),
- (Uint,
- ::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, e.dst);
- emit_lvalue(e.dst);
- m_of << " = ";
- switch(ty.m_data.as_Primitive())
- {
- case ::HIR::CoreType::U8:
- m_of << ::std::hex << "0x" << (c & 0xFF) << ::std::dec;
- break;
- case ::HIR::CoreType::U16:
- m_of << ::std::hex << "0x" << (c & 0xFFFF) << ::std::dec;
- break;
- case ::HIR::CoreType::U32:
- m_of << ::std::hex << "0x" << (c & 0xFFFFFFFF) << ::std::dec;
- break;
- case ::HIR::CoreType::U64:
- case ::HIR::CoreType::U128:
- case ::HIR::CoreType::Usize:
- m_of << ::std::hex << "0x" << c << ::std::dec;
- break;
- case ::HIR::CoreType::Char:
- assert(0 <= c && c <= 0x10FFFF);
- if( c < 256 ) {
- m_of << c;
- }
- else {
- m_of << ::std::hex << "0x" << c << ::std::dec;
- }
- break;
- default:
- MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << ty);
- }
- ),
- (Float,
- emit_lvalue(e.dst);
- m_of << " = ";
- if( ::std::isnan(c) ) {
- m_of << "NAN";
- }
- else if( ::std::isinf(c) ) {
- m_of << "INFINITY";
- }
- else {
- m_of << c;
- }
- ),
- (Bool,
- emit_lvalue(e.dst);
- m_of << " = ";
- m_of << (c ? "true" : "false");
- ),
- (Bytes,
- ::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, e.dst);
- MIR_ASSERT(mir_res, ty.m_data.is_Borrow(), "Const::Bytes returning non-borrow - " << ty);
- if( ty.m_data.as_Borrow().inner->m_data.is_Array() ) {
- // Array borrow : Cast the C string to the array
- emit_lvalue(e.dst);
- m_of << " = ";
- // - Laziness
- m_of << "(void*)\"" << ::std::oct;
- for(const auto& v : c) {
- if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
- m_of << v;
- else
- m_of << "\\" << (unsigned int)v;
- }
- m_of << "\"" << ::std::dec;
- }
- else {
- // Slice borrow (asumed), pointer and metadata
- emit_lvalue(e.dst);
- m_of << ".PTR = ";
- m_of << "\"" << ::std::oct;
- for(const auto& v : c) {
- if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
- m_of << v;
- else
- m_of << "\\" << (unsigned int)v;
- }
- m_of << "\"" << ::std::dec;
- m_of << ";\n\t";
- emit_lvalue(e.dst);
- m_of << ".META = " << c.size();
- }
- ),
- (StaticString,
- emit_lvalue(e.dst);
- m_of << ".PTR = ";
- m_of << "\"" << ::std::oct;
- for(const auto& v : c) {
- if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
- m_of << v;
- else
- m_of << "\\" << (unsigned int)v;
- }
- m_of << "\"" << ::std::dec;
-
- m_of << ";\n\t";
- emit_lvalue(e.dst);
- m_of << ".META = " << c.size();
- ),
- (Const,
- // TODO: This should have been eliminated?
- ::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, e.dst);
- const auto& lit = get_literal_for_const(c.p);
- assign_from_literal([&](){ emit_lvalue(e.dst); }, ty, lit);
- ),
- (ItemAddr,
- emit_lvalue(e.dst);
- m_of << " = ";
- TU_MATCHA( (c.m_data), (pe),
- (Generic,
- if( pe.m_path.m_components.size() > 1 && m_crate.get_typeitem_by_path(sp, pe.m_path, false, true).is_Enum() )
- ;
- else
- {
- const auto& vi = m_crate.get_valitem_by_path(sp, pe.m_path);
- if( vi.is_Function() || vi.is_StructConstructor() )
- {
- }
- else
- {
- m_of << "&";
- }
- }
- ),
- (UfcsUnknown,
- MIR_BUG(*m_mir_res, "UfcsUnknown in trans " << c);
- ),
- (UfcsInherent,
- // TODO: If the target is a function, don't emit the &
- m_of << "&";
- ),
- (UfcsKnown,
- // TODO: If the target is a function, don't emit the &
- m_of << "&";
- )
- )
- m_of << Trans_Mangle(c);
- )
- )
+ emit_lvalue(e.dst);
+ m_of << " = ";
+ emit_constant(ve, &e.dst);
),
(SizedArray,
if( ve.count == 0 ) {
}
else if( ve.count == 1 ) {
- emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_lvalue(ve.val);
+ emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_param(ve.val);
}
else if( ve.count == 2 ) {
- emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_lvalue(ve.val); m_of << ";\n\t";
- emit_lvalue(e.dst); m_of << ".DATA[1] = "; emit_lvalue(ve.val);
+ emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_param(ve.val); m_of << ";\n\t";
+ emit_lvalue(e.dst); m_of << ".DATA[1] = "; emit_param(ve.val);
}
else if( ve.count == 3 ) {
- emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_lvalue(ve.val); m_of << ";\n\t";
- emit_lvalue(e.dst); m_of << ".DATA[1] = "; emit_lvalue(ve.val); m_of << ";\n\t";
- emit_lvalue(e.dst); m_of << ".DATA[2] = "; emit_lvalue(ve.val);
+ emit_lvalue(e.dst); m_of << ".DATA[0] = "; emit_param(ve.val); m_of << ";\n\t";
+ emit_lvalue(e.dst); m_of << ".DATA[1] = "; emit_param(ve.val); m_of << ";\n\t";
+ emit_lvalue(e.dst); m_of << ".DATA[2] = "; emit_param(ve.val);
}
else {
m_of << "for(unsigned int i = 0; i < " << ve.count << "; i ++)\n";
- m_of << "\t\t"; emit_lvalue(e.dst); m_of << ".DATA[i] = "; emit_lvalue(ve.val);
+ m_of << "\t\t"; emit_lvalue(e.dst); m_of << ".DATA[i] = "; emit_param(ve.val);
}
),
(Borrow,
@@ -1648,10 +1498,11 @@ namespace {
(BinOp,
emit_lvalue(e.dst);
m_of << " = ";
+ MIR_ASSERT(mir_res, ve.val_l.is_LValue() || ve.val_r.is_LValue(), "");
::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, ve.val_l);
+ const auto& ty = mir_res.get_lvalue_type(tmp, ve.val_l.is_LValue() ? ve.val_l.as_LValue() : ve.val_r.as_LValue());
if( ty.m_data.is_Borrow() ) {
- m_of << "(slice_cmp("; emit_lvalue(ve.val_l); m_of << ", "; emit_lvalue(ve.val_r); m_of << ")";
+ m_of << "(slice_cmp("; emit_param(ve.val_l); m_of << ", "; emit_param(ve.val_r); m_of << ")";
switch(ve.op)
{
case ::MIR::eBinOp::EQ: m_of << " == 0"; break;
@@ -1672,12 +1523,12 @@ namespace {
switch(ve.op)
{
case ::MIR::eBinOp::EQ:
- emit_lvalue(ve.val_l); m_of << ".PTR == "; emit_lvalue(ve.val_r); m_of << ".PTR && ";
- emit_lvalue(ve.val_l); m_of << ".META == "; emit_lvalue(ve.val_r); m_of << ".META";
+ emit_param(ve.val_l); m_of << ".PTR == "; emit_param(ve.val_r); m_of << ".PTR && ";
+ emit_param(ve.val_l); m_of << ".META == "; emit_param(ve.val_r); m_of << ".META";
break;
case ::MIR::eBinOp::NE:
- emit_lvalue(ve.val_l); m_of << ".PTR != "; emit_lvalue(ve.val_r); m_of << ".PTR || ";
- emit_lvalue(ve.val_l); m_of << ".META != "; emit_lvalue(ve.val_r); m_of << ".META";
+ emit_param(ve.val_l); m_of << ".PTR != "; emit_param(ve.val_r); m_of << ".PTR || ";
+ emit_param(ve.val_l); m_of << ".META != "; emit_param(ve.val_r); m_of << ".META";
break;
default:
MIR_BUG(mir_res, "Unknown comparison of a *-ptr - " << e.src << " with " << ty);
@@ -1685,7 +1536,7 @@ namespace {
}
else
{
- emit_lvalue(ve.val_l);
+ emit_param(ve.val_l);
switch(ve.op)
{
case ::MIR::eBinOp::EQ: m_of << " == "; break;
@@ -1697,7 +1548,7 @@ namespace {
default:
MIR_BUG(mir_res, "Unknown comparison of a *-ptr - " << e.src << " with " << ty);
}
- emit_lvalue(ve.val_r);
+ emit_param(ve.val_r);
}
break;
}
@@ -1706,13 +1557,13 @@ namespace {
m_of << "remainderf";
else
m_of << "remainder";
- m_of << "("; emit_lvalue(ve.val_l); m_of << ", "; emit_lvalue(ve.val_r); m_of << ")";
+ m_of << "("; emit_param(ve.val_l); m_of << ", "; emit_param(ve.val_r); m_of << ")";
break;
}
else {
}
- emit_lvalue(ve.val_l);
+ emit_param(ve.val_l);
switch(ve.op)
{
case ::MIR::eBinOp::ADD: m_of << " + "; break;
@@ -1740,7 +1591,7 @@ namespace {
MIR_TODO(mir_res, "Overflow");
break;
}
- emit_lvalue(ve.val_r);
+ emit_param(ve.val_r);
),
(UniOp,
::HIR::TypeRef tmp;
@@ -1777,21 +1628,21 @@ namespace {
m_of << ";\n\t";
emit_lvalue(e.dst);
m_of << ".META = ";
- emit_lvalue(ve.meta_val);
+ emit_param(ve.meta_val);
),
(Tuple,
for(unsigned int j = 0; j < ve.vals.size(); j ++) {
if( j != 0 ) m_of << ";\n\t";
emit_lvalue(e.dst);
m_of << "._" << j << " = ";
- emit_lvalue(ve.vals[j]);
+ emit_param(ve.vals[j]);
}
),
(Array,
for(unsigned int j = 0; j < ve.vals.size(); j ++) {
if( j != 0 ) m_of << ";\n\t";
emit_lvalue(e.dst); m_of << ".DATA[" << j << "] = ";
- emit_lvalue(ve.vals[j]);
+ emit_param(ve.vals[j]);
}
),
(Variant,
@@ -1805,7 +1656,7 @@ namespace {
emit_lvalue(e.dst); m_of << ".TAG = " << ve.index << ";\n\t";
emit_lvalue(e.dst); m_of << ".DATA";
}
- m_of << ".var_" << ve.index << " = "; emit_lvalue(ve.val);
+ m_of << ".var_" << ve.index << " = "; emit_param(ve.val);
),
(Struct,
if(ve.variant_idx != ~0u) {
@@ -1822,7 +1673,7 @@ namespace {
else if( ve.variant_idx == 1 ) {
emit_lvalue(e.dst);
m_of << "._0 = ";
- emit_lvalue(ve.vals[0]);
+ emit_param(ve.vals[0]);
}
else {
}
@@ -1840,7 +1691,7 @@ namespace {
{
// HACK: Don't emit assignment of PhantomData
::HIR::TypeRef tmp;
- if( m_resolve.is_type_phantom_data( mir_res.get_lvalue_type(tmp, ve.vals[j])) )
+ if( ve.vals[j].is_LValue() && m_resolve.is_type_phantom_data( mir_res.get_lvalue_type(tmp, ve.vals[j].as_LValue())) )
continue ;
if( j != 0 ) m_of << ";\n\t";
@@ -1848,7 +1699,7 @@ namespace {
if(ve.variant_idx != ~0u)
m_of << ".DATA.var_" << ve.variant_idx;
m_of << "._" << j << " = ";
- emit_lvalue(ve.vals[j]);
+ emit_param(ve.vals[j]);
}
)
)
@@ -1971,7 +1822,7 @@ namespace {
m_of << "(";
for(unsigned int j = 0; j < e.args.size(); j ++) {
if(j != 0) m_of << ",";
- m_of << " "; emit_lvalue(e.args[j]);
+ m_of << " "; emit_param(e.args[j]);
}
m_of << " );\n";
m_of << "\tgoto bb" << e.ret_block << ";\n";
@@ -2063,17 +1914,17 @@ namespace {
}
};
auto emit_atomic_cxchg = [&](const auto& e, const char* o_succ, const char* o_fail, bool is_weak) {
- emit_lvalue(e.ret_val); m_of << "._0 = "; emit_lvalue(e.args.at(1)); m_of << ";\n\t";
+ emit_lvalue(e.ret_val); m_of << "._0 = "; emit_param(e.args.at(1)); m_of << ";\n\t";
emit_lvalue(e.ret_val); m_of << "._1 = atomic_compare_exchange_" << (is_weak ? "weak" : "strong") << "_explicit(";
- m_of << "(_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_lvalue(e.args.at(0));
+ m_of << "(_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_param(e.args.at(0));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << "._0";
- m_of << ", "; emit_lvalue(e.args.at(2));
+ m_of << ", "; emit_param(e.args.at(2));
m_of << ", "<<o_succ<<", "<<o_fail<<")";
};
auto emit_atomic_arith = [&](const char* name, const char* ordering) {
emit_lvalue(e.ret_val); m_of << " = atomic_" << name << "_explicit";
- m_of <<"((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ m_of <<"((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", " << ordering << ")";
};
if( name == "size_of" ) {
@@ -2096,19 +1947,19 @@ namespace {
if( ! ty.m_data.is_Slice() ) {
m_of << "sizeof("; emit_ctype(ty); m_of << ") + ";
}
- emit_lvalue(e.args.at(0)); m_of << ".META * sizeof("; emit_ctype(*te->inner); m_of << ")";
+ emit_param(e.args.at(0)); m_of << ".META * sizeof("; emit_ctype(*te->inner); m_of << ")";
}
else if( inner_ty == ::HIR::CoreType::Str ) {
if( ! ty.m_data.is_Primitive() ) {
m_of << "sizeof("; emit_ctype(ty); m_of << ") + ";
}
- emit_lvalue(e.args.at(0)); m_of << ".META";
+ emit_param(e.args.at(0)); m_of << ".META";
}
else if( inner_ty.m_data.is_TraitObject() ) {
if( ! ty.m_data.is_TraitObject() ) {
m_of << "sizeof("; emit_ctype(ty); m_of << ") + ";
}
- m_of << "((VTABLE_HDR*)"; emit_lvalue(e.args.at(0)); m_of << ".META)->size";
+ m_of << "((VTABLE_HDR*)"; emit_param(e.args.at(0)); m_of << ".META)->size";
}
else {
MIR_BUG(mir_res, "Unknown inner unsized type " << inner_ty << " for " << ty);
@@ -2122,10 +1973,10 @@ namespace {
case MetadataType::Slice: {
// TODO: Have a function that fetches the inner type for types like `Path` or `str`
const auto& ity = *ty.m_data.as_Slice().inner;
- emit_lvalue(e.args.at(0)); m_of << ".META * sizeof("; emit_ctype(ity); m_of << ")";
+ emit_param(e.args.at(0)); m_of << ".META * sizeof("; emit_ctype(ity); m_of << ")";
break; }
case MetadataType::TraitObject:
- m_of << "((VTABLE_HDR*)"; emit_lvalue(e.args.at(0)); m_of << ".META)->size";
+ m_of << "((VTABLE_HDR*)"; emit_param(e.args.at(0)); m_of << ".META)->size";
break;
}
#endif
@@ -2159,7 +2010,7 @@ namespace {
if( ! ty.m_data.is_TraitObject() ) {
m_of << "max( __alignof__("; emit_ctype(ty); m_of << "), ";
}
- m_of << "((VTABLE_HDR*)"; emit_lvalue(e.args.at(0)); m_of << ".META)->align";
+ m_of << "((VTABLE_HDR*)"; emit_param(e.args.at(0)); m_of << ".META)->align";
if( ! ty.m_data.is_TraitObject() ) {
m_of << " )";
}
@@ -2179,7 +2030,7 @@ namespace {
m_of << "__alignof__("; emit_ctype(ity); m_of << ")";
break; }
case MetadataType::TraitObject:
- m_of << "((VTABLE_HDR*)"; emit_lvalue(e.args.at(0)); m_of << ".META)->align";
+ m_of << "((VTABLE_HDR*)"; emit_param(e.args.at(0)); m_of << ".META)->align";
break;
}
#endif
@@ -2195,7 +2046,7 @@ namespace {
emit_lvalue(e.ret_val); m_of << ".META = " << s.size() << "";
}
else if( name == "transmute" ) {
- m_of << "memcpy( &"; emit_lvalue(e.ret_val); m_of << ", &"; emit_lvalue(e.args.at(0)); m_of << ", sizeof("; emit_ctype(params.m_types.at(0)); m_of << "))";
+ m_of << "memcpy( &"; emit_lvalue(e.ret_val); m_of << ", &"; emit_param(e.args.at(0)); m_of << ", sizeof("; emit_ctype(params.m_types.at(0)); m_of << "))";
}
else if( name == "copy_nonoverlapping" || name == "copy" ) {
if( name == "copy" ) {
@@ -2205,23 +2056,23 @@ namespace {
m_of << "memcpy";
}
// 0: Source, 1: Destination, 2: Count
- m_of << "( "; emit_lvalue(e.args.at(1));
- m_of << ", "; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(2)); m_of << " * sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")";
+ m_of << "( "; emit_param(e.args.at(1));
+ m_of << ", "; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(2)); m_of << " * sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")";
m_of << ")";
}
else if( name == "write_bytes" ) {
// 0: Destination, 1: Value, 2: Count
- m_of << "memset( "; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
- m_of << ", "; emit_lvalue(e.args.at(2)); m_of << " * sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")";
+ m_of << "memset( "; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
+ m_of << ", "; emit_param(e.args.at(2)); m_of << " * sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")";
m_of << ")";
}
else if( name == "forget" ) {
// Nothing needs to be done, this just stops the destructor from running.
}
else if( name == "drop_in_place" ) {
- emit_destructor_call( ::MIR::LValue::make_Deref({ box$(e.args.at(0).clone()) }), params.m_types.at(0), true );
+ emit_destructor_call( ::MIR::LValue::make_Deref({ box$(e.args.at(0).as_LValue().clone()) }), params.m_types.at(0), true );
}
else if( name == "needs_drop" ) {
// Returns `true` if the actual type given as `T` requires drop glue;
@@ -2244,19 +2095,19 @@ namespace {
m_of << "memset( &"; emit_lvalue(e.ret_val); m_of << ", 0, sizeof("; emit_ctype(params.m_types.at(0)); m_of << "))";
}
else if( name == "move_val_init" ) {
- m_of << "*"; emit_lvalue(e.args.at(0)); m_of << " = "; emit_lvalue(e.args.at(1));
+ m_of << "*"; emit_param(e.args.at(0)); m_of << " = "; emit_param(e.args.at(1));
}
else if( name == "abort" ) {
m_of << "abort()";
}
else if( name == "try" ) {
- emit_lvalue(e.args.at(0)); m_of << "("; emit_lvalue(e.args.at(1)); m_of << ")";
+ emit_param(e.args.at(0)); m_of << "("; emit_param(e.args.at(1)); m_of << ")";
}
else if( name == "offset" ) {
- emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " + "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << " = "; emit_param(e.args.at(0)); m_of << " + "; emit_param(e.args.at(1));
}
else if( name == "arith_offset" ) {
- emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " + "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << " = "; emit_param(e.args.at(0)); m_of << " + "; emit_param(e.args.at(1));
}
else if( name == "bswap" ) {
const auto& ty = params.m_types.at(0);
@@ -2264,19 +2115,19 @@ namespace {
switch( ty.m_data.as_Primitive() )
{
case ::HIR::CoreType::U8:
- emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0));
+ emit_lvalue(e.ret_val); m_of << " = "; emit_param(e.args.at(0));
break;
case ::HIR::CoreType::U16:
- emit_lvalue(e.ret_val); m_of << " = __builtin_bswap16("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = __builtin_bswap16("; emit_param(e.args.at(0)); m_of << ")";
break;
case ::HIR::CoreType::U32:
- emit_lvalue(e.ret_val); m_of << " = __builtin_bswap32("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = __builtin_bswap32("; emit_param(e.args.at(0)); m_of << ")";
break;
case ::HIR::CoreType::U64:
- emit_lvalue(e.ret_val); m_of << " = __builtin_bswap64("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = __builtin_bswap64("; emit_param(e.args.at(0)); m_of << ")";
break;
case ::HIR::CoreType::U128:
- emit_lvalue(e.ret_val); m_of << " = __builtin_bswap128("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = __builtin_bswap128("; emit_param(e.args.at(0)); m_of << ")";
break;
default:
MIR_TODO(mir_res, "bswap<" << ty << ">");
@@ -2290,11 +2141,11 @@ namespace {
auto it = m_enum_repr_cache.find( ty.m_data.as_Path().path.m_data.as_Generic() );
if( it != m_enum_repr_cache.end() )
{
- emit_lvalue(e.args.at(0)); emit_nonzero_path(it->second); m_of << " != 0";
+ emit_param(e.args.at(0)); emit_nonzero_path(it->second); m_of << " != 0";
}
else
{
- emit_lvalue(e.args.at(0)); m_of << "->TAG";
+ emit_param(e.args.at(0)); m_of << "->TAG";
}
}
else {
@@ -2315,56 +2166,56 @@ namespace {
// Overflowing Arithmatic
// HACK: Uses GCC intrinsics
else if( name == "add_with_overflow" ) {
- emit_lvalue(e.ret_val); m_of << "._1 = __builtin_add_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << "._1 = __builtin_add_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << "._0)";
}
else if( name == "sub_with_overflow" ) {
- emit_lvalue(e.ret_val); m_of << "._1 = __builtin_sub_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << "._1 = __builtin_sub_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << "._0)";
}
else if( name == "mul_with_overflow" ) {
- emit_lvalue(e.ret_val); m_of << "._1 = __builtin_mul_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << "._1 = __builtin_mul_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << "._0)";
}
else if( name == "overflowing_add" ) {
- m_of << "__builtin_add_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ m_of << "__builtin_add_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << ")";
}
else if( name == "overflowing_sub" ) {
- m_of << "__builtin_sub_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ m_of << "__builtin_sub_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << ")";
}
else if( name == "overflowing_mul" ) {
- m_of << "__builtin_mul_overflow("; emit_lvalue(e.args.at(0));
- m_of << ", "; emit_lvalue(e.args.at(1));
+ m_of << "__builtin_mul_overflow("; emit_param(e.args.at(0));
+ m_of << ", "; emit_param(e.args.at(1));
m_of << ", &"; emit_lvalue(e.ret_val); m_of << ")";
}
// Unchecked Arithmatic
else if( name == "unchecked_div" ) {
- emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " / "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << " = "; emit_param(e.args.at(0)); m_of << " / "; emit_param(e.args.at(1));
}
else if( name == "unchecked_rem" ) {
- emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " % "; emit_lvalue(e.args.at(1));
+ emit_lvalue(e.ret_val); m_of << " = "; emit_param(e.args.at(0)); m_of << " % "; emit_param(e.args.at(1));
}
// Bit Twiddling
// - CounT Leading Zeroes
// - CounT Trailing Zeroes
else if( name == "ctlz" || name == "cttz" ) {
- auto emit_arg0 = [&](){ emit_lvalue(e.args.at(0)); };
+ auto emit_arg0 = [&](){ emit_param(e.args.at(0)); };
const auto& ty = params.m_types.at(0);
- emit_lvalue(e.ret_val); m_of << " = ("; emit_lvalue(e.args.at(0)); m_of << " != 0 ? ";
+ emit_lvalue(e.ret_val); m_of << " = ("; emit_param(e.args.at(0)); m_of << " != 0 ? ";
if( ty == ::HIR::CoreType::U128 )
{
if( name == "ctlz" ) {
- m_of << "__builtin_clz128("; emit_lvalue(e.args.at(0)); m_of << ")";
+ m_of << "__builtin_clz128("; emit_param(e.args.at(0)); m_of << ")";
}
else {
- m_of << "__builtin_ctz128("; emit_lvalue(e.args.at(0)); m_of << ")";
+ m_of << "__builtin_ctz128("; emit_param(e.args.at(0)); m_of << ")";
}
}
else if( ty == ::HIR::CoreType::U64 || (ty == ::HIR::CoreType::Usize /*&& target_is_64_bit */) )
@@ -2379,74 +2230,74 @@ namespace {
else
{
if( name == "ctlz" ) {
- m_of << "__builtin_clz("; emit_lvalue(e.args.at(0)); m_of << ")";
+ m_of << "__builtin_clz("; emit_param(e.args.at(0)); m_of << ")";
}
else {
- m_of << "__builtin_ctz("; emit_lvalue(e.args.at(0)); m_of << ")";
+ m_of << "__builtin_ctz("; emit_param(e.args.at(0)); m_of << ")";
}
}
m_of << " : sizeof("; emit_ctype(ty); m_of << ")*8)";
}
// - CounT POPulated
else if( name == "ctpop" ) {
- emit_lvalue(e.ret_val); m_of << " = __builtin_popcount("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = __builtin_popcount("; emit_param(e.args.at(0)); m_of << ")";
}
// --- Floating Point
// > Round to nearest integer, half-way rounds away from zero
else if( name == "roundf32" && name == "roundf64" ) {
- emit_lvalue(e.ret_val); m_of << " = round" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = round" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "fabsf32" || name == "fabsf64" ) {
- emit_lvalue(e.ret_val); m_of << " = fabs" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = fabs" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "copysignf32" || name == "copysignf64" ) {
- emit_lvalue(e.ret_val); m_of << " = copysign" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = copysign" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ")";
}
// > Returns the integer part of an `f32`.
else if( name == "truncf32" || name == "truncf64" ) {
- emit_lvalue(e.ret_val); m_of << " = trunc" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = trunc" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "powif32" || name == "powif64" ) {
- emit_lvalue(e.ret_val); m_of << " = pow" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = pow" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ")";
}
else if( name == "powf32" || name == "powf64" ) {
- emit_lvalue(e.ret_val); m_of << " = pow" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = pow" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ")";
}
else if( name == "expf32" || name == "expf64" ) {
- emit_lvalue(e.ret_val); m_of << " = exp" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = exp" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "exp2f32" || name == "exp2f64" ) {
- emit_lvalue(e.ret_val); m_of << " = exp2" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = exp2" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "logf32" || name == "logf64" ) {
- emit_lvalue(e.ret_val); m_of << " = log" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = log" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "log10f32" || name == "log10f64" ) {
- emit_lvalue(e.ret_val); m_of << " = log10" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = log10" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "log2f32" || name == "log2f64" ) {
- emit_lvalue(e.ret_val); m_of << " = log2" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = log2" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "sqrtf32" || name == "sqrtf64" ) {
- emit_lvalue(e.ret_val); m_of << " = sqrt" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = sqrt" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "ceilf32" || name == "ceilf64" ) {
- emit_lvalue(e.ret_val); m_of << " = ceil" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = ceil" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "floorf32" || name == "floorf64" ) {
- emit_lvalue(e.ret_val); m_of << " = floor" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = floor" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "roundf32" || name == "roundf64" ) {
- emit_lvalue(e.ret_val); m_of << " = round" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = round" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "cosf32" || name == "cosf64" ) {
- emit_lvalue(e.ret_val); m_of << " = cos" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = cos" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "sinf32" || name == "sinf64" ) {
- emit_lvalue(e.ret_val); m_of << " = sin" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = sin" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ")";
}
else if( name == "fmaf32" || name == "fmaf64" ) {
- emit_lvalue(e.ret_val); m_of << " = fma" << (name.back()=='2'?"f":"") << "("; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ")";
+ emit_lvalue(e.ret_val); m_of << " = fma" << (name.back()=='2'?"f":"") << "("; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ", "; emit_param(e.args.at(1)); m_of << ")";
}
// --- Atomics!
// > Single-ordering atomics
@@ -2472,11 +2323,11 @@ namespace {
}
else if( name == "atomic_load" || name.compare(0, 7+4+1, "atomic_load_") == 0 ) {
auto ordering = H::get_atomic_ordering(mir_res, name, 7+4+1);
- emit_lvalue(e.ret_val); m_of << " = atomic_load_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_lvalue(e.args.at(0)); m_of << ", " << ordering << ")";
+ emit_lvalue(e.ret_val); m_of << " = atomic_load_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_param(e.args.at(0)); m_of << ", " << ordering << ")";
}
else if( name == "atomic_store" || name.compare(0, 7+5+1, "atomic_store_") == 0 ) {
auto ordering = H::get_atomic_ordering(mir_res, name, 7+5+1);
- m_of << "atomic_store_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ", " << ordering << ")";
+ m_of << "atomic_store_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ", " << ordering << ")";
}
// Comare+Exchange (has two orderings)
else if( name == "atomic_cxchg_acq_failrelaxed" ) {
@@ -2517,7 +2368,7 @@ namespace {
}
else if( name == "atomic_xchg" || name.compare(0, 7+5, "atomic_xchg_") == 0 ) {
auto ordering = H::get_atomic_ordering(mir_res, name, 7+5);
- emit_lvalue(e.ret_val); m_of << " = atomic_exchange_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_lvalue(e.args.at(0)); m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ", " << ordering << ")";
+ emit_lvalue(e.ret_val); m_of << " = atomic_exchange_explicit((_Atomic "; emit_ctype(params.m_types.at(0)); m_of << "*)"; emit_param(e.args.at(0)); m_of << ", "; emit_param(e.args.at(1)); m_of << ", " << ordering << ")";
}
else if( name == "atomic_fence" || name.compare(0, 7+6, "atomic_fence_") == 0 ) {
auto ordering = H::get_atomic_ordering(mir_res, name, 7+6);
@@ -2614,13 +2465,15 @@ namespace {
)
}
- const ::HIR::Literal& get_literal_for_const(const ::HIR::Path& path)
+ const ::HIR::Literal& get_literal_for_const(const ::HIR::Path& path, ::HIR::TypeRef& ty)
{
TU_MATCHA( (path.m_data), (pe),
(Generic,
if( pe.m_params.m_types.size() > 0 )
MIR_TODO(*m_mir_res, "get_literal_for_const - Paths with generics " << path);
- return m_crate.get_constant_by_path(Span(), pe.m_path).m_value_res;
+ const auto& c = m_crate.get_constant_by_path(Span(), pe.m_path);
+ ty = c.m_type.clone();
+ return c.m_value_res;
),
(UfcsUnknown,
MIR_BUG(*m_mir_res, "get_literal_for_const - UfcsUnknown " << path);
@@ -2931,6 +2784,153 @@ namespace {
)
)
}
+ void emit_constant(const ::MIR::Constant& ve, const ::MIR::LValue* dst_ptr=nullptr)
+ {
+ TU_MATCHA( (ve), (c),
+ (Int,
+ if( c == INT64_MIN )
+ m_of << "INT64_MIN";
+ else
+ m_of << c;
+ ),
+ (Uint,
+ ::HIR::TypeRef tmp;
+ const auto& ty = dst_ptr ? m_mir_res->get_lvalue_type(tmp, *dst_ptr) : tmp = ::HIR::CoreType::U128;
+ switch(ty.m_data.as_Primitive())
+ {
+ case ::HIR::CoreType::U8:
+ m_of << ::std::hex << "0x" << (c & 0xFF) << ::std::dec;
+ break;
+ case ::HIR::CoreType::U16:
+ m_of << ::std::hex << "0x" << (c & 0xFFFF) << ::std::dec;
+ break;
+ case ::HIR::CoreType::U32:
+ m_of << ::std::hex << "0x" << (c & 0xFFFFFFFF) << ::std::dec;
+ break;
+ case ::HIR::CoreType::U64:
+ case ::HIR::CoreType::U128:
+ case ::HIR::CoreType::Usize:
+ m_of << ::std::hex << "0x" << c << ::std::dec;
+ break;
+ case ::HIR::CoreType::Char:
+ assert(0 <= c && c <= 0x10FFFF);
+ if( c < 256 ) {
+ m_of << c;
+ }
+ else {
+ m_of << ::std::hex << "0x" << c << ::std::dec;
+ }
+ break;
+ default:
+ MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << ty);
+ }
+ ),
+ (Float,
+ if( ::std::isnan(c) ) {
+ m_of << "NAN";
+ }
+ else if( ::std::isinf(c) ) {
+ m_of << "INFINITY";
+ }
+ else {
+ m_of << c;
+ }
+ ),
+ (Bool,
+ m_of << (c ? "true" : "false");
+ ),
+ (Bytes,
+ // TODO: Need to know the desired value for this
+ // - Ideally, Bytes would always return a thin pointer (and
+ // be combined with a MakeDST to make a fat pointer)
+ ::HIR::TypeRef tmp;
+ const auto& ty = dst_ptr ? m_mir_res->get_lvalue_type(tmp, *dst_ptr) : tmp = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Shared, ::HIR::CoreType::U8);
+ MIR_ASSERT(*m_mir_res, ty.m_data.is_Borrow(), "Const::Bytes returning non-borrow - " << ty);
+ if( !dst_ptr || ty.m_data.as_Borrow().inner->m_data.is_Array() ) {
+ // Array borrow : Cast the C string to the array
+ // - Laziness
+ m_of << "(void*)\"" << ::std::oct;
+ for(const auto& v : c) {
+ if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
+ m_of << v;
+ else
+ m_of << "\\" << (unsigned int)v;
+ }
+ m_of << "\"" << ::std::dec;
+ }
+ else {
+ // Slice borrow (asumed), pointer and metadata
+ m_of << "make_sliceptr(\"" << ::std::oct;
+ for(const auto& v : c) {
+ if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
+ m_of << v;
+ else
+ m_of << "\\" << (unsigned int)v;
+ }
+ m_of << "\", " << ::std::dec << c.size() << ")";
+ }
+ ),
+ (StaticString,
+ m_of << "make_sliceptr(\"" << ::std::oct;
+ for(const auto& v : c) {
+ if( ' ' <= v && v < 0x7F && v != '"' && v != '\\' )
+ m_of << v;
+ else
+ m_of << "\\" << (unsigned int)v;
+ }
+ m_of << "\", " << ::std::dec << c.size() << ")";
+ ),
+ (Const,
+ // TODO: This should have been eliminated?
+ ::HIR::TypeRef ty;
+ const auto& lit = get_literal_for_const(c.p, ty);
+ m_of << "({"; emit_ctype(ty, FMT_CB(ss, ss<<"v";)); m_of << ";";
+ assign_from_literal([&](){ m_of << "v"; }, ty, lit);
+ m_of << "v})";
+ ),
+ (ItemAddr,
+ TU_MATCHA( (c.m_data), (pe),
+ (Generic,
+ if( pe.m_path.m_components.size() > 1 && m_crate.get_typeitem_by_path(sp, pe.m_path, false, true).is_Enum() )
+ ;
+ else
+ {
+ const auto& vi = m_crate.get_valitem_by_path(sp, pe.m_path);
+ if( vi.is_Function() || vi.is_StructConstructor() )
+ {
+ }
+ else
+ {
+ m_of << "&";
+ }
+ }
+ ),
+ (UfcsUnknown,
+ MIR_BUG(*m_mir_res, "UfcsUnknown in trans " << c);
+ ),
+ (UfcsInherent,
+ // TODO: If the target is a function, don't emit the &
+ m_of << "&";
+ ),
+ (UfcsKnown,
+ // TODO: If the target is a function, don't emit the &
+ m_of << "&";
+ )
+ )
+ m_of << Trans_Mangle(c);
+ )
+ )
+ }
+ void emit_param(const ::MIR::Param& p) {
+ TU_MATCHA( (p), (e),
+ (LValue,
+ emit_lvalue(e);
+ ),
+ (Constant,
+ emit_constant(e);
+ )
+ )
+ }
void emit_ctype(const ::HIR::TypeRef& ty) {
emit_ctype(ty, FMT_CB(_,));
}
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index 8b9fd93b..fceddfbf 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -848,6 +848,17 @@ void Trans_Enumerate_Types(EnumState& state)
)
return blank;
}
+
+ static void visit_param(TypeVisitor& tv, const Trans_Params& pp, const ::HIR::Function& fcn, const ::MIR::Param& p)
+ {
+ TU_MATCHA( (p), (e),
+ (LValue,
+ H::visit_lvalue(tv, pp, fcn, e);
+ ),
+ (Constant,
+ )
+ )
+ }
};
for(const auto& stmt : block.statements)
{
@@ -872,7 +883,7 @@ void Trans_Enumerate_Types(EnumState& state)
(Constant,
),
(SizedArray,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ H::visit_param(tv,pp,fcn, re.val);
),
(Borrow,
H::visit_lvalue(tv,pp,fcn, re.val);
@@ -881,8 +892,8 @@ void Trans_Enumerate_Types(EnumState& state)
H::visit_lvalue(tv,pp,fcn, re.val);
),
(BinOp,
- H::visit_lvalue(tv,pp,fcn, re.val_l);
- H::visit_lvalue(tv,pp,fcn, re.val_l);
+ H::visit_param(tv,pp,fcn, re.val_l);
+ H::visit_param(tv,pp,fcn, re.val_l);
),
(UniOp,
H::visit_lvalue(tv,pp,fcn, re.val);
@@ -895,22 +906,22 @@ void Trans_Enumerate_Types(EnumState& state)
),
(MakeDst,
H::visit_lvalue(tv,pp,fcn, re.ptr_val);
- H::visit_lvalue(tv,pp,fcn, re.meta_val);
+ H::visit_param(tv,pp,fcn, re.meta_val);
),
(Tuple,
for(const auto& v : re.vals)
- H::visit_lvalue(tv,pp,fcn, v);
+ H::visit_param(tv,pp,fcn, v);
),
(Array,
for(const auto& v : re.vals)
- H::visit_lvalue(tv,pp,fcn, v);
+ H::visit_param(tv,pp,fcn, v);
),
(Variant,
- H::visit_lvalue(tv,pp,fcn, re.val);
+ H::visit_param(tv,pp,fcn, re.val);
),
(Struct,
for(const auto& v : re.vals)
- H::visit_lvalue(tv,pp,fcn, v);
+ H::visit_param(tv,pp,fcn, v);
)
)
)
@@ -938,7 +949,7 @@ void Trans_Enumerate_Types(EnumState& state)
}
H::visit_lvalue(tv,pp,fcn, te.ret_val);
for(const auto& arg : te.args)
- H::visit_lvalue(tv,pp,fcn, arg);
+ H::visit_param(tv,pp,fcn, arg);
)
)
}
@@ -1353,6 +1364,30 @@ void Trans_Enumerate_FillFrom_MIR_LValue(EnumState& state, const ::MIR::LValue&
)
)
}
+void Trans_Enumerate_FillFrom_MIR_Constant(EnumState& state, const ::MIR::Constant& c, const Trans_Params& pp)
+{
+ TU_MATCHA( (c), (ce),
+ (Int, ),
+ (Uint,),
+ (Float, ),
+ (Bool, ),
+ (Bytes, ),
+ (StaticString, ), // String
+ (Const,
+ //Trans_Enumerate_FillFrom_Path(state, ce.p, pp);
+ ),
+ (ItemAddr,
+ Trans_Enumerate_FillFrom_Path(state, ce, pp);
+ )
+ )
+}
+void Trans_Enumerate_FillFrom_MIR_Param(EnumState& state, const ::MIR::Param& p, const Trans_Params& pp)
+{
+ TU_MATCHA( (p), (e),
+ (LValue, Trans_Enumerate_FillFrom_MIR_LValue(state, e, pp); ),
+ (Constant, Trans_Enumerate_FillFrom_MIR_Constant(state, e, pp); )
+ )
+}
void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code, const Trans_Params& pp)
{
for(const auto& bb : code.blocks)
@@ -1368,23 +1403,10 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
Trans_Enumerate_FillFrom_MIR_LValue(state, e, pp);
),
(Constant,
- TU_MATCHA( (e), (ce),
- (Int, ),
- (Uint,),
- (Float, ),
- (Bool, ),
- (Bytes, ),
- (StaticString, ), // String
- (Const,
- //Trans_Enumerate_FillFrom_Path(state, ce.p, pp);
- ),
- (ItemAddr,
- Trans_Enumerate_FillFrom_Path(state, ce, pp);
- )
- )
+ Trans_Enumerate_FillFrom_MIR_Constant(state, e, pp);
),
(SizedArray,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val, pp);
),
(Borrow,
Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
@@ -1393,8 +1415,8 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
),
(BinOp,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val_l, pp);
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val_r, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val_l, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val_r, pp);
),
(UniOp,
Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
@@ -1407,22 +1429,22 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
),
(MakeDst,
Trans_Enumerate_FillFrom_MIR_LValue(state, e.ptr_val, pp);
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.meta_val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.meta_val, pp);
),
(Tuple,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_LValue(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
),
(Array,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_LValue(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
),
(Variant,
- Trans_Enumerate_FillFrom_MIR_LValue(state, e.val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, e.val, pp);
),
(Struct,
for(const auto& val : e.vals)
- Trans_Enumerate_FillFrom_MIR_LValue(state, val, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, val, pp);
)
)
),
@@ -1472,7 +1494,7 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
)
)
for(const auto& arg : e.args)
- Trans_Enumerate_FillFrom_MIR_LValue(state, arg, pp);
+ Trans_Enumerate_FillFrom_MIR_Param(state, arg, pp);
)
)
}
diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp
index 3e52dfaf..13819c18 100644
--- a/src/trans/monomorphise.cpp
+++ b/src/trans/monomorphise.cpp
@@ -46,12 +46,68 @@ namespace {
)
throw "";
}
- ::std::vector<::MIR::LValue> monomorph_LValue_list(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::std::vector<::MIR::LValue>& tpl)
+ ::MIR::Constant monomorph_Constant(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::MIR::Constant& tpl)
{
- ::std::vector<::MIR::LValue> rv;
+ TU_MATCHA( (tpl), (ce),
+ (Int,
+ return ::MIR::Constant::make_Int(ce);
+ ),
+ (Uint,
+ return ::MIR::Constant::make_Uint(ce);
+ ),
+ (Float,
+ return ::MIR::Constant::make_Float(ce);
+ ),
+ (Bool,
+ return ::MIR::Constant::make_Bool(ce);
+ ),
+ (Bytes,
+ return ::MIR::Constant(ce);
+ ),
+ (StaticString,
+ return ::MIR::Constant(ce);
+ ),
+ (Const,
+ return ::MIR::Constant::make_Const({
+ params.monomorph(resolve, ce.p)
+ });
+ ),
+ (ItemAddr,
+ auto p = params.monomorph(resolve, ce);
+ // TODO: If this is a pointer to a function on a trait object, replace with the address loaded from the vtable.
+ // - Requires creating a new temporary for the vtable pointer.
+ // - Also requires knowing what the receiver is.
+ return ::MIR::Constant( mv$(p) );
+ )
+ )
+ throw "";
+ }
+ ::MIR::Param monomorph_Param(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::MIR::Param& tpl)
+ {
+ TU_MATCHA( (tpl), (e),
+ (LValue,
+ return monomorph_LValue(resolve, params, e);
+ ),
+ (Constant,
+ return monomorph_Constant(resolve, params, e);
+ )
+ )
+ throw "";
+ }
+ //::std::vector<::MIR::LValue> monomorph_LValue_list(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::std::vector<::MIR::LValue>& tpl)
+ //{
+ // ::std::vector<::MIR::LValue> rv;
+ // rv.reserve( tpl.size() );
+ // for(const auto& v : tpl)
+ // rv.push_back( monomorph_LValue(resolve, params, v) );
+ // return rv;
+ //}
+ ::std::vector<::MIR::Param> monomorph_Param_list(const ::StaticTraitResolve& resolve, const Trans_Params& params, const ::std::vector<::MIR::Param>& tpl)
+ {
+ ::std::vector<::MIR::Param> rv;
rv.reserve( tpl.size() );
for(const auto& v : tpl)
- rv.push_back( monomorph_LValue(resolve, params, v) );
+ rv.push_back( monomorph_Param(resolve, params, v) );
return rv;
}
}
@@ -113,42 +169,11 @@ namespace {
rval = ::MIR::RValue( monomorph_LValue(resolve, params, se) );
),
(Constant,
- TU_MATCHA( (se), (ce),
- (Int,
- rval = ::MIR::Constant::make_Int(ce);
- ),
- (Uint,
- rval = ::MIR::Constant::make_Uint(ce);
- ),
- (Float,
- rval = ::MIR::Constant::make_Float(ce);
- ),
- (Bool,
- rval = ::MIR::Constant::make_Bool(ce);
- ),
- (Bytes,
- rval = ::MIR::Constant(ce);
- ),
- (StaticString,
- rval = ::MIR::Constant(ce);
- ),
- (Const,
- rval = ::MIR::Constant::make_Const({
- params.monomorph(resolve, ce.p)
- });
- ),
- (ItemAddr,
- auto p = params.monomorph(resolve, ce);
- // TODO: If this is a pointer to a function on a trait object, replace with the address loaded from the vtable.
- // - Requires creating a new temporary for the vtable pointer.
- // - Also requires knowing what the receiver is.
- rval = ::MIR::Constant( mv$(p) );
- )
- )
+ rval = monomorph_Constant(resolve, params, se);
),
(SizedArray,
rval = ::MIR::RValue::make_SizedArray({
- monomorph_LValue(resolve, params, se.val),
+ monomorph_Param(resolve, params, se.val),
se.count
});
),
@@ -166,9 +191,9 @@ namespace {
),
(BinOp,
rval = ::MIR::RValue::make_BinOp({
- monomorph_LValue(resolve, params, se.val_l),
+ monomorph_Param(resolve, params, se.val_l),
se.op,
- monomorph_LValue(resolve, params, se.val_r)
+ monomorph_Param(resolve, params, se.val_r)
});
),
(UniOp,
@@ -188,17 +213,17 @@ namespace {
(MakeDst,
rval = ::MIR::RValue::make_MakeDst({
monomorph_LValue(resolve, params, se.ptr_val),
- monomorph_LValue(resolve, params, se.meta_val)
+ monomorph_Param(resolve, params, se.meta_val)
});
),
(Tuple,
rval = ::MIR::RValue::make_Tuple({
- monomorph_LValue_list(resolve, params, se.vals)
+ monomorph_Param_list(resolve, params, se.vals)
});
),
(Array,
rval = ::MIR::RValue::make_Array({
- monomorph_LValue_list(resolve, params, se.vals)
+ monomorph_Param_list(resolve, params, se.vals)
});
),
// Create a new instance of a union (and eventually enum)
@@ -206,7 +231,7 @@ namespace {
rval = ::MIR::RValue::make_Variant({
params.monomorph(resolve, se.path),
se.index,
- monomorph_LValue(resolve, params, se.val)
+ monomorph_Param(resolve, params, se.val)
});
),
// Create a new instance of a struct (or enum)
@@ -214,7 +239,7 @@ namespace {
rval = ::MIR::RValue::make_Struct({
params.monomorph(resolve, se.path),
se.variant_idx,
- monomorph_LValue_list(resolve, params, se.vals)
+ monomorph_Param_list(resolve, params, se.vals)
});
)
)
@@ -283,7 +308,7 @@ namespace {
e.ret_block, e.panic_block,
monomorph_LValue(resolve, params, e.ret_val),
H::monomorph_calltarget(resolve, params, e.fcn),
- monomorph_LValue_list(resolve, params, e.args)
+ monomorph_Param_list(resolve, params, e.args)
});
)
)