1 //===-------------- RISCVStripWSuffix.cpp - -w Suffix Removal -------------===//
2 //
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===---------------------------------------------------------------------===//
9 //
10 // This pass removes the -w suffix from each addiw and slliw instructions
11 // whenever all users are dependent only on the lower word of the result of the
12 // instruction. We do this only for addiw and slliw because the -w forms are
13 // less compressible.
14 //
15 //===---------------------------------------------------------------------===//
16
17 #include "RISCV.h"
18 #include "RISCVMachineFunctionInfo.h"
19
20 using namespace llvm;
21
22 static cl::opt<bool> DisableStripWSuffix("riscv-disable-strip-w-suffix",
23 cl::desc("Disable strip W suffix"),
24 cl::init(false), cl::Hidden);
25
26 namespace {
27
28 class RISCVStripWSuffix : public MachineFunctionPass {
29 public:
30 static char ID;
31
RISCVStripWSuffix()32 RISCVStripWSuffix() : MachineFunctionPass(ID) {
33 initializeRISCVStripWSuffixPass(*PassRegistry::getPassRegistry());
34 }
35
36 bool runOnMachineFunction(MachineFunction &MF) override;
37
getAnalysisUsage(AnalysisUsage & AU) const38 void getAnalysisUsage(AnalysisUsage &AU) const override {
39 AU.setPreservesCFG();
40 MachineFunctionPass::getAnalysisUsage(AU);
41 }
42
getPassName() const43 StringRef getPassName() const override { return "RISCV Strip W Suffix"; }
44 };
45
46 } // end anonymous namespace
47
48 char RISCVStripWSuffix::ID = 0;
49 INITIALIZE_PASS(RISCVStripWSuffix, "riscv-strip-w-suffix",
50 "RISCV Strip W Suffix", false, false)
51
createRISCVStripWSuffixPass()52 FunctionPass *llvm::createRISCVStripWSuffixPass() {
53 return new RISCVStripWSuffix();
54 }
55
runOnMachineFunction(MachineFunction & MF)56 bool RISCVStripWSuffix::runOnMachineFunction(MachineFunction &MF) {
57 if (skipFunction(MF.getFunction()) || DisableStripWSuffix)
58 return false;
59
60 MachineRegisterInfo &MRI = MF.getRegInfo();
61 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
62 const RISCVInstrInfo &TII = *ST.getInstrInfo();
63
64 if (!ST.is64Bit())
65 return false;
66
67 bool MadeChange = false;
68 for (MachineBasicBlock &MBB : MF) {
69 for (auto I = MBB.begin(), IE = MBB.end(); I != IE; ++I) {
70 MachineInstr &MI = *I;
71
72 switch (MI.getOpcode()) {
73 case RISCV::ADDW:
74 case RISCV::SLLIW:
75 if (TII.hasAllWUsers(MI, MRI)) {
76 unsigned Opc =
77 MI.getOpcode() == RISCV::ADDW ? RISCV::ADD : RISCV::SLLI;
78 MI.setDesc(TII.get(Opc));
79 MadeChange = true;
80 }
81 break;
82 }
83 }
84 }
85
86 return MadeChange;
87 }
88