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 ); }
extern void CloneCode( label_handle lbl ) /***************************************** consider: JMP L1 .... L1: POP AX RET we want to clone the code at L1 at the point of the jump, since it will be faster (and smaller since POP AX/RET is only 2 bytes while the JMP might be 3/5). */ { ins_entry *next; ins_entry *lbl_ins; ins_entry *hoist; ins_entry *jmp; unsigned size; unsigned max_size; lbl_ins = lbl->ins; if( lbl_ins == NULL ) return; size = 0; hoist = NextIns( lbl_ins ); for( next = hoist; ; next = NextIns( next ) ) { if( next == NULL ) return; if( _Class( next ) == OC_CODE && CodeHasAbsPatch( &next->oc.oc_entry ) ) return; if( _Class( next ) != OC_LABEL ) { size += _ObjLen( next ); if( size > MAX_CLONE_SIZE ) return; if( _TransferClass( _Class( next ) ) ) { break; } } } if( _Class( next ) == OC_JMP && _Label( next ) == lbl ) return; for( jmp = lbl->refs; jmp != NULL; jmp = _LblRef( jmp ) ) { if( next == jmp ) continue; if( !_TransferClass( _Class( jmp ) ) ) continue; max_size = _ObjLen( jmp ); if( size > max_size && FindShort( jmp, NULL ) ) continue; if( OptForSize < 50 ) { max_size *= (100-OptForSize) / 25; } if( size > max_size ) continue; DoCloneCode( jmp, hoist ); DelInstr( jmp ); } }
extern void CallRet( ins_entry *instr ) /*****************************************/ { ins_entry *lbl; optbegin if( _Attr( instr ) & ATTR_POP ) optreturnvoid; lbl = _Label( instr )->ins; if( lbl == NULL ) optreturnvoid; if( NextClass( lbl ) != OC_RET ) optreturnvoid; _Savings( OPT_CALLTORET, _ObjLen( instr ) ); DelInstr( instr ); optend }