LLVM 24.0.0git
RISCVLateBranchOpt.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// This file provides RISC-V specific target optimizations, currently it's
10/// limited to convert conditional branches into unconditional branches when
11/// the condition can be statically evaluated.
12///
13//===----------------------------------------------------------------------===//
14
15#include "RISCV.h"
16#include "RISCVInstrInfo.h"
17#include "RISCVSubtarget.h"
20#include "llvm/IR/Analysis.h"
21
22using namespace llvm;
23
24#define RISCV_LATE_BRANCH_OPT_NAME "RISC-V Late Branch Optimisation Pass"
25
26namespace {
27
28struct RISCVLateBranchOptLegacy : public MachineFunctionPass {
29 static char ID;
30
31 RISCVLateBranchOptLegacy() : MachineFunctionPass(ID) {}
32
33 StringRef getPassName() const override { return RISCV_LATE_BRANCH_OPT_NAME; }
34
35 void getAnalysisUsage(AnalysisUsage &AU) const override {
37 }
38
39 bool runOnMachineFunction(MachineFunction &Fn) override;
40};
41} // namespace
42
43char RISCVLateBranchOptLegacy::ID = 0;
44INITIALIZE_PASS(RISCVLateBranchOptLegacy, "riscv-late-branch-opt",
45 RISCV_LATE_BRANCH_OPT_NAME, false, false)
46
47static bool runLateBranchOptOnMBB(MachineBasicBlock &MBB,
51 if (RII->analyzeBranch(MBB, TBB, FBB, Cond, /*AllowModify=*/false))
52 return false;
53
54 if (!TBB || Cond.size() != 3)
55 return false;
56
59
60 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
61
62 // Try and convert a conditional branch that can be evaluated statically
63 // into an unconditional branch.
64 int64_t C0, C1;
67 return false;
68
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 } else
91 MBB.addSuccessor(Folded);
92
93 return true;
94}
95
97 auto &ST = Fn.getSubtarget<RISCVSubtarget>();
98 const RISCVInstrInfo *RII = ST.getInstrInfo();
99
100 bool Changed = false;
101 for (MachineBasicBlock &MBB : Fn)
102 Changed |= runLateBranchOptOnMBB(MBB, RII);
103 return Changed;
104}
105
107 return new RISCVLateBranchOptLegacy();
108}
109
110bool RISCVLateBranchOptLegacy::runOnMachineFunction(MachineFunction &MF) {
111 if (skipFunction(MF.getFunction()))
112 return false;
113 return runLateBranchOptOnMF(MF);
114}
115
116PreservedAnalyses
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
MachineBasicBlock * Folded
SmallVector< MachineOperand, 4 > Cond
const RISCVInstrInfo * RII
int64_t C1
#define RISCV_LATE_BRANCH_OPT_NAME
static bool runLateBranchOptOnMF(MachineFunction &Fn)
RISCVCC::CondCode CC
MachineRegisterInfo & MRI
int64_t C0
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
Represent the analysis usage information of a pass.
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc)
static bool evaluateCondBranch(RISCVCC::CondCode CC, int64_t C0, int64_t C1)
Return the result of the evaluation of C0 CC C1, where CC is a RISCVCC::CondCode.
static bool isFromLoadImm(const MachineRegisterInfo &MRI, const MachineOperand &Op, int64_t &Imm)
Return true if the operand is a load immediate instruction and sets Imm to the immediate value.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Pass manager infrastructure for declaring and invalidating analyses.
This is an optimization pass for GlobalISel generic memory operations.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
FunctionPass * createRISCVLateBranchOptLegacyPass()