working for folding & for loops - not enough win though

This commit is contained in:
Vern Paxson 2025-07-28 11:22:28 -07:00
parent 1fdd1f72c0
commit 59803f3589
5 changed files with 49 additions and 5 deletions

View file

@ -1568,6 +1568,8 @@ public:
ExprPtr Duplicate() override;
ExprPtr Inline(Inliner* inl) override;
ValPtr FoldVal() const override;
bool IsReduced(Reducer* c) const override;
bool HasReducedOps(Reducer* c) const override;
ExprPtr Reduce(Reducer* c, StmtPtr& red_stmt) override;

View file

@ -473,11 +473,18 @@ ExprPtr UnaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
if ( ! op->IsSingleton(c) )
op = op->ReduceToSingleton(c, red_stmt);
auto op_val = op->FoldVal();
if ( op_val ) {
auto fold = Fold(op_val.get());
if ( fold->GetType()->Tag() != TYPE_OPAQUE )
return TransformMe(make_intrusive<ConstExpr>(fold), c, red_stmt);
if ( tag != EXPR_VECTOR_CONSTRUCTOR && tag != EXPR_TABLE_CONSTRUCTOR && tag != EXPR_RECORD_CONSTRUCTOR ) {
auto op_val = op->FoldVal();
if ( ! op_val ) {
op_val = c->EvalIfGlobalAggrConstant(op);
if ( op_val )
printf("unary w/ global aggr fold: %s\n", obj_desc(this).c_str());
}
if ( op_val ) {
auto fold = Fold(op_val.get());
if ( fold->GetType()->Tag() != TYPE_OPAQUE )
return TransformMe(make_intrusive<ConstExpr>(fold), c, red_stmt);
}
}
if ( c->Optimizing() )
@ -522,7 +529,13 @@ ExprPtr BinaryExpr::Reduce(Reducer* c, StmtPtr& red_stmt) {
// We can turn the list into a ListVal.
op1_fold_val = op1->Eval(nullptr);
if ( ! op1_fold_val )
op1_fold_val = c->EvalIfGlobalAggrConstant(op1);
auto op2_fold_val = op2->FoldVal();
if ( ! op2_fold_val )
op2_fold_val = c->EvalIfGlobalAggrConstant(op2);
if ( op1_fold_val && op2_fold_val ) {
auto fold = Fold(op1_fold_val.get(), op2_fold_val.get());
if ( fold->GetType()->Tag() != TYPE_OPAQUE )
@ -2480,6 +2493,18 @@ ExprPtr ListExpr::Inline(Inliner* inl) {
return ThisPtr();
}
ValPtr ListExpr::FoldVal() const {
std::vector<ValPtr> vals;
vals.reserve(exprs.length());
loop_over_list(exprs, i) {
auto v = exprs[i]->FoldVal();
if ( ! v )
return nullptr;
vals.push_back(std::move(v));
}
return make_intrusive<ListVal>(cast_intrusive<TypeList>(type), std::move(vals));
}
bool ListExpr::IsReduced(Reducer* c) const {
for ( const auto& expr : exprs )
if ( ! expr->IsSingleton(c) ) {

View file

@ -634,6 +634,17 @@ ConstExprPtr Reducer::Fold(ExprPtr e) {
return c;
}
ValPtr Reducer::EvalIfGlobalAggrConstant(ExprPtr e) const {
if ( e->Tag() != EXPR_NAME )
return nullptr;
auto id = e->AsNameExpr()->Id();
if ( id->IsGlobal() && pfs->ConstAggrGlobals().count(id) > 0 )
return id->GetVal();
return nullptr;
}
void Reducer::FoldedTo(ExprPtr e, ConstExprPtr c) {
c->SetLocationInfo(e->GetLocationInfo());
om.AddObj(e.get());

View file

@ -145,6 +145,10 @@ public:
// (which must have constant operands).
ConstExprPtr Fold(ExprPtr e);
// If the given expression refers to a global that's both (1) an aggregate
// value, and (2) constant then returns its constant value, nil otherwise.
ValPtr EvalIfGlobalAggrConstant(ExprPtr e) const;
// Notes that the given expression has been folded to the given constant.
void FoldedTo(ExprPtr orig, ConstExprPtr c);

View file

@ -619,6 +619,8 @@ StmtPtr ForStmt::DoReduce(Reducer* c) {
e = c->OptExpr(e);
else {
e = e->Reduce(c, red_e_stmt);
if ( c->EvalIfGlobalAggrConstant(e) )
printf("for loop opt: %s\n", obj_desc(this).c_str());
c->UpdateIDs(loop_vars);
if ( value_var )