reduction of Stmt subclasses - compiles but does not yet link

This commit is contained in:
Vern Paxson 2021-01-10 14:13:16 -08:00
parent 10e80dfcd3
commit 7a9694a2a4
4 changed files with 1059 additions and 66 deletions

View file

@ -26,6 +26,9 @@ public:
// Optimization-related:
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
protected:
ExprListStmt(StmtTag t, ListExprPtr arg_l);
@ -38,6 +41,12 @@ protected:
void StmtDescribe(ODesc* d) const override;
ListExprPtr l;
// Optimization-related:
// Returns a new version of the original derived object
// based on the given list of singleton expressions.
virtual StmtPtr DoSubclassReduce(ListExprPtr singletons, Reducer* c) = 0;
};
class PrintStmt final : public ExprListStmt {
@ -51,6 +60,9 @@ public:
protected:
ValPtr DoExec(std::vector<ValPtr> vals,
StmtFlowType& flow) const override;
// Optimization-related:
StmtPtr DoSubclassReduce(ListExprPtr singletons, Reducer* c) override;
};
class ExprStmt : public Stmt {
@ -58,9 +70,15 @@ public:
explicit ExprStmt(ExprPtr e);
~ExprStmt() override;
// This constructor is only meant for internal use, but it's
// not protected since ExprPtr's mask the actual caller,
// not allowing us to use "friend" for protected access.
ExprStmt(StmtTag t, ExprPtr e);
ValPtr Exec(Frame* f, StmtFlowType& flow) const override;
const Expr* StmtExpr() const { return e.get(); }
ExprPtr StmtExprPtr() const;
void StmtDescribe(ODesc* d) const override;
@ -70,9 +88,10 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
protected:
ExprStmt(StmtTag t, ExprPtr e);
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
protected:
virtual ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) const;
bool IsPure() const override;
@ -96,6 +115,11 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
bool NoFlowAfter(bool ignore_break) const override;
protected:
ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) const override;
bool IsPure() const override;
@ -118,6 +142,8 @@ public:
const Stmt* Body() const { return s.get(); }
Stmt* Body() { return s.get(); }
void UpdateBody(StmtPtr new_body) { s = new_body; }
void Describe(ODesc* d) const override;
TraversalCode Traverse(TraversalCallback* cb) const;
@ -148,6 +174,11 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
bool NoFlowAfter(bool ignore_break) const override;
protected:
ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) const override;
bool IsPure() const override;
@ -178,28 +209,38 @@ protected:
std::vector<std::pair<ID*, int>> case_label_type_list;
};
class AddStmt final : public ExprStmt {
// Helper class. Added for script optimization, but it makes sense
// in terms of factoring even without.
class AddDelStmt : public ExprStmt {
public:
TraversalCode Traverse(TraversalCallback* cb) const override;
bool IsPure() const override;
// Optimization-related:
StmtPtr DoReduce(Reducer* c) override;
bool IsReduced(Reducer* c) const override;
protected:
AddDelStmt(StmtTag t, ExprPtr arg_e);
};
class AddStmt final : public AddDelStmt {
public:
explicit AddStmt(ExprPtr e);
bool IsPure() const override;
ValPtr Exec(Frame* f, StmtFlowType& flow) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
// Optimization-related:
StmtPtr Duplicate() override;
};
class DelStmt final : public ExprStmt {
class DelStmt final : public AddDelStmt {
public:
explicit DelStmt(ExprPtr e);
bool IsPure() const override;
ValPtr Exec(Frame* f, StmtFlowType& flow) const override;
TraversalCode Traverse(TraversalCallback* cb) const override;
// Optimization-related:
StmtPtr Duplicate() override;
};
@ -215,6 +256,8 @@ public:
// Optimization-related:
StmtPtr Duplicate() override;
StmtPtr DoReduce(Reducer* c) override;
protected:
EventExprPtr event_expr;
};
@ -232,11 +275,20 @@ public:
TraversalCode Traverse(TraversalCallback* cb) const override;
// Optimization-related:
const Stmt* CondStmt() const
{ return loop_cond_stmt ? loop_cond_stmt.get() : nullptr; }
StmtPtr CondPredStmt() const
{ return loop_cond_pred_stmt ? loop_cond_pred_stmt : nullptr; }
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
// Note, no need for a NoFlowAfter method because the loop might
// execute zero times, so it's always the default of "false".
const StmtPtr ConditionAsStmt() const
{ return stmt_loop_condition; }
protected:
ValPtr Exec(Frame* f, StmtFlowType& flow) const override;
@ -246,8 +298,14 @@ protected:
// Optimization-related member variables.
// When in reduced form, the following holds a statement (which
// might be a block) for evaluating the loop's conditional.
StmtPtr loop_cond_stmt = nullptr;
// might be a block) that's a *predecessor* necessary for evaluating
// the loop's conditional.
StmtPtr loop_cond_pred_stmt = nullptr;
// When reducing, we create a *statement* associated with
// evaluating the reduced conditional, as well as the reduced
// expression. This turns out to be useful in propagating RDs/UDs.
StmtPtr stmt_loop_condition = nullptr;
};
class ForStmt final : public ExprStmt {
@ -274,6 +332,12 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
// Note, no need for a NoFlowAfter method because the loop might
// execute zero times, so it's always the default of "false".
protected:
ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) const override;
@ -297,6 +361,9 @@ public:
// Optimization-related:
StmtPtr Duplicate() override { return SetSucc(new NextStmt()); }
bool NoFlowAfter(bool ignore_break) const override
{ return true; }
protected:
};
@ -314,6 +381,9 @@ public:
// Optimization-related:
StmtPtr Duplicate() override { return SetSucc(new BreakStmt()); }
bool NoFlowAfter(bool ignore_break) const override
{ return ! ignore_break; }
protected:
};
@ -349,6 +419,12 @@ public:
// Constructor used for duplication, when we've already done
// all of the type-checking.
ReturnStmt(ExprPtr e, bool ignored);
// Optimization-related:
StmtPtr DoReduce(Reducer* c) override;
bool NoFlowAfter(bool ignore_break) const override
{ return true; }
};
class StmtList : public Stmt {
@ -358,8 +434,8 @@ public:
ValPtr Exec(Frame* f, StmtFlowType& flow) const override;
const StmtPList& Stmts() const { return stmts; }
StmtPList& Stmts() { return stmts; }
const StmtPList& Stmts() const { return *stmts; }
StmtPList& Stmts() { return *stmts; }
void StmtDescribe(ODesc* d) const override;
@ -369,6 +445,11 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
bool NoFlowAfter(bool ignore_break) const override;
// Idioms commonly used in reduction.
StmtList(StmtPtr s1, Stmt* s2);
StmtList(StmtPtr s1, StmtPtr s2);
@ -377,7 +458,16 @@ public:
protected:
bool IsPure() const override;
StmtPList stmts;
StmtPList* stmts;
// Optimization-related:
bool ReduceStmt(int& s_i, StmtPList* f_stmts, Reducer* c);
void ResetStmts(StmtPList* new_stmts)
{
delete stmts;
stmts = new_stmts;
}
};
class InitStmt final : public Stmt {
@ -396,6 +486,9 @@ public:
// Optimization-related:
StmtPtr Duplicate() override;
bool IsReduced(Reducer* c) const override;
StmtPtr DoReduce(Reducer* c) override;
protected:
std::vector<IDPtr> inits;
};
@ -439,6 +532,8 @@ public:
StmtPtr Duplicate() override;
void Inline(Inliner* inl) override;
bool IsReduced(Reducer* c) const override;
protected:
ExprPtr cond;
StmtPtr s1;