brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 28fb0b2 Raw
112 lines · cpp
1//===-- RISCVLateBranchOpt.cpp - Late Stage Branch Optimization -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// This file provides RISC-V specific target optimizations, currently it's10/// limited to convert conditional branches into unconditional branches when11/// the condition can be statically evaluated.12///13//===----------------------------------------------------------------------===//14 15#include "RISCVInstrInfo.h"16#include "RISCVSubtarget.h"17 18using namespace llvm;19 20#define RISCV_LATE_BRANCH_OPT_NAME "RISC-V Late Branch Optimisation Pass"21 22namespace {23 24struct RISCVLateBranchOpt : public MachineFunctionPass {25  static char ID;26 27  RISCVLateBranchOpt() : MachineFunctionPass(ID) {}28 29  StringRef getPassName() const override { return RISCV_LATE_BRANCH_OPT_NAME; }30 31  void getAnalysisUsage(AnalysisUsage &AU) const override {32    MachineFunctionPass::getAnalysisUsage(AU);33  }34 35  bool runOnMachineFunction(MachineFunction &Fn) override;36 37private:38  bool runOnBasicBlock(MachineBasicBlock &MBB) const;39 40  const RISCVInstrInfo *RII = nullptr;41};42} // namespace43 44char RISCVLateBranchOpt::ID = 0;45INITIALIZE_PASS(RISCVLateBranchOpt, "riscv-late-branch-opt",46                RISCV_LATE_BRANCH_OPT_NAME, false, false)47 48bool RISCVLateBranchOpt::runOnBasicBlock(MachineBasicBlock &MBB) const {49  MachineBasicBlock *TBB, *FBB;50  SmallVector<MachineOperand, 4> Cond;51  if (RII->analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify=*/false))52    return false;53 54  if (!TBB || Cond.size() != 3)55    return false;56 57  RISCVCC::CondCode CC = RISCVInstrInfo::getCondFromBranchOpc(Cond[0].getImm());58  assert(CC != RISCVCC::COND_INVALID);59 60  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();61 62  // Try and convert a conditional branch that can be evaluated statically63  // into an unconditional branch.64  int64_t C0, C1;65  if (!RISCVInstrInfo::isFromLoadImm(MRI, Cond[1], C0) ||66      !RISCVInstrInfo::isFromLoadImm(MRI, Cond[2], C1))67    return false;68 69  MachineBasicBlock *Folded =70      RISCVInstrInfo::evaluateCondBranch(CC, C0, C1) ? TBB : FBB;71 72  // At this point, its legal to optimize.73  RII->removeBranch(MBB);74 75  // Only need to insert a branch if we're not falling through.76  if (Folded) {77    DebugLoc DL = MBB.findBranchDebugLoc();78    RII->insertBranch(MBB, Folded, nullptr, {}, DL);79  }80 81  // Update the successors. Remove them all and add back the correct one.82  while (!MBB.succ_empty())83    MBB.removeSuccessor(MBB.succ_end() - 1);84 85  // If it's a fallthrough, we need to figure out where MBB is going.86  if (!Folded) {87    MachineFunction::iterator Fallthrough = ++MBB.getIterator();88    if (Fallthrough != MBB.getParent()->end())89      MBB.addSuccessor(&*Fallthrough);90  } else91    MBB.addSuccessor(Folded);92 93  return true;94}95 96bool RISCVLateBranchOpt::runOnMachineFunction(MachineFunction &Fn) {97  if (skipFunction(Fn.getFunction()))98    return false;99 100  auto &ST = Fn.getSubtarget<RISCVSubtarget>();101  RII = ST.getInstrInfo();102 103  bool Changed = false;104  for (MachineBasicBlock &MBB : Fn)105    Changed |= runOnBasicBlock(MBB);106  return Changed;107}108 109FunctionPass *llvm::createRISCVLateBranchOptPass() {110  return new RISCVLateBranchOpt();111}112