Compare commits
1 Commits
midend-tco
...
midend-Fun
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97d83d733e |
@@ -634,22 +634,6 @@ void PeepholeOptimizer::runOnMachineFunction(MachineFunction *mfunc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 8. 消除无用移动指令: mv a, a -> (删除)
|
|
||||||
else if (mi1->getOpcode() == RVOpcodes::MV &&
|
|
||||||
mi1->getOperands().size() == 2) {
|
|
||||||
if (mi1->getOperands()[0]->getKind() == MachineOperand::KIND_REG &&
|
|
||||||
mi1->getOperands()[1]->getKind() == MachineOperand::KIND_REG) {
|
|
||||||
auto *dst = static_cast<RegOperand *>(mi1->getOperands()[0].get());
|
|
||||||
auto *src = static_cast<RegOperand *>(mi1->getOperands()[1].get());
|
|
||||||
|
|
||||||
// 检查源和目标寄存器是否相同
|
|
||||||
if (areRegsEqual(dst, src)) {
|
|
||||||
// 删除这条无用指令
|
|
||||||
instrs.erase(instrs.begin() + i);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据是否发生变化调整遍历索引
|
// 根据是否发生变化调整遍历索引
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
|
|||||||
@@ -652,6 +652,13 @@ public:
|
|||||||
} ///< 移除指定位置的指令
|
} ///< 移除指定位置的指令
|
||||||
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
||||||
|
|
||||||
|
static void bbdfs(BasicBlock* bb, std::function<bool(BasicBlock*)> func) {
|
||||||
|
if (func(bb))
|
||||||
|
return;
|
||||||
|
for (auto succ : bb->getSuccessors())
|
||||||
|
bbdfs(succ, func);
|
||||||
|
}
|
||||||
|
|
||||||
/// 清理基本块中的所有使用关系
|
/// 清理基本块中的所有使用关系
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
@@ -767,7 +774,7 @@ protected:
|
|||||||
: User(type, name), kind(kind), parent(parent) {}
|
: User(type, name), kind(kind), parent(parent) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual Instruction* copy(std::function<Value*(Value*)> getValue) const = 0;
|
||||||
public:
|
public:
|
||||||
Kind getKind() const { return kind; }
|
Kind getKind() const { return kind; }
|
||||||
std::string getKindString() const{
|
std::string getKindString() const{
|
||||||
@@ -964,6 +971,18 @@ class PhiInst : public Instruction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhiInst(Type *type,
|
||||||
|
const std::vector<std::pair<BasicBlock*, Value*>> IncomingValues,
|
||||||
|
BasicBlock *parent = nullptr,
|
||||||
|
const std::string &name = "")
|
||||||
|
: Instruction(Kind::kPhi, type, parent, name), vsize(IncomingValues.size()) {
|
||||||
|
for(size_t i = 0; i < vsize; ++i) {
|
||||||
|
addOperand(IncomingValues[i].first);
|
||||||
|
addOperand(IncomingValues[i].second);
|
||||||
|
}
|
||||||
|
refreshMap(); ///< 刷新块到值的映射关系
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量
|
unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量
|
||||||
Value *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); } ///< 获取指定位置的传入值
|
Value *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); } ///< 获取指定位置的传入值
|
||||||
@@ -1013,6 +1032,7 @@ class PhiInst : public Instruction {
|
|||||||
} ///< 刷新块到值的映射关系
|
} ///< 刷新块到值的映射关系
|
||||||
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1047,6 +1067,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Value* getOperand() const { return User::getOperand(0); }
|
Value* getOperand() const { return User::getOperand(0); }
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class UnaryInst
|
}; // class UnaryInst
|
||||||
|
|
||||||
//! Binary instruction, e.g., arithmatic, relation, logic, etc.
|
//! Binary instruction, e.g., arithmatic, relation, logic, etc.
|
||||||
@@ -1126,6 +1147,7 @@ public:
|
|||||||
return new BinaryInst(kind, type, lhs, rhs, parent, name);
|
return new BinaryInst(kind, type, lhs, rhs, parent, name);
|
||||||
}
|
}
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class BinaryInst
|
}; // class BinaryInst
|
||||||
|
|
||||||
//! The return statement
|
//! The return statement
|
||||||
@@ -1217,6 +1239,7 @@ public:
|
|||||||
return succs;
|
return succs;
|
||||||
}
|
}
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class CondBrInst
|
}; // class CondBrInst
|
||||||
|
|
||||||
class UnreachableInst : public Instruction {
|
class UnreachableInst : public Instruction {
|
||||||
@@ -1225,6 +1248,7 @@ public:
|
|||||||
explicit UnreachableInst(const std::string& name, BasicBlock *parent = nullptr)
|
explicit UnreachableInst(const std::string& name, BasicBlock *parent = nullptr)
|
||||||
: Instruction(kUnreachable, Type::getVoidType(), parent, "") {}
|
: Instruction(kUnreachable, Type::getVoidType(), parent, "") {}
|
||||||
void print(std::ostream& os) const { os << "unreachable"; }
|
void print(std::ostream& os) const { os << "unreachable"; }
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Allocate memory for stack variables, used for non-global variable declartion
|
//! Allocate memory for stack variables, used for non-global variable declartion
|
||||||
@@ -1243,6 +1267,7 @@ public:
|
|||||||
return getType()->as<PointerType>()->getBaseType();
|
return getType()->as<PointerType>()->getBaseType();
|
||||||
} ///< 获取分配的类型
|
} ///< 获取分配的类型
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class AllocaInst
|
}; // class AllocaInst
|
||||||
|
|
||||||
|
|
||||||
@@ -1281,6 +1306,7 @@ public:
|
|||||||
return new GetElementPtrInst(resultType, basePointer, indices, parent, name);
|
return new GetElementPtrInst(resultType, basePointer, indices, parent, name);
|
||||||
}
|
}
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Load a value from memory address specified by a pointer value
|
//! Load a value from memory address specified by a pointer value
|
||||||
@@ -1299,6 +1325,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Value* getPointer() const { return getOperand(0); }
|
Value* getPointer() const { return getOperand(0); }
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class LoadInst
|
}; // class LoadInst
|
||||||
|
|
||||||
//! Store a value to memory address specified by a pointer value
|
//! Store a value to memory address specified by a pointer value
|
||||||
@@ -1318,6 +1345,7 @@ public:
|
|||||||
Value* getValue() const { return getOperand(0); }
|
Value* getValue() const { return getOperand(0); }
|
||||||
Value* getPointer() const { return getOperand(1); }
|
Value* getPointer() const { return getOperand(1); }
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
}; // class StoreInst
|
}; // class StoreInst
|
||||||
|
|
||||||
//! Memset instruction
|
//! Memset instruction
|
||||||
@@ -1348,6 +1376,7 @@ public:
|
|||||||
Value* getSize() const { return getOperand(2); }
|
Value* getSize() const { return getOperand(2); }
|
||||||
Value* getValue() const { return getOperand(3); }
|
Value* getValue() const { return getOperand(3); }
|
||||||
void print(std::ostream& os) const override;
|
void print(std::ostream& os) const override;
|
||||||
|
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
@@ -1385,19 +1414,11 @@ protected:
|
|||||||
public:
|
public:
|
||||||
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
||||||
using arg_list = std::vector<Argument *>;
|
using arg_list = std::vector<Argument *>;
|
||||||
enum FunctionAttribute : uint64_t {
|
|
||||||
PlaceHolder = 0x0UL,
|
|
||||||
Pure = 0x1UL << 0,
|
|
||||||
SelfRecursive = 0x1UL << 1,
|
|
||||||
SideEffect = 0x1UL << 2,
|
|
||||||
NoPureCauseMemRead = 0x1UL << 3
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Module *parent; ///< 函数的父模块
|
Module *parent; ///< 函数的父模块
|
||||||
block_list blocks; ///< 函数包含的基本块列表
|
block_list blocks; ///< 函数包含的基本块列表
|
||||||
arg_list arguments; ///< 函数参数列表
|
arg_list arguments; ///< 函数参数列表
|
||||||
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
|
||||||
std::set<Function *> callees; ///< 函数调用的函数集合
|
std::set<Function *> callees; ///< 函数调用的函数集合
|
||||||
public:
|
public:
|
||||||
static unsigned getcloneIndex() {
|
static unsigned getcloneIndex() {
|
||||||
@@ -1405,17 +1426,12 @@ protected:
|
|||||||
cloneIndex += 1;
|
cloneIndex += 1;
|
||||||
return cloneIndex - 1;
|
return cloneIndex - 1;
|
||||||
}
|
}
|
||||||
Function* clone(const std::string &suffix = "_" + std::to_string(getcloneIndex()) + "@") const;
|
Function* copy_func();
|
||||||
const std::set<Function *>& getCallees() { return callees; }
|
const std::set<Function *>& getCallees() { return callees; }
|
||||||
void addCallee(Function *callee) { callees.insert(callee); }
|
void addCallee(Function *callee) { callees.insert(callee); }
|
||||||
void removeCallee(Function *callee) { callees.erase(callee); }
|
void removeCallee(Function *callee) { callees.erase(callee); }
|
||||||
void clearCallees() { callees.clear(); }
|
void clearCallees() { callees.clear(); }
|
||||||
std::set<Function *> getCalleesWithNoExternalAndSelf();
|
std::set<Function *> getCalleesWithNoExternalAndSelf();
|
||||||
FunctionAttribute getAttribute() const { return attribute; }
|
|
||||||
void setAttribute(FunctionAttribute attr) {
|
|
||||||
attribute = static_cast<FunctionAttribute>(attribute | attr);
|
|
||||||
}
|
|
||||||
void clearAttribute() { attribute = PlaceHolder; }
|
|
||||||
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); }
|
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); }
|
||||||
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); }
|
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); }
|
||||||
auto getBasicBlocks() { return make_range(blocks); }
|
auto getBasicBlocks() { return make_range(blocks); }
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Pass.h"
|
|
||||||
#include "Dom.h"
|
|
||||||
#include "Loop.h"
|
|
||||||
|
|
||||||
namespace sysy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class TailCallOpt
|
|
||||||
* @brief 优化尾调用的中端优化通道。
|
|
||||||
*
|
|
||||||
* 该类实现了一个针对函数级别的尾调用优化的优化通道(OptimizationPass)。
|
|
||||||
* 通过分析和转换 IR(中间表示),将可优化的尾调用转换为更高效的形式,
|
|
||||||
* 以减少函数调用的开销,提升程序性能。
|
|
||||||
*
|
|
||||||
* @note 需要传入 IRBuilder 指针用于 IR 构建和修改。
|
|
||||||
*
|
|
||||||
* @method runOnFunction
|
|
||||||
* 对指定函数进行尾调用优化。
|
|
||||||
*
|
|
||||||
* @method getPassID
|
|
||||||
* 获取当前优化通道的唯一标识符。
|
|
||||||
*
|
|
||||||
* @method getAnalysisUsage
|
|
||||||
* 指定该优化通道所依赖和失效的分析集合。
|
|
||||||
*/
|
|
||||||
class TailCallOpt : public OptimizationPass {
|
|
||||||
private:
|
|
||||||
IRBuilder* builder;
|
|
||||||
public:
|
|
||||||
TailCallOpt(IRBuilder* builder) : OptimizationPass("TailCallOpt", Granularity::Function), builder(builder) {}
|
|
||||||
static void *ID;
|
|
||||||
bool runOnFunction(Function *F, AnalysisManager &AM) override;
|
|
||||||
void *getPassID() const override { return &ID; }
|
|
||||||
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace sysy
|
|
||||||
@@ -25,7 +25,6 @@ add_library(midend_lib STATIC
|
|||||||
Pass/Optimize/GlobalStrengthReduction.cpp
|
Pass/Optimize/GlobalStrengthReduction.cpp
|
||||||
Pass/Optimize/BuildCFG.cpp
|
Pass/Optimize/BuildCFG.cpp
|
||||||
Pass/Optimize/LargeArrayToGlobal.cpp
|
Pass/Optimize/LargeArrayToGlobal.cpp
|
||||||
Pass/Optimize/TailCallOpt.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 包含中端模块所需的头文件路径
|
# 包含中端模块所需的头文件路径
|
||||||
|
|||||||
@@ -652,6 +652,12 @@ void BasicBlock::print(std::ostream &os) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Instruction::print(std::ostream &os) const {
|
||||||
|
this->getType()->print(os);
|
||||||
|
std::cerr << " %" << getName() << " ";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void PhiInst::print(std::ostream &os) const {
|
void PhiInst::print(std::ostream &os) const {
|
||||||
printVarName(os, this);
|
printVarName(os, this);
|
||||||
os << " = " << getKindString() << " " << *getType() << " ";
|
os << " = " << getKindString() << " " << *getType() << " ";
|
||||||
@@ -1440,4 +1446,76 @@ void Argument::cleanup() {
|
|||||||
uses.clear();
|
uses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function* Function::copy_func(){
|
||||||
|
std::unordered_map<Value*, Value*> valueMap;
|
||||||
|
// copy global
|
||||||
|
for (auto &gvalue : parent->getGlobals()) {
|
||||||
|
valueMap.emplace(gvalue.get(), gvalue.get());
|
||||||
|
}
|
||||||
|
// copy global const
|
||||||
|
for (auto &cvalue : parent->getConsts()) {
|
||||||
|
valueMap.emplace(cvalue.get(), cvalue.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy function
|
||||||
|
auto newFunc = new Function(parent, type, name + "_copy" + std::to_string(getcloneIndex()));
|
||||||
|
// copy arg
|
||||||
|
for(int i = 0; i < arguments.size(); i++) {
|
||||||
|
auto arg = arguments[i];
|
||||||
|
// Argument(paramActualTypes[i], function, i, paramNames[i]);
|
||||||
|
auto newarg = new Argument(arg->getType(), newFunc, i, arg->getName() + "_copy");
|
||||||
|
newFunc->insertArgument(newarg);
|
||||||
|
valueMap[arg] = newarg;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
for (auto &bb : blocks) {
|
||||||
|
BasicBlock* copybb = newFunc->addBasicBlock();
|
||||||
|
valueMap.emplace(bb, copybb);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto &bb : blocks) {
|
||||||
|
auto BB = bb.get();
|
||||||
|
auto copybb = dynamic_cast<BasicBlock*>(valueMap[BB]);
|
||||||
|
for(auto pred : BB->getPredecessors()) {
|
||||||
|
copybb->addPredecessor(dynamic_cast<BasicBlock*>(valueMap[pred]));
|
||||||
|
}
|
||||||
|
for(auto succ : BB->getSuccessors()) {
|
||||||
|
copybb->addSuccessor(dynamic_cast<BasicBlock*>(valueMap[succ]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if cant find, return itself
|
||||||
|
auto getValue = [&](Value* val) -> Value* {
|
||||||
|
if (val == nullptr) {
|
||||||
|
std::cerr << "getValue(nullptr)" << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (dynamic_cast<ConstantValue*>(val)) return val;
|
||||||
|
if (auto iter = valueMap.find(val); iter != valueMap.end()) return iter->second;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::set<BasicBlock*> visitedbb;
|
||||||
|
|
||||||
|
const auto copyBlock = [&](BasicBlock* bb) -> bool {
|
||||||
|
if (visitedbb.count(bb)) return true;
|
||||||
|
visitedbb.insert(bb);
|
||||||
|
auto bbCpy = dynamic_cast<BasicBlock*>(valueMap.at(bb));
|
||||||
|
for (auto &Inst : bb->getInstructions()) {
|
||||||
|
auto inst = Inst.get();
|
||||||
|
// inst->print(std::cerr);
|
||||||
|
// std::cerr << std::endl;
|
||||||
|
auto copyinst = inst->copy(getValue);
|
||||||
|
copyinst->setParent(bbCpy);
|
||||||
|
valueMap.emplace(inst, copyinst);
|
||||||
|
bbCpy->instructions.emplace_back(copyinst);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
//dfs基本块将指令复制到新函数中
|
||||||
|
BasicBlock::bbdfs(getEntryBlock(), copyBlock);
|
||||||
|
|
||||||
|
return newFunc;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
#include "TailCallOpt.h"
|
|
||||||
#include "IR.h"
|
|
||||||
#include "IRBuilder.h"
|
|
||||||
#include "SysYIROptUtils.h"
|
|
||||||
#include <vector>
|
|
||||||
// #include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace sysy {
|
|
||||||
|
|
||||||
void *TailCallOpt::ID = (void *)&TailCallOpt::ID;
|
|
||||||
|
|
||||||
void TailCallOpt::getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
|
|
||||||
analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID);
|
|
||||||
analysisInvalidations.insert(&LoopAnalysisPass::ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TailCallOpt::runOnFunction(Function *F, AnalysisManager &AM) {
|
|
||||||
std::vector<CallInst *> tailCallInsts;
|
|
||||||
// 遍历函数的所有基本块
|
|
||||||
for (auto &bb_ptr : F->getBasicBlocks()) {
|
|
||||||
auto BB = bb_ptr.get();
|
|
||||||
if (BB->getInstructions().empty()) continue; // 跳过空基本块
|
|
||||||
|
|
||||||
auto term_iter = BB->terminator();
|
|
||||||
if (term_iter == BB->getInstructions().end()) continue; // 没有终结指令则跳过
|
|
||||||
auto term = (*term_iter).get();
|
|
||||||
|
|
||||||
if (!term || !term->isReturn()) continue; // 不是返回指令则跳过
|
|
||||||
auto retInst = static_cast<ReturnInst *>(term);
|
|
||||||
|
|
||||||
Instruction *prevInst = nullptr;
|
|
||||||
if (BB->getInstructions().size() > 1) {
|
|
||||||
auto it = term_iter;
|
|
||||||
--it; // 获取返回指令前的指令
|
|
||||||
prevInst = (*it).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!prevInst || !prevInst->isCall()) continue; // 前一条不是调用指令则跳过
|
|
||||||
auto callInst = static_cast<CallInst *>(prevInst);
|
|
||||||
|
|
||||||
// 检查是否为尾递归调用:被调用函数与当前函数相同且返回值与调用结果匹配
|
|
||||||
if (callInst->getCallee() == F) {
|
|
||||||
// 对于尾递归,返回值应为调用结果或为 void 类型
|
|
||||||
if (retInst->getReturnValue() == callInst ||
|
|
||||||
(retInst->getReturnValue() == nullptr && callInst->getType()->isVoid())) {
|
|
||||||
tailCallInsts.push_back(callInst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tailCallInsts.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个新的入口基本块,作为循环的前置块
|
|
||||||
auto original_entry = F->getEntryBlock();
|
|
||||||
auto new_entry = F->addBasicBlock("tco.entry." + F->getName());
|
|
||||||
auto loop_header = F->addBasicBlock("tco.loop_header." + F->getName());
|
|
||||||
|
|
||||||
// 将原入口块中的所有指令移动到循环头块
|
|
||||||
loop_header->getInstructions().splice(loop_header->end(), original_entry->getInstructions());
|
|
||||||
original_entry->setName("tco.pre_header");
|
|
||||||
|
|
||||||
// 为函数参数创建 phi 节点
|
|
||||||
builder->setPosition(loop_header, loop_header->begin());
|
|
||||||
std::vector<PhiInst *> phis;
|
|
||||||
auto original_args = F->getArguments();
|
|
||||||
for (auto &arg : original_args) {
|
|
||||||
auto phi = builder->createPhiInst(arg->getType(), {}, {}, "tco.phi."+arg->getName());
|
|
||||||
phis.push_back(phi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用 phi 节点替换所有原始参数的使用
|
|
||||||
for (size_t i = 0; i < original_args.size(); ++i) {
|
|
||||||
original_args[i]->replaceAllUsesWith(phis[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置 phi 节点的输入值
|
|
||||||
for (size_t i = 0; i < phis.size(); ++i) {
|
|
||||||
phis[i]->addIncoming(original_args[i], new_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 连接各个基本块
|
|
||||||
builder->setPosition(original_entry, original_entry->end());
|
|
||||||
builder->createUncondBrInst(new_entry);
|
|
||||||
original_entry->addSuccessor(new_entry);
|
|
||||||
|
|
||||||
builder->setPosition(new_entry, new_entry->end());
|
|
||||||
builder->createUncondBrInst(loop_header);
|
|
||||||
new_entry->addSuccessor(loop_header);
|
|
||||||
loop_header->addPredecessor(new_entry);
|
|
||||||
|
|
||||||
// 处理每一个尾递归调用
|
|
||||||
for (auto callInst : tailCallInsts) {
|
|
||||||
auto tail_call_block = callInst->getParent();
|
|
||||||
|
|
||||||
// 收集尾递归调用的参数
|
|
||||||
auto args_range = callInst->getArguments();
|
|
||||||
std::vector<Value*> args;
|
|
||||||
std::transform(args_range.begin(), args_range.end(), std::back_inserter(args),
|
|
||||||
[](auto& use_ptr){ return use_ptr->getValue(); });
|
|
||||||
|
|
||||||
// 用新的参数值更新 phi 节点
|
|
||||||
for (size_t i = 0; i < phis.size(); ++i) {
|
|
||||||
phis[i]->addIncoming(args[i], tail_call_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除原有的调用和返回指令
|
|
||||||
auto term_iter = tail_call_block->terminator();
|
|
||||||
SysYIROptUtils::usedelete(term_iter);
|
|
||||||
auto call_iter = tail_call_block->findInstIterator(callInst);
|
|
||||||
SysYIROptUtils::usedelete(call_iter);
|
|
||||||
|
|
||||||
// 添加跳转回循环头块的分支指令
|
|
||||||
builder->setPosition(tail_call_block, tail_call_block->end());
|
|
||||||
builder->createUncondBrInst(loop_header);
|
|
||||||
tail_call_block->addSuccessor(loop_header);
|
|
||||||
loop_header->addPredecessor(tail_call_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sysy
|
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "LoopStrengthReduction.h"
|
#include "LoopStrengthReduction.h"
|
||||||
#include "InductionVariableElimination.h"
|
#include "InductionVariableElimination.h"
|
||||||
#include "GlobalStrengthReduction.h"
|
#include "GlobalStrengthReduction.h"
|
||||||
#include "TailCallOpt.h"
|
|
||||||
#include "Pass.h"
|
#include "Pass.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@@ -82,7 +81,6 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
|
|
||||||
registerOptimizationPass<GlobalStrengthReduction>(builderIR);
|
registerOptimizationPass<GlobalStrengthReduction>(builderIR);
|
||||||
registerOptimizationPass<Reg2Mem>(builderIR);
|
registerOptimizationPass<Reg2Mem>(builderIR);
|
||||||
registerOptimizationPass<TailCallOpt>(builderIR);
|
|
||||||
|
|
||||||
registerOptimizationPass<SCCP>(builderIR);
|
registerOptimizationPass<SCCP>(builderIR);
|
||||||
|
|
||||||
@@ -141,16 +139,6 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
this->addPass(&GVN::ID);
|
this->addPass(&GVN::ID);
|
||||||
this->run();
|
this->run();
|
||||||
|
|
||||||
this->clearPasses();
|
|
||||||
this->addPass(&TailCallOpt::ID);
|
|
||||||
this->run();
|
|
||||||
|
|
||||||
if(DEBUG) {
|
|
||||||
std::cout << "=== IR After TailCallOpt ===\n";
|
|
||||||
SysYPrinter printer(moduleIR);
|
|
||||||
printer.printIR();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
std::cout << "=== IR After GVN Optimizations ===\n";
|
std::cout << "=== IR After GVN Optimizations ===\n";
|
||||||
printPasses();
|
printPasses();
|
||||||
@@ -204,9 +192,9 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
printPasses();
|
printPasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->clearPasses();
|
// this->clearPasses();
|
||||||
this->addPass(&Reg2Mem::ID);
|
// this->addPass(&Reg2Mem::ID);
|
||||||
this->run();
|
// this->run();
|
||||||
|
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
std::cout << "=== IR After Reg2Mem Optimizations ===\n";
|
std::cout << "=== IR After Reg2Mem Optimizations ===\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user