X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodeopt.c;h=f4fe3f435b69f841907301ff4b0e3290beb5db93;hb=b8c4dc9b0661e19e46ba60372db3831cdcf5961f;hp=5508d2beedd7685f36c420283974b6d382c15de8;hpb=76f0c7c05efa2e5418a4f006cc408f4c57ea738b;p=cc65 diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 5508d2bee..f4fe3f435 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ +/* (C) 2001-2002 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ /* EMail: uz@cc65.org */ @@ -48,9 +48,11 @@ #include "codeent.h" #include "codeinfo.h" #include "coptadd.h" +#include "coptc02.h" #include "coptcmp.h" #include "coptind.h" #include "coptneg.h" +#include "coptpush.h" #include "coptstop.h" #include "coptsub.h" #include "copttest.h" @@ -1112,7 +1114,7 @@ static unsigned OptDecouple (CodeSeg* S) /*****************************************************************************/ - + #if 0 static unsigned OptSize1 (CodeSeg* S) /* Do size optimization by calling special subroutines that preload registers. @@ -1330,6 +1332,7 @@ typedef struct OptFunc OptFunc; struct OptFunc { unsigned (*Func) (CodeSeg*); /* Optimizer function */ const char* Name; /* Name of the function/group */ + unsigned CodeSizeFactor; /* Code size factor for this opt func */ unsigned long TotalRuns; /* Total number of runs */ unsigned long LastRuns; /* Last number of runs */ unsigned long TotalChanges; /* Total number of changes */ @@ -1349,57 +1352,61 @@ struct OptFunc { #define OptFuncEntry(func) static OptFuncDesc D##func = { func, #func, 0 } /* A list of all the function descriptions */ -static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 0, 0, 0, 0, 0 }; -static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 0, 0, 0, 0, 0 }; -static OptFunc DOptAdd3 = { OptAdd3, "OptAdd3", 0, 0, 0, 0, 0 }; -static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 0, 0, 0, 0, 0 }; -static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 0, 0, 0, 0, 0 }; -static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 0, 0, 0, 0, 0 }; -static OptFunc DOptCondBranches = { OptCondBranches, "OptCondBranches", 0, 0, 0, 0, 0 }; -static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 0, 0, 0, 0, 0 }; -static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 0, 0, 0, 0, 0 }; -static OptFunc DOptDecouple = { OptDecouple, "OptDecouple", 0, 0, 0, 0, 0 }; -static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 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 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 }; -static OptFunc DOptNegAX2 = { OptNegAX2, "OptNegAX2", 0, 0, 0, 0, 0 }; -static OptFunc DOptNegAX3 = { OptNegAX3, "OptNegAX3", 0, 0, 0, 0, 0 }; -static OptFunc DOptNegAX4 = { OptNegAX4, "OptNegAX4", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad1 = { OptPtrLoad1, "OptPtrLoad1", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 0, 0, 0, 0, 0 }; -static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 0, 0, 0, 0, 0 }; -static OptFunc DOptShift1 = { OptShift1, "OptShift1", 0, 0, 0, 0, 0 }; -static OptFunc DOptShift2 = { OptShift2, "OptShift2", 0, 0, 0, 0, 0 }; -/*static OptFunc DOptSize1 = { OptSize1, "OptSize1", 0, 0, 0, 0, 0 };*/ -static OptFunc DOptSize2 = { OptSize2, "OptSize2", 0, 0, 0, 0, 0 }; -static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 0, 0, 0, 0, 0 }; -static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0 }; -static OptFunc DOptSub1 = { OptSub1, "OptSub1", 0, 0, 0, 0, 0 }; -static OptFunc DOptSub2 = { OptSub2, "OptSub2", 0, 0, 0, 0, 0 }; -static OptFunc DOptTest1 = { OptTest1, "OptTest1", 0, 0, 0, 0, 0 }; -static OptFunc DOptTransfers = { OptTransfers, "OptTransfers", 0, 0, 0, 0, 0 }; -static OptFunc DOptUnusedLoads = { OptUnusedLoads, "OptUnusedLoads", 0, 0, 0, 0, 0 }; -static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0 }; +static OptFunc DOpt65C02Ind = { Opt65C02Ind, "Opt65C02Ind", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptAdd1 = { OptAdd1, "OptAdd1", 60, 0, 0, 0, 0, 0 }; +static OptFunc DOptAdd2 = { OptAdd2, "OptAdd2", 200, 0, 0, 0, 0, 0 }; +static OptFunc DOptAdd3 = { OptAdd3, "OptAdd3", 40, 0, 0, 0, 0, 0 }; +static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 85, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 75, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 85, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 50, 0, 0, 0, 0, 0 }; +static OptFunc DOptCondBranches = { OptCondBranches, "OptCondBranches", 80, 0, 0, 0, 0, 0 }; +static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptDecouple = { OptDecouple, "OptDecouple", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptDupLoads = { OptDupLoads, "OptDupLoads", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptJumpTarget = { OptJumpTarget, "OptJumpTarget", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptRTS = { OptRTS, "OptRTS", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegA1 = { OptNegA1, "OptNegA1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegA2 = { OptNegA2, "OptNegA2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegAX2 = { OptNegAX2, "OptNegAX2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegAX3 = { OptNegAX3, "OptNegAX3", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptNegAX4 = { OptNegAX4, "OptNegAX4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad1 = { OptPtrLoad1, "OptPtrLoad1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad2 = { OptPtrLoad2, "OptPtrLoad2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad3 = { OptPtrLoad3, "OptPtrLoad3", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad4 = { OptPtrLoad4, "OptPtrLoad4", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad5 = { OptPtrLoad5, "OptPtrLoad5", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrLoad6 = { OptPtrLoad6, "OptPtrLoad6", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrStore1 = { OptPtrStore1, "OptPtrStore1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPtrStore2 = { OptPtrStore2, "OptPtrStore2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptPush1 = { OptPush1, "OptPush1", 65, 0, 0, 0, 0, 0 }; +static OptFunc DOptShift1 = { OptShift1, "OptShift1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptShift2 = { OptShift2, "OptShift2", 100, 0, 0, 0, 0, 0 }; +/*static OptFunc DOptSize1 = { OptSize1, "OptSize1", 100, 0, 0, 0, 0, 0 };*/ +static OptFunc DOptSize2 = { OptSize2, "OptSize2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptStackOps = { OptStackOps, "OptStackOps", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptStoreLoad = { OptStoreLoad, "OptStoreLoad", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptSub1 = { OptSub1, "OptSub1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptSub2 = { OptSub2, "OptSub2", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptTest1 = { OptTest1, "OptTest1", 100, 0, 0, 0, 0, 0 }; +static OptFunc DOptTransfers = { OptTransfers, "OptTransfers", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptUnusedLoads = { OptUnusedLoads, "OptUnusedLoads", 0, 0, 0, 0, 0, 0 }; +static OptFunc DOptUnusedStores = { OptUnusedStores, "OptUnusedStores", 0, 0, 0, 0, 0, 0 }; /* Table containing all the steps in alphabetical order */ static OptFunc* OptFuncs[] = { + &DOpt65C02Ind, &DOptAdd1, &DOptAdd2, &DOptAdd3, @@ -1433,8 +1440,10 @@ static OptFunc* OptFuncs[] = { &DOptPtrLoad6, &DOptPtrStore1, &DOptPtrStore2, + &DOptPush1, &DOptRTS, - &DOptRTSJumps, + &DOptRTSJumps1, + &DOptRTSJumps2, &DOptShift1, &DOptShift2, /*&DOptSize1,*/ @@ -1578,7 +1587,7 @@ static void ReadOptStats (const char* Name) /* Parse the line */ if (sscanf (B, "%31s %lu %*u %lu %*u", Name, &TotalRuns, &TotalChanges) != 3) { - /* Syntax error */ + /* Syntax error */ continue; } @@ -1620,7 +1629,7 @@ static void WriteOptStats (const char* Name) "%-20s %6lu %6lu %6lu %6lu\n", O->Name, O->TotalRuns, - O->LastRuns, + O->LastRuns, O->TotalChanges, O->LastChanges); } @@ -1636,8 +1645,10 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max) { unsigned Changes, C; - /* Don't run the function if it is disabled */ - if (F->Disabled) { + /* Don't run the function if it is disabled or if it is prohibited by the + * code size factor + */ + if (F->Disabled || CodeSizeFactor < F->CodeSizeFactor) { return 0; } @@ -1663,107 +1674,174 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max) -static void RunOptGroup1 (CodeSeg* S) +static unsigned RunOptGroup1 (CodeSeg* S) /* Run the first group of optimization steps. These steps translate known * patterns emitted by the code generator into more optimal patterns. Order * of the steps is important, because some of the steps done earlier cover * the same patterns as later steps as subpatterns. */ { - RunOptFunc (S, &DOptPtrStore1, 1); - RunOptFunc (S, &DOptPtrStore2, 1); - RunOptFunc (S, &DOptPtrLoad1, 1); - RunOptFunc (S, &DOptPtrLoad2, 1); - RunOptFunc (S, &DOptPtrLoad3, 1); - RunOptFunc (S, &DOptPtrLoad4, 1); - RunOptFunc (S, &DOptPtrLoad5, 1); - RunOptFunc (S, &DOptNegAX1, 1); - RunOptFunc (S, &DOptNegAX2, 1); - RunOptFunc (S, &DOptNegAX3, 1); - RunOptFunc (S, &DOptNegAX4, 1); - RunOptFunc (S, &DOptAdd1, 1); - RunOptFunc (S, &DOptAdd2, 1); - RunOptFunc (S, &DOptShift1, 1); - RunOptFunc (S, &DOptShift2, 1); + unsigned Changes = 0; + + Changes += RunOptFunc (S, &DOptPtrStore1, 1); + Changes += RunOptFunc (S, &DOptPtrStore2, 1); + Changes += RunOptFunc (S, &DOptPtrLoad1, 1); + Changes += RunOptFunc (S, &DOptPtrLoad2, 1); + Changes += RunOptFunc (S, &DOptPtrLoad3, 1); + Changes += RunOptFunc (S, &DOptPtrLoad4, 1); + Changes += RunOptFunc (S, &DOptPtrLoad5, 1); + Changes += RunOptFunc (S, &DOptNegAX1, 1); + Changes += RunOptFunc (S, &DOptNegAX2, 1); + Changes += RunOptFunc (S, &DOptNegAX3, 1); + Changes += RunOptFunc (S, &DOptNegAX4, 1); + Changes += RunOptFunc (S, &DOptAdd1, 1); + Changes += RunOptFunc (S, &DOptAdd2, 1); + Changes += RunOptFunc (S, &DOptShift1, 1); + Changes += RunOptFunc (S, &DOptShift2, 1); + + /* Return the number of changes */ + return Changes; } -static void RunOptGroup2 (CodeSeg* S) +static unsigned RunOptGroup2 (CodeSeg* S) /* Run one group of optimization steps. This step involves just decoupling * instructions by replacing them by instructions that do not depend on * previous instructions. This makes it easier to find instructions that * aren't used. */ { - RunOptFunc (S, &DOptDecouple, 1); -} + unsigned Changes = 0; + + Changes += RunOptFunc (S, &DOptDecouple, 1); + /* Return the number of changes */ + return Changes; +} -static void RunOptGroup3 (CodeSeg* S) +static unsigned RunOptGroup3 (CodeSeg* S) /* Run one group of optimization steps. These steps depend on each other, * that means that one step may allow another step to do additional work, * so we will repeat the steps as long as we see any changes. */ { - unsigned Changes; + unsigned Changes, C; + Changes = 0; do { - Changes = 0; - - Changes += RunOptFunc (S, &DOptPtrLoad6, 1); - Changes += RunOptFunc (S, &DOptNegA1, 1); - Changes += RunOptFunc (S, &DOptNegA2, 1); - Changes += RunOptFunc (S, &DOptSub1, 1); - Changes += RunOptFunc (S, &DOptSub2, 1); - Changes += RunOptFunc (S, &DOptAdd3, 1); - Changes += RunOptFunc (S, &DOptStackOps, 1); - Changes += RunOptFunc (S, &DOptJumpCascades, 1); - Changes += RunOptFunc (S, &DOptDeadJumps, 1); - Changes += RunOptFunc (S, &DOptRTS, 1); - Changes += RunOptFunc (S, &DOptDeadCode, 1); - Changes += RunOptFunc (S, &DOptJumpTarget, 1); - Changes += RunOptFunc (S, &DOptCondBranches, 1); - Changes += RunOptFunc (S, &DOptRTSJumps, 1); - Changes += RunOptFunc (S, &DOptBoolTrans, 1); - Changes += RunOptFunc (S, &DOptCmp1, 1); - Changes += RunOptFunc (S, &DOptCmp2, 1); - Changes += RunOptFunc (S, &DOptCmp3, 1); - Changes += RunOptFunc (S, &DOptCmp4, 1); - Changes += RunOptFunc (S, &DOptCmp5, 1); - Changes += RunOptFunc (S, &DOptCmp6, 1); - Changes += RunOptFunc (S, &DOptCmp7, 1); - Changes += RunOptFunc (S, &DOptTest1, 1); - Changes += RunOptFunc (S, &DOptUnusedLoads, 1); - Changes += RunOptFunc (S, &DOptUnusedStores, 1); - Changes += RunOptFunc (S, &DOptDupLoads, 1); - Changes += RunOptFunc (S, &DOptStoreLoad, 1); - Changes += RunOptFunc (S, &DOptTransfers, 1); - - } while (Changes); + C = 0; + + C += RunOptFunc (S, &DOptPtrLoad6, 1); + C += RunOptFunc (S, &DOptNegA1, 1); + C += RunOptFunc (S, &DOptNegA2, 1); + C += RunOptFunc (S, &DOptSub1, 1); + C += RunOptFunc (S, &DOptSub2, 1); + C += RunOptFunc (S, &DOptAdd3, 1); + C += RunOptFunc (S, &DOptStackOps, 1); + C += RunOptFunc (S, &DOptJumpCascades, 1); + C += RunOptFunc (S, &DOptDeadJumps, 1); + C += RunOptFunc (S, &DOptRTS, 1); + C += RunOptFunc (S, &DOptDeadCode, 1); + C += RunOptFunc (S, &DOptJumpTarget, 1); + C += RunOptFunc (S, &DOptCondBranches, 1); + C += RunOptFunc (S, &DOptRTSJumps1, 1); + C += RunOptFunc (S, &DOptBoolTrans, 1); + C += RunOptFunc (S, &DOptCmp1, 1); + C += RunOptFunc (S, &DOptCmp2, 1); + C += RunOptFunc (S, &DOptCmp3, 1); + C += RunOptFunc (S, &DOptCmp4, 1); + C += RunOptFunc (S, &DOptCmp5, 1); + C += RunOptFunc (S, &DOptCmp6, 1); + C += RunOptFunc (S, &DOptCmp7, 1); + C += RunOptFunc (S, &DOptTest1, 1); + C += RunOptFunc (S, &DOptUnusedLoads, 1); + C += RunOptFunc (S, &DOptUnusedStores, 1); + C += RunOptFunc (S, &DOptDupLoads, 1); + C += RunOptFunc (S, &DOptStoreLoad, 1); + C += RunOptFunc (S, &DOptTransfers, 1); + + Changes += C; + + } while (C); + + /* Return the number of changes */ + return Changes; } -static void RunOptGroup4 (CodeSeg* S) -/* The last group of optimization steps. Adjust branches. +static unsigned RunOptGroup4 (CodeSeg* S) +/* 65C02 specific optimizations. */ +{ + unsigned Changes = 0; + + if (CPU >= CPU_65C02) { + /* Replace (zp),y by (zp) if Y is zero. If we have changes, run register + * load optimization again, since loads of Y may have become unnecessary. + */ + unsigned C = RunOptFunc (S, &DOpt65C02Ind, 1); + Changes += C; + if (C) { + Changes += RunOptFunc (S, &DOptUnusedLoads, 1); + } + } + + /* Return the number of changes */ + return Changes; +} + + + +static unsigned RunOptGroup5 (CodeSeg* S) +/* Run another round of pattern replacements. These are done late, since there + * may be better replacements before. */ { + unsigned Changes = 0; + + Changes += RunOptFunc (S, &DOptPush1, 1); + + /* Return the number of changes */ + return Changes; +} + + + +static unsigned RunOptGroup6 (CodeSeg* S) +/* The last group of optimization steps. Adjust branches, do size optimizations. + */ +{ + unsigned Changes = 0; + unsigned C; + /* Optimize for size, that is replace operations by shorter ones, even * if this does hinder further optimizations (no problem since we're * done soon). */ - RunOptFunc (S, &DOptSize2, 1); + Changes += RunOptFunc (S, &DOptSize2, 1); /* Run the jump target optimization again, since the size optimization * above may have opened new oportunities. */ - RunOptFunc (S, &DOptJumpTarget, 5); + Changes += RunOptFunc (S, &DOptJumpTarget, 5); + + /* Adjust branch distances */ + Changes += 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. + */ + C = RunOptFunc (S, &DOptRTSJumps2, 1); + Changes += C; + if (C) { + Changes += RunOptFunc (S, &DOptDeadCode, 1); + } - /* Finally, adjust branch distances */ - RunOptFunc (S, &DOptBranchDist, 3); + /* Return the number of changes */ + return Changes; } @@ -1775,7 +1853,7 @@ void RunOpt (CodeSeg* S) /* If we shouldn't run the optimizer, bail out */ if (!Optimize) { - return; + return; } /* Check if we are requested to write optimizer statistics */ @@ -1796,6 +1874,8 @@ void RunOpt (CodeSeg* S) RunOptGroup2 (S); RunOptGroup3 (S); RunOptGroup4 (S); + RunOptGroup5 (S); + RunOptGroup6 (S); /* Write statistics */ if (StatFileName) {