@ -776,38 +776,282 @@ void LoopCharacteristicsPass::findDerivedInductionVars(
}
}
// 递归/推进式判定
// 检查操作数是否都是不变量
bool LoopCharacteristicsPass : : isInvariantOperands ( Instruction * inst , Loop * loop , const std : : unordered_set < Value * > & invariants ) {
for ( size_t i = 0 ; i < inst - > getNumOperands ( ) ; + + i ) {
Value * op = inst - > getOperand ( i ) ;
if ( ! isClassicLoopInvariant ( op , loop , invariants ) & & ! invariants . count ( op ) ) {
return false ;
}
}
return true ;
}
// 检查内存位置是否在循环中被修改
bool LoopCharacteristicsPass : : isMemoryLocationModifiedInLoop ( Value * ptr , Loop * loop ) {
// 遍历循环中的所有Store指令, 检查是否有对该内存位置的写入
for ( BasicBlock * bb : loop - > getBlocks ( ) ) {
for ( auto & inst : bb - > getInstructions ( ) ) {
if ( auto * storeInst = dynamic_cast < StoreInst * > ( inst . get ( ) ) ) {
Value * storeTar = storeInst - > getPointer ( ) ;
// 使用别名分析检查是否可能别名
if ( aliasAnalysis ) {
auto aliasType = aliasAnalysis - > queryAlias ( ptr , storeTar ) ;
if ( aliasType ! = AliasType : : NO_ALIAS ) {
if ( DEBUG ) {
std : : cout < < " Memory location " < < ptr - > getName ( )
< < " may be modified by store to " < < storeTar - > getName ( ) < < std : : endl ;
}
return true ;
}
} else {
// 如果没有别名分析,保守处理 - 只检查精确匹配
if ( ptr = = storeTar ) {
return true ;
}
}
}
}
}
return false ;
}
// 检查内存位置是否在循环中被读取
bool LoopCharacteristicsPass : : isMemoryLocationLoadedInLoop ( Value * ptr , Loop * loop , Instruction * excludeInst ) {
// 遍历循环中的所有Load指令, 检查是否有对该内存位置的读取
for ( BasicBlock * bb : loop - > getBlocks ( ) ) {
for ( auto & inst : bb - > getInstructions ( ) ) {
if ( inst . get ( ) = = excludeInst ) continue ; // 排除当前指令本身
if ( auto * loadInst = dynamic_cast < LoadInst * > ( inst . get ( ) ) ) {
Value * loadSrc = loadInst - > getPointer ( ) ;
// 使用别名分析检查是否可能别名
if ( aliasAnalysis ) {
auto aliasType = aliasAnalysis - > queryAlias ( ptr , loadSrc ) ;
if ( aliasType ! = AliasType : : NO_ALIAS ) {
return true ;
}
} else {
// 如果没有别名分析,保守处理 - 只检查精确匹配
if ( ptr = = loadSrc ) {
return true ;
}
}
}
}
}
return false ;
}
// 检查函数调用是否为纯函数
bool LoopCharacteristicsPass : : isPureFunction ( Function * calledFunc ) {
if ( ! calledFunc ) return false ;
// 使用副作用分析检查函数是否为纯函数
if ( sideEffectAnalysis & & sideEffectAnalysis - > isPureFunction ( calledFunc ) ) {
return true ;
}
// 检查是否为内置纯函数(如数学函数)
std : : string funcName = calledFunc - > getName ( ) ;
static const std : : set < std : : string > pureFunctions = {
" abs " , " fabs " , " sqrt " , " sin " , " cos " , " tan " , " exp " , " log " , " pow " ,
" floor " , " ceil " , " round " , " min " , " max "
} ;
return pureFunctions . count ( funcName ) > 0 ;
}
// 递归/推进式判定 - 完善版本
bool LoopCharacteristicsPass : : isClassicLoopInvariant ( Value * val , Loop * loop , const std : : unordered_set < Value * > & invariants ) {
if ( DEBUG > = 2 ) {
std : : cout < < " Checking loop invariant for: " < < val - > getName ( ) < < std : : endl ;
}
// 1. 常量
if ( auto * constval = dynamic_cast < ConstantValue * > ( val ) ) return true ;
if ( auto * constval = dynamic_cast < ConstantValue * > ( val ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Constant: YES " < < std : : endl ;
return true ;
}
// 2. 参数( 函数参数) 通常不在任何BasicBlock内, 直接判定为不变量
if ( auto * arg = dynamic_cast < Argument * > ( val ) ) return true ;
// 在SSA形式下, 参数不会被重新赋值
if ( auto * arg = dynamic_cast < Argument * > ( val ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Function argument: YES " < < std : : endl ;
return true ;
}
// 3. 指令且定义在循环外
if ( auto * inst = dynamic_cast < Instruction * > ( val ) ) {
if ( ! loop - > contains ( inst - > getParent ( ) ) )
return true ;
// 4. 跳转 phi指令 副作用 不外提
if ( inst - > isTerminator ( ) | | inst - > isPhi ( ) | | sideEffectAnalysis - > hasSideEffect ( inst ) )
return false ;
// 5. 所有操作数都是不变量
for ( size_t i = 0 ; i < inst - > getNumOperands ( ) ; + + i ) {
Value * op = inst - > getOperand ( i ) ;
if ( ! isClassicLoopInvariant ( op , loop , invariants ) & & ! invariants . count ( op ) )
return false ;
}
if ( ! loop - > contains ( inst - > getParent ( ) ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Defined outside loop: YES " < < std : : endl ;
return true ;
}
// 4. 跳转指令、phi指令不能外提
if ( inst - > isTerminator ( ) | | inst - > isPhi ( ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Terminator or PHI: NO " < < std : : endl ;
return false ;
}
// 5. 根据指令类型进行具体分析
switch ( inst - > getKind ( ) ) {
case Instruction : : Kind : : kStore : {
// Store指令: 检查循环内是否有对该内存的load
auto * storeInst = dynamic_cast < StoreInst * > ( inst ) ;
Value * storePtr = storeInst - > getPointer ( ) ;
// 首先检查操作数是否不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Store: operands not invariant: NO " < < std : : endl ;
return false ;
}
// 检查是否有对该内存位置的load
if ( isMemoryLocationLoadedInLoop ( storePtr , loop , inst ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Store: memory location loaded in loop: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Store: safe to hoist: YES " < < std : : endl ;
return true ;
}
case Instruction : : Kind : : kLoad : {
// Load指令: 检查循环内是否有对该内存的store
auto * loadInst = dynamic_cast < LoadInst * > ( inst ) ;
Value * loadPtr = loadInst - > getPointer ( ) ;
// 首先检查指针操作数是否不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Load: pointer not invariant: NO " < < std : : endl ;
return false ;
}
// 检查是否有对该内存位置的store
if ( isMemoryLocationModifiedInLoop ( loadPtr , loop ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Load: memory location modified in loop: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Load: safe to hoist: YES " < < std : : endl ;
return true ;
}
case Instruction : : Kind : : kCall : {
// Call指令: 检查是否为纯函数且参数不变
auto * callInst = dynamic_cast < CallInst * > ( inst ) ;
Function * calledFunc = callInst - > getCallee ( ) ;
// 检查是否为纯函数
if ( ! isPureFunction ( calledFunc ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Call: not pure function: NO " < < std : : endl ;
return false ;
}
// 检查参数是否都不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Call: arguments not invariant: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Call: pure function with invariant args: YES " < < std : : endl ;
return true ;
}
case Instruction : : Kind : : kGetElementPtr : {
// GEP指令: 检查基址和索引是否都不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> GEP: base or indices not invariant: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> GEP: base and indices invariant: YES " < < std : : endl ;
return true ;
}
// 一元运算指令
case Instruction : : Kind : : kNeg :
case Instruction : : Kind : : kNot :
case Instruction : : Kind : : kFNeg :
case Instruction : : Kind : : kFNot :
case Instruction : : Kind : : kFtoI :
case Instruction : : Kind : : kItoF :
case Instruction : : Kind : : kBitItoF :
case Instruction : : Kind : : kBitFtoI : {
// 检查操作数是否不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Unary op: operand not invariant: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Unary op: operand invariant: YES " < < std : : endl ;
return true ;
}
// 二元运算指令
case Instruction : : Kind : : kAdd :
case Instruction : : Kind : : kSub :
case Instruction : : Kind : : kMul :
case Instruction : : Kind : : kDiv :
case Instruction : : Kind : : kRem :
case Instruction : : Kind : : kSll :
case Instruction : : Kind : : kSrl :
case Instruction : : Kind : : kSra :
case Instruction : : Kind : : kAnd :
case Instruction : : Kind : : kOr :
case Instruction : : Kind : : kFAdd :
case Instruction : : Kind : : kFSub :
case Instruction : : Kind : : kFMul :
case Instruction : : Kind : : kFDiv :
case Instruction : : Kind : : kICmpEQ :
case Instruction : : Kind : : kICmpNE :
case Instruction : : Kind : : kICmpLT :
case Instruction : : Kind : : kICmpGT :
case Instruction : : Kind : : kICmpLE :
case Instruction : : Kind : : kICmpGE :
case Instruction : : Kind : : kFCmpEQ :
case Instruction : : Kind : : kFCmpNE :
case Instruction : : Kind : : kFCmpLT :
case Instruction : : Kind : : kFCmpGT :
case Instruction : : Kind : : kFCmpLE :
case Instruction : : Kind : : kFCmpGE :
case Instruction : : Kind : : kMulh : {
// 检查所有操作数是否不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Binary op: operands not invariant: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Binary op: operands invariant: YES " < < std : : endl ;
return true ;
}
default : {
// 其他指令:使用副作用分析
if ( sideEffectAnalysis & & sideEffectAnalysis - > hasSideEffect ( inst ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Other inst: has side effect: NO " < < std : : endl ;
return false ;
}
// 检查操作数是否都不变
if ( ! isInvariantOperands ( inst , loop , invariants ) ) {
if ( DEBUG > = 2 ) std : : cout < < " -> Other inst: operands not invariant: NO " < < std : : endl ;
return false ;
}
if ( DEBUG > = 2 ) std : : cout < < " -> Other inst: no side effect, operands invariant: YES " < < std : : endl ;
return true ;
}
}
}
// 其它情况
if ( DEBUG > = 2 ) std : : cout < < " -> Other value type: NO " < < std : : endl ;
return false ;
}
bool LoopCharacteristicsPass : : hasSimpleMemoryPattern ( Loop * loop ) {
// 检查是否有简单的内存访问模式
return true ; // 暂时简化处理
}
} // namespace sysy