Fixed hangup for loops in jump cascade
git-svn-id: svn://svn.cc65.org/cc65/trunk@1734 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
47d4d62d1f
commit
2f8c281b89
1 changed files with 32 additions and 8 deletions
|
@ -261,7 +261,7 @@ unsigned OptDeadJumps (CodeSeg* S)
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Remove dead code */
|
/* Remove dead code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,16 +278,22 @@ unsigned OptDeadCode (CodeSeg* S)
|
||||||
while (I < CS_GetEntryCount (S)) {
|
while (I < CS_GetEntryCount (S)) {
|
||||||
|
|
||||||
CodeEntry* N;
|
CodeEntry* N;
|
||||||
|
CodeLabel* LN;
|
||||||
|
|
||||||
/* Get this entry */
|
/* Get this entry */
|
||||||
CodeEntry* E = CS_GetEntry (S, I);
|
CodeEntry* E = CS_GetEntry (S, I);
|
||||||
|
|
||||||
/* Check if it's an unconditional branch, and if the next entry has
|
/* Check if it's an unconditional branch, and if the next entry has
|
||||||
* no labels attached
|
* no labels attached, or if the label is just used so that the insn
|
||||||
|
* can jump to itself.
|
||||||
*/
|
*/
|
||||||
if ((E->Info & OF_DEAD) != 0 &&
|
if ((E->Info & OF_DEAD) != 0 && /* Dead code follows */
|
||||||
(N = CS_GetNextEntry (S, I)) != 0 &&
|
(N = CS_GetNextEntry (S, I)) != 0 && /* Has next entry */
|
||||||
!CE_HasLabel (N)) {
|
(!CE_HasLabel (N) || /* Don't has a label */
|
||||||
|
((N->Info & OF_UBRA) != 0 && /* Uncond branch */
|
||||||
|
(LN = N->JumpTo) != 0 && /* Jumps to known label */
|
||||||
|
LN->Owner == N && /* Attached to insn */
|
||||||
|
CL_GetRefCount (LN) == 1))) { /* Only reference */
|
||||||
|
|
||||||
/* Delete the next entry */
|
/* Delete the next entry */
|
||||||
CS_DelEntry (S, I+1);
|
CS_DelEntry (S, I+1);
|
||||||
|
@ -352,10 +358,28 @@ unsigned OptJumpCascades (CodeSeg* S)
|
||||||
((E->Info & OF_CBRA) != 0 &&
|
((E->Info & OF_CBRA) != 0 &&
|
||||||
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
|
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
|
||||||
|
|
||||||
/* This is a jump cascade and we may jump to the final target.
|
/* This is a jump cascade and we may jump to the final target,
|
||||||
* Insert a new instruction, then remove the old one
|
* provided that the other insn does not jump to itself. If
|
||||||
|
* this is the case, we can also jump to ourselves, otherwise
|
||||||
|
* insert a jump to the new instruction and remove the old one.
|
||||||
*/
|
*/
|
||||||
CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI);
|
CodeEntry* X;
|
||||||
|
CodeLabel* LN = N->JumpTo;
|
||||||
|
|
||||||
|
if (LN != 0 && LN->Owner == N) {
|
||||||
|
|
||||||
|
/* We found a jump to a jump to itself. Replace our jump
|
||||||
|
* by a jump to itself.
|
||||||
|
*/
|
||||||
|
CodeLabel* LE = CS_GenLabel (S, E);
|
||||||
|
X = NewCodeEntry (E->OPC, E->AM, LE->Name, LE, E->LI);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Jump to the final jump target */
|
||||||
|
X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo, E->LI);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Insert it behind E */
|
/* Insert it behind E */
|
||||||
CS_InsertEntry (S, X, I+1);
|
CS_InsertEntry (S, X, I+1);
|
||||||
|
|
Loading…
Add table
Reference in a new issue