Rewrite AST optimization infrastructure to be built on top of WalkAST().
Specifically, stmts and exprs are no longer responsible for first recursively optimizing their children before doing their own optimization (this turned out to be error-prone, with children sometimes being forgotten.) They now are just responsible for their own optimization, when appropriate.
This commit is contained in:
132
stmt.cpp
132
stmt.cpp
@@ -58,6 +58,15 @@
|
||||
#include <llvm/Support/IRBuilder.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Stmt
|
||||
|
||||
Stmt *
|
||||
Stmt::Optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ExprStmt
|
||||
|
||||
@@ -77,14 +86,6 @@ ExprStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ExprStmt::Optimize() {
|
||||
if (expr)
|
||||
expr = expr->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ExprStmt::TypeCheck() {
|
||||
if (expr)
|
||||
@@ -345,7 +346,7 @@ DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
// FIXME: and this is only needed to re-establish
|
||||
// constant-ness so that GetConstant below works for
|
||||
// constant artithmetic expressions...
|
||||
initExpr = initExpr->Optimize();
|
||||
initExpr = ::Optimize(initExpr);
|
||||
}
|
||||
|
||||
cinit = initExpr->GetConstant(sym->type);
|
||||
@@ -388,10 +389,8 @@ DeclStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
Stmt *
|
||||
DeclStmt::Optimize() {
|
||||
for (unsigned int i = 0; i < vars.size(); ++i) {
|
||||
if (vars[i].init != NULL) {
|
||||
vars[i].init = vars[i].init->Optimize();
|
||||
Expr *init = vars[i].init;
|
||||
|
||||
Expr *init = vars[i].init;
|
||||
if (init != NULL && dynamic_cast<ExprList *>(init) == NULL) {
|
||||
// If the variable is const-qualified, after we've optimized
|
||||
// the initializer expression, see if we have a ConstExpr. If
|
||||
// so, save it in Symbol::constValue where it can be used in
|
||||
@@ -408,8 +407,7 @@ DeclStmt::Optimize() {
|
||||
// computing array sizes from non-trivial expressions is
|
||||
// consequently limited.
|
||||
Symbol *sym = vars[i].sym;
|
||||
if (sym->type && sym->type->IsConstType() && init != NULL &&
|
||||
dynamic_cast<ExprList *>(init) == NULL &&
|
||||
if (sym->type && sym->type->IsConstType() &&
|
||||
Type::Equal(init->GetType(), sym->type))
|
||||
sym->constValue = dynamic_cast<ConstExpr *>(init);
|
||||
}
|
||||
@@ -566,18 +564,7 @@ IfStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
|
||||
|
||||
Stmt *
|
||||
IfStmt::Optimize() {
|
||||
if (test != NULL)
|
||||
test = test->Optimize();
|
||||
if (trueStmts != NULL)
|
||||
trueStmts = trueStmts->Optimize();
|
||||
if (falseStmts != NULL)
|
||||
falseStmts = falseStmts->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *IfStmt::TypeCheck() {
|
||||
IfStmt::TypeCheck() {
|
||||
if (test != NULL) {
|
||||
test = test->TypeCheck();
|
||||
if (test != NULL) {
|
||||
@@ -1133,16 +1120,6 @@ void DoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
DoStmt::Optimize() {
|
||||
if (testExpr)
|
||||
testExpr = testExpr->Optimize();
|
||||
if (bodyStmts)
|
||||
bodyStmts = bodyStmts->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
DoStmt::TypeCheck() {
|
||||
if (testExpr) {
|
||||
@@ -1345,20 +1322,6 @@ ForStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ForStmt::Optimize() {
|
||||
if (test)
|
||||
test = test->Optimize();
|
||||
if (init)
|
||||
init = init->Optimize();
|
||||
if (step)
|
||||
step = step->Optimize();
|
||||
if (stmts)
|
||||
stmts = stmts->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ForStmt::TypeCheck() {
|
||||
if (test) {
|
||||
@@ -1450,12 +1413,6 @@ BreakStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
BreakStmt::Optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
BreakStmt::TypeCheck() {
|
||||
return this;
|
||||
@@ -1495,12 +1452,6 @@ ContinueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ContinueStmt::Optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ContinueStmt::TypeCheck() {
|
||||
return this;
|
||||
@@ -1858,28 +1809,6 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ForeachStmt::Optimize() {
|
||||
bool anyErrors = false;
|
||||
for (unsigned int i = 0; i < startExprs.size(); ++i) {
|
||||
if (startExprs[i] != NULL)
|
||||
startExprs[i] = startExprs[i]->Optimize();
|
||||
anyErrors |= (startExprs[i] == NULL);
|
||||
}
|
||||
for (unsigned int i = 0; i < endExprs.size(); ++i) {
|
||||
if (endExprs[i] != NULL)
|
||||
endExprs[i] = endExprs[i]->Optimize();
|
||||
anyErrors |= (endExprs[i] == NULL);
|
||||
}
|
||||
|
||||
if (stmts != NULL)
|
||||
stmts = stmts->TypeCheck();
|
||||
anyErrors |= (stmts == NULL);
|
||||
|
||||
return anyErrors ? NULL : this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ForeachStmt::TypeCheck() {
|
||||
bool anyErrors = false;
|
||||
@@ -2007,14 +1936,6 @@ ReturnStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ReturnStmt::Optimize() {
|
||||
if (val)
|
||||
val = val->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
ReturnStmt::TypeCheck() {
|
||||
// FIXME: We don't have ctx->functionType available here; should we?
|
||||
@@ -2059,15 +1980,6 @@ StmtList::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
StmtList::Optimize() {
|
||||
for (unsigned int i = 0; i < stmts.size(); ++i)
|
||||
if (stmts[i])
|
||||
stmts[i] = stmts[i]->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
StmtList::TypeCheck() {
|
||||
for (unsigned int i = 0; i < stmts.size(); ++i)
|
||||
@@ -2280,14 +2192,6 @@ PrintStmt::Print(int indent) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
PrintStmt::Optimize() {
|
||||
if (values)
|
||||
values = values->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
PrintStmt::TypeCheck() {
|
||||
if (values)
|
||||
@@ -2364,14 +2268,6 @@ AssertStmt::Print(int indent) const {
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
AssertStmt::Optimize() {
|
||||
if (expr)
|
||||
expr = expr->Optimize();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Stmt *
|
||||
AssertStmt::TypeCheck() {
|
||||
if (expr)
|
||||
|
||||
Reference in New Issue
Block a user