diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2018-07-24 15:28:49 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2018-07-31 16:01:40 +0200 |
commit | 1bf7bc6f9929ceae0ea059b64ae0efa12228525f (patch) | |
tree | a682697177f49af89d62ec7042dd8ae2eb871663 /formula | |
parent | 58a15b452801f1f6f1b3e9f2fef49a1249538ac5 (diff) |
try to detect that a formula does not contain any implicit intersection
Commit 67444cbe disabled svDoubleRef completely for OpenCL, which means
many formulas weren't handled by OpenCL even if the implicit intersection
problems are quite rare. This patch tries to detect formulas implicit
intersections in formulas and if it's certain that a formula does not
contain one, then it's ok to use OpenCL with svDoubleRef.
The detection is done by having ScCompiler analyze each opcode call
and its parameters, which should provide sufficient information to know
if implicit intersection can take place or not. The extra compilation
can be avoided by using OpenCL's compilation and doing the svDoubleRef
conversion later on the RPN code, to be done later.
This is opt-in, so if unsure don't do anything, if it turns out that some
opcode needs special handling, it can be simply added.
Change-Id: Iaa52fa7eb8b14dc8c2b92384a21e2ab8efe0ddd7
Reviewed-on: https://gerrit.libreoffice.org/57959
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'formula')
-rw-r--r-- | formula/source/core/api/FormulaCompiler.cxx | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index c22f9edbdbe1..3329db657812 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -1349,6 +1349,10 @@ bool FormulaCompiler::GetToken() return HandleDbData(); case ocTableRef: return HandleTableRef(); + case ocPush: + if( mbComputeII ) + HandleIIOpCode(mpToken.get(), nullptr, 0); + break; default: ; // nothing } @@ -1556,7 +1560,6 @@ void FormulaCompiler::Factor() else { // standard handling of 1-parameter opcodes - OpCode eMyLastOp = eOp; pFacToken = mpToken; eOp = NextToken(); if( nNumFmt == SvNumFormatType::UNDEFINED && eOp == ocNot ) @@ -1574,10 +1577,10 @@ void FormulaCompiler::Factor() else if ( pArr->GetCodeError() == FormulaError::NONE ) { pFacToken->SetByte( 1 ); - if (mbComputeII && IsIIOpCode(eMyLastOp)) + if (mbComputeII) { FormulaToken** pArg = pCode - 1; - HandleIIOpCode(eMyLastOp, pFacToken->GetInForceArray(), &pArg, 1); + HandleIIOpCode(pFacToken, &pArg, 1); } } PutCode( pFacToken ); @@ -1621,7 +1624,7 @@ void FormulaCompiler::Factor() sal_uInt32 nSepCount = 0; if( !bNoParam ) { - bool bDoIICompute = mbComputeII && IsIIOpCode(eMyLastOp); + bool bDoIICompute = mbComputeII; // Array of FormulaToken double pointers to collect the parameters of II opcodes. FormulaToken*** pArgArray = nullptr; if (bDoIICompute) @@ -1648,7 +1651,7 @@ void FormulaCompiler::Factor() pArgArray[nSepCount - 1] = pCode - 1; // Add rest of the arguments } if (bDoIICompute) - HandleIIOpCode(eMyLastOp, pFacToken->GetInForceArray(), pArgArray, + HandleIIOpCode(pFacToken, pArgArray, std::min(nSepCount, static_cast<sal_uInt32>(FORMULA_MAXPARAMSII))); } if (bBadName) @@ -1873,10 +1876,10 @@ void FormulaCompiler::UnaryLine() FormulaTokenRef p = mpToken; NextToken(); UnaryLine(); - if (mbComputeII && IsIIOpCode(p->GetOpCode())) + if (mbComputeII) { FormulaToken** pArg = pCode - 1; - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), &pArg, 1); + HandleIIOpCode(p.get(), &pArg, 1); } PutCode( p ); } @@ -1889,10 +1892,10 @@ void FormulaCompiler::PostOpLine() UnaryLine(); while ( mpToken->GetOpCode() == ocPercentSign ) { // this operator _follows_ its operand - if (mbComputeII && IsIIOpCode(mpToken->GetOpCode())) + if (mbComputeII) { FormulaToken** pArg = pCode - 1; - HandleIIOpCode(mpToken->GetOpCode(), mpToken->GetInForceArray(), &pArg, 1); + HandleIIOpCode(mpToken.get(), &pArg, 1); } PutCode( mpToken ); NextToken(); @@ -1905,16 +1908,15 @@ void FormulaCompiler::PowLine() while (mpToken->GetOpCode() == ocPow) { FormulaTokenRef p = mpToken; - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); PostOpLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -1926,16 +1928,15 @@ void FormulaCompiler::MulDivLine() while (mpToken->GetOpCode() == ocMul || mpToken->GetOpCode() == ocDiv) { FormulaTokenRef p = mpToken; - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); PowLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -1947,16 +1948,15 @@ void FormulaCompiler::AddSubLine() while (mpToken->GetOpCode() == ocAdd || mpToken->GetOpCode() == ocSub) { FormulaTokenRef p = mpToken; - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); MulDivLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -1968,16 +1968,15 @@ void FormulaCompiler::ConcatLine() while (mpToken->GetOpCode() == ocAmpersand) { FormulaTokenRef p = mpToken; - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); AddSubLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -1989,16 +1988,15 @@ void FormulaCompiler::CompareLine() while (mpToken->GetOpCode() >= ocEqual && mpToken->GetOpCode() <= ocGreaterEqual) { FormulaTokenRef p = mpToken; - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); ConcatLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -2018,16 +2016,15 @@ OpCode FormulaCompiler::Expression() { FormulaTokenRef p = mpToken; mpToken->SetByte( 2 ); // 2 parameters! - bool bDoIICompute = mbComputeII && IsIIOpCode(p->GetOpCode()); FormulaToken** pArgArray[2]; - if (bDoIICompute) + if (mbComputeII) pArgArray[0] = pCode - 1; // Add first argument NextToken(); CompareLine(); - if (bDoIICompute) + if (mbComputeII) { pArgArray[1] = pCode - 1; // Add second argument - HandleIIOpCode(p->GetOpCode(), p->GetInForceArray(), pArgArray, 2); + HandleIIOpCode(p.get(), pArgArray, 2); } PutCode(p); } @@ -2101,6 +2098,7 @@ bool FormulaCompiler::CompileTokenArray() // Some trailing garbage that doesn't form an expression? if (eOp != ocStop) SetError( FormulaError::OperatorExpected); + PostProcessCode(); FormulaError nErrorBeforePop = pArr->GetCodeError(); |