static void PruneInductionCandidate(int tnum, LOOP *l) { if (tempInfo[tnum]->size >= ISZ_FLOAT) { briggsReset(candidates, tnum); } else { QUAD *I = tempInfo[tnum]->instructionDefines; switch(I->dc.opcode) { case i_phi: { PHIDATA *pd = I->dc.v.phi; struct _phiblock *pb = pd->temps; while (pb) { if (!briggsTest(candidates, pb->Tn) && !isInvariant(pb->Tn, l)) { briggsReset(candidates, tnum); break; } pb = pb->next; } } break; case i_add: case i_sub: if (I->temps & TEMP_RIGHT) { int tn2 = I->dc.right->offset->v.sp->value.i; if (!briggsTest(candidates, tn2)) briggsReset(candidates, tnum); } /* FALLTHROUGH */ case i_neg: case i_assn: if (I->temps & TEMP_LEFT) { int tn2 = I->dc.left->offset->v.sp->value.i; if (!briggsTest(candidates, tn2)) briggsReset(candidates, tnum); } break; default: diag("PruneInductionCandidate: invalid form"); break; } } }
int briggsIntersect(BRIGGS_SET *s1, BRIGGS_SET *s2) { int i; for (i=s1->top-1; i >= 0; i--) { if (!briggsTest(s2, s1->data[i])) { briggsReset(s1, s1->data[i]); } } return 0; }
void Prealloc(int pass) { int i; BOOL done = FALSE; BRIGGS_SET *eobGlobals; liveVariables(); globalVars = briggsAlloc(tempCount * 2 < 100 ? 100 : tempCount * 2); eobGlobals = briggsAlloc(tempCount * 2 < 100 ? 100 : tempCount * 2); if (!chosenAssembler->gen->preRegAlloc) return; for (; pass < 11 && !done; pass++) { for (i=0; i < blockCount; i++) { if (blockArray[i]) { QUAD *tail = blockArray[i]->tail; BITINT *p = blockArray[i]->liveOut; int j,k; briggsClear(globalVars); briggsClear(eobGlobals); for (j=0; j < (tempCount + BITINTBITS-1)/BITINTBITS; j++,p++) if (*p) for (k=0; k < BITINTBITS; k++) if (*p & (1 << k)) { int n = j*BITINTBITS + k; briggsSet(globalVars, n); briggsSet(eobGlobals, n); } while (tail != blockArray[i]->head) { if ((tail->temps & TEMP_ANS) && (tail->ans->mode == i_direct)) { briggsReset(globalVars, tail->ans->offset->v.sp->value.i); } done |= chosenAssembler->gen->preRegAlloc(tail, globalVars, eobGlobals, pass); if ((tail->temps & TEMP_ANS) && (tail->ans->mode == i_ind)) { if (tail->ans->offset) briggsSet(globalVars, tail->ans->offset->v.sp->value.i); if (tail->ans->offset2) briggsSet(globalVars, tail->ans->offset2->v.sp->value.i); } if (tail->temps & TEMP_LEFT) { if (tail->dc.left->offset) briggsSet(globalVars, tail->dc.left->offset->v.sp->value.i); if (tail->dc.left->offset2) briggsSet(globalVars, tail->dc.left->offset2->v.sp->value.i); } if (tail->temps & TEMP_RIGHT) { if (tail->dc.right->offset) briggsSet(globalVars, tail->dc.right->offset->v.sp->value.i); if (tail->dc.right->offset2) briggsSet(globalVars, tail->dc.right->offset2->v.sp->value.i); } tail = tail->back; } } } } }
static void markLiveInstruction(BRIGGS_SET *live, QUAD *ins) { switch(ins->dc.opcode) { case i_parmadj: case i_passthrough: case i_line: case i_varstart: case i_dbgblock: case i_dbgblockend: case i_func: case i_trap: case i_int: case i_ret: case i_fret: case i_rett: case i_cppini: case i_block: case i_blockend: case i_livein: case i_prologue: case i_epilogue: case i_pushcontext: case i_popcontext: case i_loadcontext: case i_unloadcontext: case i_tryblock: case i_loadstack: case i_savestack: case i_substack: case i_functailstart: case i_functailend: case i_swbranch: case i_skipcompare: ins->live = TRUE; break; case i_parm: case i_gosub: case i_label: case i_goto: ins->live = TRUE; break; case i_assnblock: case i_clrblock: case i_parmblock: ins->live = TRUE; break; case i_jne: case i_je: case i_jc: case i_ja: case i_jnc: case i_jbe: case i_jl: case i_jg: case i_jle: case i_jge: case i_coswitch: ins->live = TRUE; break; case i_phi: if (briggsTest(live, ins->dc.v.phi->T0)) { struct _phiblock *pb = ins->dc.v.phi->temps; ins->live = TRUE; while (pb) { briggsSet(live, pb->Tn); pb = pb->next; } } return; default: if (!(ins->temps & TEMP_ANS) || ins->ans->mode == i_ind) ins->live = TRUE; else if ((ins->temps & TEMP_ANS) && briggsTest(live, ins->ans->offset->v.sp->value.i)) ins->live = TRUE; break; } if (ins->live) { if (ins->temps & TEMP_ANS) { if (ins->ans->mode == i_direct) { briggsReset(live, ins->ans->offset->v.sp->value.i); } else if (ins->ans->mode == i_ind) { if (ins->ans->offset) briggsSet(live, ins->ans->offset->v.sp->value.i); if (ins->ans->offset2) briggsSet(live, ins->ans->offset2->v.sp->value.i); } } if (ins->temps & TEMP_LEFT) { if (ins->dc.left->mode == i_direct || ins->dc.left->mode == i_ind) { if (ins->dc.left->offset) briggsSet(live, ins->dc.left->offset->v.sp->value.i); if (ins->dc.left->offset2) briggsSet(live, ins->dc.left->offset2->v.sp->value.i); } } if (ins->temps & TEMP_RIGHT) { if (ins->dc.right->mode == i_direct || ins->dc.right->mode == i_ind) { if (ins->dc.right->offset) briggsSet(live, ins->dc.right->offset->v.sp->value.i); if (ins->dc.right->offset2) briggsSet(live, ins->dc.right->offset2->v.sp->value.i); } } } }
static void liveSetup(void) { BRIGGS_SET *exposed = briggsAllocs(tempCount); int i; for (i=0; i < blockCount; i++) { struct _block *blk = blockArray[i]; if (blk && blk->head) { QUAD *tail = blk->tail; int j; briggsClear(exposed); do { if (tail->dc.opcode == i_phi) { PHIDATA *pd = tail->dc.v.phi; struct _phiblock *pb = pd->temps; hasPhi = TRUE; briggsReset(exposed, pd->T0); clearbit(blk->liveGen, pd->T0); setbit(blk->liveKills, pd->T0); while (pb) { briggsSet(exposed, pb->Tn); setbit(blk->liveGen, pb->Tn); pb = pb->next; } } else { if (tail->temps & TEMP_ANS) { if (tail->ans->mode == i_direct) { int tnum = tail->ans->offset->v.sp->value.i; briggsReset(exposed, tnum); clearbit(blk->liveGen, tnum); setbit(blk->liveKills, tnum); } else if (tail->ans->mode == i_ind) { if (tail->ans->offset) { briggsSet(exposed, tail->ans->offset->v.sp->value.i); setbit(blk->liveGen, tail->ans->offset->v.sp->value.i); } if (tail->ans->offset2) { briggsSet(exposed, tail->ans->offset2->v.sp->value.i); setbit(blk->liveGen, tail->ans->offset2->v.sp->value.i); } } } if (tail->temps & TEMP_LEFT) if (tail->dc.left->mode == i_ind || tail->dc.left->mode == i_direct) { if (!tail->dc.left->retval) { if (tail->dc.left->offset) { briggsSet(exposed, tail->dc.left->offset->v.sp->value.i); setbit(blk->liveGen, tail->dc.left->offset->v.sp->value.i); } if (tail->dc.left->offset2) { briggsSet(exposed, tail->dc.left->offset2->v.sp->value.i); setbit(blk->liveGen, tail->dc.left->offset2->v.sp->value.i); } } } if (tail->temps & TEMP_RIGHT) if (tail->dc.right->mode == i_ind || tail->dc.right->mode == i_direct) { if (tail->dc.right->offset) { briggsSet(exposed, tail->dc.right->offset->v.sp->value.i); setbit(blk->liveGen, tail->dc.right->offset->v.sp->value.i); } if (tail->dc.right->offset2) { briggsSet(exposed, tail->dc.right->offset2->v.sp->value.i); setbit(blk->liveGen, tail->dc.right->offset2->v.sp->value.i); } } } if (tail != blk->head) /* in case tail == head */ tail = tail->back; /* skipping the actual block statement */ } while (tail != blk->head); briggsUnion(globalVars, exposed); } } for (i=0; i < globalVars->top; i++) { int t = globalVars->data[i], j; tempInfo[t]->liveAcrossBlock = TRUE; } }
void CalculateConflictGraph(BRIGGS_SET *nodes, BOOLEAN optimize) { int i, j; BRIGGS_SET *live = briggsAllocc(tempCount); resetConflict(); for (i=0 ; i < blockCount; i++) { if (blockArray[i]) { BITINT *p = blockArray[i]->liveOut; QUAD *tail = blockArray[i]->tail ; QUAD *head = blockArray[i]->head ; int j, k; briggsClear(live); for (j=0; j < (tempCount + BITINTBITS-1)/BITINTBITS; j++,p++) if (*p) for (k=0; k < BITINTBITS; k++) if (*p & (1 << k)) { if (!nodes || briggsTest(nodes, j * BITINTBITS + k)) briggsSet(live, j * BITINTBITS + k); } do { if (chosenAssembler->gen->internalConflict) chosenAssembler->gen->internalConflict(tail); if (tail->dc.opcode == i_phi) { PHIDATA *pd = tail->dc.v.phi; struct _phiblock *pb = pd->temps; if (!nodes || briggsTest(nodes, pd->T0)) { for (j=0; j < live->top; j++) { insertConflict(live->data[j], pd->T0); } } while (pb) { if (!nodes || briggsTest(nodes, pb->Tn)) { struct _phiblock *pb2 = pd->temps; while (pb2) { if (!nodes || briggsTest(nodes, pb2->Tn)) { if (briggsTest(live, pb->Tn) || briggsTest(live, pb2->Tn)) insertConflict(pb->Tn, pb2->Tn); } pb2 = pb2->next; } } pb = pb->next; } pb = pd->temps; while (pb) { if (!nodes || briggsTest(nodes, pb->Tn)) { briggsSet(live, pb->Tn); } pb = pb->next; } } else if (tail->dc.opcode == i_assnblock) { if (tail->dc.right->offset->type == en_tempref && tail->dc.left->offset->type == en_tempref) { insertConflict(tail->dc.right->offset->v.sp->value.i, tail->dc.left->offset->v.sp->value.i); } } else if (tail->temps & TEMP_ANS) { if (tail->ans->mode == i_direct) { int tnum = tail->ans->offset->v.sp->value.i; int k = -1; if (!nodes || briggsTest(nodes, tnum)) { if (optimize) { if (tail->dc.opcode == i_assn) { if ((tail->temps &(TEMP_LEFT | TEMP_ANS)) == (TEMP_LEFT | TEMP_ANS)) { if (tail->dc.left->mode == i_direct && tail->ans->mode == i_direct && !tail->ans->bits && !tail->dc.left->bits && !tail->dc.left->retval) { if (tail->dc.left->size == tail->ans->size) { if (!tail->ans->offset->v.sp->pushedtotemp && !tail->dc.left->offset->v.sp->pushedtotemp) { k = tail->dc.left->offset->v.sp->value.i; } } } } } } briggsReset(live, tnum); // processor dependent if (tail->ans->size == ISZ_ULONGLONG || tail->ans->size == -ISZ_ULONGLONG) { if (tail->dc.left->mode == i_ind) { if (tail->dc.left->offset) insertConflict(tnum, tail->dc.left->offset->v.sp->value.i); if (tail->dc.left->offset2) insertConflict(tnum, tail->dc.left->offset2->v.sp->value.i); } if (tail->dc.right && tail->dc.right->mode == i_ind) { if (tail->dc.right->offset) insertConflict(tnum, tail->dc.right->offset->v.sp->value.i); if (tail->dc.right->offset2) insertConflict(tnum, tail->dc.right->offset2->v.sp->value.i); } } for (j=0; j < live->top; j++) { if (live->data[j] != k) insertConflict(live->data[j], tnum); } } } else if (tail->ans->mode == i_ind) { if (tail->ans->offset) { int tnum = tail->ans->offset->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } if (tail->ans->offset2) { int tnum = tail->ans->offset2->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } } } if ((tail->temps & TEMP_LEFT) && !tail->dc.left->retval) { if (tail->dc.left->offset) { int tnum = tail->dc.left->offset->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } if (tail->dc.left->offset2) { int tnum = tail->dc.left->offset2->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } } if (tail->temps & TEMP_RIGHT) { if (tail->dc.right->offset) { int tnum = tail->dc.right->offset->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } if (tail->dc.right->offset2) { int tnum = tail->dc.right->offset2->v.sp->value.i; if (!nodes || briggsTest(nodes, tnum)) { briggsSet(live, tnum); } } } if (tail != head) tail = tail->back ; } while (tail != head); } } }