From e48f3721c0f89871198b06d578c9cc95a3add49c Mon Sep 17 00:00:00 2001 From: sandeep Date: Sat, 23 Sep 2000 17:58:53 +0000 Subject: [PATCH] Yet another reg alloc bug uncovered by ds390 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@402 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/SDCCicode.h | 3 ++- src/SDCClrange.c | 7 +++++-- src/SDCCsymt.h | 2 +- src/avr/ralloc.c | 40 +++++++++++++++++++++++++++------------- src/avr/ralloc.h | 1 + src/ds390/ralloc.c | 10 ++++++---- src/mcs51/ralloc.c | 10 ++++++---- src/z80/ralloc.c | 10 ++++++---- 8 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/SDCCicode.h b/src/SDCCicode.h index eb0e77b0..f5059169 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -67,6 +67,7 @@ typedef enum { #define OP_LIVEFROM(op) op->operand.symOperand->liveFrom #define OP_LIVETO(op) op->operand.symOperand->liveTo #define OP_REQV(op) op->operand.symOperand->reqv +#define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall) /* typedef for operand */ typedef struct operand { @@ -79,7 +80,7 @@ typedef struct operand { unsigned int isParm :1 ; /* is a parameter */ unsigned int isLiteral:1 ; /* operand is literal */ unsigned int noSpilLoc:1 ; /* cannot be assigned a spil location */ - + unsigned key ; int parmBytes; union { diff --git a/src/SDCClrange.c b/src/SDCClrange.c index 583aeb49..bba270ef 100644 --- a/src/SDCClrange.c +++ b/src/SDCClrange.c @@ -514,9 +514,12 @@ void rlivePoint (eBBlock **ebbs, int count) for ( lrange = hTabFirstItem(liveRanges,&k); lrange; lrange = hTabNextItem(liveRanges,&k)) { + /* if it is live then add the lrange to ic->rlive */ if (lrange->liveFrom <= ic->seq && - lrange->liveTo >= ic->seq ) - ic->rlive = bitVectSetBit(ic->rlive,lrange->key); + lrange->liveTo >= ic->seq ) { + lrange->isLiveFcall = (ic->op == CALL || ic->op == PCALL); + ic->rlive = bitVectSetBit(ic->rlive,lrange->key); + } } } } diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 0e1a7193..1829a3bf 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -190,7 +190,7 @@ typedef struct symbol { /* following flags are used by the backend for code generation and can be changed if a better scheme for backend is thought of */ - + unsigned isLiveFcall:1 ; /* is live at or across a function call */ unsigned isspilt :1 ; /* has to be spilt */ unsigned remat :1 ; /* can be remateriazed */ unsigned isptr :1 ; /* is a pointer */ diff --git a/src/avr/ralloc.c b/src/avr/ralloc.c index 05e541a7..20259605 100644 --- a/src/avr/ralloc.c +++ b/src/avr/ralloc.c @@ -619,11 +619,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - _G.blockSpil++; + if (sym != forSym) { + if (!sym->remat) { + sym->remainSpil = 1; + _G.blockSpil++; + } + return sym; } - return sym; } } @@ -1310,13 +1312,17 @@ static void regTypeNum () /* determine the type of register required */ if (sym->nRegs == 2 && /* size is two */ IS_PTR(sym->type) && /* is a pointer */ - sym->uptr) { /* has has pointer usage i.e. get/set pointer */ + sym->uptr) { /* has pointer usage i.e. get/set pointer */ sym->regType = REG_PTR ; avr_ptrRegReq++; } - else - sym->regType = REG_GPR ; - + else { + /* live accross a function call then gpr else scratch */ + if (sym->isLiveFcall) + sym->regType = REG_GPR ; + else + sym->regType = REG_SCR ; + } } else /* for the first run we don't provide */ /* registers for true symbols we will */ @@ -2211,6 +2217,7 @@ static void preAssignParms (iCode *ic) /*-----------------------------------------------------------------*/ static void setDefaultRegs(eBBlock **ebbs,int count) { + int i ; /* if no pointer registers required in this function then mark r26-27 & r30-r31 as GPR & free */ @@ -2239,17 +2246,25 @@ static void setDefaultRegs(eBBlock **ebbs,int count) regsAVR[R1_IDX].isFree = regsAVR[R24_IDX].isFree = regsAVR[R25_IDX].isFree = 0; - + /* if this has no function calls then we need to do something special a) pre-assign registers to parameters RECEIVE b) mark the remaining parameter regs as free */ if (!currFunc->hasFcall) { + /* mark the parameter regs as GPR */ + for (i= R16_IDX ; i <= R23_IDX ;i++) { + regsAVR[i].type = REG_GPR; + regsAVR[i].isFree = 1; + } preAssignParms(ebbs[0]->sch); } else { - int i=0; - for (i= R16_IDX ; i <= R23_IDX ;i++) - regsAVR[i].isFree = 0; + + /* otherwise mark them as free scratch */ + for (i= R16_IDX ; i <= R23_IDX ;i++) { + regsAVR[i].type = REG_SCR; + regsAVR[i].isFree = 1; + } } /* Y - is not allocated (it is the stack frame) */ @@ -2268,7 +2283,6 @@ void avr_assignRegisters (eBBlock **ebbs, int count) setToNull((void *)&_G.funcrUsed); avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - /* setup other default register allocation */ /* change assignments this will remove some live ranges reducing some register pressure */ for (i = 0 ; i < count ;i++ ) diff --git a/src/avr/ralloc.h b/src/avr/ralloc.h index 303c6b93..f293e60c 100644 --- a/src/avr/ralloc.h +++ b/src/avr/ralloc.h @@ -38,6 +38,7 @@ enum { R0_IDX = 0, R1_IDX , R2_IDX , R3_IDX , R4_IDX , #define REG_PTR 0x01 #define REG_GPR 0x02 +#define REG_SCR 0x03 #define REG_CND 0x04 /* definition for the registers */ diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index a9061c92..ecec03ea 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -629,11 +629,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) used in the remainder of the block */ if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - _G.blockSpil++; + if (sym != forSym) { + if (!sym->remat) { + sym->remainSpil = 1; + _G.blockSpil++; + } + return sym; } - return sym; } } diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index dd6d5a73..2a3726c3 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -627,11 +627,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) used in the remainder of the block */ if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - _G.blockSpil++; + if (sym != forSym) { + if (!sym->remat) { + sym->remainSpil = 1; + _G.blockSpil++; + } + return sym; } - return sym; } } diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 9f42f591..fc224eb4 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -569,11 +569,13 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) used in the remainder of the block */ if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - blockSpil++; + if (sym != ForSym) { + if (!sym->remat) { + sym->remainSpil = 1; + blockSpil++; + } + return sym; } - return sym; } } /* find live ranges with spillocation && not used as pointers */ -- 2.47.2