Lab4: Implement basic scalar optimizations and lower Phi nodes to assembly

This commit is contained in:
2026-05-05 10:20:15 +08:00
committed by CGH0S7
parent 0b0bc04be3
commit 8f7e0ac5b4
17 changed files with 1318 additions and 35 deletions

View File

@@ -236,7 +236,8 @@ enum class Opcode {
GEP,
ZExt,
SIToFP,
FPToSI
FPToSI,
Phi
};
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
@@ -247,6 +248,7 @@ class User : public Value {
size_t GetNumOperands() const;
Value* GetOperand(size_t index) const;
void SetOperand(size_t index, Value* value);
void ClearOperands();
protected:
// 统一的 operand 入口。
@@ -345,6 +347,18 @@ class StoreInst : public Instruction {
Value* GetPtr() const;
};
class PhiInst : public Instruction {
public:
PhiInst(std::shared_ptr<Type> ty, std::string name = "");
void AddIncoming(Value* val, BasicBlock* bb);
size_t GetNumIncoming() const;
Value* GetIncomingValue(size_t i) const;
BasicBlock* GetIncomingBlock(size_t i) const;
void SetIncomingValue(size_t i, Value* val);
void SetIncomingBlock(size_t i, BasicBlock* bb);
void RemoveIncomingBlock(BasicBlock* bb);
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
@@ -356,6 +370,15 @@ class BasicBlock : public Value {
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
void AddPredecessor(BasicBlock* pred) { predecessors_.push_back(pred); }
void AddSuccessor(BasicBlock* succ) { successors_.push_back(succ); }
void ClearPredecessors() { predecessors_.clear(); }
void ClearSuccessors() { successors_.clear(); }
void EraseInstruction(Instruction* inst);
void InsertInstructionBefore(std::unique_ptr<Instruction> inst, Instruction* before);
void InsertInstructionAtBegin(std::unique_ptr<Instruction> inst);
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
@@ -457,6 +480,7 @@ class IRBuilder {
const std::string& name = "");
CastInst* CreateFPToSI(Value* val, std::shared_ptr<Type> ty,
const std::string& name = "");
PhiInst* CreatePhi(std::shared_ptr<Type> ty, const std::string& name = "");
private:
Context& ctx_;

47
include/ir/PassManager.h Normal file
View File

@@ -0,0 +1,47 @@
#pragma once
#include "ir/IR.h"
#include <vector>
#include <unordered_map>
#include <unordered_set>
namespace ir {
// Dominator Tree Analysis
class DominatorTree {
public:
explicit DominatorTree(Function* func);
void Run();
// Query interfaces
BasicBlock* GetIdom(BasicBlock* bb) const;
const std::vector<BasicBlock*>& GetDominatedBlocks(BasicBlock* bb) const;
const std::vector<BasicBlock*>& GetDominanceFrontier(BasicBlock* bb) const;
bool Dominates(BasicBlock* a, BasicBlock* b) const;
private:
Function* func_;
std::vector<BasicBlock*> rpo_;
std::unordered_map<BasicBlock*, BasicBlock*> idom_;
std::unordered_map<BasicBlock*, std::vector<BasicBlock*>> dom_tree_;
std::unordered_map<BasicBlock*, std::vector<BasicBlock*>> df_;
void ComputeRPO();
void ComputeIdom();
void ComputeDomTree();
void ComputeDF();
};
// Individual Pass Declarations
bool RunMem2Reg(Function* func, Context& ctx);
bool RunConstProp(Function* func, Context& ctx);
bool RunConstFold(Function* func, Context& ctx);
bool RunDCE(Function* func);
bool RunCFGSimplify(Function* func);
bool RunCSE(Function* func);
// Run the optimization pipeline on a Function or Module
void RunOptimizationPasses(Module& module);
void RunFunctionOptimizationPasses(Function* func, Context& ctx);
} // namespace ir