diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-02-22 20:45:43 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-02-22 20:45:43 +0800 |
commit | 0b672c4325967ade9a8f9bd8a06071cca09c4276 (patch) | |
tree | a5cc6d90a59a4aa4b06e1a8a77d874670653f94a | |
parent | 1e8376b6bc4289832112a70323f8c1f0f0722392 (diff) | |
download | mrust-0b672c4325967ade9a8f9bd8a06071cca09c4276.tar.gz |
MIR - Add types to integer constants
-rw-r--r-- | src/hir/deserialise.cpp | 19 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 11 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 8 | ||||
-rw-r--r-- | src/hir_expand/const_eval_full.cpp | 8 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 18 | ||||
-rw-r--r-- | src/mir/dump.cpp | 8 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 29 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 100 | ||||
-rw-r--r-- | src/mir/mir.cpp | 18 | ||||
-rw-r--r-- | src/mir/mir.hpp | 19 | ||||
-rw-r--r-- | src/mir/optimise.cpp | 2 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 34 |
12 files changed, 151 insertions, 123 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index c9c94be3..4a9b5720 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -430,10 +430,21 @@ namespace { switch( m_in.read_tag() ) { #define _(x, ...) case ::MIR::Constant::TAG_##x: DEBUG("- " #x); return ::MIR::Constant::make_##x( __VA_ARGS__ ); - _(Int, m_in.read_i64c()) - _(Uint, m_in.read_u64c()) - _(Float, m_in.read_double()) - _(Bool, m_in.read_bool()) + _(Int, { + m_in.read_i64c(), + static_cast< ::HIR::CoreType>(m_in.read_tag()) + }) + _(Uint, { + m_in.read_u64c(), + static_cast< ::HIR::CoreType>(m_in.read_tag()) + }) + _(Float, { + m_in.read_double(), + static_cast< ::HIR::CoreType>(m_in.read_tag()) + }) + _(Bool, { + m_in.read_bool() + }) case ::MIR::Constant::TAG_Bytes: { ::std::vector<unsigned char> bytes; bytes.resize( m_in.read_count() ); diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 5a74e798..81319c2e 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -663,16 +663,19 @@ namespace { m_out.write_tag(v.tag()); TU_MATCHA( (v), (e), (Int, - m_out.write_i64c(e); + m_out.write_i64c(e.v); + m_out.write_tag(static_cast<unsigned>(e.t)); ), (Uint, - m_out.write_u64c(e); + m_out.write_u64c(e.v); + m_out.write_tag(static_cast<unsigned>(e.t)); ), (Float, - m_out.write_double(e); + m_out.write_double(e.v); + m_out.write_tag(static_cast<unsigned>(e.t)); ), (Bool, - m_out.write_bool(e); + m_out.write_bool(e.v); ), (Bytes, m_out.write_count(e.size()); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index be27e0a4..a70840ed 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -1086,16 +1086,16 @@ 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)); + return ::HIR::Literal(static_cast<uint64_t>(e2.v)); ), (Uint, - return ::HIR::Literal(e2); + return ::HIR::Literal(e2.v); ), (Float, - return ::HIR::Literal(e2); + return ::HIR::Literal(e2.v); ), (Bool, - return ::HIR::Literal(static_cast<uint64_t>(e2)); + return ::HIR::Literal(static_cast<uint64_t>(e2.v)); ), (Bytes, return ::HIR::Literal::make_String({e2.begin(), e2.end()}); diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp index a88d6075..a361ce59 100644 --- a/src/hir_expand/const_eval_full.cpp +++ b/src/hir_expand/const_eval_full.cpp @@ -388,16 +388,16 @@ 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)); + return ::HIR::Literal(static_cast<uint64_t>(e2.v)); ), (Uint, - return ::HIR::Literal(e2); + return ::HIR::Literal(e2.v); ), (Float, - return ::HIR::Literal(e2); + return ::HIR::Literal(e2.v); ), (Bool, - return ::HIR::Literal(static_cast<uint64_t>(e2)); + return ::HIR::Literal(static_cast<uint64_t>(e2.v)); ), (Bytes, return ::HIR::Literal::make_String({e2.begin(), e2.end()}); diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 8ab78ab2..a1da936e 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -341,19 +341,19 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR case ::HIR::CoreType::U32: case ::HIR::CoreType::U16: case ::HIR::CoreType::U8: - return ::MIR::Constant::make_Uint( lit.as_Integer() ); + return ::MIR::Constant::make_Uint({ lit.as_Integer(), te }); case ::HIR::CoreType::Isize: case ::HIR::CoreType::I128: case ::HIR::CoreType::I64: case ::HIR::CoreType::I32: case ::HIR::CoreType::I16: case ::HIR::CoreType::I8: - return ::MIR::Constant::make_Int( lit.as_Integer() ); + return ::MIR::Constant::make_Int({ static_cast<int64_t>(lit.as_Integer()), te }); case ::HIR::CoreType::F64: case ::HIR::CoreType::F32: - return ::MIR::Constant::make_Float( lit.as_Float() ); + return ::MIR::Constant::make_Float({ lit.as_Float(), te }); case ::HIR::CoreType::Bool: - return ::MIR::Constant::make_Bool( !!lit.as_Integer() ); + return ::MIR::Constant::make_Bool({ !!lit.as_Integer() }); case ::HIR::CoreType::Str: MIR_BUG(state, "Const of type `str` - " << path); } @@ -365,7 +365,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR MIR_TODO(state, "BorrowOf into pointer - " << lit << " into " << ty); } else { - auto lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint( lit.as_Integer() ) ) ); + auto lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ lit.as_Integer(), ::HIR::CoreType::Usize }) ) ); return ::MIR::RValue::make_Cast({ mv$(lval), mv$(ty) }); } ), @@ -384,7 +384,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR auto ptr_type = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, (&ty == &tmp ? mv$(tmp) : ty.clone()) ); auto ptr_lval = mutator.in_temporary( mv$(ptr_type), ::MIR::Constant::make_ItemAddr(path.clone()) ); - auto size_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint(size) ); + auto size_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ size, ::HIR::CoreType::Usize }) ); return ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }); } else if( const auto* tep = te.inner->m_data.opt_TraitObject() ) @@ -604,7 +604,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator& { const auto& in_array = src_ty.m_data.as_Array(); out_meta_ty = ::HIR::CoreType::Usize; - out_meta_val = ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) ); + out_meta_val = ::MIR::Constant::make_Uint({ static_cast<uint64_t>(in_array.size_val), ::HIR::CoreType::Usize }); return true; } else if( src_ty.m_data.is_Generic() || (src_ty.m_data.is_Path() && src_ty.m_data.as_Path().binding.is_Opaque()) ) @@ -632,7 +632,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator& // - Codegen assumes it's a pointer. if( de.m_trait.m_path.m_path == ::HIR::SimplePath() ) { - auto null_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint(0u) ); + auto null_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ 0u, ::HIR::CoreType::Usize }) ); out_meta_ty = ty_unit_ptr.clone(); out_meta_val = ::MIR::RValue::make_Cast({ mv$(null_lval), mv$(ty_unit_ptr) }); } @@ -987,7 +987,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, BUG(Span(), "Unexpected input type for DstMeta - " << ty); } if( const auto* te = ity_p->m_data.opt_Array() ) { - se.src = ::MIR::Constant::make_Uint( te->size_val ); + se.src = ::MIR::Constant::make_Uint({ te->size_val, ::HIR::CoreType::Usize }); } ), (DstPtr, diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index 1342e086..f3dee478 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -196,16 +196,16 @@ namespace { void fmt_val(::std::ostream& os, const ::MIR::Constant& e) { TU_MATCHA( (e), (ce), (Int, - os << ce; + os << ce.v; ), (Uint, - os << "0x" << ::std::hex << ce << ::std::dec; + os << "0x" << ::std::hex << ce.v << ::std::dec; ), (Float, - os << ce; + os << ce.v; ), (Bool, - os << (ce ? "true" : "false"); + os << (ce.v ? "true" : "false"); ), (Bytes, os << "b\"" << ce << "\""; diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 36d3adc4..0029432f 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -331,7 +331,7 @@ namespace { if( e.extra_bind.is_valid() ) { // 1. Obtain remaining length - auto sub_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_Constant( e.leading.size() + e.trailing.size() )); + auto sub_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ e.leading.size() + e.trailing.size(), ::HIR::CoreType::Usize })); ::MIR::LValue len_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_BinOp({ len_lval.clone(), ::MIR::eBinOp::SUB, mv$(sub_val) }) ); // 2. Obtain pointer to element @@ -934,7 +934,7 @@ namespace { { // If left is true, assign result true and return m_builder.set_cur_block( bb_true ); - m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool(true) )); + m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool({true}) )); m_builder.end_block( ::MIR::Terminator::make_Goto(bb_next) ); // If left is false, assign result to right @@ -944,7 +944,7 @@ namespace { { // If left is false, assign result false and return m_builder.set_cur_block( bb_false ); - m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool(false) )); + m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool({false}) )); m_builder.end_block( ::MIR::Terminator::make_Goto(bb_next) ); // If left is true, assign result to right @@ -1244,7 +1244,7 @@ namespace { if( ty_in.m_data.is_Array() ) { const auto& in_array = ty_in.m_data.as_Array(); - auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) ) ); + auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant::make_Uint({ static_cast<uint64_t>(in_array.size_val), ::HIR::CoreType::Usize } ) ); m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) ); } else if( ty_in.m_data.is_Generic() || (ty_in.m_data.is_Path() && ty_in.m_data.as_Path().binding.is_Opaque()) ) @@ -1294,7 +1294,7 @@ namespace { BUG(node.span(), "Indexing unsupported type " << ty_val); ), (Array, - limit_val = ::MIR::Constant( e.size_val ); + limit_val = ::MIR::Constant::make_Uint({ e.size_val, ::HIR::CoreType::Usize }); ), (Slice, limit_val = ::MIR::RValue::make_DstMeta({ m_builder.get_ptr_to_dst(node.m_value->span(), value).clone() }); @@ -1681,7 +1681,8 @@ namespace { TU_MATCHA( (node.m_data), (e), (Integer, ASSERT_BUG(node.span(), node.m_res_type.m_data.is_Primitive(), "Non-primitive return type for Integer literal - " << node.m_res_type); - switch(node.m_res_type.m_data.as_Primitive()) + auto ity = node.m_res_type.m_data.as_Primitive(); + switch(ity) { case ::HIR::CoreType::U8: case ::HIR::CoreType::U16: @@ -1689,7 +1690,10 @@ namespace { case ::HIR::CoreType::U64: case ::HIR::CoreType::U128: case ::HIR::CoreType::Usize: - m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant(e.m_value) )); + m_builder.set_result(node.span(), ::MIR::Constant::make_Uint({ e.m_value, ity }) ); + break; + case ::HIR::CoreType::Char: + m_builder.set_result(node.span(), ::MIR::Constant::make_Uint({ static_cast<uint64_t>(e.m_value), ity }) ); break; case ::HIR::CoreType::I8: case ::HIR::CoreType::I16: @@ -1697,20 +1701,19 @@ namespace { case ::HIR::CoreType::I64: case ::HIR::CoreType::I128: case ::HIR::CoreType::Isize: - m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant( static_cast<int64_t>(e.m_value) ) )); - break; - case ::HIR::CoreType::Char: - m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant( static_cast<uint64_t>(e.m_value) ) )); + m_builder.set_result(node.span(), ::MIR::Constant::make_Int({ static_cast<int64_t>(e.m_value), ity }) ); break; default: BUG(node.span(), "Integer literal with unexpected type - " << node.m_res_type); } ), (Float, - m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e.m_value) )); + ASSERT_BUG(node.span(), node.m_res_type.m_data.is_Primitive(), "Non-primitive return type for Float literal - " << node.m_res_type); + auto ity = node.m_res_type.m_data.as_Primitive(); + m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant::make_Float({ e.m_value, ity }) )); ), (Boolean, - m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e) )); + m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant::make_Bool({e}) )); ), (String, m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e) )); diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index a657ffd5..05ba510a 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -515,7 +515,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal // Yes, this is valid. ASSERT_BUG(sp, lit.is_Float(), "Matching floating point type with non-float literal - " << lit); double val = lit.as_Float(); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Float({ val, e }) ) ); } break; case ::HIR::CoreType::U8: case ::HIR::CoreType::U16: @@ -525,7 +525,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal case ::HIR::CoreType::Usize: { ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit); uint64_t val = lit.as_Integer(); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({val, e}) ) ); } break; case ::HIR::CoreType::I8: case ::HIR::CoreType::I16: @@ -535,7 +535,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal case ::HIR::CoreType::Isize: { ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit); int64_t val = static_cast<int64_t>( lit.as_Integer() ); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Int({ val, e }) ) ); } break; case ::HIR::CoreType::Bool: ASSERT_BUG(sp, lit.is_Integer(), "Matching boolean with non-integer literal - " << lit); @@ -545,7 +545,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal // Char is just another name for 'u32'... but with a restricted range ASSERT_BUG(sp, lit.is_Integer(), "Matching char with non-integer literal - " << lit); uint64_t val = lit.as_Integer(); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) ); } break; case ::HIR::CoreType::Str: BUG(sp, "Hit match over `str` - must be `&str`"); @@ -807,7 +807,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::F64: { double start = H::get_pattern_value_float(sp, pat, pe.start); double end = H::get_pattern_value_float(sp, pat, pe.end ); - this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) ); + this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Float({ start, e }), ::MIR::Constant::make_Float({ end, e })} ) ); } break; case ::HIR::CoreType::U8: case ::HIR::CoreType::U16: @@ -817,7 +817,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::Usize: { uint64_t start = H::get_pattern_value_int(sp, pat, pe.start); uint64_t end = H::get_pattern_value_int(sp, pat, pe.end ); - this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) ); + this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Uint({ start, e }), ::MIR::Constant::make_Uint({ end, e })} ) ); } break; case ::HIR::CoreType::I8: case ::HIR::CoreType::I16: @@ -827,7 +827,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::Isize: { int64_t start = H::get_pattern_value_int(sp, pat, pe.start); int64_t end = H::get_pattern_value_int(sp, pat, pe.end ); - this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) ); + this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Int({ start, e }), ::MIR::Constant::make_Int({ end, e })} ) ); } break; case ::HIR::CoreType::Bool: BUG(sp, "Can't range match on Bool"); @@ -835,7 +835,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::Char: { uint64_t start = H::get_pattern_value_int(sp, pat, pe.start); uint64_t end = H::get_pattern_value_int(sp, pat, pe.end ); - this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) ); + this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Uint({ start, e }), ::MIR::Constant::make_Uint({ end, e })} ) ); } break; case ::HIR::CoreType::Str: BUG(sp, "Hit match over `str` - must be `&str`"); @@ -849,7 +849,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::F64: { // Yes, this is valid. double val = H::get_pattern_value_float(sp, pat, pe.val); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Float({ val, e }) ) ); } break; case ::HIR::CoreType::U8: case ::HIR::CoreType::U16: @@ -858,7 +858,12 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::U128: case ::HIR::CoreType::Usize: { uint64_t val = H::get_pattern_value_int(sp, pat, pe.val); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) ); + } break; + case ::HIR::CoreType::Char: { + // Char is just another name for 'u32'... but with a restricted range + uint64_t val = H::get_pattern_value_int(sp, pat, pe.val); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) ); } break; case ::HIR::CoreType::I8: case ::HIR::CoreType::I16: @@ -867,17 +872,12 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa case ::HIR::CoreType::I128: case ::HIR::CoreType::Isize: { int64_t val = H::get_pattern_value_int(sp, pat, pe.val); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); + this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Int({ val, e }) ) ); } break; case ::HIR::CoreType::Bool: // TODO: Support values from `const` too this->push_rule( PatternRule::make_Bool( pe.val.as_Integer().value != 0 ) ); break; - case ::HIR::CoreType::Char: { - // Char is just another name for 'u32'... but with a restricted range - uint64_t val = H::get_pattern_value_int(sp, pat, pe.val); - this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) ); - } break; case ::HIR::CoreType::Str: BUG(sp, "Hit match over `str` - must be `&str`"); break; @@ -1548,7 +1548,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& (Value, auto succ_bb = builder.new_bb_unlinked(); - auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Uint())); + auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.as_Uint().v, te })); auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) })); builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) ); builder.set_cur_block(succ_bb); @@ -1571,7 +1571,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& (Value, auto succ_bb = builder.new_bb_unlinked(); - auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Int())); + auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Int({ re.as_Int().v, te })); auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) })); builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) ); builder.set_cur_block(succ_bb); @@ -1589,8 +1589,8 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& (Value, auto succ_bb = builder.new_bb_unlinked(); - auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Uint())); - auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) })); + auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.as_Uint().v, te })); + auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::EQ, mv$(test_lval) })); builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) ); builder.set_cur_block(succ_bb); ), @@ -1599,15 +1599,15 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& auto test_bb_2 = builder.new_bb_unlinked(); // IF `val` < `first` : fail_bb - auto test_lt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.first.as_Uint())); - auto cmp_lt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::LT, mv$(test_lt_lval) })); + auto test_lt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.first.as_Uint().v, te })); + auto cmp_lt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::LT, mv$(test_lt_lval) })); builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lt_lval), fail_bb, test_bb_2 }) ); builder.set_cur_block(test_bb_2); // IF `val` > `last` : fail_bb - auto test_gt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.last.as_Uint())); - auto cmp_gt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::GT, mv$(test_gt_lval) })); + auto test_gt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.last.as_Uint().v, te })); + auto cmp_gt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::GT, mv$(test_gt_lval) })); builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_gt_lval), fail_bb, succ_bb }) ); builder.set_cur_block(succ_bb); @@ -1768,7 +1768,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& const auto& re = rule.as_Slice(); // Compare length - auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint(re.len) )); + auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ re.len, ::HIR::CoreType::Usize }) )); auto len_val = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_DstMeta({ builder.get_ptr_to_dst(sp, val).clone() })); auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ mv$(len_val), ::MIR::eBinOp::EQ, mv$(test_lval) })); @@ -1787,7 +1787,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& const auto& re = rule.as_SplitSlice(); // Compare length - auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint(re.min_len) )); + auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ re.min_len, ::HIR::CoreType::Usize}) )); auto len_val = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_DstMeta({ builder.get_ptr_to_dst(sp, val).clone() })); auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ mv$(len_val), ::MIR::eBinOp::LT, mv$(test_lval) })); @@ -2535,8 +2535,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule (Int, auto& be = GET_BRANCHES(m_branches, Signed); - // TODO: De-duplicate this code between Uint and Float - from_rule_value(sp, be, ve, "Signed", rule.field_path, + from_rule_value(sp, be, ve.v, "Signed", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { assert( branch.as_Subtree() ); @@ -2552,7 +2551,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule (Uint, auto& be = GET_BRANCHES(m_branches, Unsigned); - from_rule_value(sp, be, ve, "Unsigned", rule.field_path, + from_rule_value(sp, be, ve.v, "Unsigned", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { assert( branch.as_Subtree() ); @@ -2568,7 +2567,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule (Float, auto& be = GET_BRANCHES(m_branches, Float); - from_rule_value(sp, be, ve, "Float", rule.field_path, + from_rule_value(sp, be, ve.v, "Float", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { assert( branch.as_Subtree() ); @@ -2581,7 +2580,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule }); ), (Bool, - throw ""; + BUG(sp, "Hit Bool in PatternRule::Value - " << e); ), (Bytes, TODO(sp, "Value patterns - Bytes"); @@ -2606,20 +2605,20 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule } ), (Const, - throw ""; + BUG(sp, "Hit Const in PatternRule::Value - " << e); ), (ItemAddr, - throw ""; + BUG(sp, "Hit ItemAddr in PatternRule::Value - " << e); ) ) ), (ValueRange, - ASSERT_BUG(sp, e.first.tag() == e.last.tag(), ""); + ASSERT_BUG(sp, e.first.tag() == e.last.tag(), "Constant type mismatch in ValueRange - " << e.first << " and " << e.last); TU_MATCHA( (e.first, e.last), (ve_start, ve_end), (Int, auto& be = GET_BRANCHES(m_branches, Signed); - from_rule_valuerange(sp, be, ve_start, ve_end, "Signed", rule.field_path, + from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Signed", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { @@ -2636,7 +2635,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule (Uint, // TODO: Share code between the three numeric groups auto& be = GET_BRANCHES(m_branches, Unsigned); - from_rule_valuerange(sp, be, ve_start, ve_end, "Unsigned", rule.field_path, + from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Unsigned", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { @@ -2652,7 +2651,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule ), (Float, auto& be = GET_BRANCHES(m_branches, Float); - from_rule_valuerange(sp, be, ve_start, ve_end, "Float", rule.field_path, + from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Float", rule.field_path, [&](auto& branch) { if( rule_count > 1 ) { @@ -2667,7 +2666,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule }); ), (Bool, - throw ""; + BUG(sp, "Hit Bool in PatternRule::ValueRange - " << e.first); ), (Bytes, TODO(sp, "ValueRange patterns - Bytes"); @@ -2676,10 +2675,10 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule ERROR(sp, E0000, "Use of string in value range patter"); ), (Const, - throw ""; + BUG(sp, "Hit Const in PatternRule::ValueRange - " << e.first); ), (ItemAddr, - throw ""; + BUG(sp, "Hit ItemAddr in PatternRule::ValueRange - " << e.first); ) ) ) @@ -3285,6 +3284,7 @@ void DecisionTreeGen::generate_branches_Signed( ::std::function<void(const DecisionTreeNode&)> and_then ) { + auto ity = ty.m_data.as_Primitive(); auto default_block = m_builder.new_bb_unlinked(); // TODO: Convert into an integer switch w/ offset instead of chained comparisons @@ -3293,8 +3293,8 @@ void DecisionTreeGen::generate_branches_Signed( { auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked()); - auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start)); - auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end))); + auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Int({branch.first.start, ity})); + auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Int({ branch.first.end, ity }))); auto cmp_gt_block = m_builder.new_bb_unlinked(); auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({ @@ -3332,6 +3332,7 @@ void DecisionTreeGen::generate_branches_Unsigned( ::std::function<void(const DecisionTreeNode&)> and_then ) { + auto ity = ty.m_data.as_Primitive(); auto default_block = m_builder.new_bb_unlinked(); // TODO: Convert into an integer switch w/ offset instead of chained comparisons @@ -3340,8 +3341,8 @@ void DecisionTreeGen::generate_branches_Unsigned( { auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked()); - auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start)); - auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end))); + auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.start, ity })); + auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.end, ity }))); auto cmp_gt_block = m_builder.new_bb_unlinked(); auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({ @@ -3379,14 +3380,15 @@ void DecisionTreeGen::generate_branches_Float( ::std::function<void(const DecisionTreeNode&)> and_then ) { + auto ity = ty.m_data.as_Primitive(); auto default_block = m_builder.new_bb_unlinked(); for( const auto& branch : branches ) { auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked()); - auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start)); - auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end))); + auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Float({ branch.first.start, ity })); + auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Float({ branch.first.end, ity }))); auto cmp_gt_block = m_builder.new_bb_unlinked(); auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({ @@ -3431,8 +3433,8 @@ void DecisionTreeGen::generate_branches_Char( { auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked()); - auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start)); - auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end))); + auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.start, ::HIR::CoreType::Char })); + auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.end, ::HIR::CoreType::Char }))); auto cmp_gt_block = m_builder.new_bb_unlinked(); auto val_cmp_lt = m_builder.lvalue_or_temp( sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({ @@ -3693,7 +3695,7 @@ void DecisionTreeGen::generate_branches_Slice( // TODO: Binary search instead. for( const auto& branch : branches.fixed_arms ) { - auto val_des = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant(static_cast<uint64_t>(branch.first))); + auto val_des = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ static_cast<uint64_t>(branch.first), ::HIR::CoreType::Usize })); // Special case - final just does equality if( &branch == &branches.fixed_arms.back() ) diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index aab0c53f..6ae5808b 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -11,17 +11,17 @@ namespace MIR { ::std::ostream& operator<<(::std::ostream& os, const Constant& v) { TU_MATCHA( (v), (e), (Int, - os << (e < 0 ? "-" : "+"); - os << (e < 0 ? -e : e); + os << (e.v < 0 ? "-" : "+"); + os << (e.v < 0 ? -e.v : e.v); ), (Uint, - os << e; + os << e.v; ), (Float, - os << e; + os << e.v; ), (Bool, - os << (e ? "true" : "false"); + os << (e.v ? "true" : "false"); ), (Bytes, os << "["; @@ -56,16 +56,16 @@ namespace MIR { return false; TU_MATCHA( (*this,b), (ae,be), (Int, - return ae == be; + return ae.v == be.v && ae.t == be.t; ), (Uint, - return ae == be; + return ae.v == be.v && ae.t == be.t; ), (Float, - return ae == be; + return ae.v == be.v && ae.t == be.t; ), (Bool, - return ae == be; + return ae.v == be.v; ), (Bytes, return ae == be; diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index d2d75e1c..aed7e2fc 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -91,10 +91,21 @@ enum class eUniOp // Compile-time known values TAGGED_UNION_EX(Constant, (), Int, ( - (Int, ::std::int64_t), // TODO: Include eCoreType - (Uint, ::std::uint64_t), // TODO: Include eCoreType - (Float, double), - (Bool, bool), + (Int, struct { + ::std::int64_t v; + ::HIR::CoreType t; + }), + (Uint, struct { + ::std::uint64_t v; + ::HIR::CoreType t; + }), + (Float, struct { + double v; + ::HIR::CoreType t; + }), + (Bool, struct { + bool v; // NOTE: Defensive to prevent implicit casts + }), (Bytes, ::std::vector< ::std::uint8_t>), // Byte string (StaticString, ::std::string), // String (Const, struct { ::HIR::Path p; }), // `const` diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index e487cade..b29ce728 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -1594,7 +1594,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn) if( !se.src.as_Constant().is_Bool() ) continue; val_known = true; - known_val = se.src.as_Constant().as_Bool(); + known_val = se.src.as_Constant().as_Bool().v; break; } else diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 5f87e126..b02769a0 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -2788,56 +2788,54 @@ namespace { { TU_MATCHA( (ve), (c), (Int, - if( c == INT64_MIN ) + if( c.v == INT64_MIN ) m_of << "INT64_MIN"; else - m_of << c; + m_of << c.v; ), (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()) + switch(c.t) { case ::HIR::CoreType::U8: - m_of << ::std::hex << "0x" << (c & 0xFF) << ::std::dec; + m_of << ::std::hex << "0x" << (c.v & 0xFF) << ::std::dec; break; case ::HIR::CoreType::U16: - m_of << ::std::hex << "0x" << (c & 0xFFFF) << ::std::dec; + m_of << ::std::hex << "0x" << (c.v & 0xFFFF) << ::std::dec; break; case ::HIR::CoreType::U32: - m_of << ::std::hex << "0x" << (c & 0xFFFFFFFF) << ::std::dec; + m_of << ::std::hex << "0x" << (c.v & 0xFFFFFFFF) << ::std::dec; break; case ::HIR::CoreType::U64: case ::HIR::CoreType::U128: case ::HIR::CoreType::Usize: - m_of << ::std::hex << "0x" << c << ::std::dec; + m_of << ::std::hex << "0x" << c.v << ::std::dec; break; case ::HIR::CoreType::Char: - assert(0 <= c && c <= 0x10FFFF); - if( c < 256 ) { - m_of << c; + assert(0 <= c.v && c.v <= 0x10FFFF); + if( c.v < 256 ) { + m_of << c.v; } else { - m_of << ::std::hex << "0x" << c << ::std::dec; + m_of << ::std::hex << "0x" << c.v << ::std::dec; } break; default: - MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << ty); + MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << c.t); } ), (Float, - if( ::std::isnan(c) ) { + if( ::std::isnan(c.v) ) { m_of << "NAN"; } - else if( ::std::isinf(c) ) { + else if( ::std::isinf(c.v) ) { m_of << "INFINITY"; } else { - m_of << c; + m_of << c.v; } ), (Bool, - m_of << (c ? "true" : "false"); + m_of << (c.v ? "true" : "false"); ), (Bytes, // TODO: Need to know the desired value for this |