@ -103,7 +103,29 @@ void RISCv64ISel::select() {
}
}
if ( optLevel > 0 ) {
// 仅当函数满足特定条件时,才需要保存参数寄存器,应用更精细的过滤规则
// 1. 函数包含call指令 (非叶子函数): 参数寄存器(a0-a7)是调用者保存的,
// call指令可能会覆盖这些寄存器, 因此必须保存。
// 2. 函数包含alloca指令 (需要栈分配)。
// 3. 函数的指令数量超过一个阈值( 如20) , 意味着它是一个复杂的叶子函数,
// 为安全起见,保存其参数。
// 简单的叶子函数 (如min) 则可以跳过这个步骤进行优化。
auto shouldSaveArgs = [ ] ( Function * func ) {
if ( ! func ) return false ;
int instruction_count = 0 ;
for ( const auto & bb : func - > getBasicBlocks ( ) ) {
for ( const auto & inst : bb - > getInstructions ( ) ) {
if ( dynamic_cast < CallInst * > ( inst . get ( ) ) | | dynamic_cast < AllocaInst * > ( inst . get ( ) ) ) {
return true ; // 发现call或alloca, 立即返回true
}
instruction_count + + ;
}
}
// 如果没有call或alloca, 则检查指令数量
return instruction_count > 45 ;
} ;
if ( optLevel > 0 & & shouldSaveArgs ( F ) ) {
if ( F & & ! F - > getBasicBlocks ( ) . empty ( ) ) {
// 定位到第一个MachineBasicBlock, 也就是函数入口
BasicBlock * first_ir_block = F - > getBasicBlocks_NoRange ( ) . front ( ) . get ( ) ;
@ -1311,6 +1333,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
auto gep = dynamic_cast < GetElementPtrInst * > ( node - > value ) ;
auto result_vreg = getVReg ( gep ) ;
if ( optLevel = = 0 ) {
// --- Step 1: 获取基地址 (此部分逻辑正确,保持不变) ---
auto base_ptr_node = node - > operands [ 0 ] ;
auto current_addr_vreg = getNewVReg ( gep - > getType ( ) ) ;
@ -1417,6 +1440,106 @@ void RISCv64ISel::selectNode(DAGNode* node) {
final_mv - > addOperand ( std : : make_unique < RegOperand > ( current_addr_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( final_mv ) ) ;
break ;
} else {
// 对于-O1时的处理逻辑
// --- Step 1: 获取基地址 ---
auto base_ptr_node = node - > operands [ 0 ] ;
auto base_ptr_val = base_ptr_node - > value ;
// last_step_addr_vreg 保存上一步计算的结果。
// 它首先被初始化为GEP的初始基地址。
unsigned last_step_addr_vreg ;
if ( auto alloca_base = dynamic_cast < AllocaInst * > ( base_ptr_val ) ) {
last_step_addr_vreg = getNewVReg ( gep - > getType ( ) ) ;
auto frame_addr_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : FRAME_ADDR ) ;
frame_addr_instr - > addOperand ( std : : make_unique < RegOperand > ( last_step_addr_vreg ) ) ;
frame_addr_instr - > addOperand ( std : : make_unique < RegOperand > ( getVReg ( alloca_base ) ) ) ;
CurMBB - > addInstruction ( std : : move ( frame_addr_instr ) ) ;
} else if ( auto global_base = dynamic_cast < GlobalValue * > ( base_ptr_val ) ) {
last_step_addr_vreg = getNewVReg ( gep - > getType ( ) ) ;
auto la_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : LA ) ;
la_instr - > addOperand ( std : : make_unique < RegOperand > ( last_step_addr_vreg ) ) ;
la_instr - > addOperand ( std : : make_unique < LabelOperand > ( global_base - > getName ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( la_instr ) ) ;
} else {
// 对于函数参数或来自其他指令的指针, 直接获取其vreg。
// 这个vreg必须被保护, 不能在计算中被修改。
last_step_addr_vreg = getVReg ( base_ptr_val ) ;
}
// --- Step 2: 遵循LLVM GEP语义迭代计算地址 ---
Type * current_type = gep - > getBasePointer ( ) - > getType ( ) - > as < PointerType > ( ) - > getBaseType ( ) ;
for ( size_t i = 0 ; i < gep - > getNumIndices ( ) ; + + i ) {
Value * indexValue = gep - > getIndex ( i ) ;
unsigned stride = getTypeSizeInBytes ( current_type ) ;
if ( stride ! = 0 ) {
// --- 为当前索引和步长生成偏移计算指令 ---
auto offset_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
unsigned index_vreg ;
if ( auto const_index = dynamic_cast < ConstantValue * > ( indexValue ) ) {
index_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( index_vreg ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( const_index - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
} else {
index_vreg = getVReg ( indexValue ) ;
}
if ( stride = = 1 ) {
auto mv = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( offset_vreg ) ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( index_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( mv ) ) ;
} else {
auto size_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
auto li_size = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li_size - > addOperand ( std : : make_unique < RegOperand > ( size_vreg ) ) ;
li_size - > addOperand ( std : : make_unique < ImmOperand > ( stride ) ) ;
CurMBB - > addInstruction ( std : : move ( li_size ) ) ;
auto mul = std : : make_unique < MachineInstr > ( RVOpcodes : : MULW ) ;
mul - > addOperand ( std : : make_unique < RegOperand > ( offset_vreg ) ) ;
mul - > addOperand ( std : : make_unique < RegOperand > ( index_vreg ) ) ;
mul - > addOperand ( std : : make_unique < RegOperand > ( size_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( mul ) ) ;
}
// --- 关键修复点 ---
// 创建一个新的vreg来保存本次加法的结果。
unsigned current_step_addr_vreg = getNewVReg ( gep - > getType ( ) ) ;
// 执行 add current_step, last_step, offset
// 这确保了 last_step_addr_vreg (输入) 永远不会被直接修改。
auto add = std : : make_unique < MachineInstr > ( RVOpcodes : : ADD ) ;
add - > addOperand ( std : : make_unique < RegOperand > ( current_step_addr_vreg ) ) ;
add - > addOperand ( std : : make_unique < RegOperand > ( last_step_addr_vreg ) ) ;
add - > addOperand ( std : : make_unique < RegOperand > ( offset_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( add ) ) ;
// 本次的结果成为下一次计算的输入。
last_step_addr_vreg = current_step_addr_vreg ;
}
// --- 为下一次迭代更新类型 ---
if ( auto array_type = current_type - > as < ArrayType > ( ) ) {
current_type = array_type - > getElementType ( ) ;
} else if ( auto ptr_type = current_type - > as < PointerType > ( ) ) {
current_type = ptr_type - > getBaseType ( ) ;
}
}
// --- Step 3: 将最终计算出的地址存入GEP的目标虚拟寄存器 ---
auto final_mv = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
final_mv - > addOperand ( std : : make_unique < RegOperand > ( result_vreg ) ) ;
final_mv - > addOperand ( std : : make_unique < RegOperand > ( last_step_addr_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( final_mv ) ) ;
break ;
}
}
default :