summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-02-25 12:07:12 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-02-25 12:07:12 +0800
commit8068936c1900453fdcbb74c34ed228519ac4e06b (patch)
tree2e0847a2b7a0378f49153e035bf8f7ca135ab4ce
parentcb04e0ba3611deff03566eb035b2c35b4b8890f9 (diff)
downloadmrust-8068936c1900453fdcbb74c34ed228519ac4e06b.tar.gz
MIR Gen - Use MIR::Param (and associated changes)
-rw-r--r--src/hir_expand/const_eval_full.cpp4
-rw-r--r--src/hir_typeck/common.hpp30
-rw-r--r--src/hir_typeck/static.cpp84
-rw-r--r--src/hir_typeck/static.hpp11
-rw-r--r--src/mir/from_hir.cpp26
-rw-r--r--src/mir/from_hir.hpp2
-rw-r--r--src/mir/helpers.cpp39
-rw-r--r--src/mir/helpers.hpp3
-rw-r--r--src/mir/mir_builder.cpp23
-rw-r--r--src/mir/optimise.cpp33
-rw-r--r--src/trans/codegen_c.cpp35
11 files changed, 253 insertions, 37 deletions
diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp
index a361ce59..3bdec96f 100644
--- a/src/hir_expand/const_eval_full.cpp
+++ b/src/hir_expand/const_eval_full.cpp
@@ -750,7 +750,7 @@ namespace {
// Call by invoking evaluate_constant on the function
{
TRACE_FUNCTION_F("Call const fn " << fcnp << " args={ " << call_args << " }");
- dst = evaluate_constant(sp, resolve, newval_state, FMT_CB(ss, ss << fcnp;), fcn.m_code, fcn_ms, mv$(call_args));
+ dst = evaluate_constant(sp, resolve, newval_state, FMT_CB(ss, ss << fcnp;), fcn.m_code, mv$(fcn_ms), mv$(call_args));
}
DEBUG("= " << dst);
@@ -763,7 +763,7 @@ namespace {
::HIR::Literal evaluate_constant(const Span& sp, const StaticTraitResolve& resolve, NewvalState newval_state, FmtLambda name, const ::HIR::ExprPtr& expr, MonomorphState ms, ::std::vector< ::HIR::Literal> args)
{
if( expr.m_mir ) {
- return evaluate_constant_mir(sp, resolve, mv$(newval_state), name, *expr.m_mir, ms, mv$(args));
+ return evaluate_constant_mir(sp, resolve, mv$(newval_state), name, *expr.m_mir, mv$(ms), mv$(args));
}
else {
BUG(sp, "Attempting to evaluate constant expression with no associated code");
diff --git a/src/hir_typeck/common.hpp b/src/hir_typeck/common.hpp
index 40e7e73c..54d9b038 100644
--- a/src/hir_typeck/common.hpp
+++ b/src/hir_typeck/common.hpp
@@ -45,6 +45,36 @@ struct MonomorphState
const ::HIR::PathParams* pp_impl;
const ::HIR::PathParams* pp_method;
+ ::HIR::PathParams pp_impl_data;
+
+ MonomorphState():
+ self_ty(nullptr),
+ pp_impl(nullptr),
+ pp_method(nullptr)
+ {
+ }
+ MonomorphState(MonomorphState&& x):
+ MonomorphState()
+ {
+ *this = ::std::move(x);
+ }
+
+ MonomorphState& operator=(MonomorphState&& x) {
+ this->self_ty = x.self_ty;
+ this->pp_impl = (x.pp_impl == &x.pp_impl_data ? &this->pp_impl_data : x.pp_impl);
+ this->pp_method = x.pp_method;
+ this->pp_impl_data = ::std::move(x.pp_impl_data);
+ return *this;
+ }
+ MonomorphState clone() const {
+ MonomorphState rv;
+ rv.self_ty = this->self_ty;
+ rv.pp_impl = (this->pp_impl == &this->pp_impl_data ? &rv.pp_impl_data : this->pp_impl);
+ rv.pp_method = this->pp_method;
+ rv.pp_impl_data = this->pp_impl_data.clone();
+ return rv;
+ }
+
t_cb_generic get_cb(const Span& sp) const;
::HIR::TypeRef monomorph(const Span& sp, const ::HIR::TypeRef& ty, bool allow_infer=true) const {
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp
index d719ba22..5fec2477 100644
--- a/src/hir_typeck/static.cpp
+++ b/src/hir_typeck/static.cpp
@@ -1410,3 +1410,87 @@ const ::HIR::TypeRef* StaticTraitResolve::is_type_phantom_data(const ::HIR::Type
// TODO: Properly assert?
return &pe.m_params.m_types.at(0);
}
+
+StaticTraitResolve::ValuePtr StaticTraitResolve::get_value(const Span& sp, const ::HIR::Path& p, MonomorphState& out_params, bool signature_only/*=false*/) const
+{
+ out_params = MonomorphState {};
+ TU_MATCHA( (p.m_data), (pe),
+ (Generic,
+ out_params.pp_method = &pe.m_params;
+ const ::HIR::Module& mod = m_crate.get_mod_by_path(sp, pe.m_path, true);
+ const auto& v = mod.m_value_items.at(pe.m_path.m_components.back());
+ TU_MATCHA( (v->ent), (ve),
+ (Import, BUG(sp, "Module Import");),
+ (Constant,
+ return &ve;
+ ),
+ (Static,
+ return &ve;
+ ),
+ (Function,
+ return &ve;
+ ),
+ (StructConstant,
+ TODO(sp, "StructConstant - " << p);
+ ),
+ (StructConstructor,
+ TODO(sp, "StructConstructor - " << p);
+ )
+ )
+ throw "";
+ ),
+ (UfcsKnown,
+ out_params.self_ty = &*pe.type;
+ out_params.pp_impl = &pe.trait.m_params;
+ out_params.pp_method = &pe.params;
+ const ::HIR::Trait& tr = m_crate.get_trait_by_path(sp, pe.trait.m_path);
+ if( signature_only )
+ {
+ const ::HIR::TraitValueItem& v = tr.m_values.at(pe.item);
+ TU_MATCHA( (v), (ve),
+ (Constant, return &ve; ),
+ (Static, return &ve; ),
+ (Function, return &ve; )
+ )
+ }
+ else
+ {
+ TODO(sp, "Search for trait impl");
+ }
+ throw "";
+ ),
+ (UfcsInherent,
+ out_params.self_ty = &*pe.type;
+ out_params.pp_impl = &out_params.pp_impl_data;
+ out_params.pp_method = &pe.params;
+ ValuePtr rv;
+ m_crate.find_type_impls(*pe.type, [](const auto&x)->const auto& { return x; }, [&](const auto& impl) {
+ DEBUG("Found impl" << impl.m_params.fmt_args() << " " << impl.m_type);
+ // TODO: Populate pp_impl
+ {
+ auto fit = impl.m_methods.find(pe.item);
+ if( fit != impl.m_methods.end() )
+ {
+ DEBUG("- Contains method, good");
+ rv = ValuePtr { &fit->second.data };
+ return true;
+ }
+ }
+ {
+ auto it = impl.m_constants.find(pe.item);
+ if( it != impl.m_constants.end() )
+ {
+ rv = ValuePtr { &it->second.data };
+ return true;
+ }
+ }
+ return false;
+ });
+ return rv;
+ ),
+ (UfcsUnknown,
+ BUG(sp, "UfcsUnknown - " << p);
+ )
+ )
+ throw "";
+}
diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp
index 46dcd1a1..cde9797c 100644
--- a/src/hir_typeck/static.hpp
+++ b/src/hir_typeck/static.hpp
@@ -180,5 +180,16 @@ public:
const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const;
const ::HIR::TypeRef* is_type_phantom_data(const ::HIR::TypeRef& ty) const;
+
+
+ TAGGED_UNION(ValuePtr, NotFound,
+ (NotFound, struct{}),
+ (Constant, const ::HIR::Constant*),
+ (Static, const ::HIR::Static*),
+ (Function, const ::HIR::Function*)
+ );
+
+ /// `signature_only` - Returns a pointer to an item with the correct signature, not the actual implementation (faster)
+ ValuePtr get_value(const Span& sp, const ::HIR::Path& p, MonomorphState& out_params, bool signature_only=false) const;
};
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 17c44e93..722e3aa1 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -1493,7 +1493,7 @@ namespace {
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) );
+ values.push_back( m_builder.get_result_in_param(arg->span(), arg->m_res_type) );
}
unsigned int variant_index = ~0u;
@@ -1527,7 +1527,7 @@ namespace {
if( args.size() == 1 )
{
- values.push_back( m_builder.get_result_in_lvalue(arg->span(), arg->m_res_type, /*allow_missing_value=*/true) );
+ values.push_back( m_builder.get_result_in_param(arg->span(), arg->m_res_type, /*allow_missing_value=*/true) );
}
else
{
@@ -1940,10 +1940,18 @@ namespace {
values_set[idx] = true;
this->visit_node_ptr(valnode);
- // NOTE: Have to allocate a new temporary because ordering matters
- auto tmp = m_builder.new_temporary(valnode->m_res_type);
- m_builder.push_stmt_assign( valnode->span(), tmp.clone(), m_builder.get_result(valnode->span()) );
- values.at(idx) = mv$(tmp);
+ auto res = m_builder.get_result(valnode->span());
+ if( auto* e = res.opt_Constant() )
+ {
+ values.at(idx) = mv$(*e);
+ }
+ else
+ {
+ // NOTE: Have to allocate a new temporary because ordering matters
+ auto tmp = m_builder.new_temporary(valnode->m_res_type);
+ m_builder.push_stmt_assign( valnode->span(), tmp.clone(), mv$(res) );
+ values.at(idx) = mv$(tmp);
+ }
}
for(unsigned int i = 0; i < values.size(); i ++)
{
@@ -1991,7 +1999,7 @@ namespace {
for(auto& arg : node.m_vals)
{
this->visit_node_ptr(arg);
- values.push_back( m_builder.lvalue_or_temp( arg->span(), arg->m_res_type, m_builder.get_result(arg->span()) ) );
+ values.push_back( m_builder.get_result_in_param(arg->span(), arg->m_res_type) );
}
m_builder.set_result( node.span(), ::MIR::RValue::make_Tuple({
@@ -2007,7 +2015,7 @@ namespace {
for(auto& arg : node.m_vals)
{
this->visit_node_ptr(arg);
- values.push_back( m_builder.lvalue_or_temp( arg->span(), arg->m_res_type, m_builder.get_result(arg->span()) ) );
+ values.push_back( m_builder.get_result_in_param(arg->span(), arg->m_res_type) );
}
m_builder.set_result( node.span(), ::MIR::RValue::make_Array({
@@ -2019,7 +2027,7 @@ namespace {
{
TRACE_FUNCTION_F("_ArraySized");
this->visit_node_ptr( node.m_val );
- auto value = m_builder.lvalue_or_temp( node.span(), node.m_val->m_res_type, m_builder.get_result(node.m_val->span()) );
+ auto value = m_builder.get_result_in_param(node.span(), node.m_val->m_res_type);
m_builder.set_result( node.span(), ::MIR::RValue::make_SizedArray({
mv$(value),
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp
index c687d275..c8d34151 100644
--- a/src/mir/from_hir.hpp
+++ b/src/mir/from_hir.hpp
@@ -166,6 +166,8 @@ public:
::MIR::LValue get_result_unwrap_lvalue(const Span& sp);
/// Obtains the result, copying into a temporary if required
::MIR::LValue get_result_in_lvalue(const Span& sp, const ::HIR::TypeRef& ty, bool allow_missing_value=false);
+ /// Obtains a result in a param (or a lvalue)
+ ::MIR::Param get_result_in_param(const Span& sp, const ::HIR::TypeRef& ty, bool allow_missing_value=false);
// - Statements
// Push an assignment. NOTE: This also marks the rvalue as moved
diff --git a/src/mir/helpers.cpp b/src/mir/helpers.cpp
index 9750b978..9c2107ab 100644
--- a/src/mir/helpers.cpp
+++ b/src/mir/helpers.cpp
@@ -225,6 +225,45 @@ const ::HIR::TypeRef& ::MIR::TypeResolve::get_lvalue_type(::HIR::TypeRef& tmp, c
)
throw "";
}
+
+::HIR::TypeRef MIR::TypeResolve::get_const_type(const ::MIR::Constant& c) const
+{
+ TU_MATCHA( (c), (e),
+ (Int,
+ return e.t;
+ ),
+ (Uint,
+ return e.t;
+ ),
+ (Float,
+ return e.t;
+ ),
+ (Bool,
+ return ::HIR::CoreType::Bool;
+ ),
+ (Bytes,
+ return ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ::HIR::TypeRef::new_array( ::HIR::CoreType::U8, e.size() ) );
+ ),
+ (StaticString,
+ return ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ::HIR::CoreType::Str );
+ ),
+ (Const,
+ MonomorphState p;
+ auto v = m_resolve.get_value(this->sp, e.p, p, /*signature_only=*/true);
+ if( const auto* ve = v.opt_Constant() ) {
+ const auto& ty = (*ve)->m_type;
+ MIR_TODO(*this, "Monomorphise type " << ty);
+ }
+ else {
+ MIR_BUG(*this, "");
+ }
+ ),
+ (ItemAddr,
+ MIR_TODO(*this, "Get type for constant `" << c << "`");
+ )
+ )
+ throw "";
+}
const ::HIR::TypeRef* ::MIR::TypeResolve::is_type_owned_box(const ::HIR::TypeRef& ty) const
{
return m_resolve.is_type_owned_box(ty);
diff --git a/src/mir/helpers.hpp b/src/mir/helpers.hpp
index ece20605..e8f52651 100644
--- a/src/mir/helpers.hpp
+++ b/src/mir/helpers.hpp
@@ -21,6 +21,7 @@ namespace MIR {
class Function;
class LValue;
+class Constant;
class BasicBlock;
typedef unsigned int BasicBlockId;
@@ -96,6 +97,8 @@ public:
const ::HIR::TypeRef& get_static_type(::HIR::TypeRef& tmp, const ::HIR::Path& path) const;
const ::HIR::TypeRef& get_lvalue_type(::HIR::TypeRef& tmp, const ::MIR::LValue& val) const;
+ ::HIR::TypeRef get_const_type(const ::MIR::Constant& c) const;
+
const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const;
friend ::std::ostream& operator<<(::std::ostream& os, const TypeResolve& x) {
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 13d17d91..aa42cbc1 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -170,6 +170,29 @@ void MirBuilder::define_variable(unsigned int idx)
return temp;
}
}
+::MIR::Param MirBuilder::get_result_in_param(const Span& sp, const ::HIR::TypeRef& ty, bool allow_missing_value)
+{
+ if( allow_missing_value && !block_active() )
+ {
+ return new_temporary(ty);
+ }
+
+ auto rv = get_result(sp);
+ if( auto* e = rv.opt_Constant() )
+ {
+ return mv$(*e);
+ }
+ else if( auto* e = rv.opt_Use() )
+ {
+ return mv$(*e);
+ }
+ else
+ {
+ auto temp = new_temporary(ty);
+ push_stmt_assign( sp, ::MIR::LValue(temp.clone()), mv$(rv) );
+ return temp;
+ }
+}
void MirBuilder::set_result(const Span& sp, ::MIR::RValue val)
{
if(m_result_valid) {
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index b29ce728..cb96cba0 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -625,13 +625,15 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
unsigned int var_base = ~0u;
unsigned int df_base = ~0u;
+ size_t tmp_end = 0;
+ mutable ::std::vector< ::MIR::Constant > const_assignments;
+
Cloner(const Span& sp, const ::StaticTraitResolve& resolve, ::MIR::Terminator::Data_Call& te):
sp(sp),
resolve(resolve),
te(te)
{}
- // TODO: Expand associated types
::HIR::TypeRef monomorph(const ::HIR::TypeRef& ty) const {
auto rv = monomorphise_type_with(sp, ty, params.get_cb(sp));
resolve.expand_associated_types(sp, rv);
@@ -814,9 +816,13 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
return ::MIR::LValue::make_Temporary({se.idx + this->tmp_base});
),
(Argument,
- // TODO: If this argument is a literal, need to allocate a
- // tmep for it
- return this->te.args.at(se.idx).as_LValue().clone();
+ const auto& arg = this->te.args.at(se.idx);
+ if( const auto* e = arg.opt_Constant() ) {
+ auto tmp = ::MIR::LValue::make_Temporary({ static_cast<unsigned>(this->tmp_end + this->const_assignments.size()) });
+ this->const_assignments.push_back( e->clone() );
+ return tmp;
+ }
+ return arg.as_LValue().clone();
),
(Return,
return this->te.ret_val.clone();
@@ -863,7 +869,11 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
::MIR::Param clone_param(const ::MIR::Param& src) const
{
TU_MATCHA( (src), (se),
- (LValue, return clone_lval(se);),
+ (LValue,
+ if( se.is_Argument() )
+ return this->te.args.at(se.as_Argument().idx).clone();
+ return clone_lval(se);
+ ),
(Constant, return clone_constant(se); )
)
throw "";
@@ -872,6 +882,9 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
TU_MATCHA( (src), (se),
(Use,
+ if( se.is_Argument() )
+ if( const auto* e = this->te.args.at(se.as_Argument().idx).opt_Constant() )
+ return e->clone();
return ::MIR::RValue( this->clone_lval(se) );
),
(Constant,
@@ -952,6 +965,7 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
cloner.tmp_base = fcn.temporaries.size();
for(const auto& ty : called_mir->temporaries)
fcn.temporaries.push_back( cloner.monomorph(ty) );
+ cloner.tmp_end = fcn.temporaries.size();
cloner.df_base = fcn.drop_flags.size();
fcn.drop_flags.insert( fcn.drop_flags.end(), called_mir->drop_flags.begin(), called_mir->drop_flags.end() );
cloner.bb_base = fcn.blocks.size();
@@ -963,6 +977,15 @@ bool MIR_Optimise_Inlining(::MIR::TypeResolve& state, ::MIR::Function& fcn)
{
new_blocks.push_back( cloner.clone_bb(bb) );
}
+ // > Append new temporaries
+ for(auto& val : cloner.const_assignments)
+ {
+ auto ty = state.get_const_type(val);
+ auto lv = ::MIR::LValue::make_Temporary({ static_cast<unsigned>(fcn.temporaries.size()) });
+ fcn.temporaries.push_back( mv$(ty) );
+ new_blocks[0].statements.insert( new_blocks[0].statements.begin(), ::MIR::Statement::make_Assign({ mv$(lv), mv$(val) }) );
+ }
+ cloner.const_assignments.clear();
// Apply
fcn.blocks.reserve( fcn.blocks.size() + new_blocks.size() );
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index b74589c2..5e365ceb 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -2467,25 +2467,17 @@ namespace {
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);
- 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);
- ),
- (UfcsKnown,
- MIR_TODO(*m_mir_res, "get_literal_for_const - UfcsKnown " << path);
- ),
- (UfcsInherent,
- MIR_TODO(*m_mir_res, "get_literal_for_const - UfcsInherent " << path);
- )
- )
- throw "";
+ MonomorphState params;
+ auto v = m_resolve.get_value(m_mir_res->sp, path, params);
+ if( const auto* e = v.opt_Constant() )
+ {
+ ty = params.monomorph(m_mir_res->sp, (*e)->m_type);
+ return (*e)->m_value_res;
+ }
+ else
+ {
+ MIR_BUG(*m_mir_res, "get_literal_for_const - Not a constant - " << path);
+ }
}
void assign_from_literal(::std::function<void()> emit_dst, const ::HIR::TypeRef& ty, const ::HIR::Literal& lit)
@@ -2861,11 +2853,12 @@ namespace {
),
(Const,
// TODO: This should have been eliminated?
+ // NOTE: GCC hack - statement expressions
::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 << ";";
+ m_of << "({"; emit_ctype(ty, FMT_CB(ss, ss<<"v";)); m_of << "; ";
assign_from_literal([&](){ m_of << "v"; }, ty, lit);
- m_of << "v})";
+ m_of << "; v;})";
),
(ItemAddr,
TU_MATCHA( (c.m_data), (pe),