diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-07 18:03:36 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-07 18:03:36 +0800 |
commit | 058a5dab9d2a61514265bd6718ec83f8d3721de6 (patch) | |
tree | 89bf24e52682627facffd5eefb99377ea6a3786b /src | |
parent | 7fc04390dee98081027e7ffc7510b100b929fdd0 (diff) | |
download | mrust-058a5dab9d2a61514265bd6718ec83f8d3721de6.tar.gz |
MIR - Merge two call types into one with a different target
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/deserialise.cpp | 26 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 24 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 19 | ||||
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 7 | ||||
-rw-r--r-- | src/mir/check.cpp | 11 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 53 | ||||
-rw-r--r-- | src/mir/dump.cpp | 22 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 10 | ||||
-rw-r--r-- | src/mir/mir.cpp | 22 | ||||
-rw-r--r-- | src/mir/mir.hpp | 17 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 77 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 19 | ||||
-rw-r--r-- | src/trans/monomorphise.cpp | 32 |
13 files changed, 186 insertions, 153 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 348b016c..b7fa0a67 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -313,6 +313,7 @@ namespace { ::MIR::BasicBlock deserialise_mir_basicblock(); ::MIR::Statement deserialise_mir_statement(); ::MIR::Terminator deserialise_mir_terminator(); + ::MIR::CallTarget deserialise_mir_calltarget(); ::MIR::LValue deserialise_mir_lvalue() { ::MIR::LValue rv; @@ -976,18 +977,11 @@ namespace { deserialise_mir_lvalue(), deserialise_vec_c<unsigned int>([&](){ return m_in.read_count(); }) }) - _(CallValue, { + _(Call, { static_cast<unsigned int>(m_in.read_count()), static_cast<unsigned int>(m_in.read_count()), deserialise_mir_lvalue(), - deserialise_mir_lvalue(), - deserialise_vec< ::MIR::LValue>() - }) - _(CallPath, { - static_cast<unsigned int>(m_in.read_count()), - static_cast<unsigned int>(m_in.read_count()), - deserialise_mir_lvalue(), - deserialise_path(), + deserialise_mir_calltarget(), deserialise_vec< ::MIR::LValue>() }) #undef _ @@ -996,6 +990,20 @@ namespace { } } + ::MIR::CallTarget HirDeserialiser::deserialise_mir_calltarget() + { + switch( m_in.read_tag() ) + { + #define _(x, ...) case ::MIR::CallTarget::TAG_##x: return ::MIR::CallTarget::make_##x( __VA_ARGS__ ); + _(Value, deserialise_mir_lvalue() ) + _(Path, deserialise_path() ) + _(Intrinsic, m_in.read_string() ) + #undef _ + default: + throw ""; + } + } + ::HIR::Module HirDeserialiser::deserialise_module() { TRACE_FUNCTION; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 35acaa93..65ccad6c 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -506,19 +506,27 @@ namespace { for(auto t : e.targets) m_out.write_count(t); ), - (CallValue, + (Call, m_out.write_count(e.ret_block); m_out.write_count(e.panic_block); serialise(e.ret_val); - serialise(e.fcn_val); + serialise(e.fcn); serialise_vec(e.args); + ) + ) + } + void serialise(const ::MIR::CallTarget& ct) + { + m_out.write_tag( static_cast<int>(ct.tag()) ); + TU_MATCHA( (ct), (e), + (Value, + serialise(e); ), - (CallPath, - m_out.write_count(e.ret_block); - m_out.write_count(e.panic_block); - serialise(e.ret_val); - serialise_path(e.fcn_path); - serialise_vec(e.args); + (Path, + serialise_path(e); + ), + (Intrinsic, + m_out.write_string(e); ) ) } diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index f4937043..66f484ed 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -608,15 +608,18 @@ namespace { (Switch, H::visit_lvalue(*this, te.val); ), - (CallValue, + (Call, H::visit_lvalue(*this, te.ret_val); - H::visit_lvalue(*this, te.fcn_val); - for(auto& arg : te.args) - H::visit_lvalue(*this, arg); - ), - (CallPath, - H::visit_lvalue(*this, te.ret_val); - visit_path(te.fcn_path, ::HIR::Visitor::PathContext::VALUE); + TU_MATCHA( (te.fcn), (e2), + (Value, + H::visit_lvalue(*this, e2); + ), + (Path, + visit_path(e2, ::HIR::Visitor::PathContext::VALUE); + ), + (Intrinsic, + ) + ) for(auto& arg : te.args) H::visit_lvalue(*this, arg); ) diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index c5aab190..54d2bb1b 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -1166,9 +1166,12 @@ namespace { (Return, return retval; ), - (CallPath, + (Call, + if( !e.fcn.is_Path() ) + BUG(sp, "Unexpected terminator - " << block.terminator); + const auto& fcnp = e.fcn.as_Path(); + auto& dst = get_lval(e.ret_val); - const auto& fcnp = e.fcn_path; auto& fcn = get_function(sp, crate, fcnp); ::std::vector< ::HIR::Literal> call_args; diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 24157f41..80fd65a9 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -69,11 +69,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path PUSH_BB(e.targets[i], "Switch V" << i); } ), - (CallValue, - PUSH_BB(e.ret_block, "Call ret"); - PUSH_BB(e.panic_block, "Call panic"); - ), - (CallPath, + (Call, PUSH_BB(e.ret_block, "Call ret"); PUSH_BB(e.panic_block, "Call panic"); ) @@ -289,10 +285,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path (Switch, // Check that the condition is an enum ), - (CallValue, - // Typecheck arguments and return value - ), - (CallPath, + (Call, // Typecheck arguments and return value ) ) diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index fb22a5dc..51273f53 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -35,9 +35,9 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR return nullptr; } -::MIR::Terminator MIR_Cleanup_Virtualize( +::MIR::LValue MIR_Cleanup_Virtualize( const Span& sp, const ::MIR::TypeResolve& state, ::MIR::Function& fcn, - ::MIR::BasicBlock& block, ::MIR::Terminator::Data_CallPath& e, + ::MIR::BasicBlock& block, ::MIR::LValue& receiver_lvp, const ::HIR::TypeRef::Data::Data_TraitObject& te, const ::HIR::Path::Data::Data_UfcsKnown& pe ) { @@ -82,22 +82,17 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR auto vtable_lv = ::MIR::LValue::make_Temporary({ static_cast<unsigned int>(fcn.temporaries.size()) }); fcn.temporaries.push_back( mv$(vtable_ty) ); // - Load the vtable and store it - auto vtable_rval = ::MIR::RValue::make_DstMeta({ ::MIR::LValue::make_Deref({ box$(e.args.front().clone()) }) }); + auto vtable_rval = ::MIR::RValue::make_DstMeta({ ::MIR::LValue::make_Deref({ box$(receiver_lvp.clone()) }) }); block.statements.push_back( ::MIR::Statement::make_Assign({ vtable_lv.clone(), mv$(vtable_rval) }) ); - auto ptr_rval = ::MIR::RValue::make_DstPtr({ ::MIR::LValue::make_Deref({ box$(e.args.front().clone()) }) }); + auto ptr_rval = ::MIR::RValue::make_DstPtr({ ::MIR::LValue::make_Deref({ box$(receiver_lvp.clone()) }) }); auto ptr_lv = ::MIR::LValue::make_Temporary({ static_cast<unsigned int>(fcn.temporaries.size()) }); fcn.temporaries.push_back( ::HIR::TypeRef::new_pointer(::HIR::BorrowType::Shared, ::HIR::TypeRef::new_unit()) ); block.statements.push_back( ::MIR::Statement::make_Assign({ ptr_lv.clone(), mv$(ptr_rval) }) ); - e.args.front() = mv$(ptr_lv); + receiver_lvp = mv$(ptr_lv); // Update the terminator with the new information. - auto vtable_fcn = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(vtable_lv) })), vtable_idx }); - return ::MIR::Terminator::make_CallValue({ - e.ret_block, e.panic_block, - mv$(e.ret_val), mv$(vtable_fcn), - mv$(e.args) - }); + return ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(vtable_lv) })), vtable_idx }); } void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type) @@ -199,27 +194,29 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, } } - TU_IFLET( ::MIR::Terminator, block.terminator, CallPath, e, + TU_IFLET( ::MIR::Terminator, block.terminator, Call, e, - // Detect calling `<Trait as Trait>::method()` and replace with vtable call - if( e.fcn_path.m_data.is_UfcsKnown() && e.fcn_path.m_data.as_UfcsKnown().type->m_data.is_TraitObject() ) - { - const auto& pe = e.fcn_path.m_data.as_UfcsKnown(); - const auto& te = pe.type->m_data.as_TraitObject(); - // TODO: What if the method is from a supertrait? + TU_IFLET( ::MIR::CallTarget, e.fcn, Path, path, + // Detect calling `<Trait as Trait>::method()` and replace with vtable call + if( path.m_data.is_UfcsKnown() && path.m_data.as_UfcsKnown().type->m_data.is_TraitObject() ) + { + const auto& pe = path.m_data.as_UfcsKnown(); + const auto& te = pe.type->m_data.as_TraitObject(); + // TODO: What if the method is from a supertrait? - if( te.m_trait.m_path == pe.trait || resolve.find_named_trait_in_trait( - sp, pe.trait.m_path, pe.trait.m_params, - *te.m_trait.m_trait_ptr, te.m_trait.m_path.m_path, te.m_trait.m_path.m_params, - *pe.type, - [](const auto&, auto){} + if( te.m_trait.m_path == pe.trait || resolve.find_named_trait_in_trait( + sp, pe.trait.m_path, pe.trait.m_params, + *te.m_trait.m_trait_ptr, te.m_trait.m_path.m_path, te.m_trait.m_path.m_params, + *pe.type, + [](const auto&, auto){} + ) ) - ) - { - auto new_term = MIR_Cleanup_Virtualize(sp, state, fcn, block, e, te, pe); - block.terminator = mv$(new_term); + { + auto tgt_lvalue = MIR_Cleanup_Virtualize(sp, state, fcn, block, e.args.front(), te, pe); + e.fcn = mv$(tgt_lvalue); + } } - } + ) ) } } diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index 667d1fd2..c97a2699 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -196,14 +196,20 @@ namespace { m_os << j << " => bb" << e.targets[j] << ", "; m_os << "}\n"; ), - (CallValue, - m_os << FMT_M(e.ret_val) << " = (" << FMT_M(e.fcn_val) << ")( "; - for(const auto& arg : e.args) - m_os << FMT_M(arg) << ", "; - m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n"; - ), - (CallPath, - m_os << FMT_M(e.ret_val) << " = " << e.fcn_path << "( "; + (Call, + m_os << FMT_M(e.ret_val) << " = "; + TU_MATCHA( (e.fcn), (e2), + (Value, + m_os << "(" << FMT_M(e2) << ")"; + ), + (Path, + m_os << e2; + ), + (Intrinsic, + m_os << "\"" << e2 << "\""; + ) + ) + m_os << "( "; for(const auto& arg : e.args) m_os << FMT_M(arg) << ", "; m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n"; diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 3d28ef7d..14df55c6 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1256,7 +1256,7 @@ namespace { case ::HIR::ExprNode_Emplace::Type::Boxer: { ::HIR::PathParams trait_params; trait_params.m_types.push_back( data_ty.clone() ); - m_builder.end_block(::MIR::Terminator::make_CallPath({ + m_builder.end_block(::MIR::Terminator::make_Call({ place__ok, place__panic, place.clone(), ::HIR::Path(place_type.clone(), ::HIR::GenericPath(path_BoxPlace, mv$(trait_params)), "make_place", {}), {} @@ -1283,7 +1283,7 @@ namespace { auto place_refmut = m_builder.lvalue_or_temp(node.span(), place_refmut__type, ::MIR::RValue::make_Borrow({ 0, ::HIR::BorrowType::Unique, place.clone() })); // <typeof(place) as ops::Place<T>>::pointer (T = inner) auto fcn_path = ::HIR::Path(place_type.clone(), ::HIR::GenericPath(path_Place, ::HIR::PathParams(data_ty.clone())), "pointer"); - m_builder.end_block(::MIR::Terminator::make_CallPath({ + 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) ) @@ -1319,7 +1319,7 @@ namespace { auto res = m_builder.new_temporary( node.m_res_type ); auto res__panic = m_builder.new_bb_unlinked(); auto res__ok = m_builder.new_bb_unlinked(); - m_builder.end_block(::MIR::Terminator::make_CallPath({ + m_builder.end_block(::MIR::Terminator::make_Call({ res__ok, res__panic, res.clone(), mv$(finalize_path), ::make_vec1( mv$(place) ) @@ -1385,7 +1385,7 @@ namespace { auto next_block = m_builder.new_bb_unlinked(); auto res = m_builder.new_temporary( node.m_res_type ); - m_builder.end_block(::MIR::Terminator::make_CallPath({ + m_builder.end_block(::MIR::Terminator::make_Call({ next_block, panic_block, res.clone(), node.m_path.clone(), mv$(values) @@ -1421,7 +1421,7 @@ namespace { auto panic_block = m_builder.new_bb_unlinked(); auto next_block = m_builder.new_bb_unlinked(); auto res = m_builder.new_temporary( node.m_res_type ); - m_builder.end_block(::MIR::Terminator::make_CallValue({ + m_builder.end_block(::MIR::Terminator::make_Call({ next_block, panic_block, res.clone(), mv$(fcn_val), mv$(values) diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp index 22a05276..95ad81b3 100644 --- a/src/mir/mir.cpp +++ b/src/mir/mir.cpp @@ -161,14 +161,20 @@ namespace MIR { os << j << " => bb" << e.targets[j] << ", "; os << ")"; ), - (CallValue, - os << "Call( " << e.ret_val << " = " << e.fcn_val << "( "; - for(const auto& arg : e.args) - os << arg << ", "; - os << "), bb" << e.ret_block << ", bb" << e.panic_block << ")"; - ), - (CallPath, - os << "Call( " << e.ret_val << " = " << e.fcn_path << "( "; + (Call, + os << "Call( " << e.ret_val << " = "; + TU_MATCHA( (e.fcn), (e2), + (Value, + os << "(" << e2 << ")"; + ), + (Path, + os << e2; + ), + (Intrinsic, + os << "\"" << e2 << "\""; + ) + ) + os << "( "; for(const auto& arg : e.args) os << arg << ", "; os << "), bb" << e.ret_block << ", bb" << e.panic_block << ")"; diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index 3215f9fc..4f4d70b0 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -161,6 +161,12 @@ TAGGED_UNION(RValue, Use, ); extern ::std::ostream& operator<<(::std::ostream& os, const RValue& x); +TAGGED_UNION(CallTarget, Intrinsic, + (Value, LValue), + (Path, ::HIR::Path), + (Intrinsic, ::std::string) + ); + TAGGED_UNION(Terminator, Incomplete, (Incomplete, struct {}), // Block isn't complete (ERROR in output) (Return, struct {}), // Return clealy to caller @@ -176,18 +182,11 @@ TAGGED_UNION(Terminator, Incomplete, LValue val; ::std::vector<BasicBlockId> targets; }), - (CallValue, struct { - BasicBlockId ret_block; - BasicBlockId panic_block; - LValue ret_val; - LValue fcn_val; - ::std::vector<LValue> args; - }), - (CallPath, struct { + (Call, struct { BasicBlockId ret_block; BasicBlockId panic_block; LValue ret_val; - ::HIR::Path fcn_path; + CallTarget fcn; ::std::vector<LValue> args; }) ); diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index b780d695..37c96a83 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -589,49 +589,50 @@ namespace { m_of << "\t\tcase " << j << ": goto bb" << e.targets[j] << ";\n"; m_of << "\t}\n"; ), - (CallValue, + (Call, m_of << "\t"; - { - ::HIR::TypeRef tmp; - const auto& ty = mir_res.get_lvalue_type(tmp, e.fcn_val); - if( !ty.m_data.as_Function().m_rettype->m_data.is_Diverge() ) + TU_MATCHA( (e.fcn), (e2), + (Value, { - emit_lvalue(e.ret_val); m_of << " = "; + ::HIR::TypeRef tmp; + const auto& ty = mir_res.get_lvalue_type(tmp, e2); + if( !ty.m_data.as_Function().m_rettype->m_data.is_Diverge() ) + { + emit_lvalue(e.ret_val); m_of << " = "; + } } - } - m_of << "("; emit_lvalue(e.fcn_val); 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 << " );\n"; - m_of << "\tgoto bb" << e.ret_block << ";\n"; - ), - (CallPath, - m_of << "\t"; - { - bool is_diverge = false; - TU_MATCHA( (e.fcn_path.m_data), (pe), - (Generic, - const auto& fcn = m_crate.get_function_by_path(sp, pe.m_path); - is_diverge |= fcn.m_return.m_data.is_Diverge(); - // TODO: Monomorph. - ), - (UfcsUnknown, - ), - (UfcsInherent, - // TODO: Check if the return type is ! - ), - (UfcsKnown, - // TODO: Check if the return type is ! - ) - ) - if(!is_diverge) + m_of << "("; emit_lvalue(e2); m_of << ")"; + ), + (Path, { - emit_lvalue(e.ret_val); m_of << " = "; + bool is_diverge = false; + TU_MATCHA( (e2.m_data), (pe), + (Generic, + const auto& fcn = m_crate.get_function_by_path(sp, pe.m_path); + is_diverge |= fcn.m_return.m_data.is_Diverge(); + // TODO: Monomorph. + ), + (UfcsUnknown, + ), + (UfcsInherent, + // TODO: Check if the return type is ! + ), + (UfcsKnown, + // TODO: Check if the return type is ! + ) + ) + if(!is_diverge) + { + emit_lvalue(e.ret_val); m_of << " = "; + } } - } - m_of << Trans_Mangle(e.fcn_path) << "("; + m_of << Trans_Mangle(e2); + ), + (Intrinsic, + BUG(sp, "Intrinsic not expected, should be handled above"); + ) + ) + m_of << "("; for(unsigned int j = 0; j < e.args.size(); j ++) { if(j != 0) m_of << ","; m_of << " "; emit_lvalue(e.args[j]); diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index a18b91b1..505a4d19 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -461,15 +461,18 @@ void Trans_Enumerate_FillFrom_MIR(TransList& out, const ::HIR::Crate& crate, con (Switch, Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.val, pp); ), - (CallValue, + (Call, Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ret_val, pp); - Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.fcn_val, pp); - for(const auto& arg : e.args) - Trans_Enumerate_FillFrom_MIR_LValue(out,crate, arg, pp); - ), - (CallPath, - Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e.ret_val, pp); - Trans_Enumerate_FillFrom_Path(out,crate, e.fcn_path, pp); + TU_MATCHA( (e.fcn), (e2), + (Value, + Trans_Enumerate_FillFrom_MIR_LValue(out,crate, e2, pp); + ), + (Path, + Trans_Enumerate_FillFrom_Path(out,crate, e2, pp); + ), + (Intrinsic, + ) + ) for(const auto& arg : e.args) Trans_Enumerate_FillFrom_MIR_LValue(out,crate, arg, pp); ) diff --git a/src/trans/monomorphise.cpp b/src/trans/monomorphise.cpp index c3df848e..24bf34d1 100644 --- a/src/trans/monomorphise.cpp +++ b/src/trans/monomorphise.cpp @@ -78,7 +78,6 @@ namespace { } // 2. Monomorphise all paths - // 3. Convert virtual dispatch to vtable load output.blocks.reserve( tpl->blocks.size() ); for(const auto& block : tpl->blocks) { @@ -251,20 +250,27 @@ namespace { e.targets }); ), - (CallValue, - terminator = ::MIR::Terminator::make_CallValue({ - e.ret_block, e.panic_block, - monomorph_LValue(crate, params, e.ret_val), - monomorph_LValue(crate, params, e.fcn_val), - monomorph_LValue_list(crate, params, e.args) - }); - ), - (CallPath, - // TODO: Replace vtable calls - terminator = ::MIR::Terminator::make_CallPath({ + (Call, + struct H { + static ::MIR::CallTarget monomorph_calltarget(const ::HIR::Crate& crate, const Trans_Params& params, const ::MIR::CallTarget& ct) { + TU_MATCHA( (ct), (e), + (Value, + return monomorph_LValue(crate, params, e); + ), + (Path, + return params.monomorph(crate, e); + ), + (Intrinsic, + return e; + ) + ) + throw ""; + } + }; + terminator = ::MIR::Terminator::make_Call({ e.ret_block, e.panic_block, monomorph_LValue(crate, params, e.ret_val), - params.monomorph(crate, e.fcn_path), + H::monomorph_calltarget(crate, params, e.fcn), monomorph_LValue_list(crate, params, e.args) }); ) |