+2005-03-20 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * src/port.h (struct PORT),
+ * src/avr/ralloc.c (avr_assignRegisters),
+ * src/avr/main.c,
+ * src/ds390/ralloc.c (ds390_assignRegisters),
+ * src/ds390/main.c,
+ * src/hc08/ralloc.c (hc08_assignRegisters),
+ * src/hc08/main.c,
+ * src/mcs51/ralloc.c (mcs51_assignRegisters),
+ * src/mcs51/main.c,
+ * src/pic/ralloc.c (pic14_assignRegisters),
+ * src/pic/main.c,
+ * src/pic16/ralloc.c (pic16_assignRegisters),
+ * src/pic16/main.c,
+ * src/xa51/ralloc.c (xa51_assignRegisters),
+ * src/xa51/main.c,
+ * src/z80/ralloc.c (z80_assignRegisters),
+ * src/z80/ralloc.h,
+ * src/SDCCopt.c (eBBlockFromiCode, replaceRegEqv, killDeadCode),
+ * src/SDCCcse.c (ifxOptimize, cseBBlock, cseAllBlocks),
+ * src/SDCCcse.h,
+ * src/SDCCdflow.c (computeDataFlow),
+ * src/SDCCdflow.h,
+ * src/SDCCloop.c (addDefInExprs, loopInvariants, loopOptimizations),
+ * src/SDCCloop.h,
+ * src/SDCCcflow.c (*),
+ * src/SDCCcflow.h,
+ * src/SDCCBBlock.c (iCodeBreakDown, dumpEbbsToFileExt, eBBWithEntryLabel),
+ * src/SDCCBBlock.h (struct ebbIndex): new struct that keeps two copies
+ of the eBBlock list, sorted by both bbnum and dfnum. (fixes bug with
+ immedDom() returning wrong block; probably fixes bug #1160833)
+
2005-03-20 Borut Razem <borut.razem AT siol.net>
* support/scripts/inc2h.pl: WIN32 port
fflush(file);
}
+
/*-----------------------------------------------------------------*/
/* dumpEbbsToFileExt - writeall the basic blocks to a file */
/*-----------------------------------------------------------------*/
void
-dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
+dumpEbbsToFileExt (int id, ebbIndex * ebbi)
{
FILE *of;
int i;
eBBlock *bb;
set *cseSet;
+ eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
+ int count = ebbi->count;
if (id) {
of=createDumpFile(id);
fprintf (of, "\ndominators: ");
for (d=0; d<ebbs[i]->domVect->size; d++) {
if (bitVectBitValue(ebbs[i]->domVect, d)) {
- fprintf (of, "%s ", ebbs[d]->entryLabel->name);
+ fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
}
}
}
/* eBBWithEntryLabel - finds the basic block with the entry label */
/*-----------------------------------------------------------------*/
eBBlock *
-eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count)
+eBBWithEntryLabel (ebbIndex * ebbi, symbol * eLabel)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i;
for (i = 0; i < count; i++)
/*-----------------------------------------------------------------*/
/* iCodeBreakDown : breakDown iCode chain to blocks */
/*-----------------------------------------------------------------*/
-eBBlock **
-iCodeBreakDown (iCode * ic, int *count)
+ebbIndex *
+iCodeBreakDown (iCode * ic)
{
eBBlock **ebbs = NULL;
iCode *loop = ic;
-
- *count = 0;
+ ebbIndex *ebbi;
+
+ ebbi = Safe_alloc (sizeof (ebbIndex *));
+ ebbi->count = 0;
+ ebbi->dfOrder = NULL; /* no depth first order information yet */
/* allocate for the first entry */
ebbs = Safe_alloc (sizeof (eBBlock **));
+ ebbi->bbOrder = ebbs;
while (loop)
{
ebb->ech->next = NULL; /* mark the end of this chain */
if (loop)
loop->prev = NULL;
- ebb->bbnum = *count; /* save this block number */
+ ebb->bbnum = ebbi->count; /* save this block number */
/* put it in the array */
- ebbs[(*count)++] = ebb;
+ ebbs[(ebbi->count)++] = ebb;
/* allocate for the next one. Remember to clear the new */
/* pointer at the end, that was created by realloc. */
- ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
+ ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock **));
+ ebbi->bbOrder = ebbs;
- ebbs[*count] = 0;
+ ebbs[ebbi->count] = 0;
/* if this one ends in a goto or a conditional */
/* branch then check if the block it is going */
/* to already exists, if yes then this could */
/* be a loop, add a preheader to the block it */
/* goes to if it does not already have one */
- if (ebbs[(*count) - 1]->ech &&
- (ebbs[(*count) - 1]->ech->op == GOTO ||
- ebbs[(*count) - 1]->ech->op == IFX))
+ if (ebbs[(ebbi->count) - 1]->ech &&
+ (ebbs[(ebbi->count) - 1]->ech->op == GOTO ||
+ ebbs[(ebbi->count) - 1]->ech->op == IFX))
{
symbol *label;
eBBlock *destBlock;
- if (ebbs[(*count) - 1]->ech->op == GOTO)
- label = IC_LABEL (ebbs[(*count) - 1]->ech);
- else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech)))
- label = IC_FALSE (ebbs[(*count) - 1]->ech);
+ if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
+ label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
+ else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
+ label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);
- if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) &&
+ if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
destBlock->preHeader == NULL &&
otherPathsPresent (ebbs, destBlock))
{
/* go thru all block replacing the entryLabel with new label */
/* till we reach the block , then we insert a new ebblock */
- for (i = 0; i < (*count); i++)
+ for (i = 0; i < (ebbi->count); i++)
{
if (ebbs[i] == destBlock)
break;
replaceLabel (ebbs[i], label, preHeaderLabel);
}
- (*count)++;
+ (ebbi->count)++;
/* if we have stopped at the block , allocate for an extra one */
- ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
+ ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock **));
+ ebbi->bbOrder = ebbs;
- ebbs[*count] = 0;
+ ebbs[ebbi->count] = 0;
/* then move the block down one count */
pBlock = ebbs[j = i];
- for (i += 1; i < (*count); i++)
+ for (i += 1; i < (ebbi->count); i++)
{
eBBlock *xBlock;
}
/* mark the end */
- ebbs[*count] = NULL;
+ ebbs[ebbi->count] = NULL;
- return ebbs;
+ return ebbi;
}
/*-----------------------------------------------------------------*/
/* control flow analysis */
set *succList; /* list eBBlocks which are successors */
- bitVect *succVect; /* bitVector of successors */
+ bitVect *succVect; /* bitVector of successors (index is bbnum) */
set *predList; /* predecessors of this basic block */
- bitVect *domVect; /* list of nodes this is dominated by */
+ bitVect *domVect; /* list of nodes this is dominated by (index is bbnum) */
/* data flow analysis */
set *inExprs; /* in coming common expressions */
}
eBBlock;
+typedef struct ebbIndex
+ {
+ int count; /* number of blocks in the index */
+ eBBlock **bbOrder; /* blocks in bbnum order */
+ eBBlock **dfOrder; /* blocks in dfnum (depth first) order */
+ }
+ebbIndex;
+
typedef struct edge
{
}
edge;
+
extern int eBBNum;
extern set *graphEdges;
DEFSETFUNC (printEntryLabel);
eBBlock *neweBBlock ();
edge *newEdge (eBBlock *, eBBlock *);
-eBBlock *eBBWithEntryLabel (eBBlock **, symbol *, int);
+eBBlock *eBBWithEntryLabel (ebbIndex *, symbol *);
DEFSETFUNC (ifFromIs);
set *edgesTo (eBBlock *);
void remiCodeFromeBBlock (eBBlock *, iCode *);
void addiCodeToeBBlock (eBBlock *, iCode *, iCode *);
-eBBlock **iCodeBreakDown (iCode *, int *);
+ebbIndex *iCodeBreakDown (iCode *);
void replaceSymBySym (set *, operand *, operand *);
iCode *iCodeFromeBBlock (eBBlock **, int);
int otherPathsPresent (eBBlock **, eBBlock *);
void replaceLabel (eBBlock *, symbol *, symbol *);
-void dumpEbbsToFileExt (int, eBBlock **, int);
+void dumpEbbsToFileExt (int, ebbIndex *);
void dumpLiveRanges (int, hTab * liveRanges);
void closeDumpFiles();
#include "common.h"
+static void computeDFOrdering (eBBlock *, int *);
+
/*-----------------------------------------------------------------*/
/* domSetFromVect - creates a domset from the vector */
/*-----------------------------------------------------------------*/
-set *
-domSetFromVect (eBBlock ** ebbs, bitVect * domVect)
+static set *
+domSetFromVect (ebbIndex *ebbi, bitVect * domVect)
{
int i = 0;
set *domSet = NULL;
for (i = 0; i < domVect->size; i++)
if (bitVectBitValue (domVect, i))
- addSet (&domSet, ebbs[i]);
+ addSet (&domSet, ebbi->bbOrder[i]);
return domSet;
}
/* addSuccessor - will add bb to succ also add it to the pred of */
/* the next one : */
/*-----------------------------------------------------------------*/
-void
+static void
addSuccessor (eBBlock * thisBlock, eBBlock * succ)
{
/* check for boundary conditions */
/*-----------------------------------------------------------------*/
/* eBBPredecessors - find the predecessors for each block */
/*-----------------------------------------------------------------*/
-void
-eBBPredecessors (eBBlock ** ebbs, int count)
+static void
+eBBPredecessors (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i = 0, j;
/* for each block do */
/*-----------------------------------------------------------------*/
/* eBBSuccessors- find out the successors of all the nodes */
/*-----------------------------------------------------------------*/
-void
-eBBSuccessors (eBBlock ** ebbs, int count)
+static void
+eBBSuccessors (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i = 0;
/* for all the blocks do */
for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl;
lbl = setNextItem (IC_JTLABELS (ic)))
addSuccessor (ebbs[i],
- eBBWithEntryLabel (ebbs, lbl, count));
+ eBBWithEntryLabel (ebbi, lbl));
}
else
{
switch (ic->op)
{
case GOTO: /* goto has edge to label */
- succ = eBBWithEntryLabel (ebbs, ic->label, count);
+ succ = eBBWithEntryLabel (ebbi, ic->label);
break;
case IFX: /* conditional jump */
/* if true label is present */
if (IC_TRUE (ic))
- succ = eBBWithEntryLabel (ebbs, IC_TRUE (ic), count);
+ succ = eBBWithEntryLabel (ebbi, IC_TRUE (ic));
else
- succ = eBBWithEntryLabel (ebbs, IC_FALSE (ic), count);
+ succ = eBBWithEntryLabel (ebbi, IC_FALSE (ic));
break;
case RETURN: /* block with return */
- succ = eBBWithEntryLabel (ebbs, returnLabel, count);
+ succ = eBBWithEntryLabel (ebbi, returnLabel);
break;
}
/* computeDominance - computes the dominance graph */
/* for algorithm look at Dragon book section 10.10, algo 10.16 */
/*-----------------------------------------------------------------*/
-void
-computeDominance (eBBlock ** ebbs, int count)
+static void
+computeDominance (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i, j;
/* now do the initialisation */
if (!change)
break;
}
+
}
/*-----------------------------------------------------------------*/
/* immedDom - returns the immediate dominator of a block */
/*-----------------------------------------------------------------*/
eBBlock *
-immedDom (eBBlock ** ebbs, eBBlock * ebp)
+immedDom (ebbIndex * ebbi, eBBlock * ebp)
{
/* first delete self from the list */
- set *iset = domSetFromVect (ebbs, ebp->domVect);
+ set *iset = domSetFromVect (ebbi, ebp->domVect);
eBBlock *loop;
eBBlock *idom = NULL;
/* computeDFOrdering - computes the depth first ordering of the */
/* flowgraph */
/*-----------------------------------------------------------------*/
-void
+static void
computeDFOrdering (eBBlock * ebbp, int *count)
{
/* disconBBlock - removes all control flow links for a block */
/*-----------------------------------------------------------------*/
void
-disconBBlock (eBBlock * ebp, eBBlock ** ebbs, int count)
+disconBBlock (eBBlock * ebp, ebbIndex * ebbi)
{
/* mark this block as noPath & recompute control flow */
ebp->noPath = 1;
- computeControlFlow (ebbs, count, TRUE);
+ computeControlFlow (ebbi);
}
/*-----------------------------------------------------------------*/
/* markNoPath - marks those blocks which cannot be reached from top */
/*-----------------------------------------------------------------*/
-void
-markNoPath (eBBlock ** ebbs, int count)
+static void
+markNoPath (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i;
-
/* for all blocks if the visited flag is not set : then there */
/* is no path from _entry to this block push them down in the */
/* depth first order */
if (!ebbs[i]->visited)
ebbs[i]->noPath = 1;
}
-/*-----------------------------------------------------------------*/
-/* dfNumCompare - used by qsort to sort by dfNumber */
-/*-----------------------------------------------------------------*/
-int
-dfNumCompare (const void *a, const void *b)
-{
- const eBBlock *const *i = a;
- const eBBlock *const *j = b;
-
- if ((*i)->dfnum > (*j)->dfnum)
- return 1;
-
- if ((*i)->dfnum < (*j)->dfnum)
- return -1;
-
- return 0;
-}
-
-/*-----------------------------------------------------------------*/
-/* bbNumCompare - used by qsort to sort by bbNumber */
-/*-----------------------------------------------------------------*/
-int
-bbNumCompare (const void *a, const void *b)
-{
- const eBBlock *const *i = a;
- const eBBlock *const *j = b;
-
- if ((*i)->bbnum > (*j)->bbnum)
- return 1;
-
- if ((*i)->bbnum < (*j)->bbnum)
- return -1;
-
- return 0;
-}
-
/*-----------------------------------------------------------------*/
/* computeControlFlow - does the control flow computation */
/*-----------------------------------------------------------------*/
void
-computeControlFlow (eBBlock ** ebbs, int count, int reSort)
+computeControlFlow (ebbIndex * ebbi)
{
- int saveCount = count;
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int dfCount = ebbi->count;
int i;
/* initialise some things */
- for (i = 0; i < count; i++)
+ for (i = 0; i < ebbi->count; i++)
{
setToNull ((void *) &ebbs[i]->predList);
setToNull ((void *) &ebbs[i]->domVect);
ebbs[i]->dfnum = 0;
}
- if (reSort)
- /* sort it back by block number */
- qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
-
setToNull ((void *) &graphEdges);
/* this will put in the */
/* successor information for each blk */
- eBBSuccessors (ebbs, count);
+ eBBSuccessors (ebbi);
/* compute the depth first ordering */
- computeDFOrdering (ebbs[0], &count);
+ computeDFOrdering (ebbi->bbOrder[0], &dfCount);
/* mark blocks with no paths to them */
- markNoPath (ebbs, saveCount);
+ markNoPath (ebbi);
/* with the depth first info in place */
/* add the predecessors for the blocks */
- eBBPredecessors (ebbs, saveCount);
+ eBBPredecessors (ebbi);
/* compute the dominance graph */
- computeDominance (ebbs, saveCount);
+ computeDominance (ebbi);
/* sort it by dfnumber */
- qsort (ebbs, saveCount, sizeof (eBBlock *), dfNumCompare);
+ if (!ebbi->dfOrder)
+ ebbi->dfOrder = Safe_alloc ((ebbi->count+1) * sizeof (eBBlock *));
+ for (i = 0; i < (ebbi->count+1); i++)
+ {
+ ebbi->dfOrder[i] = ebbi->bbOrder[i];
+ }
+
+ qsort (ebbi->dfOrder, ebbi->count, sizeof (eBBlock *), dfNumCompare);
}
#ifndef SDCCCFLOW_H
#define SDCCCFLOW_H 1
-void computeDFOrdering (eBBlock *, int *);
-set *domSetFromVect (eBBlock **, bitVect *);
-void addSuccessor (eBBlock *, eBBlock *);
-void eBBSuccessors (eBBlock **, int);
-void eBBPredecessors (eBBlock **, int);
-eBBlock *immedDom (eBBlock **, eBBlock *);
-DEFSETFUNC (DFOrdering);
-void markNoPath (eBBlock **, int);
-void computeControlFlow (eBBlock **, int, int);
-int dfNumCompare (const void *, const void *);
-int bbNumCompare (const void *, const void *);
-void disconBBlock (eBBlock *, eBBlock **, int);
+eBBlock *immedDom (ebbIndex *, eBBlock *);
+void computeControlFlow (ebbIndex *);
+void disconBBlock (eBBlock *, ebbIndex *);
int returnAtEnd (eBBlock *) ;
#endif
ifxOptimize (iCode * ic, set * cseSet,
int computeOnly,
eBBlock * ebb, int *change,
- eBBlock ** ebbs, int count)
+ ebbIndex * ebbi)
{
operand *pdop;
symbol *label;
/* this is very expensive but it does not happen */
/* too often, if it does happen then the user pays */
/* the price */
- computeControlFlow (ebbs, count, 1);
+ computeControlFlow (ebbi);
if (!options.lessPedantic) {
werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
}
we can remove this conditional statement */
label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic));
if (elementsInSet (ebb->succList) == 1 &&
- isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count)))
+ isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
{
if (!options.lessPedantic) {
else
{
remiCodeFromeBBlock (ebb, ic);
- computeControlFlow (ebbs, count, 1);
+ computeControlFlow (ebbi);
return;
}
}
/*-----------------------------------------------------------------*/
int
cseBBlock (eBBlock * ebb, int computeOnly,
- eBBlock ** ebbs, int count)
+ ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
set *cseSet;
iCode *ic;
int change = 0;
{
ifxOptimize (ic, cseSet, computeOnly,
ebb, &change,
- ebbs, count);
+ ebbi);
continue;
}
/* cseAllBlocks - will sequentially go thru & do cse for all blocks */
/*-----------------------------------------------------------------*/
int
-cseAllBlocks (eBBlock ** ebbs, int count, int computeOnly)
+cseAllBlocks (ebbIndex * ebbi, int computeOnly)
{
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
int i;
int change = 0;
/* if optimization turned off */
for (i = 0; i < count; i++)
- change += cseBBlock (ebbs[i], computeOnly, ebbs, count);
+ change += cseBBlock (ebbs[i], computeOnly, ebbi);
return change;
}
DEFSETFUNC (findPrevIc);
DEFSETFUNC (ifOperandsHave);
DEFSETFUNC (findCheaperOp);
-int cseBBlock (eBBlock *, int, eBBlock **, int);
-int cseAllBlocks (eBBlock **, int, int computeOnly);
-void ifxOptimize (iCode *, set *, int, eBBlock *, int *, eBBlock **, int);
+int cseBBlock (eBBlock *, int, ebbIndex *);
+int cseAllBlocks (ebbIndex *, int computeOnly);
void unsetDefsAndUses (iCode *);
void updateSpillLocation (iCode * ic,int);
void setUsesDefs (operand *, bitVect *, bitVect *, bitVect **);
}
else
{
+ //if (dest != ebp)
+ // dest->inExprs = intersectSets (dest->inExprs, ebp->outExprs, THROW_DEST);
+
/* delete only if killed in this block*/
deleteItemIf (&dest->inExprs, ifKilledInBlock, ebp);
/* union the ndompset with pointers set in this block */
/* computeDataFlow - does computations for data flow accross blocks */
/*-----------------------------------------------------------------*/
void
-computeDataFlow (eBBlock ** ebbs, int count)
+computeDataFlow (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
int i;
int change = 1;
/* get the immediate dominator and put it there */
if (!pBlock)
{
- eBBlock *idom = immedDom (ebbs, ebbs[i]);
+ eBBlock *idom = immedDom (ebbi, ebbs[i]);
if (idom)
addSetHead (&pred, idom);
}
/* do cse with computeOnly flag set to TRUE */
/* this by far the quickest way of computing */
- cseBBlock (ebbs[i], TRUE, ebbs, count);
+ cseBBlock (ebbs[i], TRUE, ebbi);
/* if it change we will need to iterate */
if (optimize.global_cse)
DEFSETFUNC (mergeInExprs);
DEFSETFUNC (ifKilledInBlock);
-void computeDataFlow (eBBlock **, int);
+void computeDataFlow (ebbIndex *);
DEFSETFUNC (mergeInDefs);
DEFSETFUNC (isDefAlive);
iCode *usedInRemaining (operand *, iCode *);
{
eBBlock *ebp = item;
V_ARG (cseDef *, cdp);
- V_ARG (eBBlock **, ebbs);
- V_ARG (int, count);
+ V_ARG (ebbIndex *, ebbi);
addSetHead (&ebp->inExprs, cdp);
- cseBBlock (ebp, optimize.global_cse, ebbs, count);
+ cseBBlock (ebp, optimize.global_cse, ebbi);
return 0;
}
/* loopInvariants - takes loop invariants out of region */
/*-----------------------------------------------------------------*/
int
-loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
+loopInvariants (region * theLoop, ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
eBBlock *lBlock;
set *lInvars = NULL;
bitVectUnSetBit (lBlock->defSet, ic->key);
bitVectUnSetBit (lBlock->ldefs, ic->key);
ivar = newCseDef (IC_RESULT (ic), ic);
- applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbs, count);
+ applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
addSet (&lInvars, ivar);
}
}
/* loopInduction - remove induction variables from a loop */
/*-----------------------------------------------------------------*/
int
-loopInduction (region * loopReg, eBBlock ** ebbs, int count)
+loopInduction (region * loopReg, ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
int change = 0;
eBBlock *lBlock, *owner, *lastBlock = NULL;
set *indVars = NULL;
/* createLoopRegions - will detect and create a set of natural loops */
/*-----------------------------------------------------------------*/
hTab *
-createLoopRegions (eBBlock ** ebbs, int count)
+createLoopRegions (ebbIndex * ebbi)
{
set *allRegion = NULL; /* set of all loops */
hTab *orderedLoops = NULL;
/* loopOptimizations - identify region & remove invariants & ind */
/*-----------------------------------------------------------------*/
int
-loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
+loopOptimizations (hTab * orderedLoops, ebbIndex * ebbi)
{
region *lp;
int change = 0;
{
if (optimize.loopInvariant)
- change += loopInvariants (lp, ebbs, count);
+ change += loopInvariants (lp, ebbi);
if (optimize.loopInduction)
- change += loopInduction (lp, ebbs, count);
+ change += loopInduction (lp, ebbi);
}
return change;
DEFSETFUNC (backEdges);
DEFSETFUNC (pregion);
DEFSETFUNC (pinduction);
-int loopOptimizations (hTab *, eBBlock **, int);
+int loopOptimizations (hTab *, ebbIndex *);
int addressTaken (set *, operand *);
-hTab *createLoopRegions (eBBlock **, int);
+hTab *createLoopRegions (ebbIndex *);
iCode *findDefInRegion (set *, operand *, eBBlock **);
int hasIncomingDefs (region *, operand *);
int findLoopEndSeq (region *);
-void addLoopBlocks (eBBlock ** ebbs, int count);
#endif
/* replaceRegEqv - replace all local variables with their reqv */
/*-----------------------------------------------------------------*/
static void
-replaceRegEqv (eBBlock ** ebbs, int count)
+replaceRegEqv (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
int i;
/* Update the symbols' def bitvector so we know if there is */
/* a defining iCode or not. Only replace a local variable */
/* with its register equivalent if there is a defining iCode; */
/* otherwise, the port's register allocater may choke. */
- cseAllBlocks (ebbs, count, TRUE);
+ cseAllBlocks (ebbi, TRUE);
for (i = 0; i < count; i++)
{
/* killDeadCode - eliminates dead assignments */
/*-----------------------------------------------------------------*/
int
-killDeadCode (eBBlock ** ebbs, int count)
+killDeadCode (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
int change = 1;
int gchange = 0;
int i = 0;
/* a dead address-of operation should die, even if volatile */
if (ic->op == ADDRESS_OF)
volLeft = FALSE;
+
+ //if (ic->op == CAST && isOperandVolatile (IC_LEFT (ic), FALSE))
+ // {
+ // volRight = IS_SYMOP (IC_RIGHT (ic));
+ // }
if (ic->next && ic->seqPoint == ic->next->seqPoint
&& (ic->next->op == '+' || ic->next->op == '-'))
}
continue;
}
-
+
change = 1;
gchange++;
} /* end of all instructions */
if (!ebbs[i]->sch && !ebbs[i]->noPath)
- disconBBlock (ebbs[i], ebbs, count);
+ disconBBlock (ebbs[i], ebbi);
} /* end of for all blocks */
eBBlock **
eBBlockFromiCode (iCode * ic)
{
- eBBlock **ebbs = NULL;
- int count = 0;
- int saveCount = 0;
+ ebbIndex *ebbi = NULL;
+ //eBBlock **ebbs = NULL;
+ //int count = 0;
+ //int saveCount = 0;
int change = 1;
int lchange = 0;
int kchange = 0;
if (!ic)
return NULL;
- count = 0;
+ //count = 0;
eBBNum = 0;
/* optimize the chain for labels & gotos
ic = iCodeLabelOptimize (ic);
/* break it down into basic blocks */
- ebbs = iCodeBreakDown (ic, &count);
- saveCount = count;
-
+ ebbi = iCodeBreakDown (ic);
+
/* hash the iCode keys so that we can quickly index */
/* them in the rest of the optimization steps */
setToNull ((void *) &iCodehTab);
iCodehTab = newHashTable (iCodeKey);
- hashiCodeKeys (ebbs, count);
+ hashiCodeKeys (ebbi->bbOrder, ebbi->count);
/* compute the control flow */
- computeControlFlow (ebbs, count, 0);
+ computeControlFlow (ebbi);
/* dumpraw if asked for */
if (options.dump_raw)
- dumpEbbsToFileExt (DUMP_RAW0, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RAW0, ebbi);
/* replace the local variables with their
register equivalents : the liveRange computation
along with the register allocation will determine
if it finally stays in the registers */
- replaceRegEqv (ebbs, count);
+ replaceRegEqv (ebbi);
/* create loop regions */
- loops = createLoopRegions (ebbs, count);
+ loops = createLoopRegions (ebbi);
/* dumpraw if asked for */
if (options.dump_raw)
- dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RAW1, ebbi);
- optimizeCastCast (ebbs, saveCount);
+ optimizeCastCast (ebbi->bbOrder, ebbi->count);
/* do common subexpression elimination for each block */
- change = cseAllBlocks (ebbs, saveCount, FALSE);
+ change = cseAllBlocks (ebbi, FALSE);
/* dumpraw if asked for */
if (options.dump_raw)
- dumpEbbsToFileExt (DUMP_CSE, ebbs, count);
+ dumpEbbsToFileExt (DUMP_CSE, ebbi);
/* compute the data flow */
- computeDataFlow (ebbs, saveCount);
+ computeDataFlow (ebbi);
/* dumpraw if asked for */
if (options.dump_raw)
- dumpEbbsToFileExt (DUMP_DFLOW, ebbs, count);
+ dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
/* global common subexpression elimination */
if (optimize.global_cse)
{
- change += cseAllBlocks (ebbs, saveCount, FALSE);
+ change += cseAllBlocks (ebbi, FALSE);
if (options.dump_gcse)
- dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
+ dumpEbbsToFileExt (DUMP_GCSE, ebbi);
}
else
{
// compute the dataflow only
- assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
+ assert(cseAllBlocks (ebbi, TRUE)==0);
}
/* kill dead code */
- kchange = killDeadCode (ebbs, saveCount);
+ kchange = killDeadCode (ebbi);
if (options.dump_kill)
- dumpEbbsToFileExt (DUMP_DEADCODE, ebbs, count);
+ dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
/* do loop optimizations */
- change += (lchange = loopOptimizations (loops, ebbs, count));
+ change += (lchange = loopOptimizations (loops, ebbi));
if (options.dump_loop)
- dumpEbbsToFileExt (DUMP_LOOP, ebbs, count);
+ dumpEbbsToFileExt (DUMP_LOOP, ebbi);
/* recompute the data flow and apply global cse again
if loops optimizations or dead code caused a change:
subexpression once more */
if (lchange || kchange)
{
- computeDataFlow (ebbs, saveCount);
- change += cseAllBlocks (ebbs, saveCount, FALSE);
+ computeDataFlow (ebbi);
+ change += cseAllBlocks (ebbi, FALSE);
if (options.dump_loop)
- dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
+ dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
/* if loop optimizations caused a change then do
dead code elimination once more : this will
get rid of the extra assignments to the induction
variables created during loop optimizations */
- killDeadCode (ebbs, saveCount);
+ killDeadCode (ebbi);
if (options.dump_loop)
- dumpEbbsToFileExt (DUMP_LOOPD, ebbs, count);
+ dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
}
/* sort it back by block number */
- qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
+ //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
if (!options.lessPedantic) {
// this is a good place to check missing return values
&& !FUNC_ISNAKED(currFunc->type)) {
eBBlock *bp;
// make sure all predecessors of the last block end in a return
- for (bp=setFirstItem(ebbs[saveCount-1]->predList);
+ for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
bp;
- bp=setNextItem(ebbs[saveCount-1]->predList)) {
+ bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList)) {
if (bp->ech->op != RETURN) {
werrorfl (bp->ech->filename, bp->ech->lineno,
W_VOID_FUNC, currFunc->name);
/* if cyclomatic info requested then print it */
if (options.cyclomatic)
- printCyclomatic (ebbs, saveCount);
+ printCyclomatic (ebbi->bbOrder, ebbi->count);
/* convert operations with support routines
written in C to function calls : Iam doing
this at this point since I want all the
operations to be as they are for optimzations */
- convertToFcall (ebbs, count);
+ convertToFcall (ebbi->bbOrder, ebbi->count);
/* compute the live ranges */
- computeLiveRanges (ebbs, count);
+ computeLiveRanges (ebbi->bbOrder, ebbi->count);
if (options.dump_range)
- dumpEbbsToFileExt (DUMP_RANGE, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RANGE, ebbi);
/* Now that we have the live ranges, discard parameter
* receives for unused parameters.
*/
- discardDeadParamReceives (ebbs, count);
+ discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
/* allocate registers & generate code */
- port->assignRegisters (ebbs, count);
+ port->assignRegisters (ebbi);
/* throw away blocks */
setToNull ((void *) &graphEdges);
- ebbs = NULL;
return NULL;
}
return 0;
}
-void avr_assignRegisters (eBBlock ** ebbs, int count);
+void avr_assignRegisters (ebbIndex *);
static bool
_avr_parseOptions (int *pargc, char **argv, int *i)
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-avr_assignRegisters (eBBlock ** ebbs, int count)
+avr_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
redoStackOffsets ();
if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
{ "__builtin_memcmp_c2x","c",3,{"cx*","cp*","i"}}, /* void __builtin_memcmp_c2x (xdata char *,code char *,int) */
{ NULL , NULL,0, {NULL}} /* mark end of table */
};
-void ds390_assignRegisters (eBBlock ** ebbs, int count);
+void ds390_assignRegisters (ebbIndex * ebbi);
static int regParmFlg = 0; /* determine if we can register a parameter */
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-ds390_assignRegisters (eBBlock ** ebbs, int count)
+ds390_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
}
if (options.dump_rassgn) {
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
};
-void hc08_assignRegisters (eBBlock ** ebbs, int count);
+void hc08_assignRegisters (ebbIndex *);
static int regParmFlg = 0; /* determine if we can register a parameter */
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-hc08_assignRegisters (eBBlock ** ebbs, int count)
+hc08_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
if (options.dump_rassgn)
{
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
-void mcs51_assignRegisters (eBBlock ** ebbs, int count);
+void mcs51_assignRegisters (ebbIndex *);
static int regParmFlg = 0; /* determine if we can register a parameter */
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-mcs51_assignRegisters (eBBlock ** ebbs, int count)
+mcs51_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
if (options.dump_rassgn)
{
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
void pCodeInitRegisters(void);
-void pic14_assignRegisters (eBBlock ** ebbs, int count);
+void pic14_assignRegisters (ebbIndex *);
/* Also defined in gen.h, but the #include is commented out */
/* for an unknowned reason. - EEP */
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-pic14_assignRegisters (eBBlock ** ebbs, int count)
+pic14_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
}
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
redoStackOffsets ();
if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
void pic16_pCodeInitRegisters(void);
-void pic16_assignRegisters (eBBlock ** ebbs, int count);
+void pic16_assignRegisters (ebbIndex *);
static int regParmFlg = 0; /* determine if we can register a parameter */
/* pic16_assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-pic16_assignRegisters (eBBlock ** ebbs, int count)
+pic16_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
redoStackOffsets ();
if (options.dump_rassgn)
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
/* now get back the chain */
ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
char *parm_types[MAX_BUILTIN_ARGS]; /* each parm type as string : see typeFromStr */
} builtins ;
+struct ebbIndex;
+
/* Processor specific names */
typedef struct
{
options are parsed. */
void (*setDefaultOptions) (void);
/** Does the dirty work. */
- void (*assignRegisters) (struct eBBlock **, int);
+ void (*assignRegisters) (struct ebbIndex *);
/** Returns the register name of a symbol.
Used so that 'regs' can be an incomplete type. */
//rewinds==1 ? '\0' : 's');
}
-void xa51_assignRegisters (eBBlock ** ebbs, int count);
+void xa51_assignRegisters (ebbIndex *);
static int regParmFlg = 0; /* determine if we can register a parameter */
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-xa51_assignRegisters (eBBlock ** ebbs, int count)
+xa51_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
if (options.dump_rassgn)
{
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
/* assignRegisters - assigns registers to each live range as need */
/*-----------------------------------------------------------------*/
void
-z80_assignRegisters (eBBlock ** ebbs, int count)
+z80_assignRegisters (ebbIndex * ebbi)
{
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
iCode *ic;
int i;
recomputeLiveRanges (ebbs, count);
if (options.dump_pack)
- dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
+ dumpEbbsToFileExt (DUMP_PACK, ebbi);
/* first determine for each live range the number of
registers & the type of registers required for each */
}
if (options.dump_rassgn) {
- dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
+ dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
dumpLiveRanges (DUMP_LRANGE, liveRanges);
}
void assignRegisters (eBBlock **, int);
regs *regWithIdx (int);
-void z80_assignRegisters (eBBlock ** ebbs, int count);
+void z80_assignRegisters (ebbIndex *);
bitVect *z80_rUmaskForOp (operand * op);
#endif