Пример #1
0
/*****************************************************************************
 *                          siUpdate
 *
 * Called at the start of basic blocks, and during code-gen of a block,
 * for non-debuggable code, whenever the life of any tracked variable changes
 * and the appropriate code has been generated. For debuggable code, variables are
 * live over their entire scope, and so they go live or dead only on
 * block boundaries.
 */
void        CodeGen::siUpdate ()
{ 
    if (!compiler->opts.compScopeInfo)
        return;

    if (compiler->opts.compDbgCode)
        return;

    if (compiler->info.compVarScopesCount == 0)
        return;

 #if FEATURE_EH_FUNCLETS
    if (siInFuncletRegion)
        return;
#endif // FEATURE_EH_FUNCLETS

    VARSET_TP VARSET_INIT_NOCOPY(killed, VarSetOps::Diff(compiler, siLastLife, compiler->compCurLife));
    assert(VarSetOps::IsSubset(compiler, killed, compiler->lvaTrackedVars));

    VARSET_ITER_INIT(compiler, iter, killed, i);
    while (iter.NextElem(compiler, &i))
    {
#ifdef DEBUG
        unsigned        lclNum = compiler->lvaTrackedToVarNum[i];
        LclVarDsc *     lclVar = &compiler->lvaTable[lclNum];        
        assert(lclVar->lvTracked);
#endif

        siScope * scope = siLatestTrackedScopes[i];
        siEndTrackedScope(i);
    }

    VarSetOps::Assign(compiler, siLastLife, compiler->compCurLife);
}
Пример #2
0
CodeGen::siScope *          CodeGen::siNewScope( unsigned       LVnum,
                                                 unsigned       varNum)
{
    bool        tracked      = compiler->lvaTable[varNum].lvTracked;
    unsigned    varIndex     = compiler->lvaTable[varNum].lvVarIndex;

    if (tracked)
    {
        siEndTrackedScope(varIndex);
    }


    siScope * newScope       = (siScope*) compiler->compGetMem(sizeof(*newScope), CMK_SiScope);

    newScope->scStartLoc.CaptureLocation(getEmitter());
    assert(newScope->scStartLoc.Valid());

    newScope->scEndLoc.Init();

    newScope->scLVnum        = LVnum;
    newScope->scVarNum       = varNum;
    newScope->scNext         = NULL;
    newScope->scStackLevel   = genStackLevel;       // used only by stack vars

    siOpenScopeLast->scNext  = newScope;
    newScope->scPrev         = siOpenScopeLast;
    siOpenScopeLast          = newScope;

    if (tracked)
    {
        siLatestTrackedScopes[varIndex] = newScope;
    }

    return newScope;
}
Пример #3
0
void        CodeGen::siEndBlock(BasicBlock* block)
{
    assert(compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0));

#if FEATURE_EH_FUNCLETS
    if (siInFuncletRegion)
        return;
#endif // FEATURE_EH_FUNCLETS

#ifdef DEBUG
    if (verbose)
    {
        printf("\nScope info: end block BB%02u, IL range ", block->bbNum);
        block->dspBlockILRange();
        printf("\n");
    }
#endif // DEBUG

    unsigned endOffs = block->bbCodeOffsEnd;

    if (endOffs == BAD_IL_OFFSET)
    {
        JITDUMP("Scope info: ignoring block end\n");
        return;
    }

    // If non-debuggable code, find all scopes which end over this block
    // and close them. For debuggable code, scopes will only end on block
    // boundaries.

    VarScopeDsc* varScope;
    while ((varScope = compiler->compGetNextExitScope(endOffs, !compiler->opts.compDbgCode)) != NULL)
    {
        // brace-matching editor workaround for following line: (
        JITDUMP("Scope info: ending scope, LVnum=%u [%03X..%03X)\n", varScope->vsdLVnum, varScope->vsdLifeBeg, varScope->vsdLifeEnd);

        unsigned    varNum     = varScope->vsdVarNum;
        LclVarDsc * lclVarDsc1 = &compiler->lvaTable[varNum];

        assert(lclVarDsc1);

        if (lclVarDsc1->lvTracked)
        {
            siEndTrackedScope(lclVarDsc1->lvVarIndex);
        }
        else
        {
            siEndScope(varNum);
        }
    }

    siLastEndOffs = endOffs;

#ifdef DEBUG
    if (verbose)
        siDispOpenScopes();
#endif

}
Пример #4
0
/*****************************************************************************
 *                          siUpdate
 *
 * Called at the start of basic blocks, and during code-gen of a block,
 * for non-debuggable code, whenever the life of any tracked variable changes
 * and the appropriate code has been generated. For debuggable code, variables are
 * live over their entire scope, and so they go live or dead only on
 * block boundaries.
 */
void CodeGen::siUpdate()
{
    if (!compiler->opts.compScopeInfo)
    {
        return;
    }

    if (compiler->opts.compDbgCode)
    {
        return;
    }

    if (compiler->info.compVarScopesCount == 0)
    {
        return;
    }

#if FEATURE_EH_FUNCLETS
    if (siInFuncletRegion)
    {
        return;
    }
#endif // FEATURE_EH_FUNCLETS

    VARSET_TP killed(VarSetOps::Diff(compiler, siLastLife, compiler->compCurLife));
    assert(VarSetOps::IsSubset(compiler, killed, compiler->lvaTrackedVars));

    VarSetOps::Iter iter(compiler, killed);
    unsigned        varIndex = 0;
    while (iter.NextElem(&varIndex))
    {
#ifdef DEBUG
        unsigned   lclNum = compiler->lvaTrackedToVarNum[varIndex];
        LclVarDsc* lclVar = &compiler->lvaTable[lclNum];
        assert(lclVar->lvTracked);
#endif

        siScope* scope = siLatestTrackedScopes[varIndex];
        siEndTrackedScope(varIndex);
    }

    VarSetOps::Assign(compiler, siLastLife, compiler->compCurLife);
}