Commit 84249fde by Nicolas Capens Committed by Nicolas Capens

Don't needlessly traverse the left hand side of assignments.

Previously we processed assignments in PostVisit, i.e. after both the left and right side had been traversed. This produces temporaries for the left hand side, which we don't use since we want to assign to the lvalue. So instead we can explicitly traverse the right hand side, and for the left hand side only traverse indirect indexing expressions. Change-Id: I9ec0596a9c256921b65a9f70428d950959f66aa0 Reviewed-on: https://swiftshader-review.googlesource.com/13630Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 91b425b2
...@@ -507,32 +507,30 @@ namespace glsl ...@@ -507,32 +507,30 @@ namespace glsl
switch(node->getOp()) switch(node->getOp())
{ {
case EOpAssign: case EOpAssign:
if(visit == PostVisit) assert(visit == PreVisit);
{ right->traverse(this);
assignLvalue(left, right); assignLvalue(left, right);
copy(result, right); copy(result, right);
} return false;
break;
case EOpInitialize: case EOpInitialize:
if(visit == PostVisit) assert(visit == PreVisit);
{ right->traverse(this);
copy(left, right); copy(left, right);
} return false;
break;
case EOpMatrixTimesScalarAssign: case EOpMatrixTimesScalarAssign:
if(visit == PostVisit) assert(visit == PreVisit);
right->traverse(this);
for(int i = 0; i < leftType.getNominalSize(); i++)
{ {
for(int i = 0; i < leftType.getNominalSize(); i++) emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);
{
emit(sw::Shader::OPCODE_MUL, result, i, left, i, right);
}
assignLvalue(left, result);
} }
break;
assignLvalue(left, result);
return false;
case EOpVectorTimesMatrixAssign: case EOpVectorTimesMatrixAssign:
if(visit == PostVisit) assert(visit == PreVisit);
{ {
right->traverse(this);
int size = leftType.getNominalSize(); int size = leftType.getNominalSize();
for(int i = 0; i < size; i++) for(int i = 0; i < size; i++)
...@@ -543,10 +541,11 @@ namespace glsl ...@@ -543,10 +541,11 @@ namespace glsl
assignLvalue(left, result); assignLvalue(left, result);
} }
break; return false;
case EOpMatrixTimesMatrixAssign: case EOpMatrixTimesMatrixAssign:
if(visit == PostVisit) assert(visit == PreVisit);
{ {
right->traverse(this);
int dim = leftType.getNominalSize(); int dim = leftType.getNominalSize();
for(int i = 0; i < dim; i++) for(int i = 0; i < dim; i++)
...@@ -563,7 +562,7 @@ namespace glsl ...@@ -563,7 +562,7 @@ namespace glsl
assignLvalue(left, result); assignLvalue(left, result);
} }
break; return false;
case EOpIndexDirect: case EOpIndexDirect:
if(visit == PostVisit) if(visit == PostVisit)
{ {
...@@ -2311,9 +2310,8 @@ namespace glsl ...@@ -2311,9 +2310,8 @@ namespace glsl
void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src) void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)
{ {
if(src && if((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) ||
((src->isVector() && (!dst->isVector() || (src->getNominalSize() != dst->getNominalSize()))) || (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize()))))
(src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize()) || (src->getSecondarySize() != dst->getSecondarySize())))))
{ {
return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix"); return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");
} }
...@@ -2337,21 +2335,25 @@ namespace glsl ...@@ -2337,21 +2335,25 @@ namespace glsl
} }
else else
{ {
for(int offset = 0; offset < dst->totalRegisterCount(); offset++) Instruction *mov1 = new Instruction(sw::Shader::OPCODE_MOV);
Temporary address(this);
int swizzle = lvalue(mov1->dst, address, dst);
argument(mov1->src[0], src);
mov1->src[0].swizzle = swizzleSwizzle(mov1->src[0].swizzle, swizzle);
shader->append(mov1);
for(int offset = 1; offset < dst->totalRegisterCount(); offset++)
{ {
Instruction *mov = new Instruction(sw::Shader::OPCODE_MOV); Instruction *mov = new Instruction(sw::Shader::OPCODE_MOV);
Temporary address(this); mov->dst = mov1->dst;
int swizzle = lvalue(mov->dst, address, dst);
mov->dst.index += offset; mov->dst.index += offset;
mov->dst.mask = writeMask(dst, offset);
if(offset > 0)
{
mov->dst.mask = writeMask(dst, offset);
}
argument(mov->src[0], src, offset); argument(mov->src[0], src, offset);
mov->src[0].swizzle = swizzleSwizzle(mov->src[0].swizzle, swizzle);
shader->append(mov); shader->append(mov);
} }
...@@ -2402,6 +2404,8 @@ namespace glsl ...@@ -2402,6 +2404,8 @@ namespace glsl
break; break;
case EOpIndexIndirect: case EOpIndexIndirect:
{ {
right->traverse(this);
if(left->isRegister()) if(left->isRegister())
{ {
// Requires INSERT instruction (handled by calling function) // Requires INSERT instruction (handled by calling function)
......
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