@ -642,7 +642,8 @@ namespace mir
int caller_saved_threshold ,
const std : : unordered_map < int , int > & interval_length ,
const std : : unordered_map < int , int > & ref_count ,
const std : : set < int > & rematerializable_vregs )
const std : : set < int > & rematerializable_vregs ,
const std : : unordered_map < int , int > & move_preferences )
{
const int K = static_cast < int > ( allocatable_regs . size ( ) ) ;
GraphColoringResult result ;
@ -788,8 +789,24 @@ namespace mir
}
int assigned_color = - 1 ;
// 尝试使用 move 偏好颜色(如果偏好变量已分配且无冲突)
auto pref_it = move_preferences . find ( v ) ;
if ( pref_it ! = move_preferences . end ( ) )
{
int pref_v = pref_it - > second ;
auto col_it = colored . find ( pref_v ) ;
if ( col_it ! = colored . end ( ) )
{
int pref_color = col_it - > second ;
if ( used_colors . find ( pref_color ) = = used_colors . end ( ) )
assigned_color = pref_color ;
}
}
// 第一遍:优先选 caller-saved 颜色 (c < caller_saved_threshold)
for ( int c : allocatable_regs )
if ( assigned_color < 0 )
{
for ( int c : allocatable_regs )
{
if ( c > = caller_saved_threshold ) break ;
if ( used_colors . find ( c ) = = used_colors . end ( ) )
@ -811,6 +828,7 @@ namespace mir
}
}
}
}
if ( assigned_color > = 0 )
{
@ -1104,6 +1122,56 @@ namespace mir
rematerializable_vregs . insert ( pair . first ) ;
}
// 收集 MovReg 的 move 偏好映射
std : : unordered_map < int , int > move_preferences ;
for ( auto & block : function . GetBlocks ( ) )
{
for ( auto & inst : block - > GetInstructions ( ) )
{
if ( inst . GetOpcode ( ) = = Opcode : : MovReg )
{
const auto & ops = inst . GetOperands ( ) ;
if ( ops . size ( ) > = 2 & &
ops [ 0 ] . GetKind ( ) = = Operand : : Kind : : VReg & &
ops [ 1 ] . GetKind ( ) = = Operand : : Kind : : VReg )
{
int def_vreg = ops [ 0 ] . GetVRegId ( ) ;
int use_vreg = ops [ 1 ] . GetVRegId ( ) ;
if ( function . GetVRegClass ( def_vreg ) = = function . GetVRegClass ( use_vreg ) )
move_preferences [ def_vreg ] = use_vreg ;
}
}
}
}
// 检测并打破 move 偏好循环
{
std : : unordered_set < int > visited ;
for ( auto & pair : move_preferences )
{
int cur = pair . first ;
if ( visited . count ( cur ) ) continue ;
std : : unordered_set < int > path ;
std : : vector < int > chain ;
int node = cur ;
while ( node ! = 0 & & ! visited . count ( node ) )
{
visited . insert ( node ) ;
path . insert ( node ) ;
chain . push_back ( node ) ;
auto it = move_preferences . find ( node ) ;
if ( it = = move_preferences . end ( ) ) break ;
int next = it - > second ;
if ( path . count ( next ) )
{
move_preferences . erase ( chain . back ( ) ) ;
break ;
}
node = next ;
}
}
}
std : : vector < int > gp_alloc ( GP_ALLOCATABLE , GP_ALLOCATABLE + GP_NUM_ALLOCATABLE ) ;
std : : vector < int > fp_alloc ( FP_ALLOCATABLE , FP_ALLOCATABLE + FP_NUM_ALLOCATABLE ) ;
@ -1113,10 +1181,10 @@ namespace mir
auto gp_result = ColorGraph ( gp_graph , gp_alloc , function , 19 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs );
rematerializable_vregs , move_preferences );
auto fp_result = ColorGraph ( fp_graph , fp_alloc , function , 16 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs );
rematerializable_vregs , move_preferences );
if ( gp_result . spilled . empty ( ) & & fp_result . spilled . empty ( ) )
{
@ -1255,6 +1323,56 @@ namespace mir
rematerializable_vregs . insert ( pair . first ) ;
}
// 收集 MovReg 的 move 偏好映射
std : : unordered_map < int , int > move_preferences ;
for ( auto & block : function . GetBlocks ( ) )
{
for ( auto & inst : block - > GetInstructions ( ) )
{
if ( inst . GetOpcode ( ) = = Opcode : : MovReg )
{
const auto & ops = inst . GetOperands ( ) ;
if ( ops . size ( ) > = 2 & &
ops [ 0 ] . GetKind ( ) = = Operand : : Kind : : VReg & &
ops [ 1 ] . GetKind ( ) = = Operand : : Kind : : VReg )
{
int def_vreg = ops [ 0 ] . GetVRegId ( ) ;
int use_vreg = ops [ 1 ] . GetVRegId ( ) ;
if ( function . GetVRegClass ( def_vreg ) = = function . GetVRegClass ( use_vreg ) )
move_preferences [ def_vreg ] = use_vreg ;
}
}
}
}
// 检测并打破 move 偏好循环
{
std : : unordered_set < int > visited ;
for ( auto & pair : move_preferences )
{
int cur = pair . first ;
if ( visited . count ( cur ) ) continue ;
std : : unordered_set < int > path ;
std : : vector < int > chain ;
int node = cur ;
while ( node ! = 0 & & ! visited . count ( node ) )
{
visited . insert ( node ) ;
path . insert ( node ) ;
chain . push_back ( node ) ;
auto it = move_preferences . find ( node ) ;
if ( it = = move_preferences . end ( ) ) break ;
int next = it - > second ;
if ( path . count ( next ) )
{
move_preferences . erase ( chain . back ( ) ) ;
break ;
}
node = next ;
}
}
}
std : : vector < int > gp_alloc ( GP_ALLOCATABLE , GP_ALLOCATABLE + GP_NUM_ALLOCATABLE ) ;
std : : vector < int > fp_alloc ( FP_ALLOCATABLE , FP_ALLOCATABLE + FP_NUM_ALLOCATABLE ) ;
InterferenceGraph gp_graph , fp_graph ;
@ -1262,10 +1380,10 @@ namespace mir
BuildInterferenceForFP ( function , liveness . block_liveness , fp_alloc , fp_graph ) ;
auto gp_result = ColorGraph ( gp_graph , gp_alloc , function , 19 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs );
rematerializable_vregs , move_preferences );
auto fp_result = ColorGraph ( fp_graph , fp_alloc , function , 16 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs );
rematerializable_vregs , move_preferences );
std : : set < int > all_spilled = gp_result . spilled ;
for ( int v : fp_result . spilled )
all_spilled . insert ( v ) ;