[midend]增加全局强度削弱优化遍

This commit is contained in:
rain2133
2025-08-18 11:30:40 +08:00
parent f317010d76
commit c9a0c700e1
4 changed files with 1150 additions and 0 deletions

View File

@ -0,0 +1,107 @@
#pragma once
#include "Pass.h"
#include "IR.h"
#include "SideEffectAnalysis.h"
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
namespace sysy {
// 魔数乘法结构,用于除法优化
struct MagicNumber {
uint32_t multiplier;
int shift;
bool needAdd;
MagicNumber(uint32_t m, int s, bool add = false)
: multiplier(m), shift(s), needAdd(add) {}
};
// 全局强度削弱优化遍的核心逻辑封装类
class GlobalStrengthReductionContext {
public:
// 构造函数接受IRBuilder参数
explicit GlobalStrengthReductionContext(IRBuilder* builder) : builder(builder) {}
// 运行优化的主要方法
void run(Function* func, AnalysisManager* AM, bool& changed);
private:
IRBuilder* builder; // IR构建器
// 分析结果
SideEffectAnalysisResult* sideEffectAnalysis = nullptr;
// 优化计数
int algebraicOptCount = 0;
int strengthReductionCount = 0;
int divisionOptCount = 0;
// 主要优化方法
bool processBasicBlock(BasicBlock* bb);
bool processInstruction(Instruction* inst);
// 代数优化方法
bool tryAlgebraicOptimization(Instruction* inst);
bool optimizeAddition(BinaryInst* inst);
bool optimizeSubtraction(BinaryInst* inst);
bool optimizeMultiplication(BinaryInst* inst);
bool optimizeDivision(BinaryInst* inst);
bool optimizeComparison(BinaryInst* inst);
bool optimizeLogical(BinaryInst* inst);
// 强度削弱方法
bool tryStrengthReduction(Instruction* inst);
bool reduceMultiplication(BinaryInst* inst);
bool reduceDivision(BinaryInst* inst);
bool reducePower(CallInst* inst);
// 复杂乘法强度削弱方法
bool tryComplexMultiplication(BinaryInst* inst, Value* variable, int constant);
bool findOptimalShiftDecomposition(int constant, std::vector<int>& shifts);
Value* createShiftDecomposition(BinaryInst* inst, Value* variable, const std::vector<int>& shifts);
// 魔数乘法相关方法
MagicNumber computeMagicNumber(uint32_t divisor);
std::pair<int, int> computeMulhMagicNumbers(int divisor);
Value* createMagicDivision(BinaryInst* divInst, uint32_t divisor, const MagicNumber& magic);
Value* createMagicDivisionLibdivide(BinaryInst* divInst, int divisor, const std::pair<int, int>& magicPair);
bool isPowerOfTwo(uint32_t n);
int log2OfPowerOfTwo(uint32_t n);
// 辅助方法
bool isConstantInt(Value* val, int& constVal);
bool isConstantInt(Value* val, uint32_t& constVal);
ConstantInteger* getConstantInt(int val);
bool hasOnlyLocalUses(Instruction* inst);
void replaceWithOptimized(Instruction* original, Value* replacement);
};
// 全局强度削弱优化遍类
class GlobalStrengthReduction : public OptimizationPass {
private:
IRBuilder* builder; // IR构建器用于创建新指令
public:
// 静态成员作为该遍的唯一ID
static void* ID;
// 构造函数接受IRBuilder参数
explicit GlobalStrengthReduction(IRBuilder* builder)
: OptimizationPass("GlobalStrengthReduction", Granularity::Function), builder(builder) {}
// 在函数上运行优化
bool runOnFunction(Function* func, AnalysisManager& AM) override;
// 返回该遍的唯一ID
void* getPassID() const override { return ID; }
// 声明分析依赖
void getAnalysisUsage(std::set<void*>& analysisDependencies,
std::set<void*>& analysisInvalidations) const override;
};
} // namespace sysy

View File

@ -22,6 +22,7 @@ add_library(midend_lib STATIC
Pass/Optimize/LICM.cpp
Pass/Optimize/LoopStrengthReduction.cpp
Pass/Optimize/InductionVariableElimination.cpp
Pass/Optimize/GlobalStrengthReduction.cpp
Pass/Optimize/BuildCFG.cpp
Pass/Optimize/LargeArrayToGlobal.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
#include "LICM.h"
#include "LoopStrengthReduction.h"
#include "InductionVariableElimination.h"
#include "GlobalStrengthReduction.h"
#include "Pass.h"
#include <iostream>
#include <queue>
@ -179,6 +180,16 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
printPasses();
}
// 全局强度削弱优化,包括代数优化和魔数除法
this->clearPasses();
this->addPass(&GlobalStrengthReduction::ID);
this->run();
if(DEBUG) {
std::cout << "=== IR After Global Strength Reduction Optimizations ===\n";
printPasses();
}
// this->clearPasses();
// this->addPass(&Reg2Mem::ID);
// this->run();