]> git.sur5r.net Git - cc65/commitdiff
Added another optimization
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 12 Oct 2001 09:06:42 +0000 (09:06 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 12 Oct 2001 09:06:42 +0000 (09:06 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1044 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeopt.c
src/cc65/coptind.c
src/cc65/coptind.h

index 5508d2beedd7685f36c420283974b6d382c15de8..57cb394e60077d82973c99252d3fba0b0aa07aa3 100644 (file)
@@ -1112,7 +1112,7 @@ static unsigned OptDecouple (CodeSeg* S)
 /*****************************************************************************/
 
 
-               
+
 #if 0
 static unsigned OptSize1 (CodeSeg* S)
 /* Do size optimization by calling special subroutines that preload registers.
@@ -1369,7 +1369,8 @@ static OptFunc DOptDupLoads     = { OptDupLoads,     "OptDupLoads",     0, 0, 0,
 static OptFunc DOptJumpCascades        = { OptJumpCascades, "OptJumpCascades", 0, 0, 0, 0, 0 };
 static OptFunc DOptJumpTarget          = { OptJumpTarget,   "OptJumpTarget",   0, 0, 0, 0, 0 };
 static OptFunc DOptRTS                 = { OptRTS,          "OptRTS",          0, 0, 0, 0, 0 };
-static OptFunc DOptRTSJumps            = { OptRTSJumps,     "OptRTSJumps",     0, 0, 0, 0, 0 };
+static OptFunc DOptRTSJumps1    = { OptRTSJumps1,    "OptRTSJumps1",   0, 0, 0, 0, 0 };
+static OptFunc DOptRTSJumps2    = { OptRTSJumps2,    "OptRTSJumps2",   0, 0, 0, 0, 0 };
 static OptFunc DOptNegA1               = { OptNegA1,        "OptNegA1",        0, 0, 0, 0, 0 };
 static OptFunc DOptNegA2               = { OptNegA2,        "OptNegA2",        0, 0, 0, 0, 0 };
 static OptFunc DOptNegAX1              = { OptNegAX1,       "OptNegAX1",       0, 0, 0, 0, 0 };
@@ -1434,7 +1435,8 @@ static OptFunc* OptFuncs[] = {
     &DOptPtrStore1,
     &DOptPtrStore2,
     &DOptRTS,
-    &DOptRTSJumps,
+    &DOptRTSJumps1,
+    &DOptRTSJumps2,
     &DOptShift1,
     &DOptShift2,
     /*&DOptSize1,*/
@@ -1726,7 +1728,7 @@ static void RunOptGroup3 (CodeSeg* S)
                Changes += RunOptFunc (S, &DOptDeadCode, 1);
                Changes += RunOptFunc (S, &DOptJumpTarget, 1);
        Changes += RunOptFunc (S, &DOptCondBranches, 1);
-       Changes += RunOptFunc (S, &DOptRTSJumps, 1);
+       Changes += RunOptFunc (S, &DOptRTSJumps1, 1);
        Changes += RunOptFunc (S, &DOptBoolTrans, 1);
        Changes += RunOptFunc (S, &DOptCmp1, 1);
        Changes += RunOptFunc (S, &DOptCmp2, 1);
@@ -1762,8 +1764,15 @@ static void RunOptGroup4 (CodeSeg* S)
      */
     RunOptFunc (S, &DOptJumpTarget, 5);
 
-    /* Finally, adjust branch distances */
+    /* Adjust branch distances */
     RunOptFunc (S, &DOptBranchDist, 3);
+
+    /* Replace conditional branches to RTS. If we had changes, we must run dead
+     * code elimination again, since the change may have introduced dead code.
+     */
+    if (RunOptFunc (S, &DOptRTSJumps2, 1)) {
+       RunOptFunc (S, &DOptDeadCode, 1);
+    }
 }
 
 
index 67ab7b6c5bd57be9682d857a54c3289b0ad4c439..c36e5a3972f0ebecdfb97302364b2176d6566a28 100644 (file)
 
 
 /*****************************************************************************/
-/*                       Replace jumps to RTS by RTS                        */
+/*                       Replace jumps to RTS by RTS                        */
 /*****************************************************************************/
 
 
 
-unsigned OptRTSJumps (CodeSeg* S)
+unsigned OptRTSJumps1 (CodeSeg* S)
 /* Replace jumps to RTS by RTS */
 {
     unsigned Changes = 0;
@@ -88,6 +88,64 @@ unsigned OptRTSJumps (CodeSeg* S)
 
 
 
+unsigned OptRTSJumps2 (CodeSeg* S)
+/* Replace long conditional jumps to RTS */
+{
+    unsigned Changes = 0;
+
+    /* Walk over all entries minus the last one */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* N;
+
+       /* Get the next entry */
+       CodeEntry* E = CS_GetEntry (S, I);
+
+               /* Check if it's an unconditional branch to a local target */
+               if ((E->Info & OF_CBRA) != 0            &&   /* Conditional branch */
+           (E->Info & OF_LBRA) != 0            &&   /* Long branch */
+           E->JumpTo != 0                      &&   /* Local label */
+           E->JumpTo->Owner->OPC == OP65_RTS   &&   /* Target is an RTS */
+           (N = CS_GetNextEntry (S, I)) != 0) {     /* There is a next entry */
+
+           CodeEntry* X;
+           CodeLabel* LN;
+           opc_t      NewBranch;
+
+           /* We will create a jump around an RTS instead of the long branch */
+           X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->JumpTo->Owner->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           /* Get the new branch opcode */
+           NewBranch = MakeShortBranch (GetInverseBranch (E->OPC));
+
+           /* Get the label attached to N, create a new one if needed */
+           LN = CS_GenLabel (S, N);
+
+           /* Generate the branch */
+           X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI);
+           CS_InsertEntry (S, X, I+1);
+
+           /* Delete the long branch */
+           CS_DelEntry (S, I);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
 /*****************************************************************************/
 /*                            Remove dead jumps                             */
 /*****************************************************************************/
index bb61f81ce3e77cebce26450e45ed351145780267..44fe8f1ceeab8675c1838179d16f085c5534d394 100644 (file)
 
 
 
-unsigned OptRTSJumps (CodeSeg* S);
+unsigned OptRTSJumps1 (CodeSeg* S);
 /* Replace jumps to RTS by RTS */
 
+unsigned OptRTSJumps2 (CodeSeg* S);
+/* Replace long conditional jumps to RTS */
+
 unsigned OptDeadJumps (CodeSeg* S);
 /* Remove dead jumps (jumps to the next instruction) */