LLVM  13.0.0git
RISCVCleanupVSETVLI.cpp
Go to the documentation of this file.
1 //===- RISCVCleanupVSETVLI.cpp - Cleanup unneeded VSETVLI instructions ----===//
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 implements a function pass that removes duplicate vsetvli
10 // instructions within a basic block.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "RISCV.h"
15 #include "RISCVSubtarget.h"
17 using namespace llvm;
18 
19 #define DEBUG_TYPE "riscv-cleanup-vsetvli"
20 #define RISCV_CLEANUP_VSETVLI_NAME "RISCV Cleanup VSETVLI pass"
21 
22 namespace {
23 
24 class RISCVCleanupVSETVLI : public MachineFunctionPass {
25 public:
26  static char ID;
27 
28  RISCVCleanupVSETVLI() : MachineFunctionPass(ID) {
30  }
31  bool runOnMachineFunction(MachineFunction &MF) override;
32  bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
33 
34  MachineFunctionProperties getRequiredProperties() const override {
37  }
38 
39  // This pass modifies the program, but does not modify the CFG
40  void getAnalysisUsage(AnalysisUsage &AU) const override {
41  AU.setPreservesCFG();
43  }
44 
45  StringRef getPassName() const override { return RISCV_CLEANUP_VSETVLI_NAME; }
46 };
47 
48 } // end anonymous namespace
49 
51 
52 INITIALIZE_PASS(RISCVCleanupVSETVLI, DEBUG_TYPE,
53  RISCV_CLEANUP_VSETVLI_NAME, false, false)
54 
55 static bool isRedundantVSETVLI(MachineInstr &MI, MachineInstr *PrevVSETVLI) {
56  // If we don't have a previous VSET{I}VLI or the VL output isn't dead, we
57  // can't remove this VSETVLI.
58  if (!PrevVSETVLI || !MI.getOperand(0).isDead())
59  return false;
60 
61  // Does this VSET{I}VLI use the same VTYPE immediate.
63  int64_t VTYPEImm = MI.getOperand(2).getImm();
64  if (PrevVTYPEImm != VTYPEImm)
65  return false;
66 
67  if (MI.getOpcode() == RISCV::PseudoVSETIVLI) {
68  // If the previous opcode wasn't vsetivli we can't compare them.
69  if (PrevVSETVLI->getOpcode() != RISCV::PseudoVSETIVLI)
70  return false;
71 
72  // For VSETIVLI, we can just compare the immediates.
73  return PrevVSETVLI->getOperand(1).getImm() == MI.getOperand(1).getImm();
74  }
75 
76  assert(MI.getOpcode() == RISCV::PseudoVSETVLI);
77  Register AVLReg = MI.getOperand(1).getReg();
79 
80  // If this VSETVLI isn't changing VL, it is redundant.
81  if (AVLReg == RISCV::X0 && MI.getOperand(0).getReg() == RISCV::X0)
82  return true;
83 
84  // If the previous VSET{I}VLI's output (which isn't X0) is fed into this
85  // VSETVLI, this one isn't changing VL so is redundant.
86  // Only perform this on virtual registers to avoid the complexity of having
87  // to work out if the physical register was clobbered somewhere in between.
88  if (AVLReg.isVirtual() && AVLReg == PrevOutVL)
89  return true;
90 
91  // If the previous opcode isn't vsetvli we can't do any more comparison.
92  if (PrevVSETVLI->getOpcode() != RISCV::PseudoVSETVLI)
93  return false;
94 
95  // Does this VSETVLI use the same AVL register?
96  if (AVLReg != PrevVSETVLI->getOperand(1).getReg())
97  return false;
98 
99  // If the AVLReg is X0 we must be setting VL to VLMAX. Keeping VL unchanged
100  // was handled above.
101  if (AVLReg == RISCV::X0) {
102  // This instruction is setting VL to VLMAX, this is redundant if the
103  // previous VSETVLI was also setting VL to VLMAX. But it is not redundant
104  // if they were setting it to any other value or leaving VL unchanged.
105  return PrevOutVL != RISCV::X0;
106  }
107 
108  // This vsetvli is redundant.
109  return true;
110 }
111 
112 bool RISCVCleanupVSETVLI::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
113  bool Changed = false;
114  MachineInstr *PrevVSETVLI = nullptr;
115 
116  for (auto MII = MBB.begin(), MIE = MBB.end(); MII != MIE;) {
117  MachineInstr &MI = *MII++;
118 
119  if (MI.getOpcode() != RISCV::PseudoVSETVLI &&
120  MI.getOpcode() != RISCV::PseudoVSETIVLI) {
121  if (PrevVSETVLI &&
122  (MI.isCall() || MI.modifiesRegister(RISCV::VL) ||
123  MI.modifiesRegister(RISCV::VTYPE))) {
124  // Old VL/VTYPE is overwritten.
125  PrevVSETVLI = nullptr;
126  }
127  continue;
128  }
129 
130  if (isRedundantVSETVLI(MI, PrevVSETVLI)) {
131  // This VSETVLI is redundant, remove it.
132  MI.eraseFromParent();
133  Changed = true;
134  } else {
135  // Otherwise update VSET{I}VLI for the next iteration.
136  PrevVSETVLI = &MI;
137  }
138  }
139 
140  return Changed;
141 }
142 
143 bool RISCVCleanupVSETVLI::runOnMachineFunction(MachineFunction &MF) {
144  if (skipFunction(MF.getFunction()))
145  return false;
146 
147  // Skip if the vector extension is not enabled.
149  if (!ST.hasStdExtV())
150  return false;
151 
152  bool Changed = false;
153 
154  for (MachineBasicBlock &MBB : MF)
155  Changed |= runOnMachineBasicBlock(MBB);
156 
157  return Changed;
158 }
159 
160 /// Returns an instance of the Cleanup VSETVLI pass.
162  return new RISCVCleanupVSETVLI();
163 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm
Definition: AllocatorList.h:23
llvm::initializeRISCVCleanupVSETVLIPass
void initializeRISCVCleanupVSETVLIPass(PassRegistry &)
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::MachineFunctionProperties::Property::IsSSA
@ IsSSA
llvm::MachineFunctionProperties
Properties which a MachineFunction may have at a given point in time.
Definition: MachineFunction.h:111
INITIALIZE_PASS
INITIALIZE_PASS(RISCVCleanupVSETVLI, DEBUG_TYPE, RISCV_CLEANUP_VSETVLI_NAME, false, false) static bool isRedundantVSETVLI(MachineInstr &MI
DEBUG_TYPE
#define DEBUG_TYPE
Definition: RISCVCleanupVSETVLI.cpp:19
llvm::createRISCVCleanupVSETVLIPass
FunctionPass * createRISCVCleanupVSETVLIPass()
Returns an instance of the Cleanup VSETVLI pass.
Definition: RISCVCleanupVSETVLI.cpp:161
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:534
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:488
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:166
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::Register::isVirtual
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
MachineFunctionPass.h
llvm::RISCVSubtarget
Definition: RISCVSubtarget.h:35
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:357
PrevOutVL
Register PrevOutVL
Definition: RISCVCleanupVSETVLI.cpp:78
RISCV.h
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:478
PrevVSETVLI
MachineInstr * PrevVSETVLI
Definition: RISCVCleanupVSETVLI.cpp:55
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
PrevVTYPEImm
int64_t PrevVTYPEImm
Definition: RISCVCleanupVSETVLI.cpp:62
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:521
VTYPEImm
int64_t VTYPEImm
Definition: RISCVCleanupVSETVLI.cpp:63
assert
assert(MI.getOpcode()==RISCV::PseudoVSETVLI)
RISCVSubtarget.h
AVLReg
Register AVLReg
Definition: RISCVCleanupVSETVLI.cpp:77
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
RISCV_CLEANUP_VSETVLI_NAME
#define RISCV_CLEANUP_VSETVLI_NAME
Definition: RISCVCleanupVSETVLI.cpp:20
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38