@@ -89,22 +89,27 @@ void RISCv64LinearScan::linearizeBlocks() {
}
}
// 步骤 1.2: 计算活跃区间
// RISCv64LinearScan.cpp
void RISCv64LinearScan : : computeLiveIntervals ( ) {
instr_numbering . clear ( ) ;
live_intervals . clear ( ) ;
unhandled . clear ( ) ;
// a. 对所有指令进行线性编号
// a. 对所有指令进行线性编号, 并记录CALL指令的位置
int num = 0 ;
std : : set < int > call_locations ;
for ( auto * mbb : linear_order_blocks ) {
for ( auto & instr : mbb - > getInstructions ( ) ) {
instr_numbering [ instr . get ( ) ] = num ;
if ( instr - > getOpcode ( ) = = RVOpcodes : : CALL ) {
call_locations . insert ( num ) ;
}
num + = 2 ; // 指令编号间隔为2, 方便在溢出重写时插入指令
}
}
// b. (新逻辑) 遍历所有指令, 记录每个vreg首次和末次出现的位置
// b. 遍历所有指令, 记录每个vreg首次和末次出现的位置
std : : map < unsigned , std : : pair < int , int > > vreg_ranges ; // vreg -> {first_instr_num, last_instr_num}
for ( auto * mbb : linear_order_blocks ) {
@@ -114,28 +119,31 @@ void RISCv64LinearScan::computeLiveIntervals() {
std : : set < unsigned > use , def ;
getInstrUseDef ( instr , use , def ) ;
// 合并use和def集合, 获取本条指令涉及的所有vreg
auto all_vregs = use ;
all_vregs . insert ( def . begin ( ) , def . end ( ) ) ;
// 更新每个vreg的区间边界
for ( unsigned vreg : all_vregs ) {
if ( vreg_ranges . find ( vreg ) = = vreg_ranges . end ( ) ) {
// 第一次见到这个vreg, 记录首次和末次位置
vreg_ranges [ vreg ] = { instr_num , instr_num } ;
} else {
// 更新末次位置
vreg_ranges [ vreg ] . second = std : : max ( vreg_ranges [ vreg ] . second , instr_num ) ;
}
}
}
}
// c. 根据记录的边界, 创建LiveInterval对象
// c. 根据记录的边界, 创建LiveInterval对象, 并检查是否跨越CALL
for ( auto const & [ vreg , range ] : vreg_ranges ) {
live_intervals . emplace ( vreg , LiveInterval ( vreg ) ) ;
live_intervals . at ( vreg ) . start = range . first ;
live_ intervals . at ( vreg ) . end = range . second ;
auto & interval = live_intervals . at ( vreg ) ;
interval . start = range . first ;
interval . end = range . second ;
// 检查此区间是否跨越了任何CALL指令
auto it = call_locations . lower_bound ( interval . start ) ;
if ( it ! = call_locations . end ( ) & & * it < interval . end ) {
interval . crosses_call = true ;
}
}
// d. 将所有计算出的活跃区间放入 unhandled 列表
@@ -147,62 +155,106 @@ void RISCv64LinearScan::computeLiveIntervals() {
} ) ;
}
// 步骤 2: 线性扫描主算法
// RISCv64LinearScan.cpp
// 在类的定义中添加一个辅助函数来判断寄存器类型
bool isCalleeSaved ( PhysicalReg preg ) {
if ( preg > = PhysicalReg : : S1 & & preg < = PhysicalReg : : S11 ) return true ;
if ( preg = = PhysicalReg : : S0 ) return true ; // s0 通常也作为被调用者保存
// 浮点寄存器
if ( preg > = PhysicalReg : : F8 & & preg < = PhysicalReg : : F9 ) return true ;
if ( preg > = PhysicalReg : : F18 & & preg < = PhysicalReg : : F27 ) return true ;
return false ;
}
// 线性扫描主算法
bool RISCv64LinearScan : : linearScan ( ) {
// 初始化/重置状态
active . clear ( ) ;
spilled_vregs . clear ( ) ;
vreg_to_preg_map . clear ( ) ;
free_int_regs . clear ( ) ;
free_fp_regs . clear ( ) ;
free_int_regs . insert ( allocable_int_regs . begin ( ) , allocable_int_regs . end ( ) ) ;
free_fp_regs . insert ( allocable_fp_regs . begin ( ) , allocable_fp_regs . end ( ) ) ;
// 1. 将ABI参数的vreg直接分配给其固定的物理寄存器
// 将寄存器池分为调用者保存和被调用者保存两类
std : : set < PhysicalReg > free_caller_int_regs , free_callee_int_regs ;
std : : set < PhysicalReg > free_caller_fp_regs , free_callee_fp_regs ;
for ( auto preg : allocable_int_regs ) {
if ( isCalleeSaved ( preg ) ) free_callee_int_regs . insert ( preg ) ;
else free_caller_int_regs . insert ( preg ) ;
}
for ( auto preg : allocable_fp_regs ) {
if ( isCalleeSaved ( preg ) ) free_callee_fp_regs . insert ( preg ) ;
else free_caller_fp_regs . insert ( preg ) ;
}
// 预处理ABI参数寄存器
vreg_to_preg_map . insert ( abi_vreg_map . begin ( ) , abi_vreg_map . end ( ) ) ;
// 2. 从unhandled列表中移除这些ABI参数区间, 并将其加入active列表
std : : vector < LiveInterval * > normal_unhandled ;
for ( LiveInterval * interval : unhandled ) {
if ( abi_vreg_map . count ( interval - > vreg ) ) {
// 这是一个ABI参数区间, 它已经被“预分配”
active . push_back ( interval ) ;
// 从空闲池中移除对应的物理寄存器
PhysicalReg preg = abi_vreg_map . at ( interval - > vreg ) ;
if ( isFPVReg ( interval - > vreg ) ) {
free _fp_regs. erase ( preg ) ;
if ( isCalleeSaved ( preg ) ) free_callee_fp_regs . erase ( preg ) ; else free_caller _fp_regs. erase ( preg ) ;
} else {
free _int_regs. erase ( preg ) ;
if ( isCalleeSaved ( preg ) ) free_callee_int_regs . erase ( preg ) ; else free_caller _int_regs. erase ( preg ) ;
}
} else {
// 这是一个普通区间,留待后续处理
normal_unhandled . push_back ( interval ) ;
}
}
unhandled = normal_unhandled ; // 更新unhandled列表, 只包含普通区间
// 3. 对active列表( 现在只包含ABI参数) 按结束点排序
std : : sort ( active . begin ( ) , active . end ( ) , [ ] ( const LiveInterval * a , const LiveInterval * b ) {
return a - > end < b - > end ;
} ) ;
unhandled = normal_unhandled ;
std : : sort ( active . begin ( ) , active . end ( ) , [ ] ( const LiveInterval * a , const LiveInterval * b ) { return a - > end < b - > end ; } ) ;
// 主循环
for ( LiveInterval * current : unhandled ) {
// a. 检查并 释放 active 列表中已经 结束的区间
// a. 释放active列表中已结束的区间
std : : vector < LiveInterval * > new_active ;
for ( LiveInterval * active_interval : active ) {
if ( active_interval - > end < current - > start ) {
// 此区间已结束,释放其物理寄存器
PhysicalReg preg = vreg_to_preg_map . at ( active_interval - > vreg ) ;
if ( isFPVReg ( active_interval - > vreg ) ) free_fp_regs . insert ( preg ) ;
else free_int _regs. insert ( preg ) ;
if ( isFPVReg ( active_interval - > vreg ) ) {
if ( isCalleeSaved ( preg ) ) free_callee_fp_regs . insert ( preg ) ; else free_caller_fp _regs . insert ( preg ) ;
} else {
if ( isCalleeSaved ( preg ) ) free_callee_int_regs . insert ( preg ) ; else free_caller_int_regs . insert ( preg ) ;
}
} else {
new_active . push_back ( active_interval ) ;
}
}
active = new_active ;
// b. 尝试 为当前区间分配寄存器
chooseRegForInterval ( current ) ;
// b. 约束化地 为当前区间分配寄存器
bool is_fp = isFPVReg ( current - > vreg ) ;
auto & free_caller = is_fp ? free_caller_fp_regs : free_caller_int_regs ;
auto & free_callee = is_fp ? free_callee_fp_regs : free_callee_int_regs ;
PhysicalReg allocated_preg = PhysicalReg : : INVALID ;
if ( current - > crosses_call ) {
// 跨调用区间:必须使用被调用者保存寄存器
if ( ! free_callee . empty ( ) ) {
allocated_preg = * free_callee . begin ( ) ;
free_callee . erase ( allocated_preg ) ;
}
} else {
// 非跨调用区间:优先使用调用者保存寄存器
if ( ! free_caller . empty ( ) ) {
allocated_preg = * free_caller . begin ( ) ;
free_caller . erase ( allocated_preg ) ;
} else if ( ! free_callee . empty ( ) ) {
allocated_preg = * free_callee . begin ( ) ;
free_callee . erase ( allocated_preg ) ;
}
}
if ( allocated_preg ! = PhysicalReg : : INVALID ) {
vreg_to_preg_map [ current - > vreg ] = allocated_preg ;
active . push_back ( current ) ;
std : : sort ( active . begin ( ) , active . end ( ) , [ ] ( const LiveInterval * a , const LiveInterval * b ) { return a - > end < b - > end ; } ) ;
} else {
// c. 没有可用寄存器,需要溢出
spillAtInterval ( current ) ;
}
}
return ! spilled_vregs . empty ( ) ;
}
@@ -228,33 +280,29 @@ void RISCv64LinearScan::chooseRegForInterval(LiveInterval* current) {
}
void RISCv64LinearScan : : spillAtInterval ( LiveInterval * current ) {
// 启发式:比较当前区间和 active 列表中结束点最晚的区间
LiveInterval * spill_candidate = active . back ( ) ; // active已按end排序, 最后一个就是结束最晚的
if ( spill_candidate - > end > current - > end ) {
// active中的区间结束得更晚, 溢出它
PhysicalReg preg = vreg_to_preg_map . at ( spill_candidate - > vreg ) ;
// 将被溢出区间的物理寄存器分配给当前区间
vreg_to_preg_map [ current - > vreg ] = preg ;
// 更新 active 列表
active . pop_back ( ) ; // 移除被溢出的
active . push_back ( current ) ; // 加入当前的
std : : sort ( active . begin ( ) , active . end ( ) , [ ] ( const LiveInterval * a , const LiveInterval * b ) {
return a - > end < b - > end ;
} ) ;
LiveInterval * spill_candidate = nullptr ;
// 启发式溢出:
// 如果current需要callee-saved, 则从active中找一个占用callee-saved且结束最晚的区间比较
// 否则, 找active中结束最晚的区间
// 这里简化处理: 总是找active中结束最晚的区间
auto last_active = active . back ( ) ;
if ( last_active - > end > current - > end ) {
// 溢出active中的区间
spill_candidate = last_active ;
PhysicalReg preg = vreg_to_preg_map . at ( spill_candidate - > vreg ) ;
vreg_to_preg_map [ current - > vreg ] = preg ; // 把换出的寄存器给current
// 更新active列表
active . pop_back ( ) ;
active . push_back ( current ) ;
std : : sort ( active . begin ( ) , active . end ( ) , [ ] ( const LiveInterval * a , const LiveInterval * b ) { return a - > end < b - > end ; } ) ;
spilled_vregs . insert ( spill_candidate - > vreg ) ;
if ( DEBUG ) std : : cerr < < " Spilling vreg " < < spill_candidate - > vreg < < " to make room for vreg " < < current - > vreg < < " \n " ;
} else {
// 当前区间结束得更晚,直接 溢出当前区间
// 溢出当前区间
spilled_vregs . insert ( current - > vreg ) ;
if ( DEBUG ) std : : cerr < < " Spilling current vreg " < < current - > vreg < < " \n " ;
}
}
// 步骤 3: 重写程序,插入溢出代码
void RISCv64LinearScan : : rewriteProgram ( ) {
StackFrameInfo & frame_info = MFunc - > getFrameInfo ( ) ;
@@ -276,15 +324,20 @@ void RISCv64LinearScan::rewriteProgram() {
for ( auto it = instrs . begin ( ) ; it ! = instrs . end ( ) ; + + it ) {
auto & instr = * it ;
std : : set < unsigned > use , def ;
getInstrUseDef ( instr . get ( ) , use , def ) ;
std : : set < unsigned > use_vregs , def_vregs ;
getInstrUseDef ( instr . get ( ) , use_vregs , def_vregs ) ;
// 为每个溢出的 use 创建 load
for ( unsigned old_vreg : use ) {
if ( spilled_vregs . count ( old_vreg ) ) {
// 建立溢出vreg到新临时vreg的映射
std : : map < unsigned , unsigned > use_remap ;
std : : map < unsigned , unsigned > def_remap ;
// 1. 为所有溢出的USE创建LOAD指令和映射
for ( unsigned old_vreg : use_vregs ) {
if ( spilled_vregs . count ( old_vreg ) & & use_remap . find ( old_vreg ) = = use_remap . end ( ) ) {
Type * type = vreg_type_map . at ( old_vreg ) ;
unsigned new_temp_vreg = ISel - > getNewVReg ( type ) ;
use_remap [ old_vreg ] = new_temp_vreg ;
RVOpcodes load_op = isFPVReg ( old_vreg ) ? RVOpcodes : : FLW : ( type - > isPointer ( ) ? RVOpcodes : : LD : RVOpcodes : : LW ) ;
auto load = std : : make_unique < MachineInstr > ( load_op ) ;
load - > addOperand ( std : : make_unique < RegOperand > ( new_temp_vreg ) ) ;
@@ -293,52 +346,74 @@ void RISCv64LinearScan::rewriteProgram() {
std : : make_unique < ImmOperand > ( frame_info . spill_offsets . at ( old_vreg ) )
) ) ;
new_instrs . push_back ( std : : move ( load ) ) ;
}
}
// 替换原指令中的 use
for ( auto & op : instr - > getOperands ( ) ) {
if ( op - > getKind ( ) = = MachineOperand : : KIND_REG ) {
auto reg_op = static_cast < RegOperand * > ( o p . ge t( ) ) ;
if ( reg_op - > isVirtual ( ) & & reg_op - > getVRegNum ( ) = = old_vreg ) {
reg_op - > setVRegNum ( new_temp_vreg ) ;
}
} else if ( op - > getKind ( ) = = MachineOperand : : KIND_MEM ) {
auto mem_op = static_cast < MemOperand * > ( op . get ( ) ) ;
auto base_reg = mem_op - > getBase ( ) ;
if ( base_reg - > isVirtual ( ) & & base_reg - > getVRegNum ( ) = = old_vreg ) {
base_reg - > setVRegNum ( new_temp_vreg ) ;
}
}
}
// 2. 为所有溢出的DEF创建映射
for ( unsigned old_vreg : def_vregs ) {
if ( spilled_vregs . count ( old_vreg ) & & def_remap . find ( old_vreg ) = = def_remap . end ( ) ) {
Type * type = vreg_type_ma p. a t( old_vreg ) ;
unsigned new_temp_vreg = ISel - > getNew VReg ( type ) ;
def_remap [ old_vreg ] = new_temp_vreg ;
}
}
new_instrs . push_back ( std : : move ( instr ) ) ;
// 3. 基于角色精确地替换原指令中的操作数
auto opcode = instr - > getOpcode ( ) ;
auto & operands = instr - > getOperands ( ) ;
// 为每个溢出的 def 创建 store
for ( unsigned old_vreg : def ) {
if ( spilled_vregs . coun t( old_vreg ) ) {
Type * type = vreg_type_map . at ( old_vreg ) ;
unsigned new_temp_vreg = ISel - > getNewVReg ( type ) ;
// 替换原指令中的 def
for ( auto & op : new_instrs . back ( ) - > getOperands ( ) ) {
if ( op - > getKind ( ) = = MachineOperand : : KIND_REG ) {
auto reg_op = static_cast < RegOperand * > ( op . get ( ) ) ;
if ( reg_op - > isVirtual ( ) & & reg_op - > getVRegNum ( ) = = old_vreg ) {
reg_op - > setVRegNum ( new_temp_vreg ) ;
}
auto replace_reg_op = [ ] ( RegOperand * reg_op , const std : : map < unsigned , unsigned > & remap ) {
i f ( reg_op - > isVirtual ( ) & & remap . count ( reg_op - > getVRegNum ( ) ) ) {
reg_op - > setVRegNum ( remap . a t( reg_op - > getVRegNum ( ) ) ) ;
}
} ;
if ( op_info . count ( opcode ) ) {
const auto & info = op_info . at ( opcode ) ;
// 替换 Defs
for ( int idx : info . first ) {
if ( idx < operands . size ( ) & & operands [ idx ] - > getKind ( ) = = MachineOperand : : KIND_REG ) {
replace_reg_op ( static_cast < RegOperand * > ( operands [ idx ] . get ( ) ) , def_remap ) ;
}
}
// 替换 Uses
for ( int idx : info . second ) {
if ( idx < operands . size ( ) ) {
if ( operands [ idx ] - > getKind ( ) = = MachineOperand : : KIND_REG ) {
replace_reg_op ( static_cast < RegOperand * > ( operands [ idx ] . get ( ) ) , use_remap ) ;
} else if ( operands [ idx ] - > getKind ( ) = = MachineOperand : : KIND_MEM ) {
replace_reg_op ( static_cast < MemOperand * > ( operands [ idx ] . get ( ) ) - > getBase ( ) , use_remap ) ;
}
}
RVOpcodes store_op = isFPVReg ( old_vreg ) ? RVOpcodes : : FSW : ( type - > isPointer ( ) ? RVOpcodes : : SD : RVOpcodes : : SW ) ;
auto store = std : : make_unique < MachineInstr > ( store_op ) ;
store - > addOperand ( std : : make_unique < RegOperand > ( new_temp_vreg ) ) ;
store - > addOperand ( std : : make_unique < MemOperand > (
std : : make_unique < RegOperand > ( PhysicalReg : : S0 ) ,
std : : make_unique < ImmOperand > ( frame_info . spill_offsets . at ( old_vreg ) )
) ) ;
new_instrs . push_back ( std : : move ( store ) ) ;
}
} else if ( opcode = = RVOpcodes : : CALL ) {
// 特殊处理 CALL 指令
if ( ! operands . empty ( ) & & operands [ 0 ] - > getKind ( ) = = MachineOperand : : KIND_REG ) {
replace_reg_op ( static_cast < RegOperand * > ( operands [ 0 ] . get ( ) ) , def_remap ) ;
}
for ( size_t i = 1 ; i < operands . size ( ) ; + + i ) {
if ( operands [ i ] - > getKind ( ) = = MachineOperand : : KIND_REG ) {
replace_reg_op ( static_cast < RegOperand * > ( operands [ i ] . get ( ) ) , use_remap ) ;
}
}
}
// 4. 将修改后的指令放入新列表
new_instrs . push_back ( std : : move ( instr ) ) ;
// 5. 为所有溢出的DEF创建STORE指令
for ( const auto & pair : def_remap ) {
unsigned old_vreg = pair . first ;
unsigned new_temp_vreg = pair . second ;
Type * type = vreg_type_map . at ( old_vreg ) ;
RVOpcodes store_op = isFPVReg ( old_vreg ) ? RVOpcodes : : FSW : ( type - > isPointer ( ) ? RVOpcodes : : SD : RVOpcodes : : SW ) ;
auto store = std : : make_unique < MachineInstr > ( store_op ) ;
store - > addOperand ( std : : make_unique < RegOperand > ( new_temp_vreg ) ) ;
store - > addOperand ( std : : make_unique < MemOperand > (
std : : make_unique < RegOperand > ( PhysicalReg : : S0 ) ,
std : : make_unique < ImmOperand > ( frame_info . spill_offsets . at ( old_vreg ) )
) ) ;
new_instrs . push_back ( std : : move ( store ) ) ;
}
}
instrs = std : : move ( new_instrs ) ;
@@ -382,33 +457,12 @@ void RISCv64LinearScan::applyAllocation() {
}
}
// 辅助函数: 获取指令的use/def集合 (仅虚拟寄存器)
void RISCv64LinearScan : : getInstrUseDef ( const MachineInstr * instr , std : : set < unsigned > & use , std : : set < unsigned > & def ) {
// 这个函数与图着色版本中的 getInstrUseDef 逻辑完全相同,此处直接复用
auto opcode = instr - > getOpcode ( ) ;
const auto & operands = instr - > getOperands ( ) ;
static const std : : map < RVOpcodes , std : : pair < std : : vector < int > , std : : vector < int > > > op_info = {
{ RVOpcodes : : ADD , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : SUB , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : MUL , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : DIV , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : REM , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : ADDW , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : SUBW , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : MULW , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : DIVW , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : REMW , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : SLT , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : SLTU , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : ADDI , { { 0 } , { 1 } } } , { RVOpcodes : : ADDIW , { { 0 } , { 1 } } } , { RVOpcodes : : XORI , { { 0 } , { 1 } } } ,
{ RVOpcodes : : SLTI , { { 0 } , { 1 } } } , { RVOpcodes : : SLTIU , { { 0 } , { 1 } } } , { RVOpcodes : : LB , { { 0 } , { } } } ,
{ RVOpcodes : : LH , { { 0 } , { } } } , { RVOpcodes : : LW , { { 0 } , { } } } , { RVOpcodes : : LD , { { 0 } , { } } } ,
{ RVOpcodes : : LBU , { { 0 } , { } } } , { RVOpcodes : : LHU , { { 0 } , { } } } , { RVOpcodes : : LWU , { { 0 } , { } } } ,
{ RVOpcodes : : FLW , { { 0 } , { } } } , { RVOpcodes : : FLD , { { 0 } , { } } } , { RVOpcodes : : SB , { { } , { 0 , 1 } } } ,
{ RVOpcodes : : SH , { { } , { 0 , 1 } } } , { RVOpcodes : : SW , { { } , { 0 , 1 } } } , { RVOpcodes : : SD , { { } , { 0 , 1 } } } ,
{ RVOpcodes : : FSW , { { } , { 0 , 1 } } } , { RVOpcodes : : FSD , { { } , { 0 , 1 } } } , { RVOpcodes : : BEQ , { { } , { 0 , 1 } } } ,
{ RVOpcodes : : BNE , { { } , { 0 , 1 } } } , { RVOpcodes : : BLT , { { } , { 0 , 1 } } } , { RVOpcodes : : BGE , { { } , { 0 , 1 } } } ,
{ RVOpcodes : : JALR , { { 0 } , { 1 } } } , { RVOpcodes : : LI , { { 0 } , { } } } , { RVOpcodes : : LA , { { 0 } , { } } } ,
{ RVOpcodes : : MV , { { 0 } , { 1 } } } , { RVOpcodes : : SEQZ , { { 0 } , { 1 } } } , { RVOpcodes : : SNEZ , { { 0 } , { 1 } } } ,
{ RVOpcodes : : RET , { { } , { } } } , { RVOpcodes : : FADD_S , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : FSUB_S , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : FMUL_S , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : FDIV_S , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : FEQ_S , { { 0 } , { 1 , 2 } } } ,
{ RVOpcodes : : FLT_S , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : FLE_S , { { 0 } , { 1 , 2 } } } , { RVOpcodes : : FCVT_S_W , { { 0 } , { 1 } } } ,
{ RVOpcodes : : FCVT_W_S , { { 0 } , { 1 } } } , { RVOpcodes : : FMV_S , { { 0 } , { 1 } } } , { RVOpcodes : : FMV_W_X , { { 0 } , { 1 } } } ,
{ RVOpcodes : : FMV_X_W , { { 0 } , { 1 } } } , { RVOpcodes : : FNEG_S , { { 0 } , { 1 } } }
} ;
// op_info 的定义已被移到函数外部的命名空间中
auto get_vreg_id_if_virtual = [ & ] ( const MachineOperand * op , std : : set < unsigned > & s ) {
if ( op - > getKind ( ) = = MachineOperand : : KIND_REG ) {
@@ -425,9 +479,13 @@ void RISCv64LinearScan::getInstrUseDef(const MachineInstr* instr, std::set<unsig
const auto & info = op_info . at ( opcode ) ;
for ( int idx : info . first ) if ( idx < operands . size ( ) ) get_vreg_id_if_virtual ( operands [ idx ] . get ( ) , def ) ;
for ( int idx : info . second ) if ( idx < operands . size ( ) ) get_vreg_id_if_virtual ( operands [ idx ] . get ( ) , use ) ;
// MemOperand 的基址寄存器总是一个 use
for ( const auto & op : operands ) if ( op - > getKind ( ) = = MachineOperand : : KIND_MEM ) get_vreg_id_if_virtual ( op . get ( ) , use ) ;
} else if ( opcode = = RVOpcodes : : CALL ) {
// CALL指令的特殊处理
// 第一个操作数( 如果有) 是def( 返回值)
if ( ! operands . empty ( ) & & operands [ 0 ] - > getKind ( ) = = MachineOperand : : KIND_REG ) get_vreg_id_if_virtual ( operands [ 0 ] . get ( ) , def ) ;
// 后续的寄存器操作数是use( 参数)
for ( size_t i = 1 ; i < operands . size ( ) ; + + i ) if ( operands [ i ] - > getKind ( ) = = MachineOperand : : KIND_REG ) get_vreg_id_if_virtual ( operands [ i ] . get ( ) , use ) ;
}
}