static void CalculateLoopedBlocks(LOOP *l) { if (l->type != LT_BLOCK) { LIST *l1 = l->contains; while (l1) { CalculateLoopedBlocks((LOOP *)l1->data); l1= l1->next; } l1 = l->contains; l->blocks = briggsAlloc(blockCount); while (l1) { LOOP *lm = (LOOP *)l1->data; if (lm->type == LT_BLOCK) briggsSet(l->blocks, lm->entry->blocknum); else { int i; for (i=0; i < lm->blocks->top; i++) briggsSet(l->blocks, lm->blocks->data[i]); } l1 = l1->next; } } }
void reflowConditional(BLOCK *src, BLOCK *dst) { BLOCKLIST *bl, *bl1 = src->succ; BLOCKLIST temp; BRIGGS_SET *bls = briggsAlloc(blockCount); int i; temp.block = dst; temp.next = NULL; src->succ = &temp; for (i=0; i < blockCount; i++) if (blockArray[i]) blockArray[i]->temp = FALSE; removeMark(bls, blockArray[0]); for (i=1; i < blockCount; i++) if (blockArray[i] && blockArray[i]->alwayslive) removeMark(bls, blockArray[i]); src->succ = bl1; for (i=0; i < blockCount; i++) if (blockArray[i]) blockArray[i]->temp = FALSE; bl = bl1; while (bl) { if (bl->block != dst) removeDeadBlocks(bls, src, bl->block); bl = bl->next; } if (dst->critical) { BLOCK *crit = dst; BLOCKLIST *bl = crit->succ->block->pred; while (bl) { if (bl->block == crit) { bl->block = src; break; } bl = bl->next; } dst = crit->succ->block; crit->succ = crit->pred = NULL; blockArray[crit->blocknum] = NULL; } src->succ->block = dst; src->succ->next = NULL; }
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; }
void CalculateInduction(void) { int i; inductionCandidateStack = oAlloc(sizeof(unsigned short) * tempCount); candidates = briggsAlloc(tempCount); CalculateLoopInvariants(blockArray[0]); for (i=0; i < loopCount; i++) { LOOP *lp = loopArray[i]; if (lp && lp->type == LT_SINGLE) { LIST *strongTemps; LIST *anchors = NULL; CalculateInductionCandidates(lp); strongTemps = strongRegions(lp, &anchors); if (strongTemps && anchors) { LIST *regions = strongTemps; while (regions) { LIST *r = (LIST *)regions->data; if (r->next) { LIST *t = anchors; while (t) { while (r) { if (t->data == r->data) break; r = r->next; } if (!r || t->data == r->data) break; t = t->next; } if (t || r) { INDUCTION_LIST *temp = oAlloc(sizeof(INDUCTION_LIST)); LIST *q; temp->vars = regions->data; temp->next = lp->inductionSets; lp->inductionSets = temp; q = regions->data; while (q) { /* the dominator walk will visit inner loops first, * the outer loops have higher indexes * we want the outermost loop */ tempInfo[(int)q->data]->inductionLoop = max(i, tempInfo[(int)q->data]->inductionLoop); q = q->next; } } } regions = regions->next; } } } } }
void BuildLoopTree(void) { BLOCKLIST bl; BLOCK *b; int i; QUAD *tail; BOOL skip = FALSE; /* this is padded, but, in a really really complex program it could get to be too small */ loopArray = oAlloc(sizeof(LOOP *) * blockCount * 4); loopItems = briggsAlloc((blockCount) * 4); loopCount = 0; for (i=0; i < blockCount; i++) { if (blockArray[i]) { blockArray[i]->visiteddfst = FALSE; blockArray[i]->loopParent = NULL; blockArray[i]->loopName = oAlloc(sizeof(LOOP)); blockArray[i]->loopName->type = LT_BLOCK; blockArray[i]->loopName->entry = blockArray[i]; blockArray[i]->loopName->loopnum = loopCount; blockArray[i]->loopGenerators = NULL; loopArray[loopCount++] = blockArray[i]->loopName; } // else // loopCount++; } Loop(blockArray[0]); // CalculateSuccessors(loopArray[loopCount-1]); memset(&bl, 0, sizeof(bl)); bl.block = blockArray[exitBlock]; FindBody(&bl, blockArray[0], LT_ROOT); CalculateLoopedBlocks(loopArray[loopCount-1]); if (cparams.prm_icdfile) { fprintf(icdFile, "; loop dump\n"); dump_loops(); } tail = intermed_tail; b = tail->block; while (tail) { switch(tail->dc.opcode) { case i_skipcompare: skip = !skip; break; case i_block: b = tail->block; break; } if (tail->block) { if (skip) { tail->block->inclusiveLoopParent = b->loopParent; } else { tail->block->inclusiveLoopParent = tail->block->loopParent; } } tail = tail->back; } if (loopCount >= blockCount * 4) fatal("internal error"); }
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); } } }