================ @@ -0,0 +1,121 @@ +//===---- LoongArchLateBranchOpt.cpp - Late Stage Branch Optimization -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// This file provides LoongArch specific target optimizations, currently it's +/// limited to convert conditional branches into unconditional branches when +/// the condition can be statically evaluated. +/// +//===----------------------------------------------------------------------===// + +#include "LoongArchInstrInfo.h" +#include "LoongArchSubtarget.h" + +using namespace llvm; + +#define LOONGARCH_LATE_BRANCH_OPT_NAME "LoongArch Late Branch Optimisation Pass" + +namespace { + +struct LoongArchLateBranchOpt : public MachineFunctionPass { + static char ID; + + LoongArchLateBranchOpt() : MachineFunctionPass(ID) {} + + StringRef getPassName() const override { + return LOONGARCH_LATE_BRANCH_OPT_NAME; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + MachineFunctionPass::getAnalysisUsage(AU); + } + + bool runOnMachineFunction(MachineFunction &Fn) override; + +private: + bool runOnBasicBlock(MachineBasicBlock &MBB) const; + + const LoongArchInstrInfo *TII = nullptr; +}; +} // namespace + +char LoongArchLateBranchOpt::ID = 0; +INITIALIZE_PASS(LoongArchLateBranchOpt, "loongarch-late-branch-opt", + LOONGARCH_LATE_BRANCH_OPT_NAME, false, false) + +bool LoongArchLateBranchOpt::runOnBasicBlock(MachineBasicBlock &MBB) const { + MachineBasicBlock *TBB, *FBB; + SmallVector<MachineOperand, 4> Cond; + if (TII->analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify=*/false)) + return false; + + if (!TBB || Cond.size() < 1) + return false; + + // Try and convert a conditional branch that can be evaluated statically + // into an unconditional branch. + unsigned Opc = Cond[0].getImm(); + MachineBasicBlock *Folded; + switch (Opc) { + case LoongArch::BEQZ: + case LoongArch::BNEZ: + if (Cond.size() < 2 || !Cond[1].isReg() || + Cond[1].getReg() != LoongArch::R0) + return false; + Folded = (Opc == LoongArch::BEQZ) ? TBB : FBB; + break; + case LoongArch::BEQ: + case LoongArch::BNE: + if (Cond.size() < 3 || !Cond[1].isReg() || !Cond[2].isReg() || + Cond[1].getReg() != Cond[2].getReg()) + return false; + Folded = (Opc == LoongArch::BEQ) ? TBB : FBB; + break; ---------------- zhaoqi5 wrote:
Aha! I see. Thanks for your explanation. https://github.com/llvm/llvm-project/pull/216261 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
