Exemple #1
0
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;
        }
    }
}
Exemple #2
0
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;
}
Exemple #3
0
/* finds all the successors to the loop */
static void CalculateSuccessors(LOOP *lp)
{
    LIST *contains;
    contains = lp->contains;
    while(contains)
    {
        LOOP *current = (LOOP *)contains->data;
        if (lp->type != LT_BLOCK)
            CalculateSuccessors(current);
        contains = contains->next;
    }
    contains = lp->contains;
    while (contains)
    {
        LOOP *inner = (LOOP *)contains->data;
        if (inner->type == LT_BLOCK)
        {
            BLOCKLIST *bl = inner->entry->succ;
            while (bl)
            {
                BLOCKLIST *newExit = oAlloc(sizeof(BLOCKLIST));
                newExit->next = lp->successors;
                lp->successors = newExit;
                newExit->block = bl->block;
                bl = bl->next;
            }
        }
        else
        {
            /* only have to add blocks that exited an inner loop
             * and only if they also exit this loop
             */
            BLOCKLIST *prevSuccessors = inner->successors;
            while (prevSuccessors)
            {
                if (!briggsTest(inner->blocks, prevSuccessors->block->blocknum))
                {
                    BLOCKLIST *newExit = oAlloc(sizeof(BLOCKLIST));
                    newExit->next = lp->successors;
                    lp->successors = newExit;
                    newExit->block = prevSuccessors->block;
                }
                prevSuccessors = prevSuccessors->next;
            }
        }
        contains = contains->next;
    }
}
Exemple #4
0
/* this returns a two-layer list
 * the top layer is a linked list of strong regions
 * each secondary layer is the induction set for the region
 * first element of list is the anchors
 */
static LIST *strongRegions(LOOP *lp, LIST **anchors)
{
    int i;
    QUAD *head;
    LIST *rv = NULL;
    *anchors = NULL;
    strongStack = oAlloc(sizeof(unsigned short) *tempCount);
    max_dfs = 0;
    strongStackTop = 0;
    for (i=0; i < tempCount; i++)
    {
        tempInfo[i]->dfstOrder = 0;
        tempInfo[i]->visiteddfst = FALSE;
        tempInfo[i]->temp = INT_MAX;
    }
    head = lp->entry->head->fwd;
    while (head != lp->entry->tail->fwd && 
           (head->ignoreMe || head->dc.opcode == i_label))
        head = head->fwd;
    while (head != lp->entry->tail->fwd && head->dc.opcode == i_phi)
    {
        PHIDATA *pd = head->dc.v.phi;
        if (briggsTest(candidates, pd->T0) && tempInfo[pd->T0]->size < ISZ_FLOAT)
        {
            LIST *l1 = strongRegiondfs(pd->T0);
            if (l1)
            {
                l1->next = rv;
                rv = l1;
            }
            l1 = oAlloc(sizeof(LIST));
            l1->data = (void *)pd->T0;
            l1->next = *anchors;
            *anchors = l1;
        }
        head = head->fwd;
    }
    return rv;
}
Exemple #5
0
static void removeDeadBlocks(BRIGGS_SET *brs, BLOCK *back, BLOCK *b)
{
    if (b->temp)
        return;
    b->temp = TRUE;
    if (!briggsTest(brs, b->blocknum) && b->blocknum != exitBlock)
    {
        BLOCKLIST *bl2 = b->succ;
        while (bl2)
        {
            removeDeadBlocks(brs, b, bl2->block);
            if (!bl2->block->dead)
            {
                BLOCKLIST **bl3 = &bl2->block->pred;
                int n = 0;
                while (*bl3)
                {
                    if ((*bl3)->block == b)
                    {
                        QUAD *head = bl2->block->head->fwd;
                        *bl3 = (*bl3)->next;
                        while (head != bl2->block->tail->fwd && (head->dc.opcode == i_label ||
                               head->ignoreMe))
                        {
                            head = head->fwd;
                        }
                        while (head->dc.opcode == i_phi && head != bl2->block->tail->fwd)
                        {
                            PHIDATA *pd = head->dc.v.phi;
                            struct _phiblock **pb = &pd->temps;
                            int i;
                            for (i=0; i < n; i++, pb = &(*pb)->next) ;
                            (*pb) = (*pb)->next;			
                            head = head->fwd;
                        }
                        break;
                    }
                    n++;
                    bl3 = &(*bl3)->next;
                }
            }
            bl2 = bl2->next;
        }
        b->head->fwd = b->tail->fwd;
        b->tail->fwd->back = b->head;
        b->tail = b->head;
        b->succ = b->pred = NULL;
        b->dead = TRUE;
        b->critical = FALSE;
        blockArray[b->blocknum] = NULL;
    }
    else
    {
        QUAD *head ;
        int n = 0;
        BLOCKLIST **bl = &b->pred;
        while (bl)
        {
            if ((*bl)->block == back)
            {
                *bl = (*bl)->next;
                break;
            }
            n++;
            bl = &(*bl)->next;
        }
        
        head = b->head->fwd;
        while (head != b->tail->fwd && (head->dc.opcode == i_label || 
               head->ignoreMe))
        {
            head = head->fwd;
        }
        while (head->dc.opcode == i_phi && head != b->tail->fwd)
        {
            PHIDATA *pd = head->dc.v.phi;
            struct _phiblock **pb = &pd->temps;
            int i;
            for (i=0; i < n; i++, pb = &(*pb)->next) ;
            (*pb) = (*pb)->next;			
            head = head->fwd;
        }
    }
}
Exemple #6
0
/* 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;
            }
        }
    }
}
Exemple #7
0
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;
    }	
}
Exemple #8
0
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);
            }
        }
    }
}
Exemple #9
0
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);
        }
    }
}