static void PostDominators(void) { int w, i; domCount = 0; WalkFlowgraph(blockArray[exitBlock], domNumber, FALSE); vectorData = tAlloc(sizeof(struct _tarjan *) * (domCount + 1)); for (i=0; i <= domCount; i++) { vectorData[i] = tAlloc(sizeof(struct _tarjan)); vectorData[i]->bucket = briggsAlloct(domCount+1); } WalkFlowgraph(blockArray[exitBlock], domInit, FALSE); for (w = domCount; w>=2; w--) { int p = vectorData[w]->parent; int j; struct _tarjan *v = vectorData[w]; BLOCKLIST *bl = v->preds; while (bl) { int u = domEval(bl->block->dfstOrder); if (vectorData[w]->semi > vectorData[u]->semi) vectorData[w]->semi = vectorData[u]->semi; bl = bl->next; } briggsSet(vectorData[vectorData[w]->semi]->bucket, w); domLink(p, w); for (j = vectorData[p]->bucket->top -1 ; j >= 0; j--) { int v = vectorData[p]->bucket->data[j]; int u = domEval(v); if (vectorData[u]->semi >= p) vectorData[v]->idom = p; else vectorData[v]->idom = u; } briggsClear(vectorData[p]->bucket); } for (w=2; w <=domCount; w++) { if (vectorData[w]->idom != vectorData[w]->semi) { vectorData[w]->idom = vectorData[vectorData[w]->idom]->idom; } /* transfer idom to our block struct */ blockArray[vectorData[w]->blocknum]->pdom = vectorData[vectorData[w]->idom]->blocknum; } tFree(); }
BRIGGS_SET *briggsReAlloc(BRIGGS_SET *set, int size) { if (!set || set->size < size) { BRIGGS_SET *set2 = briggsAlloc(size); #ifdef XXXXX if (set) { memcpy(set2->data, set->data, set->top * sizeof(*set->data)); memcpy(set2->indexes, set->indexes, set->size * sizeof(*set->indexes)); set2->top = set->top; } #endif set = set2; } else briggsClear(set); return set; }
static void Dominators(void) { int w, i; domCount = 0; WalkFlowgraph(blockArray[0], domNumber, TRUE); vectorData = tAlloc(sizeof(struct _tarjan *) * (domCount + 1)); for (i=0; i <= domCount; i++) { vectorData[i] = tAlloc(sizeof(struct _tarjan)); vectorData[i]->bucket = briggsAlloct(domCount+1); } WalkFlowgraph(blockArray[0], domInit, TRUE); for (w = domCount; w>=2; w--) { int p = vectorData[w]->parent; int j; struct _tarjan *v = vectorData[w]; BLOCKLIST *bl = v->preds; while (bl) { int u = domEval(bl->block->dfstOrder); if (vectorData[w]->semi > vectorData[u]->semi) vectorData[w]->semi = vectorData[u]->semi; bl = bl->next; } briggsSet(vectorData[vectorData[w]->semi]->bucket, w); domLink(p, w); for (j = vectorData[p]->bucket->top -1 ; j >= 0; j--) { int v = vectorData[p]->bucket->data[j]; int u = domEval(v); if (vectorData[u]->semi >= p) vectorData[v]->idom = p; else vectorData[v]->idom = u; } briggsClear(vectorData[p]->bucket); } for (w=2; w <=domCount; w++) { if (vectorData[w]->idom != vectorData[w]->semi) { vectorData[w]->idom = vectorData[vectorData[w]->idom]->idom; } /* transfer idom to our block struct */ blockArray[vectorData[w]->blocknum]->idom = vectorData[vectorData[w]->idom]->blocknum; } /* now make the forward tree */ for (i=blockCount-1; i >=1; i--) { /* make dominates lists by walking the idom tree backwards from each node*/ if (blockArray[i] && blockArray[i]->pred) { int w = blockArray[i]->idom; BLOCK *ub = blockArray[w]; BLOCKLIST *bl = oAlloc(sizeof(BLOCKLIST)); bl->block = blockArray[i]; bl->next = ub->dominates; ub->dominates = bl; } } tFree(); }
/* minor problem: if an induction variable spans multiple loops * an induction set will be created for each loop. These sets will * be identical */ static void CalculateInductionCandidates(LOOP *l) { LIST *blocks , *p; int i; briggsClear(candidates); inductionCandidateStackTop = 0; /* done here just in case for some reason an induction set drills down * into a lower loop */ for (i=0; i < tempCount; i++) tempInfo[i]->onstack = FALSE; for (i=0; i < l->blocks->top; i++) { BLOCK *b = blockArray[l->blocks->data[i]]; if (b) { QUAD *head = b->head; while (head != b->tail->fwd) { switch(head->dc.opcode) { case i_add: case i_sub: if ((head->temps & TEMP_ANS) && head->ans->mode == i_direct) { if (head->dc.left->mode == i_immed || (head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct)//FIXME && || if (head->dc.right->mode == i_immed || (head->temps & TEMP_RIGHT) && head->dc.right->mode == i_direct)//FIXME && || { if (head->ans->size < ISZ_FLOAT && head->dc.left->size < ISZ_FLOAT && head->dc.right->size < ISZ_FLOAT) { int tnum = head->ans->offset->v.sp->value.i; briggsSet(candidates, tnum); inductionCandidateStack[inductionCandidateStackTop++] = tnum; tempInfo[tnum]->onstack = TRUE; } } } break; case i_neg: case i_assn: if ((head->temps & TEMP_ANS) && head->ans->mode == i_direct) { if (head->dc.left->mode == i_immed || (head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct)//FIXME && || { if (head->ans->size < ISZ_FLOAT && head->dc.left->size < ISZ_FLOAT) { int tnum = head->ans->offset->v.sp->value.i; briggsSet(candidates, tnum); inductionCandidateStack[inductionCandidateStackTop++] = tnum; tempInfo[tnum]->onstack = TRUE; } } } break; case i_phi: { PHIDATA *pd = head->dc.v.phi; int tnum = pd->T0; if (tempInfo[tnum]->size < ISZ_FLOAT) { briggsSet(candidates, tnum); inductionCandidateStack[inductionCandidateStackTop++] = tnum; tempInfo[tnum]->onstack = TRUE; } } break; } /* prep for reshaping */ switch (head->dc.opcode) { case i_add: case i_sub: case i_mul: case i_lsl: if (head->ans->size < ISZ_FLOAT && head->dc.left->size < ISZ_FLOAT) { if (head->temps & TEMP_ANS) { int tnum = head->ans->offset->v.sp->value.i; INSTRUCTIONLIST *l = tempInfo[tnum]->instructionUses; while (l) { if ((l->ins->temps & TEMP_ANS) && l->ins->ans->mode == i_ind) { if (tnum == l->ins->ans->offset->v.sp->value.i) { tempInfo[tnum]->expressionRoot = TRUE; } } if (l->ins->temps & TEMP_LEFT) { if (tnum == l->ins->dc.left->offset->v.sp->value.i) { if (l->ins->dc.left->mode == i_ind) tempInfo[tnum]->expressionRoot = TRUE; else if (head->dc.opcode != i_not && head->dc.opcode != i_neg) if (!matchesop(head->dc.opcode, l->ins->dc.opcode)) tempInfo[tnum]->expressionRoot = TRUE; } } if (l->ins->temps & TEMP_RIGHT) { if (tnum == l->ins->dc.right->offset->v.sp->value.i) { if (l->ins->dc.right->mode == i_ind) tempInfo[tnum]->expressionRoot = TRUE; else if (head->dc.opcode != i_not && head->dc.opcode != i_neg) if (!matchesop(head->dc.opcode, l->ins->dc.opcode)) tempInfo[tnum]->expressionRoot = TRUE; } } l = l->next; } } } break; } head = head->fwd; } } } while (inductionCandidateStackTop) { int tnum = inductionCandidateStack[--inductionCandidateStackTop]; tempInfo[tnum]->onstack = FALSE; PruneInductionCandidate(tnum, l); if (!briggsTest(candidates, tnum)) { INSTRUCTIONLIST *li = tempInfo[tnum]->instructionUses; while (li) { if (briggsTest(l->blocks, li->ins->block->blocknum)) { if (li->ins->temps & TEMP_ANS) { int tnum = li->ins->ans->offset->v.sp->value.i; if (briggsTest(candidates, tnum)) { if (!tempInfo[tnum]->onstack) inductionCandidateStack[inductionCandidateStackTop++] = tnum; } } } li = li->next; } } } }
static void FindBody(BLOCKLIST *gen, BLOCK *head, enum e_lt type) { LIST *queue = NULL, **qx; LOOP *lp, **lpp ; int i; if (!gen) return; briggsClear(loopItems); while (gen) { LOOP *l = LoopAncestor(gen->block); if (l && !briggsTest(loopItems, l->loopnum)) { LIST *bl = oAlloc(sizeof(LIST)); bl->data = l; bl->next = queue; queue = bl; briggsSet(loopItems, l->loopnum); } gen = gen->next; } while (queue) { if (((LOOP *)queue->data)->entry) { BLOCKLIST *p = ((LOOP *)queue->data)->entry->pred; queue = queue->next; while (p) { if (p->block != head) { LOOP *l = LoopAncestor(p->block); if (l && !briggsTest(loopItems, l->loopnum)) { LIST *bl = oAlloc(sizeof(LIST)); bl->data = l; bl->next = queue; queue = bl; briggsSet(loopItems, l->loopnum); } } p = p->next; } } else queue = queue->next; } lp = oAlloc(sizeof(LOOP)); loopArray[loopCount] = lp; lp->type = type; lp->loopnum = loopCount++; lp->entry = head; lp->parent = NULL; head->loopParent = lp; qx = &lp->contains; *qx = oAlloc(sizeof(LIST)); (*qx)->data = head->loopName; qx = &(*qx)->next; for (i=0; i < loopItems->top; i++) { LIST *l = oAlloc(sizeof(LIST)); int n = loopItems->data[i]; l->data = loopArray[n]; *qx = l; qx = &(*qx)->next; if (loopArray[n]->type == LT_BLOCK) loopArray[n]->entry->loopParent = lp; else loopArray[n]->parent = lp; } }
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; } } } } }
void removeDead(BLOCK *b) { static BRIGGS_SET *live; BITINT *p; int j,k; QUAD *tail; BLOCKLIST *bl; BOOL done = FALSE; if (b == blockArray[0]) { int i; liveVariables(); live = briggsAlloc(tempCount); for (i=0; i < blockCount; i++) if (blockArray[i]) { QUAD *tail = blockArray[i]->head; while (tail != blockArray[i]->tail->fwd) { tail->live = tail->alwayslive; tail = tail->fwd; } blockArray[i]->visiteddfst = FALSE; } } b->visiteddfst = TRUE; briggsClear(live); p = b->liveOut; for (j=0; j < (tempCount + BITINTBITS-1)/BITINTBITS; j++,p++) if (*p) for (k=0; k < BITINTBITS; k++) if (*p & (1 << k)) { briggsSet(live, j*BITINTBITS + k); } tail = b->tail; while (tail != b->head->back) { markLiveInstruction(live, tail); tail = tail->back; } bl = b->succ; while (bl) { if (!bl->block->visiteddfst) removeDead(bl->block); bl = bl->next; } if (b == blockArray[0]) { QUAD *head = intermed_head; BOOL changed = FALSE; int i; for (i=0; i < blockCount; i++) { BLOCK *b1 = blockArray[i]; if (b1) { QUAD *head = b1->head; while (head != b1->tail->fwd) { if (!head->live) { if (head->dc.opcode != i_block && !head->ignoreMe && head->dc.opcode != i_label) { changed = TRUE; RemoveInstruction(head); if (head->dc.opcode == i_coswitch || head->dc.opcode >= i_jne && head->dc.opcode <= i_jge)//FIXME && || { BLOCKLIST *bl = head->block->succ->next; head->block->succ->next = NULL; while (bl) { if (bl->block->critical) UnlinkCritical(bl->block); bl = bl->next; } } } } head = head->fwd; } } } if (changed) { removeDead(b); } } }
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); } } }