summaryrefslogtreecommitdiff
path: root/formula
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2018-07-24 15:28:49 +0200
committerLuboš Luňák <l.lunak@collabora.com>2018-07-31 16:01:40 +0200
commit1bf7bc6f9929ceae0ea059b64ae0efa12228525f (patch)
treea682697177f49af89d62ec7042dd8ae2eb871663 /formula
parent58a15b452801f1f6f1b3e9f2fef49a1249538ac5 (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.cxx64
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();