static bool JustMoveLabel( common_info *max, ins_entry *ins ) /***************************************************************/ { oc_class cl; ins_entry *lbl; ins_entry *add; ins_entry *next; optbegin if( PrevClass( max->start_del ) != OC_LABEL ) optreturn( FALSE ); lbl = PrevIns( max->start_del ); if( _Attr( lbl ) & ATTR_SHORT ) optreturn( FALSE ); cl = PrevClass( lbl ); if( !_TransferClass( cl ) ) optreturn( FALSE ); DeleteQueue( lbl ); InsertQueue( lbl, PrevIns( max->start_com ) ); add = PrevIns( max->start_del ); for( ;; ) { next = NextIns( add ); DelInstr( next ); if( next == ins ) { break; } } Untangle( lbl ); optreturn( TRUE ); }
extern ins_entry *IsolatedCode( ins_entry *instr ) /*******************************************************/ { ins_entry *next; optbegin next = NextIns( instr ); for( ;; ) { if( next == NULL ) optreturn( next ); if( _Class( next ) == OC_LABEL ) break; _Savings( OPT_ISOLATED, _ObjLen( next ) ); if( _Class( next ) == OC_INFO ) { next = next->ins.next; } else { next = DelInstr( next ); } if( _Class( instr ) == OC_DEAD ) { break; } } next = Untangle( next ); optreturn( next ); }
static void TransformJumps( ins_entry *ins, ins_entry *first ) /****************************************************************/ { ins_entry *add; ins_entry *next; ins_entry *lbl; oc_class cl; optbegin if( _Class( ins ) == OC_RET ) optreturnvoid; lbl = _Label( ins )->ins; if( lbl == NULL ) optreturnvoid; add = lbl; for( ;; ) { if( add == NULL ) optreturnvoid; cl = _Class( add ); if( _TransferClass( cl ) ) break; if( cl == OC_LABEL ) { if( _Attr( add ) & ATTR_SHORT ) optreturnvoid; _ClrStatus( _Label( add ), SHORTREACH ); } add = NextIns( add ); } if( add == first || add == ins ) optreturnvoid; if( FindShort( first, lbl ) ) optreturnvoid; for( ;; ) { next = PrevIns( add ); DeleteQueue( add ); InsertQueue( add, first ); if( add == lbl ) break; add = next; } DeleteQueue( first ); InsertQueue( first, next ); Untangle( NextIns( first ) ); optend }
extern bool StraightenCode( ins_entry *jump ) /***********************************************/ { ins_entry *next; ins_entry *insert; ins_entry *hoist; ins_entry *end_hoist; oc_class cl; obj_length align; optbegin hoist = _Label( jump )->ins; if( hoist == NULL ) optreturn( false ); if( hoist == LastIns ) optreturn( false ); cl = PrevClass( hoist ); if( !_TransferClass( cl ) ) optreturn( false ); end_hoist = NULL; for( next = hoist; ; next = NextIns( next ) ) { if( next == jump ) { // pushing code down to jump if( end_hoist == NULL ) optreturn( false ); if( FindShort( hoist, end_hoist ) ) optreturn( false ); break; } if( next == NULL ) { // hauling code up to jump if( FindShort( jump, hoist ) ) optreturn( false ); break; } cl = _Class( next ); if( end_hoist == NULL && _TransferClass( cl ) ) { end_hoist = next; } } align = _ObjLen( hoist ); insert = jump; for( ;; ) { if( hoist == NULL ) { ChgLblRef( jump, AddNewLabel( LastIns, align ) ); next = LastIns; break; } next = NextIns( hoist ); DeleteQueue( hoist ); InsertQueue( hoist, insert ); if( hoist == jump ) optreturn( false ); insert = hoist; cl = _Class( hoist ); if( _TransferClass( cl ) ) { IsolatedCode( insert ); break; } hoist = next; } InsDelete = true; Untangle( next ); if( _Class( jump ) != OC_DEAD ) { Untangle( _Label( jump )->ins ); } optreturn( true ); }