+2003-10-04 Bernhard Held <bernhard@bernhardheld.de>
+
+ Applied liferange patch from Klaus Flittner <klaus_flittner@gmx.de>
+ * src/SDCCBBlock.h
+ * src/SDCCloop.c
+ * src/SDCCloop.h
+ * src/SDCClrange.c
+
2003-10-03 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/z80/gen.h,
iCode *ech; /* pointer to last of code chain */
struct eBBlock *preHeader; /* preheader if this is a loop entry */
- struct region *partOfLoop; /* pointer to the loop region this block is part of */
+ set *partOfLoop; /* set of loop regions this block is part of */
/* control flow analysis */
set *succList; /* list eBBlocks which are successors */
ebp->depth = depth;
/* put the loop region info in the block */
- /* NOTE: here we will update only the inner most loop
- that it is a part of */
- if (!ebp->partOfLoop)
- ebp->partOfLoop = lr;
+ if (!isinSet (ebp->partOfLoop, lr))
+ addSetHead (&ebp->partOfLoop, lr);
/* if any of the successors go out of the loop then */
/* we add this one to the exits */
return change;
}
+
+/*-----------------------------------------------------------------*/
+/* addLoopBlocks - will add all blocks inside a loop to this loop */
+/* this should fix most of the liverange problems */
+/*-----------------------------------------------------------------*/
+void
+addLoopBlocks (eBBlock ** ebbs, int count)
+{
+ region *aloop;
+ struct eBBlock *block;
+ int seqMin, seqMax;
+ int i, j;
+
+ for (i = 0; i < count; i++)
+ {
+ if (!ebbs[i]->partOfLoop)
+ continue;
+
+ /* for all loops this block belongs to */
+ /* add inner block not already marked as part of this loop */
+ aloop = setFirstItem (ebbs[i]->partOfLoop);
+ for (; aloop; aloop = setNextItem (ebbs[i]->partOfLoop))
+ {
+
+ if (aloop->visited)
+ continue;
+
+ aloop->visited = 1;
+
+ /* set max & min Seq for loopRegion */
+ block = setFirstItem (aloop->regBlocks);
+ seqMax = block->lSeq;
+ seqMin = block->fSeq;
+ for (; block; block = setNextItem (aloop->regBlocks))
+ {
+ if (block->lSeq > seqMax)
+ seqMax = block->lSeq;
+ if (block->fSeq < seqMin)
+ seqMin = block->fSeq;
+ }
+
+ /* add all blocks between seqMin, seqMax to loop */
+ for (j = 0; j < count; j++)
+ {
+ if (ebbs[j]->fSeq > seqMin && ebbs[j]->lSeq < seqMax &&
+ !isinSet (aloop->regBlocks, ebbs[j]))
+ {
+ if (!isinSet (ebbs[i]->partOfLoop, aloop))
+ addSetHead (&ebbs[j]->partOfLoop, aloop);
+ }
+ }
+ }
+ }
+}
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
#include "SDCCBBlock.h"
#include "SDCCcse.h"
{
unsigned int merged:1;
+ unsigned int visited:1;
eBBlock *entry; /* entry Block */
int containsLoops; /* contains other loops */
set *regBlocks; /* set of all blocks */
iCode *findDefInRegion (set *, operand *, eBBlock **);
int hasIncomingDefs (region *, operand *);
int findLoopEndSeq (region *);
-
+void addLoopBlocks (eBBlock ** ebbs, int count);
#endif
if (usedInRemaining (op, ic))
return 0;
- /* if not then check any of the successor blocks use it */
- for (i = 0; i < count; ebbs[i++]->visited = 0);
- if (applyToSet (ebp->succList, isOpAlive, op, ebp, ic))
- return 0;
+ /* if not then check any of the following blocks use it */
+ for (i = 0; i < count; i++)
+ {
+ if (ebbs[i]->fSeq <= ebp->fSeq)
+ continue;
+ if (usedInRemaining (op, ebbs[i]->sch))
+ return 0;
+ }
/* this is the last use */
return 1;
/* if this is a SEND then the toRange should be extended
to the call */
- if (ic->op == SEND) {
+ if (ic->op == SEND)
+ {
iCode *lic ;
- for (lic = ic->next ; lic ; lic = lic->next) {
- if (lic->op == CALL || lic->op == PCALL) break;
- }
+ for (lic = ic->next ; lic ; lic = lic->next)
+ {
+ if (lic->op == CALL || lic->op == PCALL)
+ break;
+ }
/* found it : mark */
- if (lic) torange = lic->prev->seq;
- }
- /* if this is the last use then if this block belongs
- to a loop & some definition comes into the loop
+ if (lic)
+ torange = lic->prev->seq;
+ }
+ /* if this is the last use then if this block belongs
+ to a loop & some definition comes into the loop
then extend the live range to the end of the loop */
- if (ebp->partOfLoop
- && hasIncomingDefs (ebp->partOfLoop, op))
- {
- torange = findLoopEndSeq (ebp->partOfLoop);
+ if (ebp->partOfLoop)
+ {
+ region *aloop;
+
+ aloop = setFirstItem (ebp->partOfLoop);
+ for (; aloop; aloop = setNextItem (ebp->partOfLoop))
+ {
+ if (hasIncomingDefs (aloop, op))
+ torange = findLoopEndSeq (aloop);
+ }
}
-
+
op = operandFromOperand (op);
setToRange (op, torange, FALSE);
}
computeLiveRanges (eBBlock ** ebbs, int count)
{
int i = 0;
- /* sequence the code the live ranges are computed
- in terms of this sequence additionally the
+ /* sequence the code the live ranges are computed
+ in terms of this sequence additionally the
routine will also create a hashtable of instructions */
iCodeSeq = 0;
setToNull ((void **) &iCodehTab);
iCodeSeqhTab = newHashTable (iCodeKey);
sequenceiCode (ebbs, count);
+ /* add blocks between loop blocks as part of that loop */
+ addLoopBlocks (ebbs, count);
+
/* call routine to mark the from & to live ranges for
variables used */
setToNull ((void **) &liveRanges);