#include "ir/IR.h" #include #include 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 ty, const std::string& name) { auto phi = std::make_unique(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>& BasicBlock::GetInstructions() { return instructions_; } const std::vector>& BasicBlock::GetInstructions() const { return instructions_; } const std::vector& BasicBlock::GetPredecessors() const { return predecessors_; } const std::vector& BasicBlock::GetSuccessors() const { return successors_; } bool BasicBlock::EraseInstruction(Instruction* inst) { auto it = std::find_if(instructions_.begin(), instructions_.end(), [&](const std::unique_ptr& candidate) { return candidate.get() == inst; }); if (it == instructions_.end()) { return false; } (*it)->DropAllOperands(); instructions_.erase(it); return true; } } // namespace ir