@ -1,6 +1,7 @@
# include "mir/MIR.h"
# include <algorithm>
# include <functional>
# include <limits>
# include <queue>
# include <set>
@ -643,7 +644,8 @@ namespace mir
const std : : unordered_map < int , int > & interval_length ,
const std : : unordered_map < int , int > & ref_count ,
const std : : set < int > & rematerializable_vregs ,
const std : : unordered_map < int , int > & move_preferences )
const std : : unordered_map < int , int > & move_preferences ,
const std : : unordered_map < int , int > & vreg_loop_depth )
{
const int K = static_cast < int > ( allocatable_regs . size ( ) ) ;
GraphColoringResult result ;
@ -903,8 +905,13 @@ namespace mir
auto rit = ref_count . find ( v ) ;
if ( rit ! = ref_count . end ( ) ) ref = rit - > second ;
int d = degree [ v ] ;
// 可再物化变量( MovImm 常量)大幅降权,优先 spill
int cost = len * 5 + ref * 15 - d * 25 ;
// 循环深度加权: depth=0 → × 1, depth=1 → × 10, depth=2 → × 100
int depth = 0 ;
auto dit = vreg_loop_depth . find ( v ) ;
if ( dit ! = vreg_loop_depth . end ( ) ) depth = dit - > second ;
int loop_mult = 1 ;
for ( int i = 0 ; i < depth ; i + + ) loop_mult * = 10 ;
int cost = ( len * 5 + ref * 15 ) * loop_mult - d * 25 ;
if ( rematerializable_vregs . count ( v ) )
cost - = 100000 ;
return cost ;
@ -1301,6 +1308,71 @@ namespace mir
auto liveness = ComputeBlockLiveness ( function ) ;
// === 回边检测:计算基本块的循环嵌套深度 ===
size_t num_blocks = function . GetBlocks ( ) . size ( ) ;
std : : vector < int > loop_depth ( num_blocks , 0 ) ;
{
std : : unordered_map < int , size_t > blk_label_to_idx ;
for ( size_t i = 0 ; i < liveness . block_liveness . size ( ) ; + + i )
blk_label_to_idx [ function . GetBlocks ( ) [ i ] - > GetLabelId ( ) ] = i ;
std : : vector < int > dfs_state ( num_blocks , 0 ) ; // 0=未访问, 1=栈中, 2=已完成
std : : function < void ( size_t ) > dfs = [ & ] ( size_t cur ) {
dfs_state [ cur ] = 1 ;
const auto & insts = function . GetBlocks ( ) [ cur ] - > GetInstructions ( ) ;
for ( const auto & inst : insts )
{
size_t succ = static_cast < size_t > ( - 1 ) ;
if ( inst . GetOpcode ( ) = = Opcode : : Br & & inst . GetOperands ( ) . size ( ) > = 1 & &
inst . GetOperands ( ) [ 0 ] . GetKind ( ) = = Operand : : Kind : : Label )
{
auto it = blk_label_to_idx . find ( inst . GetOperands ( ) [ 0 ] . GetLabel ( ) ) ;
if ( it ! = blk_label_to_idx . end ( ) ) succ = it - > second ;
}
if ( inst . GetOpcode ( ) = = Opcode : : CondBr & & inst . GetOperands ( ) . size ( ) > = 2 & &
inst . GetOperands ( ) [ 1 ] . GetKind ( ) = = Operand : : Kind : : Label )
{
auto it = blk_label_to_idx . find ( inst . GetOperands ( ) [ 1 ] . GetLabel ( ) ) ;
if ( it ! = blk_label_to_idx . end ( ) ) succ = it - > second ;
}
if ( succ = = static_cast < size_t > ( - 1 ) ) continue ;
if ( dfs_state [ succ ] = = 1 )
{
// 回边: cur → succ 且 succ 在栈中
loop_depth [ succ ] + + ;
loop_depth [ cur ] + + ;
}
else if ( dfs_state [ succ ] = = 0 )
{
dfs ( succ ) ;
if ( loop_depth [ succ ] > 0 )
loop_depth [ cur ] = std : : max ( loop_depth [ cur ] , loop_depth [ succ ] ) ;
}
}
dfs_state [ cur ] = 2 ;
} ;
dfs ( 0 ) ;
}
// 为每个 vreg 确定其最大循环深度(取定义所在块的 loop_depth)
std : : unordered_map < int , int > vreg_loop_depth ;
for ( size_t bi = 0 ; bi < num_blocks ; + + bi )
{
const auto & insts = function . GetBlocks ( ) [ bi ] - > GetInstructions ( ) ;
for ( const auto & inst : insts )
{
auto du = GetInstDefUse ( inst , function ) ;
for ( int d : du . defs )
{
auto it = vreg_loop_depth . find ( d ) ;
int cur_depth = loop_depth [ bi ] ;
if ( it = = vreg_loop_depth . end ( ) | | cur_depth > it - > second )
vreg_loop_depth [ d ] = cur_depth ;
}
}
}
// 构建可再物化 vreg 集合( MovImm 常量)
std : : set < int > rematerializable_vregs ;
for ( const auto & pair : vreg_def_inst )
@ -1368,10 +1440,12 @@ namespace mir
auto gp_result = ColorGraph ( gp_graph , gp_alloc , function , 19 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs , move_preferences ) ;
rematerializable_vregs , move_preferences ,
vreg_loop_depth ) ;
auto fp_result = ColorGraph ( fp_graph , fp_alloc , function , 16 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs , move_preferences ) ;
rematerializable_vregs , move_preferences ,
vreg_loop_depth ) ;
if ( gp_result . spilled . empty ( ) & & fp_result . spilled . empty ( ) )
{
@ -1524,6 +1598,69 @@ namespace mir
auto liveness = ComputeBlockLiveness ( function ) ;
// === 回边检测:计算基本块的循环嵌套深度 ===
size_t num_blocks = function . GetBlocks ( ) . size ( ) ;
std : : vector < int > loop_depth ( num_blocks , 0 ) ;
{
std : : unordered_map < int , size_t > blk_label_to_idx ;
for ( size_t i = 0 ; i < liveness . block_liveness . size ( ) ; + + i )
blk_label_to_idx [ function . GetBlocks ( ) [ i ] - > GetLabelId ( ) ] = i ;
std : : vector < int > dfs_state ( num_blocks , 0 ) ;
std : : function < void ( size_t ) > dfs = [ & ] ( size_t cur ) {
dfs_state [ cur ] = 1 ;
const auto & insts = function . GetBlocks ( ) [ cur ] - > GetInstructions ( ) ;
for ( const auto & inst : insts )
{
size_t succ = static_cast < size_t > ( - 1 ) ;
if ( inst . GetOpcode ( ) = = Opcode : : Br & & inst . GetOperands ( ) . size ( ) > = 1 & &
inst . GetOperands ( ) [ 0 ] . GetKind ( ) = = Operand : : Kind : : Label )
{
auto it = blk_label_to_idx . find ( inst . GetOperands ( ) [ 0 ] . GetLabel ( ) ) ;
if ( it ! = blk_label_to_idx . end ( ) ) succ = it - > second ;
}
if ( inst . GetOpcode ( ) = = Opcode : : CondBr & & inst . GetOperands ( ) . size ( ) > = 2 & &
inst . GetOperands ( ) [ 1 ] . GetKind ( ) = = Operand : : Kind : : Label )
{
auto it = blk_label_to_idx . find ( inst . GetOperands ( ) [ 1 ] . GetLabel ( ) ) ;
if ( it ! = blk_label_to_idx . end ( ) ) succ = it - > second ;
}
if ( succ = = static_cast < size_t > ( - 1 ) ) continue ;
if ( dfs_state [ succ ] = = 1 )
{
loop_depth [ succ ] + + ;
loop_depth [ cur ] + + ;
}
else if ( dfs_state [ succ ] = = 0 )
{
dfs ( succ ) ;
if ( loop_depth [ succ ] > 0 )
loop_depth [ cur ] = std : : max ( loop_depth [ cur ] , loop_depth [ succ ] ) ;
}
}
dfs_state [ cur ] = 2 ;
} ;
dfs ( 0 ) ;
}
std : : unordered_map < int , int > vreg_loop_depth ;
for ( size_t bi = 0 ; bi < num_blocks ; + + bi )
{
const auto & insts = function . GetBlocks ( ) [ bi ] - > GetInstructions ( ) ;
for ( const auto & inst : insts )
{
auto du = GetInstDefUse ( inst , function ) ;
for ( int d : du . defs )
{
auto it = vreg_loop_depth . find ( d ) ;
int cur_depth = loop_depth [ bi ] ;
if ( it = = vreg_loop_depth . end ( ) | | cur_depth > it - > second )
vreg_loop_depth [ d ] = cur_depth ;
}
}
}
// 构建可再物化 vreg 集合
std : : set < int > rematerializable_vregs ;
for ( const auto & pair : vreg_def_inst )
@ -1589,10 +1726,12 @@ 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 , move_preferences ) ;
rematerializable_vregs , move_preferences ,
vreg_loop_depth ) ;
auto fp_result = ColorGraph ( fp_graph , fp_alloc , function , 16 ,
liveness . interval_length , liveness . ref_count ,
rematerializable_vregs , move_preferences ) ;
rematerializable_vregs , move_preferences ,
vreg_loop_depth ) ;
std : : set < int > all_spilled = gp_result . spilled ;
for ( int v : fp_result . spilled )
all_spilled . insert ( v ) ;