employ explicit conversions to/from "any" and "vector of any" types

This commit is contained in:
Vern Paxson 2021-05-30 18:05:11 -07:00
parent 292bd1b671
commit 8044926e00
3 changed files with 85 additions and 14 deletions

View file

@ -1568,15 +1568,20 @@ bool AssignExpr::IsReduced(Reducer* c) const
// Cascaded assignments are never reduced.
return false;
auto lhs_is_any = op1->GetType()->Tag() == TYPE_ANY;
auto rhs_is_any = op2->GetType()->Tag() == TYPE_ANY;
const auto& t1 = op1->GetType();
const auto& t2 = op2->GetType();
auto lhs_is_any = t1->Tag() == TYPE_ANY;
auto rhs_is_any = t2->Tag() == TYPE_ANY;
if ( lhs_is_any != rhs_is_any && op2->Tag() != EXPR_CONST )
return NonReduced(this);
auto t1 = op1->Tag();
if ( t1->Tag() == TYPE_VECTOR && t1->Yield()->Tag() != TYPE_ANY &&
t2->Yield() && t2->Yield()->Tag() == TYPE_ANY )
return NonReduced(this);
if ( t1 == EXPR_REF &&
if ( op1->Tag() == EXPR_REF &&
op2->HasConstantOps() && op2->Tag() != EXPR_TO_ANY_COERCE )
// We are not reduced because we should instead
// be folded.
@ -1618,8 +1623,11 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
// These are generated for reduced expressions.
return ThisPtr();
auto lhs_is_any = op1->GetType()->Tag() == TYPE_ANY;
auto rhs_is_any = op2->GetType()->Tag() == TYPE_ANY;
auto& t1 = op1->GetType();
auto& t2 = op2->GetType();
auto lhs_is_any = t1->Tag() == TYPE_ANY;
auto rhs_is_any = t2->Tag() == TYPE_ANY;
StmtPtr rhs_reduce;
@ -1637,12 +1645,20 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt)
op2 = make_intrusive<CoerceToAnyExpr>(red_rhs);
}
else
op2 = make_intrusive<CoerceFromAnyExpr>(red_rhs,
op1->GetType());
op2 = make_intrusive<CoerceFromAnyExpr>(red_rhs, t1);
op2->SetLocationInfo(op2_loc);
}
if ( t1->Tag() == TYPE_VECTOR && t1->Yield()->Tag() != TYPE_ANY &&
t2->Yield() && t2->Yield()->Tag() == TYPE_ANY )
{
auto op2_loc = op2->GetLocationInfo();
ExprPtr red_rhs = op2->ReduceToSingleton(c, rhs_reduce);
op2 = make_intrusive<CoerceFromAnyVecExpr>(red_rhs, t1);
op2->SetLocationInfo(op2_loc);
}
auto lhs_ref = op1->AsRefExprPtr();
auto lhs_expr = lhs_ref->GetOp1();
@ -2881,7 +2897,7 @@ ExprPtr CoerceToAnyExpr::Duplicate()
CoerceFromAnyExpr::CoerceFromAnyExpr(ExprPtr arg_op, TypePtr to_type)
: UnaryExpr(EXPR_FROM_ANY_COERCE, std::move(arg_op))
{
type = to_type;
type = std::move(to_type);
}
ValPtr CoerceFromAnyExpr::Fold(Val* v) const
@ -2901,6 +2917,35 @@ ExprPtr CoerceFromAnyExpr::Duplicate()
}
CoerceFromAnyVecExpr::CoerceFromAnyVecExpr(ExprPtr arg_op, TypePtr to_type)
: UnaryExpr(EXPR_FROM_ANY_VEC_COERCE, std::move(arg_op))
{
type = std::move(to_type);
}
ValPtr CoerceFromAnyVecExpr::Eval(Frame* f) const
{
if ( IsError() )
return nullptr;
auto v = op->Eval(f);
if ( ! v )
return nullptr;
auto vv = v->AsVectorVal();
if ( ! vv->Concretize(type->Yield()) )
RuntimeError("incompatible \"vector of any\" type");
return v;
}
ExprPtr CoerceFromAnyVecExpr::Duplicate()
{
return SetSucc(new CoerceFromAnyVecExpr(op->Duplicate(), type));
}
AnyIndexExpr::AnyIndexExpr(ExprPtr arg_op, int _index)
: UnaryExpr(EXPR_ANY_INDEX, std::move(arg_op))
{