|
|
// IR 基本块:
|
|
|
// - 保存指令序列
|
|
|
// - 为后续 CFG 分析预留前驱/后继接口
|
|
|
//
|
|
|
// 当前仍是最小实现:
|
|
|
// - BasicBlock 已纳入 Value 体系,但类型先用 void 占位;
|
|
|
// - 指令追加与 terminator 约束主要在头文件中的 Append 模板里处理;
|
|
|
// - 前驱/后继容器已经预留,但当前项目里还没有分支指令与自动维护逻辑。
|
|
|
|
|
|
#include "ir/IR.h"
|
|
|
|
|
|
#include <algorithm>
|
|
|
#include <utility>
|
|
|
|
|
|
namespace ir {
|
|
|
|
|
|
// 当前 BasicBlock 还没有专门的 label type,因此先用 void 作为占位类型。
|
|
|
BasicBlock::BasicBlock(std::string name)
|
|
|
: Value(Type::GetVoidType(), std::move(name)) {}
|
|
|
|
|
|
Function* BasicBlock::GetParent() const { return parent_; }
|
|
|
|
|
|
void BasicBlock::SetParent(Function* parent) { parent_ = parent; }
|
|
|
|
|
|
|
|
|
bool BasicBlock::HasTerminator() const {
|
|
|
return !instructions_.empty() && instructions_.back()->IsTerminator();
|
|
|
}
|
|
|
|
|
|
// 按插入顺序返回块内指令序列。
|
|
|
const std::vector<std::unique_ptr<Instruction>>& BasicBlock::GetInstructions()
|
|
|
const {
|
|
|
return instructions_;
|
|
|
}
|
|
|
|
|
|
// 前驱/后继接口先保留给后续 CFG 扩展使用。
|
|
|
// 当前最小 IR 中还没有 branch 指令,因此这些列表通常为空。
|
|
|
const std::vector<BasicBlock*>& BasicBlock::GetPredecessors() const {
|
|
|
return predecessors_;
|
|
|
}
|
|
|
|
|
|
const std::vector<BasicBlock*>& BasicBlock::GetSuccessors() const {
|
|
|
return successors_;
|
|
|
}
|
|
|
|
|
|
void BasicBlock::AddPredecessor(BasicBlock* bb) {
|
|
|
if (bb) predecessors_.push_back(bb);
|
|
|
}
|
|
|
|
|
|
void BasicBlock::RemovePredecessor(BasicBlock* bb) {
|
|
|
predecessors_.erase(
|
|
|
std::remove(predecessors_.begin(), predecessors_.end(), bb),
|
|
|
predecessors_.end());
|
|
|
}
|
|
|
|
|
|
void BasicBlock::ClearPredecessors() { predecessors_.clear(); }
|
|
|
|
|
|
void BasicBlock::AddSuccessor(BasicBlock* bb) {
|
|
|
if (bb) successors_.push_back(bb);
|
|
|
}
|
|
|
|
|
|
void BasicBlock::ClearSuccessors() { successors_.clear(); }
|
|
|
|
|
|
void BasicBlock::RemoveInstruction(Instruction* inst) {
|
|
|
for (auto it = instructions_.begin(); it != instructions_.end(); ++it) {
|
|
|
if (it->get() == inst) {
|
|
|
instructions_.erase(it);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void BasicBlock::InsertBefore(Instruction* inst, Instruction* before) {
|
|
|
if (!before) {
|
|
|
// append (respecting terminator)
|
|
|
if (!instructions_.empty() && instructions_.back()->IsTerminator()) {
|
|
|
instructions_.insert(instructions_.end() - 1,
|
|
|
std::unique_ptr<Instruction>(inst));
|
|
|
} else {
|
|
|
instructions_.push_back(std::unique_ptr<Instruction>(inst));
|
|
|
}
|
|
|
} else {
|
|
|
for (auto it = instructions_.begin(); it != instructions_.end(); ++it) {
|
|
|
if (it->get() == before) {
|
|
|
instructions_.insert(it, std::unique_ptr<Instruction>(inst));
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
// before not found, append instead
|
|
|
instructions_.push_back(std::unique_ptr<Instruction>(inst));
|
|
|
}
|
|
|
inst->SetParent(this);
|
|
|
}
|
|
|
|
|
|
} // namespace ir
|