From 5cbdef02fbe4db10cda38022e2320f7c0f3d494b Mon Sep 17 00:00:00 2001 From: Antoine ELIAS Date: Thu, 17 Aug 2017 16:33:28 +0200 Subject: [PATCH] add size in constantvisitor //test function r = test(M) if size(M) == [2 3] then r = M + 1; else r = M + 2; end end tic();for i = 1:1d4, a = test([1 2 3, 4 5 6]);end,toc analyzerOptions(1); tic();for i = 1:1d4, a = test([1 2 3, 4 5 6]);end,toc Change-Id: I5b81fb83df6137c04cd542c4486d760b6a9b8ad8 --- .../ast/src/cpp/analysis/ConstantVisitor.cpp | 54 ++++++++++++++++++++ .../modules/ast/src/cpp/analysis/SizeAnalyzer.cpp | 50 +++++++++--------- .../ast/src/cpp/analysis/VisitAssignExp.cpp | 14 +++-- 3 files changed, 84 insertions(+), 34 deletions(-) diff --git a/scilab/modules/ast/src/cpp/analysis/ConstantVisitor.cpp b/scilab/modules/ast/src/cpp/analysis/ConstantVisitor.cpp index eab77f9..89d6d6c 100644 --- a/scilab/modules/ast/src/cpp/analysis/ConstantVisitor.cpp +++ b/scilab/modules/ast/src/cpp/analysis/ConstantVisitor.cpp @@ -15,6 +15,7 @@ #include "AnalysisVisitor.hxx" #include "ConstantVisitor.hxx" +#include "double.hxx" namespace analysis { @@ -259,6 +260,59 @@ void ConstantVisitor::visit(ast::CallExp & e) isConstant = true; } } + else if (name == L"size") + { + if (parent->getAnalyzer(sym)->analyze(*parent, lhs, e)) + { + switch (lhs) + { + case 1: // a = size(x) + { + std::vector & res = parent->getLHSContainer(); + double row; + res.front().getConstant().getDblValue(row); + + double col; + res.back().getConstant().getDblValue(col); + + types::Double* pIT = new types::Double(1, 2); + pIT->get()[0] = row; + pIT->get()[1] = col; + e.replace(new ast::DoubleExp(e.getLocation(), pIT)); + isConstant = true; + break; + } + case 2: // [a, b] = size(x) + { + double val; + ast::exps_t * exps = new ast::exps_t(); + exps->reserve(2); + std::vector & res = parent->getLHSContainer(); + res.front().getConstant().getDblValue(val); + exps->push_back(new ast::DoubleExp(e.getLocation(), val)); + res.back().getConstant().getDblValue(val); + exps->push_back(new ast::DoubleExp(e.getLocation(), val)); + e.replace(new ast::ArrayListExp(e.getLocation(), *exps)); + isConstant = true; + break; + } + } + } + } + } + else if (parent && args.size() == 2) + { + if (name == L"size") + { + if (parent->getAnalyzer(sym)->analyze(*parent, lhs, e)) + { + //a = size(x, "dims") or a = size(x, dim) + double val; + parent->getResult().getConstant().getDblValue(val); + e.replace(new ast::DoubleExp(e.getLocation(), val)); + isConstant = true; + } + } } } } diff --git a/scilab/modules/ast/src/cpp/analysis/SizeAnalyzer.cpp b/scilab/modules/ast/src/cpp/analysis/SizeAnalyzer.cpp index 4bf9b23..8a9d56e 100644 --- a/scilab/modules/ast/src/cpp/analysis/SizeAnalyzer.cpp +++ b/scilab/modules/ast/src/cpp/analysis/SizeAnalyzer.cpp @@ -29,10 +29,8 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as } const ast::exps_t args = e.getArgs(); - enum Kind - { - ROWS, COLS, ROWSTIMESCOLS, ROWSCOLS, ONE, BOTH, DUNNO - } kind = DUNNO; + SizeCall::Kind kind = SizeCall::DUNNO; + const std::size_t size = args.size(); if (size == 0 || size >= 3) { @@ -57,11 +55,11 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as case 1: if (lhs == 1) { - kind = BOTH; + kind = SizeCall::BOTH; } else if (lhs == 2) { - kind = ROWSCOLS; + kind = SizeCall::R_C; } break; case 2: @@ -74,15 +72,15 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as const std::wstring & arg2 = static_cast(second)->getValue(); if (arg2 == L"r") { - kind = ROWS; + kind = SizeCall::R; } else if (arg2 == L"c") { - kind = COLS; + kind = SizeCall::C; } else if (arg2 == L"*") { - kind = ROWSTIMESCOLS; + kind = SizeCall::RC; } else { @@ -95,16 +93,16 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as const double arg2 = static_cast(second)->getValue(); if (arg2 == 1) { - kind = ROWS; + kind = SizeCall::R; } else if (arg2 == 2) { - kind = COLS; + kind = SizeCall::C; } else if (arg2 >= 3) { // TODO: we should handle hypermatrix - kind = ONE; + kind = SizeCall::ONE; } else { @@ -129,7 +127,7 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as switch (kind) { - case ROWS: + case SizeCall::R: { SymbolicDimension & rows = res.getType().rows; Result & _res = e.getDecorator().setResult(type); @@ -138,7 +136,7 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as visitor.setResult(_res); break; } - case COLS: + case SizeCall::C: { SymbolicDimension & cols = res.getType().cols; Result & _res = e.getDecorator().setResult(type); @@ -147,19 +145,27 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as visitor.setResult(_res); break; } - case ROWSTIMESCOLS: + case SizeCall::RC: { SymbolicDimension & rows = res.getType().rows; SymbolicDimension & cols = res.getType().cols; SymbolicDimension prod = rows * cols; + Result & _res = e.getDecorator().setResult(type); _res.getConstant() = prod.getValue(); e.getDecorator().setCall(new SizeCall(SizeCall::RC)); visitor.setResult(_res); break; } - case ROWSCOLS: + case SizeCall::R_C: + case SizeCall::BOTH: { + if (kind == SizeCall::BOTH) + { + TIType _type(visitor.getGVN(), TIType::DOUBLE, 1, 2); + Result & _res = e.getDecorator().setResult(_type); + } + SymbolicDimension & rows = res.getType().rows; SymbolicDimension & cols = res.getType().cols; std::vector & mlhs = visitor.getLHSContainer(); @@ -170,10 +176,10 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as mlhs.emplace_back(type); mlhs.back().getConstant() = cols.getValue(); - e.getDecorator().setCall(new SizeCall(SizeCall::R_C)); + e.getDecorator().setCall(new SizeCall(kind)); break; } - case ONE: + case SizeCall::ONE: { Result & _res = e.getDecorator().setResult(type); _res.getConstant() = new types::Double(1); @@ -181,14 +187,6 @@ bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, as visitor.setResult(_res); break; } - case BOTH: - { - TIType _type(visitor.getGVN(), TIType::DOUBLE, 1, 2); - Result & _res = e.getDecorator().setResult(_type); - e.getDecorator().setCall(new SizeCall(SizeCall::BOTH)); - visitor.setResult(_res); - break; - } default: return false; } diff --git a/scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp b/scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp index fc67b8f..73317fd 100644 --- a/scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp +++ b/scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp @@ -48,14 +48,7 @@ void AnalysisVisitor::visit(ast::AssignExp & e) if (e.getRightExp().isCallExp()) // A = foo(...) { - if (e.getRightExp().isCallExp()) - { - visit(static_cast(e.getRightExp()), /* LHS */ 1); - } - else - { - e.getRightExp().accept(*this); - } + visit(static_cast(e.getRightExp()), /* LHS */ 1); } else // A = 1 + 2 { @@ -100,6 +93,11 @@ void AnalysisVisitor::visit(ast::AssignExp & e) if (e.getRightExp().isCallExp()) { const ast::exps_t & exps = ale.getExps(); + + // apply the ConstantVisitor + cv.setLHS(exps.size()); + e.getRightExp().accept(cv); + visit(static_cast(e.getRightExp()), /* LHS */ exps.size()); std::vector::iterator j = multipleLHS.begin(); for (const auto exp : exps) -- 1.7.9.5