[midend-IVE]增加无用归纳变量消除遍
This commit is contained in:
157
src/include/midend/Pass/Optimize/InductionVariableElimination.h
Normal file
157
src/include/midend/Pass/Optimize/InductionVariableElimination.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
|
||||
#include "Pass.h"
|
||||
#include "IR.h"
|
||||
#include "LoopCharacteristics.h"
|
||||
#include "Loop.h"
|
||||
#include "Dom.h"
|
||||
#include "SideEffectAnalysis.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <memory>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// 前向声明
|
||||
class LoopCharacteristicsResult;
|
||||
class LoopAnalysisResult;
|
||||
|
||||
/**
|
||||
* @brief 死归纳变量信息
|
||||
* 记录一个可以被消除的归纳变量
|
||||
*/
|
||||
struct DeadInductionVariable {
|
||||
PhiInst* phiInst; // phi 指令
|
||||
std::vector<Instruction*> relatedInsts; // 相关的递增/递减指令
|
||||
Loop* containingLoop; // 所在循环
|
||||
bool canEliminate; // 是否可以安全消除
|
||||
|
||||
DeadInductionVariable(PhiInst* phi, Loop* loop)
|
||||
: phiInst(phi), containingLoop(loop), canEliminate(false) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 归纳变量消除上下文类
|
||||
* 封装归纳变量消除优化的核心逻辑和状态
|
||||
*/
|
||||
class InductionVariableEliminationContext {
|
||||
public:
|
||||
InductionVariableEliminationContext() {}
|
||||
|
||||
/**
|
||||
* 运行归纳变量消除优化
|
||||
* @param F 目标函数
|
||||
* @param AM 分析管理器
|
||||
* @return 是否修改了IR
|
||||
*/
|
||||
bool run(Function* F, AnalysisManager& AM);
|
||||
|
||||
private:
|
||||
// 分析结果缓存
|
||||
LoopAnalysisResult* loopAnalysis = nullptr;
|
||||
LoopCharacteristicsResult* loopCharacteristics = nullptr;
|
||||
DominatorTree* dominatorTree = nullptr;
|
||||
SideEffectAnalysisResult* sideEffectAnalysis = nullptr;
|
||||
|
||||
// 死归纳变量存储
|
||||
std::vector<std::unique_ptr<DeadInductionVariable>> deadIVs;
|
||||
std::unordered_map<Loop*, std::vector<DeadInductionVariable*>> loopToDeadIVs;
|
||||
|
||||
// ========== 核心分析和优化阶段 ==========
|
||||
|
||||
/**
|
||||
* 阶段1:识别死归纳变量
|
||||
* 找出没有被有效使用的归纳变量
|
||||
*/
|
||||
void identifyDeadInductionVariables(Function* F);
|
||||
|
||||
/**
|
||||
* 阶段2:分析消除的安全性
|
||||
* 确保消除操作不会破坏程序语义
|
||||
*/
|
||||
void analyzeSafetyForElimination();
|
||||
|
||||
/**
|
||||
* 阶段3:执行归纳变量消除
|
||||
* 删除死归纳变量及其相关指令
|
||||
*/
|
||||
bool performInductionVariableElimination();
|
||||
|
||||
// ========== 辅助方法 ==========
|
||||
|
||||
/**
|
||||
* 检查归纳变量是否为死归纳变量
|
||||
* @param iv 归纳变量信息
|
||||
* @param loop 所在循环
|
||||
* @return 如果是死归纳变量返回相关信息,否则返回nullptr
|
||||
*/
|
||||
std::unique_ptr<DeadInductionVariable>
|
||||
isDeadInductionVariable(const InductionVarInfo* iv, Loop* loop);
|
||||
|
||||
/**
|
||||
* 检查归纳变量是否只用于自身更新
|
||||
* @param phiInst phi指令
|
||||
* @param loop 所在循环
|
||||
* @return 是否只用于自身更新
|
||||
*/
|
||||
bool isUsedOnlyForSelfUpdate(PhiInst* phiInst, Loop* loop);
|
||||
|
||||
/**
|
||||
* 收集与归纳变量相关的所有指令
|
||||
* @param phiInst phi指令
|
||||
* @param loop 所在循环
|
||||
* @return 相关指令列表
|
||||
*/
|
||||
std::vector<Instruction*> collectRelatedInstructions(PhiInst* phiInst, Loop* loop);
|
||||
|
||||
/**
|
||||
* 检查消除归纳变量的安全性
|
||||
* @param deadIV 死归纳变量
|
||||
* @return 是否可以安全消除
|
||||
*/
|
||||
bool isSafeToEliminate(const DeadInductionVariable* deadIV);
|
||||
|
||||
/**
|
||||
* 消除单个死归纳变量
|
||||
* @param deadIV 死归纳变量
|
||||
* @return 是否成功消除
|
||||
*/
|
||||
bool eliminateDeadInductionVariable(DeadInductionVariable* deadIV);
|
||||
|
||||
/**
|
||||
* 打印调试信息
|
||||
*/
|
||||
void printDebugInfo();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 归纳变量消除优化遍
|
||||
* 消除循环中无用的归纳变量,减少寄存器压力
|
||||
*/
|
||||
class InductionVariableElimination : public OptimizationPass {
|
||||
public:
|
||||
// 唯一的 Pass ID
|
||||
static void *ID;
|
||||
|
||||
InductionVariableElimination()
|
||||
: OptimizationPass("InductionVariableElimination", Granularity::Function) {}
|
||||
|
||||
/**
|
||||
* 在函数上运行归纳变量消除优化
|
||||
* @param F 目标函数
|
||||
* @param AM 分析管理器
|
||||
* @return 是否修改了IR
|
||||
*/
|
||||
bool runOnFunction(Function* F, AnalysisManager& AM) override;
|
||||
|
||||
/**
|
||||
* 声明分析依赖和失效信息
|
||||
*/
|
||||
void getAnalysisUsage(std::set<void*>& analysisDependencies,
|
||||
std::set<void*>& analysisInvalidations) const override;
|
||||
|
||||
void* getPassID() const override { return &ID; }
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
Reference in New Issue
Block a user