X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fizt%2Fralloc.c;h=48a3a6a0c1ee9d7a554841f28a389481ec02ce9a;hb=56d0ea9144facb91da4bf0c6da418b80f2632bcd;hp=f01ec1b8ab1305d7e9d3c1a74cfddeeb0b1096d8;hpb=8b194ce521ec1d8a69f019f1b286a0a1c8ff2343;p=fw%2Fsdcc diff --git a/src/izt/ralloc.c b/src/izt/ralloc.c index f01ec1b8..48a3a6a0 100644 --- a/src/izt/ralloc.c +++ b/src/izt/ralloc.c @@ -3,15 +3,18 @@ #include "izt.h" /// Static data. -static struct { - struct { +static struct + { + struct + { /// Used to generate a unique name for the spill location. int loc; /// Set of all iTemps spilt onto the stack. set *set; /// Similar to stackSpill bitVect *vect; - } spill; + } + spill; /// Bitvector of all registers used in this function. bitVect *funcUsedRegs; /// If a bit is set in this then the iCode at that sequence has had @@ -19,297 +22,344 @@ static struct { bitVect *regAssigned; int blockSpill; int stackExtend; -} _G; + } +_G; -static REG *_findRegById(REG_ID id) +static REG * +_findRegById (REG_ID id) { - REG *r = izt_port->regs; - - while (r->size) { - if (r->id == id) - return r; - r++; + REG *r = izt_port->regs; + + while (r->size) + { + if (r->id == id) + return r; + r++; } - wassert(0); - return NULL; + wassert (0); + return NULL; } -static REG *_getSubReg(REG *r, int size, int offset) +static REG * +_getSubReg (REG * r, int size, int offset) { - wassert(r->size >= size); - - if (r->size == size) { - wassert(offset == 0); - return r; + wassert (r->size >= size); + + if (r->size == size) + { + wassert (offset == 0); + return r; } - // We use the hiding table to get the parts of the register. - else if (size == 1) { - wassert(offset == 0 || offset == 1); - return _findRegById(r->hides[offset]); + // We use the hiding table to get the parts of the register. + else if (size == 1) + { + wassert (offset == 0 || offset == 1); + return _findRegById (r->hides[offset]); } - else if (size == 2) { - wassert(offset == 0); - return _findRegById(r->hides[2]); + else if (size == 2) + { + wassert (offset == 0); + return _findRegById (r->hides[2]); } - // Cant. - wassert(0); - return NULL; + // Cant. + wassert (0); + return NULL; } -static int _numRegsAvailable(int size) +static int +_numRegsAvailable (int size) { - REG *r = izt_port->regs; - int ret = 0; - - while (r->size) { - if (r->size == size && r->used == 0) - ret++; - r++; + REG *r = izt_port->regs; + int ret = 0; + + while (r->size) + { + if (r->size == size && r->used == 0) + ret++; + r++; } - - return ret; + + return ret; } -static void _setClearUsed(REG_ID id, int clear) +static void +_setClearUsed (REG_ID id, int clear) { - REG *r = _findRegById(id); - wassert(r); - - if (!clear) { - // The parent shouldnt be able to be allocated if this child - // is already. - wassert((r->used & REG_USED_HIDDEN) == 0); - r->used |= REG_USED_HIDDEN; + REG *r = _findRegById (id); + wassert (r); + + if (!clear) + { + // The parent shouldnt be able to be allocated if this child + // is already. + wassert ((r->used & REG_USED_HIDDEN) == 0); + r->used |= REG_USED_HIDDEN; } - else { - wassert((r->used & REG_USED_HIDDEN) != 0); - r->used &= ~REG_USED_HIDDEN; + else + { + wassert ((r->used & REG_USED_HIDDEN) != 0); + r->used &= ~REG_USED_HIDDEN; } } -static void _markAsUsed(REG_ID id) +static void +_markAsUsed (REG_ID id) { - _setClearUsed(id, FALSE); + _setClearUsed (id, FALSE); } -static void _markAsFree(REG_ID id) +static void +_markAsFree (REG_ID id) { - _setClearUsed(id, TRUE); + _setClearUsed (id, TRUE); } -static REG *_allocateReg(int size) +static REG * +_allocateReg (int size) { - REG *r = izt_port->regs; - - while (r->size) { - if (r->size == size && r->used == 0) { - // Now go through the interference table and mark all other - // registers as used. - int i; - for (i=0; i < NUM_OF(r->hides); i++) { - if (r->hides[i] == REG_ID_NONE) { - break; + REG *r = izt_port->regs; + + while (r->size) + { + if (r->size == size && r->used == 0) + { + // Now go through the interference table and mark all other + // registers as used. + int i; + for (i = 0; i < NUM_OF (r->hides); i++) + { + if (r->hides[i] == REG_ID_NONE) + { + break; } - _markAsUsed(r->hides[i]); + _markAsUsed (r->hides[i]); } - r->used |= REG_USED; - return r; + r->used |= REG_USED; + return r; } - r++; + r++; } - return NULL; + return NULL; } -static bitVect *_markRegBits(bitVect *v, REG *r) +static bitVect * +_markRegBits (bitVect * v, REG * r) { - int i; + int i; - // Mark the primary register. - v = bitVectSetBit(v, r->id); + // Mark the primary register. + v = bitVectSetBit (v, r->id); - // Now add all the hidden registers. - for (i=0; i < NUM_OF(r->hides); i++) { - if (r->hides[i] == REG_ID_NONE) { - break; + // Now add all the hidden registers. + for (i = 0; i < NUM_OF (r->hides); i++) + { + if (r->hides[i] == REG_ID_NONE) + { + break; } - v = bitVectSetBit(v, r->hides[i]); + v = bitVectSetBit (v, r->hides[i]); } - return v; + return v; } -static void _freeReg(REG *r) +static void +_freeReg (REG * r) { - int i; - wassert(r->used == REG_USED); - - r->used = 0; + int i; + wassert (r->used == REG_USED); - for (i=0; i < NUM_OF(r->hides); i++) { - if (r->hides[i] == REG_ID_NONE) { - break; + r->used = 0; + + for (i = 0; i < NUM_OF (r->hides); i++) + { + if (r->hides[i] == REG_ID_NONE) + { + break; } - _markAsFree(r->hides[i]); + _markAsFree (r->hides[i]); } } -static void _freeAllRegs(viod) +static void +_freeAllRegs (viod) { - REG *r = izt_port->regs; + REG *r = izt_port->regs; - while (r->size) { - r->used = 0; - r++; + while (r->size) + { + r->used = 0; + r++; } } -static void _dumpRegs(void) +static void +_dumpRegs (void) { - REG *r = izt_port->regs; + REG *r = izt_port->regs; - while (r->size) { - printf("%u\t%u\t%s\t%u\n", r->size, r->id, r->name, r->used); - r++; + while (r->size) + { + printf ("%u\t%u\t%s\t%u\n", r->size, r->id, r->name, r->used); + r++; } } -void izt_init(IZT_PORT *port) +void +izt_init (IZT_PORT * port) { - wassert(port && port->regs); - izt_port = port; - izt_initEmitters(); + wassert (port && port->regs); + izt_port = port; + izt_initEmitters (); } /// Lower register pressure by packing iTemps where possible. -static void _packRegisters(eBBlock *ebp) +static void +_packRegisters (eBBlock * ebp) { - // PENDING: Assignment packing - // PENDING: Mark address of a true symbol as remat. - // PENDING: Propagate remat through equals. - // PENDING: Assign bitwise which is followed by a conditional into carry. - // PENDING: Pack for one use on pointer get or set. Assumes that the pointer - // is stored in the scratch register. - // PENDING: Pack short use iTemps into ACC or the scratch register. + // PENDING: Assignment packing + // PENDING: Mark address of a true symbol as remat. + // PENDING: Propagate remat through equals. + // PENDING: Assign bitwise which is followed by a conditional into carry. + // PENDING: Pack for one use on pointer get or set. Assumes that the pointer + // is stored in the scratch register. + // PENDING: Pack short use iTemps into ACC or the scratch register. } -static void _computeRequiredRegs(void) +static void +_computeRequiredRegs (void) { - symbol *sym; - int k; + symbol *sym; + int k; - // Iterate over each live range. - for (sym = hTabFirstItem(liveRanges, &k); sym ; - sym = hTabNextItem(liveRanges, &k)) { + // Iterate over each live range. + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) + { - sym->nRegs = 0; + sym->nRegs = 0; - // If the symbol is never used, then next. - if ((sym->liveTo - sym->liveFrom) == 0) - continue; + // If the symbol is never used, then next. + if ((sym->liveTo - sym->liveFrom) == 0) + continue; - // Only temporaries need registers. - if (!sym->isitmp) - continue; + // Only temporaries need registers. + if (!sym->isitmp) + continue; - // Conditionals live in carry and dont need registers. - if (sym->regType == REG_TYPE_CND) - continue; + // Conditionals live in carry and dont need registers. + if (sym->regType == REG_TYPE_CND) + continue; - -#if 0 // PENDING. Currently we dont compute ruonly or accuse. - if (sym->ruonly || sym->accuse) { - if (IS_AGGREGATE(sym->type) || sym->isptr) - sym->type = aggrToPtr(sym->type,FALSE); - continue ; + +#if 0 // PENDING. Currently we dont compute ruonly or accuse. + if (sym->ruonly || sym->accuse) + { + if (IS_AGGREGATE (sym->type) || sym->isptr) + sym->type = aggrToPtr (sym->type, FALSE); + continue; } #endif - // We need registers. - if (IS_AGGREGATE(sym->type) || sym->isptr) { - // Turn an aggregate into something real. - sym->type = aggrToPtr(sym->type, FALSE); + // We need registers. + if (IS_AGGREGATE (sym->type) || sym->isptr) + { + // Turn an aggregate into something real. + sym->type = aggrToPtr (sym->type, FALSE); } - sym->nRegs = getSize(sym->type); - wassert(sym->nRegs <= 4); + sym->nRegs = getSize (sym->type); + wassert (sym->nRegs <= 4); } } -static bool _doesntNeedRegs(iCode *ic) +static bool +_doesntNeedRegs (iCode * ic) { - // Some types of instructions dont need registers. - // PENDING: Flush out the types and make processor specific. - if (SKIP_IC2(ic) || - ic->op == JUMPTABLE || - ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - ic->op == RETURN) { - return TRUE; + // Some types of instructions dont need registers. + // PENDING: Flush out the types and make processor specific. + if (SKIP_IC2 (ic) || + ic->op == JUMPTABLE || + ic->op == IFX || + ic->op == IPUSH || + ic->op == IPOP || + ic->op == RETURN) + { + return TRUE; } - return FALSE; + return FALSE; } -static bool _willCauseSpill(int size) +static bool +_willCauseSpill (int size) { - return _numRegsAvailable(size) == 0; + return _numRegsAvailable (size) == 0; } -static void _deassignLRs(iCode *ic, eBBlock *ebp) +static void +_deassignLRs (iCode * ic, eBBlock * ebp) { - symbol *sym; - int ignored; - symbol *result; - - // For each symbol - for (sym = hTabFirstItem(liveRanges, &ignored); sym; sym = hTabNextItem(liveRanges, &ignored)) { - - // Has this symbol expired yet? - if (sym->liveTo > ic->seq) { - // No. Cant deassign. - continue; + symbol *sym; + int ignored; + symbol *result; + + // For each symbol + for (sym = hTabFirstItem (liveRanges, &ignored); sym; sym = hTabNextItem (liveRanges, &ignored)) + { + + // Has this symbol expired yet? + if (sym->liveTo > ic->seq) + { + // No. Cant deassign. + continue; } - // It has expired. Free up the resources. - - // If it was spilt, then free up the stack spill location. - if (sym->isspilt) { - if (sym->stackSpil) { - sym->usl.spillLoc->isFree = 1; - sym->stackSpil = 0; + // It has expired. Free up the resources. + + // If it was spilt, then free up the stack spill location. + if (sym->isspilt) + { + if (sym->stackSpil) + { + sym->usl.spillLoc->isFree = 1; + sym->stackSpil = 0; } - continue; + continue; } - // If it currently has no registers assigned, then continue. - if (bitVectBitValue(_G.regAssigned, sym->key) == 0) { - continue; + // If it currently has no registers assigned, then continue. + if (bitVectBitValue (_G.regAssigned, sym->key) == 0) + { + continue; } - - // If it has no registers assigned to it, then continue. - if (sym->nRegs == 0) { - continue; + + // If it has no registers assigned to it, then continue. + if (sym->nRegs == 0) + { + continue; } - // Mark this sym as not having registers assigned. - bitVectUnSetBit(_G.regAssigned, sym->key); - - // Free the registers. - _freeReg(sym->regs[0]); - - // If deallocating will free up enough registers for this iCode - // then steal them immediatly. - if (IC_RESULT(ic) && !_doesntNeedRegs(ic)) { - result = OP_SYMBOL(IC_RESULT(ic)); - if (result && // Has a result - result->liveTo > ic->seq && // and lives past this instruction - result->liveTo <= ebp->lSeq && // and doesnt go past this block - result->nRegs && // and actually needs registers - !result->isspilt && // and doesnt have them yet - !result->remat && // and wouldnt waste them - !bitVectBitValue(_G.regAssigned, result->key) && // doesnt have them yet - !_willCauseSpill(result->nRegs) - ) { - result->regs[0] = _allocateReg(result->nRegs); + // Mark this sym as not having registers assigned. + bitVectUnSetBit (_G.regAssigned, sym->key); + + // Free the registers. + _freeReg (sym->regs[0]); + + // If deallocating will free up enough registers for this iCode + // then steal them immediatly. + if (IC_RESULT (ic) && !_doesntNeedRegs (ic)) + { + result = OP_SYMBOL (IC_RESULT (ic)); + if (result && // Has a result + result->liveTo > ic->seq && // and lives past this instruction + result->liveTo <= ebp->lSeq && // and doesnt go past this block + result->nRegs && // and actually needs registers + !result->isspilt && // and doesnt have them yet + !result->remat && // and wouldnt waste them + !bitVectBitValue (_G.regAssigned, result->key) && // doesnt have them yet + !_willCauseSpill (result->nRegs) + ) + { + result->regs[0] = _allocateReg (result->nRegs); } } } @@ -317,496 +367,566 @@ static void _deassignLRs(iCode *ic, eBBlock *ebp) /// Returns true if the live range of the given symbol doesnt overlap /// with any of the live ranges in the set. -static bool _noOverlap (set *itmpStack, symbol *fsym) +static bool +_noOverlap (set * itmpStack, symbol * fsym) { - symbol *sym; - - for (sym = setFirstItem(itmpStack); sym; sym = setNextItem(itmpStack)) { - if (sym->liveTo > fsym->liveFrom) { - return FALSE; + symbol *sym; + + for (sym = setFirstItem (itmpStack); sym; sym = setNextItem (itmpStack)) + { + if (sym->liveTo > fsym->liveFrom) + { + return FALSE; } } - return TRUE; + return TRUE; } /// Set operator that returns 1 if a free spill location is found. -DEFSETFUNC(_stackIsFree) -{ - symbol *sym = item; - V_ARG(symbol **,sloc); - V_ARG(symbol *,fsym); - - // Dont bother if one has already been found. - if (*sloc) - return 0; - - if (sym->isFree && // This location is free... - _noOverlap(sym->usl.itmpStack, fsym) && // and its usage doesnt overlap with the usage of this sym - getSize(sym->type) >= getSize(fsym->type) && // and the location is big enough to hold the sym - 1) { - // All good. Take this location. - *sloc = sym; - return 1; +DEFSETFUNC (_stackIsFree) +{ + symbol *sym = item; + V_ARG (symbol **, sloc); + V_ARG (symbol *, fsym); + + // Dont bother if one has already been found. + if (*sloc) + return 0; + + if (sym->isFree && // This location is free... + _noOverlap (sym->usl.itmpStack, fsym) && // and its usage doesnt overlap with the usage of this sym + getSize (sym->type) >= getSize (fsym->type) && // and the location is big enough to hold the sym + 1) + { + // All good. Take this location. + *sloc = sym; + return 1; } - else { - // No match. - return 0; + else + { + // No match. + return 0; } } /// Create a new spill location on the stack for this symbol. -symbol *_createStackSpill(symbol *sym) -{ - symbol *sloc= NULL; - - // Try to reuse an exisiting spill location. - if (applyToSet(_G.spill.set, _stackIsFree, &sloc, sym)) { - // Found one. Take it over. - sym->usl.spillLoc = sloc; - sym->stackSpil = TRUE; - sloc->isFree = 0; - addSetHead(&sloc->usl.itmpStack, sym); - return sym; +symbol * +_createStackSpill (symbol * sym) +{ + symbol *sloc = NULL; + + // Try to reuse an exisiting spill location. + if (applyToSet (_G.spill.set, _stackIsFree, &sloc, sym)) + { + // Found one. Take it over. + sym->usl.spillLoc = sloc; + sym->stackSpil = TRUE; + sloc->isFree = 0; + addSetHead (&sloc->usl.itmpStack, sym); + return sym; } - // No existing location. Time to create one. - // Give it a pretty name. - sprintf(buffer, "sloc%d", ++_G.spill.loc); - // And create. - sloc = newiTemp(buffer); - - // Setup the type. - sloc->type = copyLinkChain(sym->type); - sloc->etype = getSpec(sloc->type); - SPEC_SCLS(sloc->etype) = S_AUTO ; - - allocLocal(sloc); - - // "To prevent compiler warning" - sloc->isref = 1; - - // Increase the local variable stack size on this function. - if (IN_STACK(sloc->etype)) { - currFunc->stack += getSize(sloc->type); - _G.stackExtend += getSize(sloc->type); - } else { - // The IZT port currently doesnt support loading locals into data space. - wassert(0); + // No existing location. Time to create one. + // Give it a pretty name. + sprintf (buffer, "sloc%d", ++_G.spill.loc); + // And create. + sloc = newiTemp (buffer); + + // Setup the type. + sloc->type = copyLinkChain (sym->type); + sloc->etype = getSpec (sloc->type); + SPEC_SCLS (sloc->etype) = S_AUTO; + + allocLocal (sloc); + + // "To prevent compiler warning" + sloc->isref = 1; + + // Increase the local variable stack size on this function. + if (IN_STACK (sloc->etype)) + { + currFunc->stack += getSize (sloc->type); + _G.stackExtend += getSize (sloc->type); } + else + { + // The IZT port currently doesnt support loading locals into data space. + wassert (0); + } + + // And add it to the spill set. + addSetHead (&_G.spill.set, sloc); + sym->usl.spillLoc = sloc; + sym->stackSpil = TRUE; - // And add it to the spill set. - addSetHead(&_G.spill.set, sloc); - sym->usl.spillLoc = sloc; - sym->stackSpil = TRUE; - - // "Add it to the set of itempStack set of the spill location - addSetHead(&sloc->usl.itmpStack,sym); + // "Add it to the set of itempStack set of the spill location + addSetHead (&sloc->usl.itmpStack, sym); - return sym; + return sym; } -static void _spillThis(symbol *sym) +static void +_spillThis (symbol * sym) { - // Create a spill location if it needs one and doesnt have one yet. - if (!(sym->remat || sym->usl.spillLoc)) { - _createStackSpill(sym); + // Create a spill location if it needs one and doesnt have one yet. + if (!(sym->remat || sym->usl.spillLoc)) + { + _createStackSpill (sym); } - sym->isspilt = TRUE; - // Add it to the spilt set. - _G.spill.vect = bitVectSetBit(_G.spill.vect, sym->key); - // and remove it from the 'has registers' set. - bitVectUnSetBit(_G.regAssigned, sym->key); - - // Free up any registers that were assigned to this. - if (sym->regs[0]) { - _freeReg(sym->regs[0]); - sym->regs[0] = NULL; + sym->isspilt = TRUE; + // Add it to the spilt set. + _G.spill.vect = bitVectSetBit (_G.spill.vect, sym->key); + // and remove it from the 'has registers' set. + bitVectUnSetBit (_G.regAssigned, sym->key); + + // Free up any registers that were assigned to this. + if (sym->regs[0]) + { + _freeReg (sym->regs[0]); + sym->regs[0] = NULL; } - // CHECK: If this sym now has a spill location, mark it as allocated - // so that the stack packing later doesnt remove it. - if (sym->usl.spillLoc && !sym->remat) { - sym->usl.spillLoc->allocreq = TRUE; + // CHECK: If this sym now has a spill location, mark it as allocated + // so that the stack packing later doesnt remove it. + if (sym->usl.spillLoc && !sym->remat) + { + sym->usl.spillLoc->allocreq = TRUE; } - return; + return; } -static bitVect *_findSpillable(iCode *ic) +static bitVect * +_findSpillable (iCode * ic) { - bitVect *spillable; + bitVect *spillable; - // First create a copy of the currently live ranges. - spillable = bitVectCopy(ic->rlive); - // Remove those which are already spilt. - spillable = bitVectCplAnd(spillable, _G.spill.vect); - // Remove those that this iCode uses. - spillable = bitVectCplAnd(spillable, ic->uses); - // Remove those that this iCode defines. - bitVectUnSetBit(spillable, ic->defKey); + // First create a copy of the currently live ranges. + spillable = bitVectCopy (ic->rlive); + // Remove those which are already spilt. + spillable = bitVectCplAnd (spillable, _G.spill.vect); + // Remove those that this iCode uses. + spillable = bitVectCplAnd (spillable, ic->uses); + // Remove those that this iCode defines. + bitVectUnSetBit (spillable, ic->defKey); - // Only those that have registers assigned can actually be spilt :) - spillable = bitVectIntersect(spillable, _G.regAssigned); + // Only those that have registers assigned can actually be spilt :) + spillable = bitVectIntersect (spillable, _G.regAssigned); - return spillable; + return spillable; } /// Finds the least used live range -static symbol *_leastUsedLR(set *sset) -{ - // sym is the currently least used symbol. - symbol *sym; - // walk walks the list of symbols in the scan set. - symbol *walk; - - // Use the first as the seed. - sym = walk = setFirstItem(sset); - - while (walk) { - // Prefer spilling the symbol with the least allocated registers. - // PENDING: Why? - if (walk->used == sym->used) { - if (getSize(walk->type) < getSize(sym->type)) { - sym = walk; +static symbol * +_leastUsedLR (set * sset) +{ + // sym is the currently least used symbol. + symbol *sym; + // walk walks the list of symbols in the scan set. + symbol *walk; + + // Use the first as the seed. + sym = walk = setFirstItem (sset); + + while (walk) + { + // Prefer spilling the symbol with the least allocated registers. + // PENDING: Why? + if (walk->used == sym->used) + { + if (getSize (walk->type) < getSize (sym->type)) + { + sym = walk; } } - else if (walk->used < sym->used) { - // This is used less than the current best. It looses. - sym = walk; + else if (walk->used < sym->used) + { + // This is used less than the current best. It looses. + sym = walk; } - - walk = setNextItem(sset); - } - setToNull((void **)&sset); - sym->blockSpil = 0; + walk = setNextItem (sset); + } + + setToNull ((void **) &sset); + sym->blockSpil = 0; - return sym; + return sym; } /// Applies a function to a given set of live ranges. -static set *_liveRangesWith(bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *), - eBBlock *ebp, iCode *ic) +static set * +_liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *), + eBBlock * ebp, iCode * ic) { - set *rset = NULL; - int i; + set *rset = NULL; + int i; - // Dont do anything if the bitVect is empty. - if (!lrs || !lrs->size) - return NULL; + // Dont do anything if the bitVect is empty. + if (!lrs || !lrs->size) + return NULL; - for (i = 1; i < lrs->size; i++ ) { - symbol *sym; + for (i = 1; i < lrs->size; i++) + { + symbol *sym; - // If this bit isnt turned on, skip. - if (!bitVectBitValue(lrs, i)) - continue ; + // If this bit isnt turned on, skip. + if (!bitVectBitValue (lrs, i)) + continue; - // If we don't find it in the live range hash table we are in serious trouble. - if (!(sym = hTabItemWithKey(liveRanges, i))) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "liveRangesWith could not find liveRange"); - exit(1); + // If we don't find it in the live range hash table we are in serious trouble. + if (!(sym = hTabItemWithKey (liveRanges, i))) + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "liveRangesWith could not find liveRange"); + exit (1); } - - // If the function likes it, and it has registers assigned to - // it, add it to the return set. - if (func(sym, ebp, ic) && bitVectBitValue(_G.regAssigned, sym->key)) { - addSetHead(&rset,sym); + + // If the function likes it, and it has registers assigned to + // it, add it to the return set. + if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key)) + { + addSetHead (&rset, sym); } } - return rset; + return rset; } /// Returns TRUE always. Used to fetch all live ranges. -static int _allLRs(symbol *sym, eBBlock *ebp, iCode *ic) +static int +_allLRs (symbol * sym, eBBlock * ebp, iCode * ic) { - return 1; + return 1; } -static void _serialRegAssign(eBBlock **ebbs, int count) +static void +_serialRegAssign (eBBlock ** ebbs, int count) { - int i; + int i; + + // For each block, do... + for (i = 0; i < count; i++) + { + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + { + // PENDING: Dont understand. + continue; + } - // For each block, do... - for (i=0; inoPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) { - // PENDING: Dont understand. - continue; - } - - - // For each iCode in this block, do... - for (ic = ebbs[i]->sch; ic; ic = ic->next) { - symbol *sym; - bitVect *spillable; - int willCauseSpill; - - // Dont support IPOP - wassert(ic->op != IPOP); - - // if result is present && is a true symbol - if (IC_RESULT(ic) && ic->op != IFX && - IS_TRUE_SYMOP(IC_RESULT(ic))) - OP_SYMBOL(IC_RESULT(ic))->allocreq = 1; - - // Take away registers from live ranges that end at this - // instruction. - _deassignLRs(ic, ebbs[i]); - - // Some instructions dont need registers. - if (_doesntNeedRegs(ic)) { - continue; + // For each iCode in this block, do... + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + symbol *sym; + bitVect *spillable; + int willCauseSpill; + + // Dont support IPOP + wassert (ic->op != IPOP); + + // if result is present && is a true symbol + if (IC_RESULT (ic) && ic->op != IFX && + IS_TRUE_SYMOP (IC_RESULT (ic))) + OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; + + // Take away registers from live ranges that end at this + // instruction. + _deassignLRs (ic, ebbs[i]); + + // Some instructions dont need registers. + if (_doesntNeedRegs (ic)) + { + continue; } - // If there is no result, then it doesnt need registers. - if (!IC_RESULT(ic)) { - continue; + // If there is no result, then it doesnt need registers. + if (!IC_RESULT (ic)) + { + continue; } - sym = OP_SYMBOL(IC_RESULT(ic)); + sym = OP_SYMBOL (IC_RESULT (ic)); - // Does it need any registers? - if (sym->nRegs == 0) { - continue; + // Does it need any registers? + if (sym->nRegs == 0) + { + continue; } - // Is it already split? - if (sym->isspilt) { - continue; + // Is it already split? + if (sym->isspilt) + { + continue; } - // Does it already have registers assigned? - if (bitVectBitValue(_G.regAssigned,sym->key)) { - continue; + // Does it already have registers assigned? + if (bitVectBitValue (_G.regAssigned, sym->key)) + { + continue; } - // Will it live past this instruction? - if (sym->liveTo <= ic->seq) { - continue; + // Will it live past this instruction? + if (sym->liveTo <= ic->seq) + { + continue; } - // MLH Doesnt understand this. - /* "Iif some liverange has been spilt at the block level - and this one live beyond this block then spil this - to be safe" */ - if (_G.blockSpill && sym->liveTo > ebbs[i]->lSeq) { - _spillThis(sym); - continue; + // MLH Doesnt understand this. + /* "Iif some liverange has been spilt at the block level + and this one live beyond this block then spil this + to be safe" */ + if (_G.blockSpill && sym->liveTo > ebbs[i]->lSeq) + { + _spillThis (sym); + continue; } - - // Seems that this symbol needs registers. See if - // allocating will cause a spill. - willCauseSpill = _willCauseSpill(sym->nRegs); - spillable = _findSpillable(ic); - - // If this is remat., then dont waste any regsiters on it. - if (sym->remat) { - _spillThis(sym); - continue; + + // Seems that this symbol needs registers. See if + // allocating will cause a spill. + willCauseSpill = _willCauseSpill (sym->nRegs); + spillable = _findSpillable (ic); + + // If this is remat., then dont waste any regsiters on it. + if (sym->remat) + { + _spillThis (sym); + continue; } - // If trying to allocate will cause a spill, and nothing - // else is spillable then this sym looses. - if (willCauseSpill && bitVectIsZero(spillable)) { - _spillThis(sym); - continue; + // If trying to allocate will cause a spill, and nothing + // else is spillable then this sym looses. + if (willCauseSpill && bitVectIsZero (spillable)) + { + _spillThis (sym); + continue; } - // If this will cause a spill, and it already has a spill - // location then spill this if it is the least used. - if (willCauseSpill && sym->usl.spillLoc) { - symbol *leastUsed = _leastUsedLR(_liveRangesWith(spillable, _allLRs, ebbs[i], ic)); - if (leastUsed && leastUsed->used > sym->used) { - _spillThis(sym); - continue; + // If this will cause a spill, and it already has a spill + // location then spill this if it is the least used. + if (willCauseSpill && sym->usl.spillLoc) + { + symbol *leastUsed = _leastUsedLR (_liveRangesWith (spillable, _allLRs, ebbs[i], ic)); + if (leastUsed && leastUsed->used > sym->used) + { + _spillThis (sym); + continue; } } - // Hmm. Here we could have no registers available but - // we'll still try to allocate. MLH wonders how this will - // work. - - // Mark this iCode as having registers assigned to it. - _G.regAssigned = bitVectSetBit(_G.regAssigned, sym->key); + // Hmm. Here we could have no registers available but + // we'll still try to allocate. MLH wonders how this will + // work. + + // Mark this iCode as having registers assigned to it. + _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); - // And do it. - sym->regs[0] = _allocateReg(sym->nRegs); + // And do it. + sym->regs[0] = _allocateReg (sym->nRegs); } } } -static DEFSETFUNC(_deallocStackSpil) +static +DEFSETFUNC (_deallocStackSpil) { - symbol *sym = item; + symbol *sym = item; - deallocLocal(sym); - return 0; + deallocLocal (sym); + return 0; } /// Compute the register mask for an operand. -bitVect *_rUmaskForOp(operand *op) +bitVect * +_rUmaskForOp (operand * op) { - bitVect *rumask; - symbol *sym; - - // "Only temporaries are assigned registers" - if (!IS_ITEMP(op)) - return NULL; + bitVect *rumask; + symbol *sym; + + // "Only temporaries are assigned registers" + if (!IS_ITEMP (op)) + return NULL; + + sym = OP_SYMBOL (op); - sym = OP_SYMBOL(op); - - // If its spilt or no registers are needed, then no regs are assigned. - if (sym->isspilt || !sym->nRegs) - return NULL; + // If its spilt or no registers are needed, then no regs are assigned. + if (sym->isspilt || !sym->nRegs) + return NULL; - rumask = newBitVect(REG_ID_MAX); + rumask = newBitVect (REG_ID_MAX); - if (sym->regs[0]) { - rumask = _markRegBits(rumask, sym->regs[0]); + if (sym->regs[0]) + { + rumask = _markRegBits (rumask, sym->regs[0]); } - return rumask; + return rumask; } /// Returns bit vector of registers used in iCode. -bitVect *_regsUsedIniCode (iCode *ic) +bitVect * +_regsUsedIniCode (iCode * ic) { - bitVect *rmask = newBitVect(REG_ID_MAX); - - do { - // Special cases first. - if (ic->op == IFX ) { - rmask = bitVectUnion(rmask, _rUmaskForOp(IC_COND(ic))); - break; + bitVect *rmask = newBitVect (REG_ID_MAX); + + do + { + // Special cases first. + if (ic->op == IFX) + { + rmask = bitVectUnion (rmask, _rUmaskForOp (IC_COND (ic))); + break; } - if (ic->op == JUMPTABLE) { - rmask = bitVectUnion(rmask, _rUmaskForOp(IC_JTCOND(ic))); - break; + if (ic->op == JUMPTABLE) + { + rmask = bitVectUnion (rmask, _rUmaskForOp (IC_JTCOND (ic))); + break; } - // Now the good old left, right, and result. - if (IC_LEFT(ic)) { - rmask = bitVectUnion(rmask, _rUmaskForOp(IC_LEFT(ic))); + // Now the good old left, right, and result. + if (IC_LEFT (ic)) + { + rmask = bitVectUnion (rmask, _rUmaskForOp (IC_LEFT (ic))); } - - if (IC_RIGHT(ic)) { - rmask = bitVectUnion(rmask, _rUmaskForOp(IC_RIGHT(ic))); + + if (IC_RIGHT (ic)) + { + rmask = bitVectUnion (rmask, _rUmaskForOp (IC_RIGHT (ic))); } - if (IC_RESULT(ic)) { - rmask = bitVectUnion(rmask, _rUmaskForOp(IC_RESULT(ic))); + if (IC_RESULT (ic)) + { + rmask = bitVectUnion (rmask, _rUmaskForOp (IC_RESULT (ic))); } - } while (0); + } + while (0); - return rmask; + return rmask; } /// Compute the helper bitVect that contains the register used mask. -static void _createRegMask(eBBlock **ebbs, int count) +static void +_createRegMask (eBBlock ** ebbs, int count) { - int i; + int i; + + /* for all blocks */ + for (i = 0; i < count; i++) + { + iCode *ic; + + // If this code is unused, skip it. + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + { + continue; + } - /* for all blocks */ - for (i = 0; i < count; i++) { - iCode *ic ; + /* for all instructions */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + int j; - // If this code is unused, skip it. - if ( ebbs[i]->noPath && - ( ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) { + if (SKIP_IC2 (ic) || !ic->rlive) continue; - } - /* for all instructions */ - for (ic = ebbs[i]->sch; ic; ic = ic->next) { - int j; - - if (SKIP_IC2(ic) || !ic->rlive) - continue ; - - // Mark the registers used in this instruction. - ic->rUsed = _regsUsedIniCode(ic); - // Mark them as used at least once in the function. - _G.funcUsedRegs = bitVectUnion(_G.funcUsedRegs, ic->rUsed); - - /* now create the register mask for those - registers that are in use : this is a - super set of ic->rUsed */ - ic->rMask = newBitVect(REG_ID_MAX+1); - - // "For all live Ranges alive at this point" - for (j = 1; j < ic->rlive->size; j++) { - symbol *sym; - - // "If if not alive then continue" - if (!bitVectBitValue(ic->rlive,j)) { - continue; + // Mark the registers used in this instruction. + ic->rUsed = _regsUsedIniCode (ic); + // Mark them as used at least once in the function. + _G.funcUsedRegs = bitVectUnion (_G.funcUsedRegs, ic->rUsed); + + /* now create the register mask for those + registers that are in use : this is a + super set of ic->rUsed */ + ic->rMask = newBitVect (REG_ID_MAX + 1); + + // "For all live Ranges alive at this point" + for (j = 1; j < ic->rlive->size; j++) + { + symbol *sym; + + // "If if not alive then continue" + if (!bitVectBitValue (ic->rlive, j)) + { + continue; } - // "Find the live range we are interested in" - if (!(sym = hTabItemWithKey(liveRanges,j))) { - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - "createRegMask cannot find live range"); - exit(0); + // "Find the live range we are interested in" + if (!(sym = hTabItemWithKey (liveRanges, j))) + { + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "createRegMask cannot find live range"); + exit (0); } - // "If no register assigned to it" - if (!sym->nRegs || sym->isspilt) { - continue; + // "If no register assigned to it" + if (!sym->nRegs || sym->isspilt) + { + continue; } - // If this has any registers allocated, mark them as such. - if (sym->regs[0]) { - ic->rMask = _markRegBits(ic->rMask, sym->regs[0]); + // If this has any registers allocated, mark them as such. + if (sym->regs[0]) + { + ic->rMask = _markRegBits (ic->rMask, sym->regs[0]); } } } } } -void izt_assignRegisters(eBBlock **ebbs, int count) +void +izt_assignRegisters (eBBlock ** ebbs, int count) { - // Contains a flat version of ebbs used in code generation. - iCode *chain; + // Contains a flat version of ebbs used in code generation. + iCode *chain; - // Clear the bit vector of registers used in this function. - // Assumes that assignRegisters is called once per function. - setToNull((void *)&_G.funcUsedRegs); + // Clear the bit vector of registers used in this function. + // Assumes that assignRegisters is called once per function. + setToNull ((void *) &_G.funcUsedRegs); - // First scan each live range, and figure out what registers - // are required. - _computeRequiredRegs(); + // First scan each live range, and figure out what registers + // are required. + _computeRequiredRegs (); - // Now allocate the registers. - _serialRegAssign(ebbs, count); + // Now allocate the registers. + _serialRegAssign (ebbs, count); - // And create the helper register used mask. - _createRegMask(ebbs, count); + // And create the helper register used mask. + _createRegMask (ebbs, count); - // Turn the bblock array into an optimised list of iCode entries. - chain = iCodeLabelOptimize(iCodeFromeBBlock(ebbs,count)); + // Turn the bblock array into an optimised list of iCode entries. + chain = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); - // Redo the stack offsets. This will remove any redundent stack - // locations ie iTemps that exist only in registers. - redoStackOffsets(); + // Redo the stack offsets. This will remove any redundent stack + // locations ie iTemps that exist only in registers. + redoStackOffsets (); - izt_gen(chain); + izt_gen (chain); - // Deallocate any stack spill locations. - applyToSet(_G.spill.set, _deallocStackSpil); + // Deallocate any stack spill locations. + applyToSet (_G.spill.set, _deallocStackSpil); - _G.spill.loc = 0; - setToNull((void **)&_G.spill.set); - setToNull((void **)&_G.spill.vect); + _G.spill.loc = 0; + setToNull ((void **) &_G.spill.set); + setToNull ((void **) &_G.spill.vect); - // And free all registers. - _freeAllRegs(); + // And free all registers. + _freeAllRegs (); +} + +void +warningStopper (void) +{ + // For now references all unused functions. + _dumpRegs (); + _packRegisters (NULL); + _getSubReg (NULL, 0, 0); }