From 3ac1a08baf4ecdaa85cb5d2aa8e14ec0697852c8 Mon Sep 17 00:00:00 2001 From: cuz Date: Mon, 7 Jun 2004 21:16:49 +0000 Subject: [PATCH] Cleaned up the code used for handling jump labels and the label name. Fixed a problem that caused the optimizer not to detect that flags set by a load are used, if the use is "hidden" behind an unconditional branch. This caused the optimizer to remove the load. git-svn-id: svn://svn.cc65.org/cc65/trunk@3111 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeent.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/cc65/codeent.h | 8 +++++++- src/cc65/codeseg.c | 9 ++++++--- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index e87311c30..233080712 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -323,6 +323,22 @@ void CE_AttachLabel (CodeEntry* E, CodeLabel* L) +void CE_ClearJumpTo (CodeEntry* E) +/* Clear the JumpTo entry and the argument (which contained the name of the + * label). Note: The function will not clear the backpointer from the label, + * so use it with care. + */ +{ + /* Clear the JumpTo entry */ + E->JumpTo = 0; + + /* Clear the argument and assign the empty one */ + FreeArg (E->Arg); + E->Arg = EmptyArg; +} + + + void CE_MoveLabel (CodeLabel* L, CodeEntry* E) /* Move the code label L from it's former owner to the code entry E. */ { @@ -391,6 +407,33 @@ int CE_UseLoadFlags (const CodeEntry* E) * a register (N and Z). */ { + /* Follow unconditional branches, but beware of endless loops. After this, + * E will point to the first entry that is not a branch. + */ + if (E->Info & OF_UBRA) { + Collection C = AUTO_COLLECTION_INITIALIZER; + + /* Follow the chain */ + while (E->Info & OF_UBRA) { + + /* Remember the entry so we can detect loops */ + CollAppend (&C, (void*) E); + + /* Check the target */ + if (E->JumpTo == 0 || CollIndex (&C, E->JumpTo->Owner) >= 0) { + /* Unconditional jump to external symbol, or endless loop. */ + DoneCollection (&C); + return 0; /* Flags not used */ + } + + /* Follow the chain */ + E = E->JumpTo->Owner; + } + + /* Delete the collection */ + DoneCollection (&C); + } + /* A branch will use the flags */ if (E->Info & OF_FBRA) { return 1; @@ -429,7 +472,7 @@ void CE_FreeRegInfo (CodeEntry* E) /* Free an existing register info struct */ { if (E->RI) { - FreeRegInfo (E->RI); + FreeRegInfo (E->RI); E->RI = 0; } } diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 2c42faf35..99c003b74 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -115,6 +115,12 @@ int CodeEntriesAreEqual (const CodeEntry* E1, const CodeEntry* E2); void CE_AttachLabel (CodeEntry* E, CodeLabel* L); /* Attach the label to the entry */ +void CE_ClearJumpTo (CodeEntry* E); +/* Clear the JumpTo entry and the argument (which contained the name of the + * label). Note: The function will not clear the backpointer from the label, + * so use it with care. + */ + #if defined(HAVE_INLINE) INLINE int CE_HasLabel (const CodeEntry* E) /* Check if the given code entry has labels attached */ @@ -157,7 +163,7 @@ INLINE int CE_HasMark (const CodeEntry* E) #else # define CE_HasMark(E) (((E)->Flags & CEF_USERMARK) != 0) #endif - + #if defined(HAVE_INLINE) INLINE void CE_SetMark (CodeEntry* E) /* Set the CEF_USERMARK flag for the given entry */ diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 8eb594f79..1126e08ee 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -829,7 +829,7 @@ void CS_DelLabel (CodeSeg* S, CodeLabel* L) /* Get the insn referencing this label */ CodeEntry* E = CollAt (&L->JumpFrom, I); /* Remove the reference */ - E->JumpTo = 0; + CE_ClearJumpTo (E); } CollDeleteAll (&L->JumpFrom); @@ -875,7 +875,10 @@ void CS_MergeLabels (CodeSeg* S) for (J = 0; J < CL_GetRefCount (X); ++J) { /* Get the entry referencing this label */ CodeEntry* E = CL_GetRef (X, J); - /* And remove the reference */ + /* And remove the reference. Do NOT call CE_ClearJumpTo + * here, because this will also clear the label name, + * which is not what we want. + */ E->JumpTo = 0; } @@ -999,7 +1002,7 @@ void CS_RemoveLabelRef (CodeSeg* S, struct CodeEntry* E) CollDeleteItem (&L->JumpFrom, E); /* The entry jumps no longer to L */ - E->JumpTo = 0; + CE_ClearJumpTo (E); /* If there are no more references, delete the label */ if (CollCount (&L->JumpFrom) == 0) { -- 2.39.5