forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.6 KiB
98 lines
2.6 KiB
#include "ir/IR.h"
|
|
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
namespace ir {
|
|
|
|
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();
|
|
}
|
|
|
|
Instruction* BasicBlock::GetTerminator() {
|
|
return HasTerminator() ? instructions_.back().get() : nullptr;
|
|
}
|
|
|
|
const Instruction* BasicBlock::GetTerminator() const {
|
|
return HasTerminator() ? instructions_.back().get() : nullptr;
|
|
}
|
|
|
|
void BasicBlock::AddSuccessor(BasicBlock* succ) {
|
|
if (!succ) {
|
|
return;
|
|
}
|
|
if (std::find(successors_.begin(), successors_.end(), succ) ==
|
|
successors_.end()) {
|
|
successors_.push_back(succ);
|
|
}
|
|
if (std::find(succ->predecessors_.begin(), succ->predecessors_.end(), this) ==
|
|
succ->predecessors_.end()) {
|
|
succ->predecessors_.push_back(this);
|
|
}
|
|
}
|
|
|
|
void BasicBlock::ClearCFG() {
|
|
predecessors_.clear();
|
|
successors_.clear();
|
|
}
|
|
|
|
bool BasicBlock::RemoveSuccessor(BasicBlock* succ) {
|
|
auto old_size = successors_.size();
|
|
successors_.erase(
|
|
std::remove(successors_.begin(), successors_.end(), succ), successors_.end());
|
|
return successors_.size() != old_size;
|
|
}
|
|
|
|
PhiInst* BasicBlock::InsertPhi(std::shared_ptr<Type> ty, const std::string& name) {
|
|
auto phi = std::make_unique<PhiInst>(std::move(ty), name);
|
|
auto* ptr = phi.get();
|
|
ptr->SetParent(this);
|
|
auto insert_pos = instructions_.begin();
|
|
while (insert_pos != instructions_.end() &&
|
|
(*insert_pos)->GetOpcode() == Opcode::Phi) {
|
|
++insert_pos;
|
|
}
|
|
instructions_.insert(insert_pos, std::move(phi));
|
|
return ptr;
|
|
}
|
|
|
|
std::vector<std::unique_ptr<Instruction>>& BasicBlock::GetInstructions() {
|
|
return instructions_;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<Instruction>>& BasicBlock::GetInstructions()
|
|
const {
|
|
return instructions_;
|
|
}
|
|
|
|
const std::vector<BasicBlock*>& BasicBlock::GetPredecessors() const {
|
|
return predecessors_;
|
|
}
|
|
|
|
const std::vector<BasicBlock*>& BasicBlock::GetSuccessors() const {
|
|
return successors_;
|
|
}
|
|
|
|
bool BasicBlock::EraseInstruction(Instruction* inst) {
|
|
auto it =
|
|
std::find_if(instructions_.begin(), instructions_.end(),
|
|
[&](const std::unique_ptr<Instruction>& candidate) {
|
|
return candidate.get() == inst;
|
|
});
|
|
if (it == instructions_.end()) {
|
|
return false;
|
|
}
|
|
(*it)->DropAllOperands();
|
|
instructions_.erase(it);
|
|
return true;
|
|
}
|
|
|
|
} // namespace ir
|