Example #1
0
static  void            PreOptimize( void )
/*****************************************/
{
    bool        change;

    if( _IsntModel( NO_OPTIMIZATION ) ) {
//      CharsAndShortsToInts();
        MakeMovAddrConsts();
        PushPostOps();
        DeadTemps();
        InsDead();
        MakeFlowGraph();
        BlockTrim();
        CommonSex( _IsModel( LOOP_OPTIMIZATION ) );
        SetOnCondition();
        BlockTrim();
        AddANop();
        if( _IsModel( LOOP_OPTIMIZATION ) ) {
            change = FALSE;
            if( TransLoops( FALSE ) ) {
                change = TRUE;
            }
            if( LoopInvariant() ) {
                change = TRUE;
            }
            if( change ) {
                CommonSex(TRUE);
                InsDead();
                CommonInvariant();
            }
            if( IndVars() ) {
                CommonSex(FALSE);
                InsDead();
                change = TRUE;
            }
            BlockTrim();
            if( TransLoops( TRUE ) ) {
                BlockTrim();
                CommonSex( FALSE );
                change = TRUE;
            }
            if( change ) {
                ReConstFold();
            }
            LoopEnregister();
            if( change ) {
                BlockTrim();
            }
        }
        MulToShiftAdd();
        KillMovAddrConsts();
        FindReferences();
    } else {
        MakeFlowGraph();
        AddANop();
        FindReferences();
    }
}
Example #2
0
extern  void    CVDefSegs( void ){
/**************************/
    if( _IsModel( DBG_LOCALS ) ) {
        CVSyms = DbgSegDef( "$$SYMBOLS", "DEBSYM", SEG_COMB_PRIVATE+SEG_USE_32 );
    }
    if( _IsModel( DBG_TYPES ) ) {
        CVTypes = DbgSegDef( "$$TYPES", "DEBTYP", SEG_COMB_PRIVATE+SEG_USE_32 );
    }
}
Example #3
0
extern  void    CVDefSegs( void ){
/**************************/
    if( _IsModel( DBG_LOCALS ) ) {
        CVSyms = DbgSegDef( ".debug$S"  );
        CVSymMain = FindSection( CVSyms );
        owlCVSym = CVSymMain->owl_handle;
    }
    if( _IsModel( DBG_TYPES ) ) {
        CVTypes = DbgSegDef( ".debug$T" );
    }
}
Example #4
0
extern  void    DFDefSegs( void ){
/*************************************************/
    int         i;

    if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
        for( i = 0; i < DW_DEBUG_MAX; ++i ){
            DwarfSegs[i].seg = DbgSegDef( DwarfSegNames[i].seg_name );
            DwarfSegs[i].bck = NULL;
        }
    } else if( _IsModel( NUMBERS ) ) {
        DwarfSegs[DW_DEBUG_LINE].seg = DbgSegDef( DwarfSegNames[DW_DEBUG_LINE].seg_name );
        DwarfSegs[DW_DEBUG_LINE].bck = NULL;
    }
}
Example #5
0
extern void  CVDefSymComdat( owl_section_handle depof ){
/**********************************/
    if( _IsModel( DBG_LOCALS ) ) {
        CVSymMain->owl_handle = DbgSectDefComdat( ".debug$S" );
        OWLComdatDep( CVSymMain->owl_handle, depof );
    }
}
Example #6
0
static  bool  ZapsMemory( name *result, name *op, bool for_index ) {
/*********************************************************************
    Could redefining "result" redefine N_MEMORY name "op"?
*/

    switch( result->n.class ) {
    case N_TEMP:
        return( false );
    case N_MEMORY:
        if( result->v.symbol != op->v.symbol )
            return( false );
        /* can be used for memory ops as well */
        if( for_index )
            return( true );
        return( TempsOverlap( result, op ) );
    case N_INDEXED:
        if( result->i.base == NULL ) {
            if( _IsModel( FORTRAN_ALIASING ) )
                return( false );
            if( op->v.usage & USE_ADDRESS )
                return( true );
            return( _IsntModel( RELAX_ALIAS ) );
        }
        if( result->i.base->n.class == N_TEMP ) {
            return( _IsntModel( RELAX_ALIAS ) );
        } else { /* it must be N_MEMORY*/
            return( ZapsMemory( result->i.base, op, true ) );
        }
    case N_REGISTER:
        return( false );
    default:
        _Zoiks( ZOIKS_023 );
        return( false );
    }
Example #7
0
static  void    InitSegBck( void )
/********************************/
{
    segment_id  old_segid;

    if( _IsModel( DBG_LOCALS ) ) {
        old_segid = SetOP( CVSyms );
        DataLong( CV_OMF_SIG );
        SetOP( old_segid );
    }
    if( _IsModel( DBG_TYPES ) ) {
        old_segid = SetOP( CVTypes );
        DataLong( CV_OMF_SIG );
        SetOP( old_segid );
    }
}
Example #8
0
extern  void    DFObjFiniDbgInfo( offset codesize ) {
/******************************/
    segment_id      old;
    offset          here;
    back_handle     bck;

    if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
        bck = Comp_High;
        if( bck != NULL ){
            old = SetOP( AskCodeSeg() );
            OutLabel( bck->lbl );
            SetOP( old );
            BEFreeBack( bck );
            Comp_High = NULL;
        }
        DWEndCompileUnit( Client );
        DWFini( Client );
        old = SetOP( UnitSize->segment );
        here = AskLocation();
        SetLocation( UnitSize->offset );
        DataLong( codesize );
        SetLocation( here );
        SetOP( old );
        FiniSegBck();
    }
}
Example #9
0
static  bool    ChkMemLimit( pointer_int limit )
/**********************************************/
{
    if( _IsModel( MEMORY_LOW_FAILS ) ) return( FALSE );
    if( MemInUse() - FrlSize <= limit ) return( FALSE );
    FlushSomeOpt( MemInUse() - limit - FrlSize );
    if( MemInUse() - FrlSize <= limit ) return( FALSE );
    return( TRUE );
}
Example #10
0
static  void    InitVisitedTemps( void )
/***************************************
    Mark all N_TEMP and N_MEMORY names as Not visited. If NO_OPTIMIZATION
    is on, mark them all as visited.
*/
{
    name        *op;
    name        *alias;

    op = Names[ N_TEMP ];
    while( op != NULL ) {
        op->t.temp_flags &= ~VISITED;
        op = op->n.next_name;
    }
    op = Names[ N_TEMP ];
    while( op != NULL ) {
        if( op->v.usage & (USE_ADDRESS|VAR_VOLATILE) ) {
            alias = op;
            do {
                alias->t.temp_flags |= VISITED;
                alias = alias->t.alias;
            } while( alias != op );
        }
        op = op->n.next_name;
    }
    if( _IsModel( NO_OPTIMIZATION ) ) {
        op = Names[ N_TEMP ];
        while( op != NULL ) {
            if( _FrontEndTmp( op ) ) {
                op->t.temp_flags |= VISITED;
            }
            op = op->n.next_name;
        }
    }
    if( BlockByBlock || _IsModel ( NO_OPTIMIZATION ) ) {
        op = Names[ N_TEMP ];
        while( op != NULL ) {
            if( op->v.usage & USE_IN_ANOTHER_BLOCK ) {
                op->t.temp_flags |= VISITED;
            }
            op = op->n.next_name;
        }
    }
}
Example #11
0
extern  void    DFSymRange( cg_sym_handle sym, offset size ) {
    /*********************************************************/
    // I don't see what this is good for. The aranges for any
    // comdat symbols will be taken care of by DFSegRange().
    // Running this code may produce overlapping aranges that
    // confuse the hell out of the debugger. However, not running
    // this may cause debug information to be missing... call it
    // a FIXME

    if( !_IsModel( DBG_LOCALS | DBG_TYPES ) )return;
    ARange = FEBack( sym );
    DWAddress( Client, size );
}
Example #12
0
static  source_line_number      DumpLineNum( source_line_number n,
                                             source_line_number last,
                                             bool label_line ) {
/*************************************************************************/

    if( _IsModel( NUMBERS ) ) {
        if( n > 0 && n != last ) {
            last = n;
            CodeLineNum( n, label_line );
        }
    }
    return( last );
}
Example #13
0
extern  void    DFSegRange( void ) {
    /****************************/
    /* do arange for the current segment */
    back_handle bck;
    offset      off;
    offset      size;

    if( !_IsModel( DBG_LOCALS | DBG_TYPES ) )return;
    size = AskMaxSize();
    if( size > 0 ) {
        bck = MakeLabel();
        off = AskLocation();
        SetLocation( 0 );
        DataLabel( bck->lbl );
        SetLocation( off );
        ARange = bck;
        DWAddress( Client, size );
        BEFreeBack( bck );
    }
}
Example #14
0
static  void    BlockToCode( bool partly_done )
/*********************************************/
{
    block_num           inputs;
    block_num           targets;
    block_edge          *input_edges;
    conflict_node       *curr;
    conflict_node       **owner;
    conflict_node       *conflist;
    block_num           id;



    /* try to get back some memory*/
    _MemLow;

    /* make the block look like an entire procedure*/

    HeadBlock = CurrBlock;
    BlockList = CurrBlock;
    HeadBlock->prev_block = NULL;
    if( HeadBlock->next_block != NULL ) {
        HeadBlock->next_block->prev_block = NULL;
    }
    /* Kludge - need a pointer to the next block for CALL_LABEL - puke! */
    if( HeadBlock->class & CALL_LABEL ) {
        HeadBlock->v.next = HeadBlock->next_block;
    }
    HeadBlock->next_block = NULL;

    /* force anything that spans blocks to memory */

    HeadBlock->u.partition = HeadBlock;
    ConstFold( HeadBlock );
    HeadBlock->u.partition = NULL;

    ForceTempsMemory();
    if( partly_done == FALSE ) {
        FixMemRefs();
        HaveLiveInfo = FALSE;
        if( _IsntModel( NO_OPTIMIZATION | FORTRAN_ALIASING ) ) {
            FindReferences();
            CommonSex(FALSE);
            PushPostOps();
        }
        FindReferences();
        DeadTemps();
        if( _IsModel( NO_OPTIMIZATION ) ) {
            SetInOut( HeadBlock );
        } else {
            MakeConflicts();
        }
        MakeLiveInfo();
        HaveLiveInfo = TRUE;
        AxeDeadCode();
        FixIndex();
        FixSegments();
        FPRegAlloc();
        RegAlloc( TRUE );
        FreeConflicts();
        HaveLiveInfo = FALSE;
    } else {
        conflist = NULL;
        owner = &ConfList;
        for( ;; ) {
            curr = *owner;
            if( curr == NULL ) break;
            if( curr->start_block == HeadBlock ) {
                *owner = curr->next_conflict;
                curr->next_conflict = conflist;
                conflist = curr;
            } else {
                owner = &curr->next_conflict;
            }
        }
        curr = ConfList;
        ConfList = conflist;
        RegAlloc( TRUE );
        FreeConflicts();
        ConfList = curr;
    }
    input_edges = HeadBlock->input_edges;
    inputs = HeadBlock->inputs;
    targets = HeadBlock->targets;
    HeadBlock->inputs = 0;
    HeadBlock->input_edges = NULL;
    HeadBlock->targets = 0;
    FPParms();
    PostOptimize();
    HeadBlock->input_edges = input_edges;
    HeadBlock->inputs = inputs;
    HeadBlock->targets = targets;

    /* generate a prolog that saves all registers*/

    if( ( CurrProc->prolog_state & GENERATED_PROLOG ) == 0 ) {
        CurrProc->state.used = AllCacheRegs();
        GenProlog();
    }

    id = CurrBlock->id;
    AssgnMoreTemps( id );
    OptSegs();

    /* generate the code for the block*/

    if( CurrBlock->class & RETURN ) {
        GenObject();
        FiniStackMap();
        FreeProc();
    } else {
Example #15
0
static  bool    ScoreStomp( score_info *x, score_info *y ) {
/**********************************************************/

    score_info  *tmp;

    /* get the 'free' index into x if there is one*/
    if( y->class == N_INDEXED && y->base == NULL ) {
        tmp = x;
        x = y;
        y = tmp;
    }
    if( x->class == N_INDEXED && x->base == NULL ) {
        switch( y->class ) {
        case N_MEMORY:
            if( _IsModel( RELAX_ALIAS ) )
            return( FALSE );
            /* fall through */
        case N_INDEXED:
            return( TRUE );
        case N_TEMP:
            if( y->symbol.v->usage & USE_ADDRESS )
            return( TRUE );
            return( FALSE );
        }
    }
    /* get the 'bound' index into x if there is one*/
    if( y->class == N_INDEXED ) {
        tmp = x;
        x = y;
        y = tmp;
    }
    if( x->class == N_INDEXED && x->base != NULL ) {
        switch( y->class ) {
        case N_TEMP:
            if( x->base->n.class == N_TEMP ) {
                if( y->symbol.t->v.id == x->base->t.v.id )
            return( TRUE );
            }
            break;
        case N_MEMORY:
            if( x->base->n.class == N_MEMORY ) {
                if( y->symbol.p == x->base->v.symbol )
            return( TRUE );
            }
            break;
        case N_INDEXED:
            if( y->base == NULL )
            return( TRUE );
            if( y->base->n.class != x->base->n.class )
            return( FALSE );
            switch( x->base->n.class ) {
            case N_TEMP:
                return( y->base->t.v.id == x->base->t.v.id );
            case N_MEMORY:
                return( y->base->v.symbol == x->base->v.symbol );
            }
            break;
        }
    }
    return( FALSE );
}
Example #16
0
static  void            PostOptimize( void )
/******************************************/
{
    if( _IsntModel( NO_OPTIMIZATION ) ) {
        // Run peephole optimizer again. Important: It is critical that the
        // new instructions can be directly generated because RegAlloc is
        // done by now. PeepOpt() is responsible for verifying that.
        if( PeepOpt( HeadBlock, NextBlock, NULL, TRUE ) ) {
            LiveInfoUpdate();
        }
        // this is important as BuildIndex cannot handle instructions with no operands
        DeadInstructions();
        BuildIndex();
        DeadInstructions();
    }
    MergeIndex();
    if( _IsntModel( NO_OPTIMIZATION ) ) {
    #if !(_TARGET & _TARG_RISC)
        //
        // Calling Conditions() at this point has nice optimization effect,
        // but doesn't working correctly right now. It optimizes conditions
        // making them dependent from previous conditions codes, but riscifier
        // generates XOR's which will trash cond. codes. Either Conditions()
        // either riscifier must be fixed to handle this situation.
        //
    #if 0
        // Get rid of unused conditions on variables level
        // to decrease number of referenced vars in LdStAlloc() and Score()
        if( _IsntTargetModel( STATEMENT_COUNTING ) ) {
            Conditions();
            DeadInstructions(); // cleanup junk after Conditions()
        }
    #endif
    #endif
        // OptCloseMoves();  // todo: merge constant moves before riscifier
        LdStAlloc();
        Score();
        DeadInstructions(); // cleanup junk after Score()
        // deRISCify before LoopRegInvariant() or Shedule() are run:
        // they're moving RISCified pair.
        LdStCompress();
        // Reuse registers freed by deriscifier
        Score();
        DeadInstructions(); // cleanup junk after Score()
        if( !BlockByBlock ) LoopRegInvariant();
    #if !(_TARGET & _TARG_RISC)
        // Get rid of remaining unused conditions on register level.
        if( _IsntTargetModel( STATEMENT_COUNTING ) ) {
            Conditions();
        }
    #endif
    }
    FPExpand();
    if( _IsntModel( NO_OPTIMIZATION ) ) {
        DeadInstructions();   // cleanup junk after Conditions()
        // Run scheduler last, when all instructions are stable
        if( _IsModel( INS_SCHEDULING ) ) {
            HaveLiveInfo = FALSE;
            Schedule(); /* NOTE: Schedule messes up live information */
            LiveInfoUpdate();
            HaveLiveInfo = TRUE;
        }
        // run this again in case Scheduler messed around with indices
        if( PeepOpt( HeadBlock, NextBlock, NULL, TRUE ) ) {
            LiveInfoUpdate();
        }
    }
    FPOptimize();
}
Example #17
0
void    CVObjInitDbgInfo( void )
/******************************/
/* called by objinit to init segments and for codeview */
{
    cv_out      out[1];
    cs_objname  *optr;
    cs_compile  *cptr;
    char        *name;

    InitSegBck();
    if( _IsModel( DBG_LOCALS ) ) {
        NewBuff( out, CVSyms );
        optr = StartSym(  out, SG_OBJNAME );
        optr->signature = 0;
        name =  FEAuxInfo( NULL, OBJECT_FILE_NAME );
        CVPutStr( out, name );
        EndSym( out );
        buffEnd( out );
        NewBuff( out, CVSyms );
        cptr = StartSym(  out, SG_COMPILE );
        cptr->language  = SetLang();
        cptr->flags.s = 0; /* set default */
    #if _TARGET & _TARG_IAPX86
        cptr->flags.f.Mode32 = false;
        cptr->machine = MACH_INTEL_8080;
    #elif _TARGET & _TARG_80386
        cptr->machine = MACH_INTEL_80386;
        cptr->flags.f.Mode32 = true;
    #elif _TARGET & _TARG_AXP
        cptr->machine = MACH_DECALPHA;
        cptr->flags.f.Mode32 = true;
        cptr->flags.f.FloatPrecision = 1;
    #endif
        switch( GetMemModel() ){
            case 'h':
                cptr->flags.f.AmbientData = AMBIENT_HUGE;
                cptr->flags.f.AmbientCode = AMBIENT_FAR;
                break;
            case 'l':
                cptr->flags.f.AmbientData = AMBIENT_FAR;
                cptr->flags.f.AmbientCode = AMBIENT_FAR;
                break;
            case 'f':
            case 's':
                cptr->flags.f.AmbientData = AMBIENT_NEAR;
                cptr->flags.f.AmbientCode = AMBIENT_NEAR;
                break;
            case 'c':
                cptr->flags.f.AmbientData = AMBIENT_FAR;
                cptr->flags.f.AmbientCode = AMBIENT_NEAR;
                break;
            case 'm':
                cptr->flags.f.AmbientData = AMBIENT_NEAR;
                cptr->flags.f.AmbientCode = AMBIENT_FAR;
                break;
            default:
                break;
        }
        CVPutStr( out, "WATCOM CV 10.5   " );
        EndSym( out );
        buffEnd( out );
    }
}
Example #18
0
extern void  CVDefSymNormal( void ){
/**********************************/
    if( _IsModel( DBG_LOCALS ) ) {
        CVSymMain->owl_handle = owlCVSym;
    }
}
Example #19
0
extern  void    DFBegCCU( segment_id code, dw_sym_handle dbg_pch )
/****************************************************************/
// Call when codeseg hase been defined
{
    dw_cu_info      cu;
    back_handle     bck;
    segment_id      old;
    type_def        *tipe_addr;

    if( !_IsModel( DBG_LOCALS | DBG_TYPES ) ) {
        return;
    }
    if( CcuDef ) {
        cu.source_filename = FEAuxInfo( NULL, SOURCE_NAME );
        cu.directory = "";
        cu.dbg_pch = dbg_pch;
        cu.inc_list = NULL;
        cu.inc_list_len = 0;
        old = SetOP( code );
#if _TARGET & ( _TARG_IAPX86 | _TARG_80386 )
        if( _IsTargetModel( FLAT_MODEL ) ) {
            bck = MakeLabel();
            OutLabel( bck->lbl );
            Pc_Low = bck;
            Pc_High = MakeLabel();
            // Emitting DW_AT_low_pc and DW_AT_high_pc is valid *only* if the
            // compilation unit's code is in a single contiguous block (see
            // DWARF 2, section 3.1).
            // I don't know how to find out at the time of this call if there's
            // only one code segment or not, hence these attributes are always
            // disabled. The low/high pc attribs should probably be handled by
            // the linker.
            cu.flags = FALSE;
            cu.segment_size = 0;
        } else {
            bck = NULL;
            cu.flags = FALSE;
            Pc_Low = NULL;
            Pc_High = NULL;
            cu.segment_size = 2;
        }
#else
        bck = MakeLabel();
        OutLabel( bck->lbl );
        Pc_Low = bck;
        Pc_High = MakeLabel();
        cu.flags = TRUE;
        cu.segment_size = 0;
#endif
        SetOP( old );
        Comp_High = Pc_High;
        tipe_addr = TypeAddress( TY_NEAR_POINTER );
        cu.offset_size = tipe_addr->length;
        switch( GetMemModel() ) {
        case 'h':
            cu.model = DW_MODEL_HUGE;
            break;
        case 'l':
            cu.model = DW_MODEL_LARGE;
            break;
        case 'f':
            cu.model = DW_MODEL_FLAT;
            break;
        case 's':
            cu.model = DW_MODEL_SMALL;
            break;
        default:
            cu.model = DW_MODEL_NONE;
            break;
        }
        DWBeginCompileUnit( Client, &cu );
        if( cu.flags ) {
            BEFreeBack( bck );
        }
    } else {
        CcuDef = TRUE;
    }
}
Example #20
0
extern  void    DFObjInitDbgInfo( void ) {
/*****************************************************/
/* called by objinit to init segments and dwarf writing library */
    static const dw_funcs cli_funcs = {
        CLIReloc,
        CLIWrite,
        CLISeek,
        CLITell,
        CLIAlloc,
        CLIFree
    };
    dw_init_info    info;
    cg_sym_handle   abbrev_sym;
    cg_sym_handle   debug_pch;
    fe_attr         attr;

    if( _IsntModel( DBG_LOCALS | DBG_TYPES ) ){
        return;
    }
    info.compiler_options = DW_CM_DEBUGGER;
    info.abbrev_sym = 0;
    info.producer_name = SetDwarfProducer();
    info.language = SetLang();
    if( setjmp( info.exception_handler ) == 0 ) {
        info.funcs = cli_funcs;
        InitSegBck(); // start each seg with a ref label
        if( _IsModel( DBG_PREDEF ) ) {
            abbrev_sym = FEAuxInfo( NULL, DBG_PREDEF_SYM );
            info.abbrev_sym = (dw_sym_handle)abbrev_sym;
            attr = FEAttr( abbrev_sym );
            if( (attr & FE_IMPORT) ) {
                info.compiler_options |= DW_CM_ABBREV_PRE;
            }else{
                back_handle bck;
                segment_id  old;

                info.compiler_options |= DW_CM_ABBREV_GEN;
                bck = FEBack( abbrev_sym ); // dump out export label
                bck->seg = DwarfSegs[DW_DEBUG_ABBREV].seg;
                old = SetOP( DwarfSegs[DW_DEBUG_ABBREV].seg );
                DataLabel( bck->lbl );
                SetOP( old );
            }
        }
        debug_pch = FEAuxInfo( NULL, DBG_PCH_SYM );
        if( debug_pch != NULL ){
            attr = FEAttr( debug_pch );
            if( !(attr & FE_IMPORT) ) {
                back_handle bck;
                segment_id  old;

                bck = FEBack( debug_pch );
                bck->seg = DwarfSegs[DW_DEBUG_INFO].seg;
                old = SetOP( DwarfSegs[DW_DEBUG_INFO].seg );
                DataLabel( bck->lbl );
                SetOP( old );
                debug_pch = NULL;
            }
        }
        Client = DWInit( &info );
        if( Client == NULL ) {
            Zoiks( ZOIKS_107 ); /* Bad */
        }
        DFBegCCU( AskCodeSeg(), (dw_sym_handle)debug_pch );
    } else {
        Zoiks( ZOIKS_107 ); /* Big Error */
    }
}