Commit cd74a5a4 by Nicolas Capens

Fix predicating instructions before return in loops.

Only the instructions following a return statement were being marked as affected by it so predication would be applied. But in a loop the instructions above the return statement are also affected by it. Bug b/25220690 Change-Id: If2490a6e0b4e9cf8b6e28b33cbbbcec8b4ebfdaa Reviewed-on: https://swiftshader-review.googlesource.com/5183Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent e2c7154e
......@@ -1090,14 +1090,14 @@ namespace sw
return opcode == OPCODE_BREAK || opcode == OPCODE_BREAKC || opcode == OPCODE_BREAKP;
}
bool Shader::Instruction::isLoopOrSwitch() const
bool Shader::Instruction::isLoop() const
{
return opcode == OPCODE_LOOP || opcode == OPCODE_REP || opcode == OPCODE_WHILE || opcode == OPCODE_SWITCH;
return opcode == OPCODE_LOOP || opcode == OPCODE_REP || opcode == OPCODE_WHILE;
}
bool Shader::Instruction::isEndLoopOrSwitch() const
bool Shader::Instruction::isEndLoop() const
{
return opcode == OPCODE_ENDLOOP || opcode == OPCODE_ENDREP || opcode == OPCODE_ENDWHILE || opcode == OPCODE_ENDSWITCH;;
return opcode == OPCODE_ENDLOOP || opcode == OPCODE_ENDREP || opcode == OPCODE_ENDWHILE;
}
bool Shader::Instruction::isPredicated() const
......@@ -1657,6 +1657,7 @@ namespace sw
int breakDepth = 0;
int continueDepth = 0;
bool leaveReturn = false;
unsigned int functionBegin = 0;
for(unsigned int i = 0; i < instruction.size(); i++)
{
......@@ -1688,11 +1689,11 @@ namespace sw
if(breakDepth > 0)
{
if(instruction[i]->isLoopOrSwitch()) // Nested loop or switch, don't make the end of it disable the break execution mask
if(instruction[i]->isLoop() || instruction[i]->opcode == OPCODE_SWITCH) // Nested loop or switch, don't make the end of it disable the break execution mask
{
breakDepth++;
}
else if(instruction[i]->isEndLoopOrSwitch())
else if(instruction[i]->isEndLoop() || instruction[i]->opcode == OPCODE_ENDSWITCH)
{
breakDepth--;
}
......@@ -1713,11 +1714,11 @@ namespace sw
if(continueDepth > 0)
{
if(instruction[i]->isLoopOrSwitch()) // Nested loop or switch, don't make the end of it disable the break execution mask
if(instruction[i]->isLoop() || instruction[i]->opcode == OPCODE_SWITCH) // Nested loop or switch, don't make the end of it disable the break execution mask
{
continueDepth++;
}
else if(instruction[i]->isEndLoopOrSwitch())
else if(instruction[i]->isEndLoop() || instruction[i]->opcode == OPCODE_ENDSWITCH)
{
continueDepth--;
}
......@@ -1734,11 +1735,29 @@ namespace sw
if(instruction[i]->opcode == OPCODE_LEAVE)
{
leaveReturn = true;
// Mark loop body instructions prior to the return statement
for(unsigned int l = functionBegin; l < i; l++)
{
if(instruction[l]->isLoop())
{
for(unsigned int r = l + 1; r < i; r++)
{
instruction[r]->analysisLeave = true;
}
break;
}
}
}
else if(instruction[i]->opcode == OPCODE_RET) // End of the function
{
leaveReturn = false;
}
else if(instruction[i]->opcode == OPCODE_LABEL)
{
functionBegin = i;
}
if(leaveReturn)
{
......
......@@ -495,8 +495,8 @@ namespace sw
bool isBranch() const;
bool isCall() const;
bool isBreak() const;
bool isLoopOrSwitch() const;
bool isEndLoopOrSwitch() const;
bool isLoop() const;
bool isEndLoop() const;
bool isPredicated() const;
......
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