diff options
author | 2017-01-19 16:31:32 +0000 | |
---|---|---|
committer | 2017-01-19 16:31:44 +0000 | |
commit | 6415e0d2417d133af28ac523400d3f958d2bcd1c (patch) | |
tree | 92fbe77322ba50e984f6d85870f40bad70ccacf4 /src/sksl/SkSLCompiler.cpp | |
parent | f54b07121f81a56145fb118a2e18841fc135717d (diff) |
Revert "Added constant propagation and better variable liveness tracking to"
This reverts commit f54b07121f81a56145fb118a2e18841fc135717d.
Reason for revert: ASAN failure
Original change's description:
> Added constant propagation and better variable liveness tracking to
> skslc.
>
> This allows skslc to track the values of variables with constant
> values across multiple statements and replace variable references with
> constant values where appropriate.
>
> The improved liveness tracking allows skslc to realize that a
> variable is no longer alive if all references to it have been
> replaced. It is not yet doing much with this information; better
> dead code elimination is coming in a followup change.
>
> BUG=skia:
>
> Change-Id: I6bf267d478b769caf0063ac3597dc16bbe618cb4
> Reviewed-on: https://skia-review.googlesource.com/7033
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
> Reviewed-by: Greg Daniel <egdaniel@google.com>
>
TBR=egdaniel@google.com,ethannicholas@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Change-Id: Id2e26bce96b27df73948f8b32d3dff2e358ae0d6
Reviewed-on: https://skia-review.googlesource.com/7274
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/sksl/SkSLCompiler.cpp')
-rw-r--r-- | src/sksl/SkSLCompiler.cpp | 119 |
1 files changed, 33 insertions, 86 deletions
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 743745ad14..9faf836156 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -156,8 +156,8 @@ Compiler::~Compiler() { } // add the definition created by assigning to the lvalue to the definition set -void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, - DefinitionMap* definitions) { +void Compiler::addDefinition(const Expression* lvalue, const Expression* expr, + std::unordered_map<const Variable*, const Expression*>* definitions) { switch (lvalue->fKind) { case Expression::kVariableReference_Kind: { const Variable& var = ((VariableReference*) lvalue)->fVariable; @@ -174,19 +174,19 @@ void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expressio // but since we pass foo as a whole it is flagged as an error) unless we perform a much // more complicated whole-program analysis. This is probably good enough. this->addDefinition(((Swizzle*) lvalue)->fBase.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, + fContext.fDefined_Expression.get(), definitions); break; case Expression::kIndex_Kind: // see comments in Swizzle this->addDefinition(((IndexExpression*) lvalue)->fBase.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, + fContext.fDefined_Expression.get(), definitions); break; case Expression::kFieldAccess_Kind: // see comments in Swizzle this->addDefinition(((FieldAccess*) lvalue)->fBase.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, + fContext.fDefined_Expression.get(), definitions); break; default: @@ -197,58 +197,25 @@ void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expressio // add local variables defined by this node to the set void Compiler::addDefinitions(const BasicBlock::Node& node, - DefinitionMap* definitions) { + std::unordered_map<const Variable*, const Expression*>* definitions) { switch (node.fKind) { case BasicBlock::Node::kExpression_Kind: { - ASSERT(node.fExpression); - const Expression* expr = (Expression*) node.fExpression->get(); - switch (expr->fKind) { - case Expression::kBinary_Kind: { - BinaryExpression* b = (BinaryExpression*) expr; - if (b->fOperator == Token::EQ) { - this->addDefinition(b->fLeft.get(), &b->fRight, definitions); - } else if (Token::IsAssignment(b->fOperator)) { - this->addDefinition( - b->fLeft.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, - definitions); - - } - break; - } - case Expression::kPrefix_Kind: { - const PrefixExpression* p = (PrefixExpression*) expr; - if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { - this->addDefinition( - p->fOperand.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, - definitions); - } - break; + const Expression* expr = (Expression*) node.fNode; + if (expr->fKind == Expression::kBinary_Kind) { + const BinaryExpression* b = (BinaryExpression*) expr; + if (b->fOperator == Token::EQ) { + this->addDefinition(b->fLeft.get(), b->fRight.get(), definitions); } - case Expression::kPostfix_Kind: { - const PostfixExpression* p = (PostfixExpression*) expr; - if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { - this->addDefinition( - p->fOperand.get(), - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, - definitions); - - } - break; - } - default: - break; } break; } case BasicBlock::Node::kStatement_Kind: { - const Statement* stmt = (Statement*) node.fStatement; + const Statement* stmt = (Statement*) node.fNode; if (stmt->fKind == Statement::kVarDeclarations_Kind) { - VarDeclarationsStatement* vd = (VarDeclarationsStatement*) stmt; - for (VarDeclaration& decl : vd->fDeclaration->fVars) { + const VarDeclarationsStatement* vd = (VarDeclarationsStatement*) stmt; + for (const VarDeclaration& decl : vd->fDeclaration->fVars) { if (decl.fValue) { - (*definitions)[decl.fVar] = &decl.fValue; + (*definitions)[decl.fVar] = decl.fValue.get(); } } } @@ -261,7 +228,7 @@ void Compiler::scanCFG(CFG* cfg, BlockId blockId, std::set<BlockId>* workList) { BasicBlock& block = cfg->fBlocks[blockId]; // compute definitions after this block - DefinitionMap after = block.fBefore; + std::unordered_map<const Variable*, const Expression*> after = block.fBefore; for (const BasicBlock::Node& n : block.fNodes) { this->addDefinitions(n, &after); } @@ -270,20 +237,19 @@ void Compiler::scanCFG(CFG* cfg, BlockId blockId, std::set<BlockId>* workList) { for (BlockId exitId : block.fExits) { BasicBlock& exit = cfg->fBlocks[exitId]; for (const auto& pair : after) { - std::unique_ptr<Expression>* e1 = pair.second; - auto found = exit.fBefore.find(pair.first); - if (found == exit.fBefore.end()) { - // exit has no definition for it, just copy it - workList->insert(exitId); + const Expression* e1 = pair.second; + if (exit.fBefore.find(pair.first) == exit.fBefore.end()) { exit.fBefore[pair.first] = e1; } else { - // exit has a (possibly different) value already defined - std::unique_ptr<Expression>* e2 = exit.fBefore[pair.first]; + const Expression* e2 = exit.fBefore[pair.first]; if (e1 != e2) { // definition has changed, merge and add exit block to worklist workList->insert(exitId); - exit.fBefore[pair.first] = - (std::unique_ptr<Expression>*) &fContext.fDefined_Expression; + if (!e1 || !e2) { + exit.fBefore[pair.first] = nullptr; + } else { + exit.fBefore[pair.first] = fContext.fDefined_Expression.get(); + } } } } @@ -292,13 +258,12 @@ void Compiler::scanCFG(CFG* cfg, BlockId blockId, std::set<BlockId>* workList) { // returns a map which maps all local variables in the function to null, indicating that their value // is initially unknown -static DefinitionMap compute_start_state(const CFG& cfg) { - DefinitionMap result; +static std::unordered_map<const Variable*, const Expression*> compute_start_state(const CFG& cfg) { + std::unordered_map<const Variable*, const Expression*> result; for (const auto& block : cfg.fBlocks) { for (const auto& node : block.fNodes) { if (node.fKind == BasicBlock::Node::kStatement_Kind) { - ASSERT(node.fStatement); - const Statement* s = node.fStatement; + const Statement* s = (Statement*) node.fNode; if (s->fKind == Statement::kVarDeclarations_Kind) { const VarDeclarationsStatement* vd = (const VarDeclarationsStatement*) s; for (const VarDeclaration& decl : vd->fDeclaration->fVars) { @@ -330,37 +295,19 @@ void Compiler::scanCFG(const FunctionDefinition& f) { for (size_t i = 0; i < cfg.fBlocks.size(); i++) { if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() && cfg.fBlocks[i].fNodes.size()) { - Position p; - switch (cfg.fBlocks[i].fNodes[0].fKind) { - case BasicBlock::Node::kStatement_Kind: - p = cfg.fBlocks[i].fNodes[0].fStatement->fPosition; - break; - case BasicBlock::Node::kExpression_Kind: - p = (*cfg.fBlocks[i].fNodes[0].fExpression)->fPosition; - break; - } - this->error(p, SkString("unreachable")); + this->error(cfg.fBlocks[i].fNodes[0].fNode->fPosition, SkString("unreachable")); } } if (fErrorCount) { return; } - // check for undefined variables, perform constant propagation - for (BasicBlock& b : cfg.fBlocks) { - DefinitionMap definitions = b.fBefore; - for (BasicBlock::Node& n : b.fNodes) { + // check for undefined variables + for (const BasicBlock& b : cfg.fBlocks) { + std::unordered_map<const Variable*, const Expression*> definitions = b.fBefore; + for (const BasicBlock::Node& n : b.fNodes) { if (n.fKind == BasicBlock::Node::kExpression_Kind) { - ASSERT(n.fExpression); - Expression* expr = n.fExpression->get(); - if (n.fConstantPropagation) { - std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, - definitions); - if (optimized) { - n.fExpression->reset(optimized.release()); - expr = n.fExpression->get(); - } - } + const Expression* expr = (const Expression*) n.fNode; if (expr->fKind == Expression::kVariableReference_Kind) { const Variable& var = ((VariableReference*) expr)->fVariable; if (var.fStorage == Variable::kLocal_Storage && |