Kaydet (Commit) 292ffa80 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

First cut on checking the token array on whether we could do vectorization.

Not tested yet.

Change-Id: I87f8a8595229d8d8e83526dc0334891d253cf2c7
üst 3a09e007
......@@ -94,6 +94,8 @@
#define SC_OPCODE_NEG_SUB 62
#define SC_OPCODE_STOP_UN_OP 63
#define SC_OPCODE_START_FUNCTION 65
/*** Functions without parameters ***/
#define SC_OPCODE_START_NO_PAR 65
#define SC_OPCODE_PI 65
......@@ -403,6 +405,8 @@
#define SC_OPCODE_STOP_2_PAR 407
#define SC_OPCODE_LAST_OPCODE_ID 406 /* last OpCode */
#define SC_OPCODE_STOP_FUNCTION 407
/*** Internal ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999
#define SC_OPCODE_TTT 9999
......
......@@ -192,6 +192,12 @@ public:
*/
bool Fill(const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& _aSequence, ExternalReferenceHelper* _pRef = NULL);
/**
* Do some checking based on the individual tokens. For now, we use this
* only to check whether we can vectorize the token array.
*/
virtual void CheckToken( const FormulaToken& t );
FormulaToken* AddToken( const FormulaToken& );
FormulaToken* AddString( const sal_Unicode* pStr );
FormulaToken* AddString( const String& rStr );
......
......@@ -708,6 +708,11 @@ void FormulaTokenArray::Clear()
ClearRecalcMode();
}
void FormulaTokenArray::CheckToken( const FormulaToken& /*r*/ )
{
// Do nothing.
}
FormulaToken* FormulaTokenArray::AddToken( const FormulaToken& r )
{
return Add( r.Clone() );
......@@ -724,6 +729,7 @@ FormulaToken* FormulaTokenArray::Add( FormulaToken* t )
pCode = new FormulaToken*[ MAXCODE ];
if( nLen < MAXCODE-1 )
{
CheckToken(*t);
pCode[ nLen++ ] = t;
if( t->GetOpCode() == ocPush
&& ( t->GetType() == svSingleRef || t->GetType() == svDoubleRef ) )
......
......@@ -33,9 +33,18 @@ struct ScComplexRefData;
class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
{
friend class ScCompiler;
/**
* When vectorization is enabled, we could potentially mass-calculate a
* series of formula token arrays in adjacent formula cells in one step,
* provided that they all contain identical set of tokens.
*/
enum VectorState { Disabled = 0, Enabled, CheckReference };
bool ImplGetReference( ScRange& rRange, bool bValidOnly ) const;
size_t mnHashValue;
VectorState meVectorState;
public:
ScTokenArray();
......@@ -61,6 +70,7 @@ public:
formula::FormulaToken* AddRawToken( const ScRawToken& );
virtual bool AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken,formula::ExternalReferenceHelper* _pRef);
virtual void CheckToken( const formula::FormulaToken& r );
virtual formula::FormulaToken* AddOpCode( OpCode eCode );
/** ScSingleRefToken with ocPush. */
formula::FormulaToken* AddSingleReference( const ScSingleRefData& rRef );
......
......@@ -1246,6 +1246,78 @@ bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _a
}
return bError;
}
void ScTokenArray::CheckToken( const FormulaToken& r )
{
if (meVectorState == Disabled)
// It's already disabled. No more checking needed.
return;
OpCode eOp = r.GetOpCode();
if (SC_OPCODE_START_FUNCTION <= eOp && eOp < SC_OPCODE_STOP_FUNCTION)
{
// This is a function opcode. For now, we only support vectorization
// for min, max, sum and average.
switch (eOp)
{
case ocAverage:
case ocMin:
case ocMinA:
case ocMax:
case ocMaxA:
case ocSum:
// Don't change the state.
break;
default:
meVectorState = Disabled;
}
return;
}
if (eOp == ocPush)
{
// This is a stack variable. See if this is a reference.
switch (r.GetType())
{
case svByte:
case svDouble:
case svString:
// Don't change the state.
break;
case svSingleRef:
case svDoubleRef:
// Depends on the reference state.
meVectorState = CheckReference;
break;
case svError:
case svEmptyCell:
case svExternal:
case svExternalDoubleRef:
case svExternalName:
case svExternalSingleRef:
case svFAP:
case svHybridCell:
case svHybridValueCell:
case svIndex:
case svJump:
case svJumpMatrix:
case svMatrix:
case svMatrixCell:
case svMissing:
case svRefList:
case svSep:
case svSubroutine:
case svUnknown:
// We don't support vectorization on these.
meVectorState = Disabled;
default:
;
}
}
}
bool ScTokenArray::ImplGetReference( ScRange& rRange, bool bValidOnly ) const
{
bool bIs = false;
......@@ -1380,13 +1452,15 @@ bool ScTokenArray::IsValidReference( ScRange& rRange ) const
ScTokenArray::ScTokenArray() :
FormulaTokenArray(),
mnHashValue(0)
mnHashValue(0),
meVectorState(Enabled)
{
}
ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) :
FormulaTokenArray(rArr),
mnHashValue(rArr.mnHashValue)
mnHashValue(rArr.mnHashValue),
meVectorState(rArr.meVectorState)
{
}
......@@ -1411,6 +1485,8 @@ ScTokenArray* ScTokenArray::Clone() const
p->nError = nError;
p->bHyperLink = bHyperLink;
p->mnHashValue = mnHashValue;
p->meVectorState = meVectorState;
FormulaToken** pp;
if( nLen )
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment