are more specific version of the comparison removal #895
This commit is contained in:
committed by
Oliver Schmidt
parent
7a863e5cda
commit
4642421da4
@@ -819,6 +819,7 @@ unsigned OptCmp8 (CodeSeg* S)
|
|||||||
/* We are able to evaluate the compare at compile time. Check if
|
/* We are able to evaluate the compare at compile time. Check if
|
||||||
** one or more branches are ahead.
|
** one or more branches are ahead.
|
||||||
*/
|
*/
|
||||||
|
unsigned ProtectCompare = 0;
|
||||||
unsigned JumpsChanged = 0;
|
unsigned JumpsChanged = 0;
|
||||||
CodeEntry* N;
|
CodeEntry* N;
|
||||||
while ((N = CS_GetNextEntry (S, I)) != 0 && /* Followed by something.. */
|
while ((N = CS_GetNextEntry (S, I)) != 0 && /* Followed by something.. */
|
||||||
@@ -878,6 +879,21 @@ unsigned OptCmp8 (CodeSeg* S)
|
|||||||
CodeEntry* X = NewCodeEntry (OP65_JMP, AM65_BRA, LabelName, L, N->LI);
|
CodeEntry* X = NewCodeEntry (OP65_JMP, AM65_BRA, LabelName, L, N->LI);
|
||||||
CS_InsertEntry (S, X, I+2);
|
CS_InsertEntry (S, X, I+2);
|
||||||
CS_DelEntry (S, I+1);
|
CS_DelEntry (S, I+1);
|
||||||
|
/* Normally we can remove the compare as well,
|
||||||
|
** but some comparisons generate code with a
|
||||||
|
** shared branch operation. This prevents the unsafe
|
||||||
|
** removal of the compare for known problem cases.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
/* Jump to branch that relies on the comparison. */
|
||||||
|
(L->Owner->Info & (OF_CBRA | OF_ZBRA)) ||
|
||||||
|
/* Jump to boolean transformer that relies on the comparison. */
|
||||||
|
(L->Owner->OPC == OP65_JSR &&
|
||||||
|
(FindBoolCmpCond (L->Owner->Arg)) != CMP_INV)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
++ProtectCompare;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember, we had changes */
|
/* Remember, we had changes */
|
||||||
@@ -885,16 +901,10 @@ unsigned OptCmp8 (CodeSeg* S)
|
|||||||
++Changes;
|
++Changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "If we have made changes above, we may also remove the compare."
|
/* Delete the original compare, if safe to do so. */
|
||||||
**
|
if (JumpsChanged && !ProtectCompare) {
|
||||||
** Removing the compare was too aggressive. E.g. for 16-bit compares the compiler
|
CS_DelEntry (S, I);
|
||||||
** may generate a branch to a second shared branch that still requires the flag
|
}
|
||||||
** result of the first compare instruction.
|
|
||||||
**
|
|
||||||
**if (JumpsChanged) {
|
|
||||||
** CS_DelEntry (S, I);
|
|
||||||
**}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NextEntry:
|
NextEntry:
|
||||||
|
|||||||
Reference in New Issue
Block a user