#include "SysYIRCFGOpt.h"
#include "SysYIROptUtils.h"
#include <cassert>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <iostream>
#include <queue> // 引入队列，SysYDelNoPreBLock需要

namespace sysy {

// 定义静态ID
void *SysYDelInstAfterBrPass::ID = (void *)&SysYDelInstAfterBrPass::ID;
void *SysYDelEmptyBlockPass::ID = (void *)&SysYDelEmptyBlockPass::ID;
void *SysYDelNoPreBLockPass::ID = (void *)&SysYDelNoPreBLockPass::ID;
void *SysYBlockMergePass::ID = (void *)&SysYBlockMergePass::ID;
void *SysYAddReturnPass::ID = (void *)&SysYAddReturnPass::ID;
void *SysYCondBr2BrPass::ID = (void *)&SysYCondBr2BrPass::ID;


// ======================================================================
// SysYCFGOptUtils: 辅助工具类，包含实际的CFG优化逻辑
// ======================================================================

// 删除br后的无用指令
bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) {
  bool changed = false;
  
  auto basicBlocks = func->getBasicBlocks();
  for (auto &basicBlock : basicBlocks) {
    bool Branch = false;
    auto &instructions = basicBlock->getInstructions();
    auto Branchiter = instructions.end();
    for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
      if ((*iter)->isTerminator()){
        Branch = true;
        Branchiter = iter;
        break;
      }
    }
    if (Branchiter != instructions.end()) ++Branchiter;
    while (Branchiter != instructions.end()) {
      changed = true;
      Branchiter = instructions.erase(Branchiter);
    }
    
    if (Branch) {  // 更新前驱后继关系
      auto thelastinstinst = basicBlock->getInstructions().end();
      --thelastinstinst;
      auto &Successors = basicBlock->getSuccessors();
      for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) {
        (*iterSucc)->removePredecessor(basicBlock.get());
        basicBlock->removeSuccessor(*iterSucc);
      }
      if (thelastinstinst->get()->isUnconditional()) {
        BasicBlock* branchBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(0));
        basicBlock->addSuccessor(branchBlock);
        branchBlock->addPredecessor(basicBlock.get());
      } else if (thelastinstinst->get()->isConditional()) {
        BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(1));
        BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(thelastinstinst->get()->getOperand(2));
        basicBlock->addSuccessor(thenBlock);
        basicBlock->addSuccessor(elseBlock);
        thenBlock->addPredecessor(basicBlock.get());
        elseBlock->addPredecessor(basicBlock.get());
      }
    }
  }

  return changed;
}

// 合并基本块
bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
  bool changed = false;

  for (auto blockiter = func->getBasicBlocks().begin();
        blockiter != func->getBasicBlocks().end();) {
    if (blockiter->get()->getNumSuccessors() == 1) {
      // 如果当前块只有一个后继块
      // 且后继块只有一个前驱块
      // 则将当前块和后继块合并
      if (((blockiter->get())->getSuccessors()[0])->getNumPredecessors() == 1) {
        // std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
        BasicBlock* block = blockiter->get();
        BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
        // auto nextarguments = nextBlock->getArguments();
        // 删除br指令
        if (block->getNumInstructions() != 0) {
          auto thelastinstinst = block->end();
          (--thelastinstinst);
          if (thelastinstinst->get()->isUnconditional()) {
            SysYIROptUtils::usedelete(thelastinstinst->get());
            thelastinstinst = block->getInstructions().erase(thelastinstinst);
          } else if (thelastinstinst->get()->isConditional()) {
            // 如果是条件分支，判断条件是否相同，主要优化相同布尔表达式
            if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
              SysYIROptUtils::usedelete(thelastinstinst->get());
              thelastinstinst = block->getInstructions().erase(thelastinstinst); 
            }
          }
        }
        // 将后继块的指令移动到当前块
        // 并将后继块的父指针改为当前块
        for (auto institer = nextBlock->begin(); institer != nextBlock->end();) {
          institer->get()->setParent(block);
          block->getInstructions().emplace_back(institer->release());
          institer = nextBlock->getInstructions().erase(institer);   
        }
        // 更新前驱后继关系，类似树节点操作
        block->removeSuccessor(nextBlock);
        nextBlock->removePredecessor(block);
        std::list<BasicBlock *> succshoulddel;
        for (auto &succ : nextBlock->getSuccessors()) {
          block->addSuccessor(succ);
          succ->replacePredecessor(nextBlock, block);
          succshoulddel.push_back(succ);
        }
        for (auto del : succshoulddel) {
          nextBlock->removeSuccessor(del);
        }

        func->removeBasicBlock(nextBlock);
        changed = true;

      } else {
        blockiter++;
      }
    } else {
      blockiter++;
    }
  }

  return changed;
}

// 删除无前驱块，兼容SSA后的处理
bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) {
  
  bool changed = false;

  for (auto &block : func->getBasicBlocks()) {
    block->setreachableFalse();
  }
  // 对函数基本块做一个拓扑排序，排查不可达基本块
  auto entryBlock = func->getEntryBlock();
  entryBlock->setreachableTrue();
  std::queue<BasicBlock *> blockqueue;
  blockqueue.push(entryBlock);
  while (!blockqueue.empty()) {
    auto block = blockqueue.front();
    blockqueue.pop();
    for (auto &succ : block->getSuccessors()) {
      if (!succ->getreachable()) {
        succ->setreachableTrue();
        blockqueue.push(succ);
      }
    }
  }

  // 删除不可达基本块指令
  for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end(); blockIter++) {
    if (!blockIter->get()->getreachable()) {
      for (auto instIter = blockIter->get()->getInstructions().begin();
          instIter != blockIter->get()->getInstructions().end();) {
        SysYIROptUtils::usedelete(instIter->get());
        instIter = blockIter->get()->getInstructions().erase(instIter);
      }
    }
  }

  
  for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) {
    if (!blockIter->get()->getreachable()) {
      for (auto succblock : blockIter->get()->getSuccessors()) {
        for (auto &phiinst : succblock->getInstructions()) {
        if (phiinst->getKind() != Instruction::kPhi) {
          break;
        }
          // 使用 delBlk 方法正确地删除对应于被删除基本块的传入值
          dynamic_cast<PhiInst *>(phiinst.get())->delBlk(blockIter->get());
        }
      }
      // 删除不可达基本块，注意迭代器不可达问题
      func->removeBasicBlock((blockIter++)->get());
      changed = true;
    } else {
      blockIter++;
    }
  }
  
  return changed;
}

// 删除空块
bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder) {
  bool changed = false;

  // 收集不可达基本块
  // 这里的不可达基本块是指没有实际指令的基本块
  // 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时，也会被视作不可达
  auto basicBlocks = func->getBasicBlocks();
  std::map<sysy::BasicBlock *, BasicBlock *> EmptyBlocks;
  // 空块儿和后继的基本块的映射
  for (auto &basicBlock : basicBlocks) {
    if (basicBlock->getNumInstructions() == 0) {
      if (basicBlock->getNumSuccessors() == 1) {
        EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
      }
    }
    else{
      // 如果只有phi指令和一个uncondbr。(phi)*(uncondbr)?
        // 判断除了最后一个指令之外是不是只有phi指令
      bool onlyPhi = true;
      for (auto &inst : basicBlock->getInstructions()) {
        if (!inst->isPhi() && !inst->isUnconditional()) {
          onlyPhi = false;
          break;
        }
      }
      if(onlyPhi && basicBlock->getNumSuccessors() == 1) // 确保有后继且只有一个
        EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front();
    }
  }
  // 更新基本块信息，增加必要指令
  for (auto &basicBlock : basicBlocks) {
    // 把空块转换成只有跳转指令的不可达块 (这段逻辑在优化遍中可能需要调整，这里是原样保留)
    // 通常，DelEmptyBlock 应该在BlockMerge之后运行，如果存在完全空块，它会尝试填充一个Br指令。
    // 但是，它主要目的是重定向跳转。
    if (distance(basicBlock->begin(), basicBlock->end()) == 0) {
      if (basicBlock->getNumSuccessors() == 0) {
        continue;
      }
      if (basicBlock->getNumSuccessors() > 1) {
        // 如果一个空块有多个后继，说明CFG结构有问题或者需要特殊处理，这里简单assert
        assert(false && "Empty block with multiple successors found during SysYDelEmptyBlock");
      }
      // 这里的逻辑有点问题，如果一个块是空的，且只有一个后继，应该直接跳转到后继。
      // 如果这个块最终被删除了，那么其前驱也需要重定向。
      // 这个循环的目的是重定向现有的跳转指令，而不是创建新的。
      // 所以下面的逻辑才是核心。
      // pBuilder->setPosition(basicBlock.get(), basicBlock->end());
      // pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
      continue;
    }

    auto thelastinst = basicBlock->getInstructions().end();
    --thelastinst;

    // 根据br指令传递的后继块信息，跳过空块链
    if (thelastinst->get()->isUnconditional()) {
      BasicBlock* OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
      BasicBlock *thelastBlockOld = nullptr;
      // 如果空块链表为多个块
      while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)))) {
        thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
        thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]);
      }

      // 如果有重定向发生
      if (thelastBlockOld != nullptr) {
          basicBlock->removeSuccessor(OldBrBlock);
          OldBrBlock->removePredecessor(basicBlock.get());
          basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
          dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
          changed = true; // 标记IR被修改
      }


      if (thelastBlockOld != nullptr) {
        for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
        if (InstInNew->isPhi()) {
          // 使用 delBlk 方法删除 oldBlock 对应的传入值
          dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
        } else {
          break;
        }
  }
      }

    } else if (thelastinst->get()->getKind() == Instruction::kCondBr) {
      auto OldThenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
      auto OldElseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
      bool thenChanged = false;
      bool elseChanged = false;


      BasicBlock *thelastBlockOld = nullptr;
      while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)))) {
        thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
        thelastinst->get()->replaceOperand(
            1, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))]);
        thenChanged = true;
      }

      if (thenChanged) {
        basicBlock->removeSuccessor(OldThenBlock);
        OldThenBlock->removePredecessor(basicBlock.get());
        basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)));
        dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get());
        changed = true; // 标记IR被修改
      }
      
      // 处理 then 和 else 分支合并的情况
      if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
          dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
        auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
        SysYIROptUtils::usedelete(thelastinst->get());
        thelastinst = basicBlock->getInstructions().erase(thelastinst);
        pBuilder->setPosition(basicBlock.get(), basicBlock->end());
        pBuilder->createUncondBrInst(thebrBlock, {});
        changed = true; // 标记IR被修改
        continue;
      }
      
      if (thelastBlockOld != nullptr) {
        for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1))->getInstructions()) {
          if (InstInNew->isPhi()) {
            // 使用 delBlk 方法删除 oldBlock 对应的传入值
            dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
          } else {
            break;
          }
       }
      }

      thelastBlockOld = nullptr;
      while (EmptyBlocks.count(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)))) {
        thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
        thelastinst->get()->replaceOperand(
            2, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))]);
        elseChanged = true;
      }
      
      if (elseChanged) {
        basicBlock->removeSuccessor(OldElseBlock);
        OldElseBlock->removePredecessor(basicBlock.get());
        basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2)));
        dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get());
        changed = true; // 标记IR被修改
      }

      // 处理 then 和 else 分支合并的情况
      if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
          dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
        auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
        SysYIROptUtils::usedelete(thelastinst->get());
        thelastinst = basicBlock->getInstructions().erase(thelastinst);
        pBuilder->setPosition(basicBlock.get(), basicBlock->end());
        pBuilder->createUncondBrInst(thebrBlock, {});
        changed = true; // 标记IR被修改
        continue;
      }
      

      // 如果有重定向发生
      // 需要更新后继块的前驱关系
      if (thelastBlockOld != nullptr) {
        for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))->getInstructions()) {
          if (InstInNew->isPhi()) {
            // 使用 delBlk 方法删除 oldBlock 对应的传入值
            dynamic_cast<PhiInst *>(InstInNew.get())->delBlk(thelastBlockOld);
          } else {
            break;
          }
        } 
      }
      
    } else {
      // 如果不是终止指令，但有后继 (例如，末尾没有显式终止指令的块)
      // 这段逻辑可能需要更严谨的CFG检查来确保正确性
      if (basicBlock->getNumSuccessors() == 1) {
        // 这里的逻辑似乎是想为没有terminator的块添加一个，但通常这应该在CFG构建阶段完成。
        // 如果这里仍然执行，确保它符合预期。
        // pBuilder->setPosition(basicBlock.get(), basicBlock->end());
        // pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
        // auto thelastinst = basicBlock->getInstructions().end();
        // (--thelastinst);
        // auto OldBrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
        // sysy::BasicBlock *thelastBlockOld = nullptr;
        // while (EmptyBlocks.find(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))) !=
        //         EmptyBlocks.end()) {
        //   thelastBlockOld = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));

        //   thelastinst->get()->replaceOperand(
        //       0, EmptyBlocks[dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))]);
        // }
        
        // basicBlock->removeSuccessor(OldBrBlock);
        // OldBrBlock->removePredecessor(basicBlock.get());
        // basicBlock->addSuccessor(dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0)));
        // dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get());
        // changed = true; // 标记IR被修改
        // if (thelastBlockOld != nullptr) {
        //   int indexphi = 0;
        //   for (auto &pred : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getPredecessors()) {
        //     if (pred == thelastBlockOld) {
        //       break;
        //     }
        //     indexphi++;
        //   }

        //   for (auto &InstInNew : dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0))->getInstructions()) {
        //     if (InstInNew->isPhi()) {
        //       dynamic_cast<PhiInst *>(InstInNew.get())->removeOperand(indexphi + 1);
        //     } else {
        //       break;
        //     }
        //   }
        // }
      }
    }
  }

  // 真正的删除空块
  for (auto iter = func->getBasicBlocks().begin(); iter != func->getBasicBlocks().end();) {
    
    if (EmptyBlocks.count(iter->get())) {
      // EntryBlock跳过
      if (iter->get() == func->getEntryBlock()) {
        ++iter;
        continue;
      }

      for (auto instIter = iter->get()->getInstructions().begin();
         instIter != iter->get()->getInstructions().end();) {
        SysYIROptUtils::usedelete(instIter->get()); // 仅删除 use 关系
        // 显式地从基本块中删除指令并更新迭代器
        instIter = iter->get()->getInstructions().erase(instIter);
      }
      // 删除不可达基本块的phi指令的操作数
      for (auto &succ : iter->get()->getSuccessors()) {
        for (auto &instinsucc : succ->getInstructions()) {
          if (instinsucc->isPhi()) {
            // iter->get() 就是当前被删除的空基本块，它作为前驱连接到这里的Phi指令
            dynamic_cast<PhiInst *>(instinsucc.get())->delBlk(iter->get());
          } else {
            // Phi 指令通常在基本块的开头，如果不是 Phi 指令就停止检查
            break;
          }
        }
      }

      func->removeBasicBlock((iter++)->get());
      changed = true;
    } else {
      ++iter;
    }
  }
  
  return changed;
}

// 如果函数没有返回指令，则添加一个默认返回指令(主要解决void函数没有返回指令的问题)
bool SysYCFGOptUtils::SysYAddReturn(Function *func, IRBuilder* pBuilder) {
  bool changed = false;
  auto basicBlocks = func->getBasicBlocks();
  for (auto &block : basicBlocks) {
    if (block->getNumSuccessors() == 0) {
      // 如果基本块没有后继块，则添加一个返回指令
      if (block->getNumInstructions() == 0) {
        pBuilder->setPosition(block.get(), block->end());
        pBuilder->createReturnInst();
        changed = true; // 标记IR被修改
      } else {
        auto thelastinst = block->getInstructions().end();
        --thelastinst;
        if (thelastinst->get()->getKind() != Instruction::kReturn) {
          // std::cout << "Warning: Function " << func->getName() << " has no return instruction, adding default return." << std::endl;

          pBuilder->setPosition(block.get(), block->end());
          // TODO: 如果int float函数缺少返回值是否需要报错
          if (func->getReturnType()->isInt()) {
            pBuilder->createReturnInst(ConstantInteger::get(0));
          } else if (func->getReturnType()->isFloat()) {
            pBuilder->createReturnInst(ConstantFloating::get(0.0F));
          } else {
            pBuilder->createReturnInst();
          }
          changed = true; // 标记IR被修改
        }
      }
    }
  }
  
  return changed;
}

// 条件分支转换为无条件分支
// 主要针对已知条件值的分支转换为无条件分支
// 例如 if (cond) { ... } else { ... } 中的 cond 已经
// 确定为 true 或 false 的情况
bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder* pBuilder) {
  bool changed = false;

  for (auto &basicblock : func->getBasicBlocks()) {
    if (basicblock->getNumInstructions() == 0)
      continue;
    
    auto thelast = basicblock->getInstructions().end();
    --thelast;

    if (thelast->get()->isConditional()){
      ConstantValue *constOperand = dynamic_cast<ConstantValue *>(thelast->get()->getOperand(0));
      std::string opname;
      int constint = 0;
      float constfloat = 0.0F;
      bool constint_Use = false;
      bool constfloat_Use = false;
      if (constOperand != nullptr) {
        if (constOperand->isFloat()) {
          constfloat = constOperand->getFloat();
          constfloat_Use = true;
        } else {
          constint = constOperand->getInt();
          constint_Use = true;
        }
      }
      // 如果可以计算
      if (constfloat_Use || constint_Use) {
        changed = true;

        auto thenBlock = dynamic_cast<BasicBlock *>(thelast->get()->getOperand(1));
        auto elseBlock = dynamic_cast<BasicBlock *>(thelast->get()->getOperand(2));
        SysYIROptUtils::usedelete(thelast->get());
        thelast = basicblock->getInstructions().erase(thelast);
        if ((constfloat_Use && constfloat == 1.0F) || (constint_Use && constint == 1)) {
          // cond为true或非0
          pBuilder->setPosition(basicblock.get(), basicblock->end());
          pBuilder->createUncondBrInst(thenBlock, {});
          
          // 更新CFG关系
          basicblock->removeSuccessor(elseBlock);
          elseBlock->removePredecessor(basicblock.get());
          
          // 删除elseBlock的phi指令中对应的basicblock.get()的传入值
          for (auto &phiinst : elseBlock->getInstructions()) {
            if (phiinst->getKind() != Instruction::kPhi) {
              break;
            }
            // 使用 delBlk 方法删除 basicblock.get() 对应的传入值
            dynamic_cast<PhiInst *>(phiinst.get())->delBlk(basicblock.get());
          }
          
        } else { // cond为false或0

          pBuilder->setPosition(basicblock.get(), basicblock->end());
          pBuilder->createUncondBrInst(elseBlock, {});

          // 更新CFG关系
          basicblock->removeSuccessor(thenBlock);
          thenBlock->removePredecessor(basicblock.get());

          // 删除thenBlock的phi指令中对应的basicblock.get()的传入值
          for (auto &phiinst : thenBlock->getInstructions()) {
            if (phiinst->getKind() != Instruction::kPhi) {
              break;
            }
            // 使用 delBlk 方法删除 basicblock.get() 对应的传入值
            dynamic_cast<PhiInst *>(phiinst.get())->delBlk(basicblock.get());
          }

        }
      }
    }
  }

  return changed;
}

// ======================================================================
// 独立的CFG优化遍的实现
// ======================================================================

bool SysYDelInstAfterBrPass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYDelInstAfterBr(F);
}

bool SysYDelEmptyBlockPass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYDelEmptyBlock(F, pBuilder);
}

bool SysYDelNoPreBLockPass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYDelNoPreBLock(F);
}

bool SysYBlockMergePass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYBlockMerge(F);
}

bool SysYAddReturnPass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYAddReturn(F, pBuilder);
}

bool SysYCondBr2BrPass::runOnFunction(Function *F, AnalysisManager& AM) {
  return SysYCFGOptUtils::SysYCondBr2Br(F, pBuilder);
}

}  // namespace sysy