diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -34,11 +34,10 @@ RISCVMacroFusion.cpp RISCVMCInstLower.cpp RISCVMergeBaseOffset.cpp + RISCVOptWInstrs.cpp RISCVRedundantCopyElimination.cpp RISCVRegisterInfo.cpp RISCVRVVInitUndef.cpp - RISCVSExtWRemoval.cpp - RISCVStripWSuffix.cpp RISCVSubtarget.cpp RISCVTargetMachine.cpp RISCVTargetObjectFile.cpp diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -47,11 +47,8 @@ FunctionPass *createRISCVGatherScatterLoweringPass(); void initializeRISCVGatherScatterLoweringPass(PassRegistry &); -FunctionPass *createRISCVSExtWRemovalPass(); -void initializeRISCVSExtWRemovalPass(PassRegistry &); - -FunctionPass *createRISCVStripWSuffixPass(); -void initializeRISCVStripWSuffixPass(PassRegistry &); +FunctionPass *createRISCVOptWInstrsPass(); +void initializeRISCVOptWInstrsPass(PassRegistry &); FunctionPass *createRISCVMergeBaseOffsetOptPass(); void initializeRISCVMergeBaseOffsetOptPass(PassRegistry &); diff --git a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp rename from llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp rename to llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp --- a/llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp +++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp @@ -1,4 +1,4 @@ -//===-------------- RISCVSExtWRemoval.cpp - MI sext.w Removal -------------===// +//===- RISCVOptWInstrs.cpp - MI W instruction optimizations ---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,9 +6,16 @@ // //===---------------------------------------------------------------------===// // -// This pass removes unneeded sext.w instructions at the MI level. Either -// because the sign extended bits aren't consumed or because the input was -// already sign extended by an earlier instruction. +// This pass does some optimizations for *W instructions at the MI level. +// +// First it removes unneeded sext.w instructions. Either because the sign +// extended bits aren't consumed or because the input was already sign extended +// by an earlier instruction. +// +// Then it removes the -w suffix from each addiw and slliw instructions +// whenever all users are dependent only on the lower word of the result of the +// instruction. We do this only for addiw, slliw, and mulw because the -w forms +// are less compressible. // //===---------------------------------------------------------------------===// @@ -21,7 +28,8 @@ using namespace llvm; -#define DEBUG_TYPE "riscv-sextw-removal" +#define DEBUG_TYPE "riscv-opt-w-instrs" +#define RISCV_OPT_W_INSTRS_NAME "RISC-V Optimize W Instructions" STATISTIC(NumRemovedSExtW, "Number of removed sign-extensions"); STATISTIC(NumTransformedToWInstrs, @@ -30,34 +38,42 @@ static cl::opt DisableSExtWRemoval("riscv-disable-sextw-removal", cl::desc("Disable removal of sext.w"), cl::init(false), cl::Hidden); +static cl::opt DisableStripWSuffix("riscv-disable-strip-w-suffix", + cl::desc("Disable strip W suffix"), + cl::init(false), cl::Hidden); + namespace { -class RISCVSExtWRemoval : public MachineFunctionPass { +class RISCVOptWInstrs : public MachineFunctionPass { public: static char ID; - RISCVSExtWRemoval() : MachineFunctionPass(ID) { - initializeRISCVSExtWRemovalPass(*PassRegistry::getPassRegistry()); + RISCVOptWInstrs() : MachineFunctionPass(ID) { + initializeRISCVOptWInstrsPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; + bool removeSExtWInstrs(MachineFunction &MF, const RISCVInstrInfo &TII, + MachineRegisterInfo &MRI); + bool stripWSuffixes(MachineFunction &MF, const RISCVInstrInfo &TII, + MachineRegisterInfo &MRI); void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); } - StringRef getPassName() const override { return "RISC-V sext.w Removal"; } + StringRef getPassName() const override { return RISCV_OPT_W_INSTRS_NAME; } }; } // end anonymous namespace -char RISCVSExtWRemoval::ID = 0; -INITIALIZE_PASS(RISCVSExtWRemoval, DEBUG_TYPE, "RISC-V sext.w Removal", false, +char RISCVOptWInstrs::ID = 0; +INITIALIZE_PASS(RISCVOptWInstrs, DEBUG_TYPE, RISCV_OPT_W_INSTRS_NAME, false, false) -FunctionPass *llvm::createRISCVSExtWRemovalPass() { - return new RISCVSExtWRemoval(); +FunctionPass *llvm::createRISCVOptWInstrsPass() { + return new RISCVOptWInstrs(); } // This function returns true if the machine instruction always outputs a value @@ -317,19 +333,13 @@ } } -bool RISCVSExtWRemoval::runOnMachineFunction(MachineFunction &MF) { - if (skipFunction(MF.getFunction()) || DisableSExtWRemoval) - return false; - - MachineRegisterInfo &MRI = MF.getRegInfo(); - const RISCVSubtarget &ST = MF.getSubtarget(); - const RISCVInstrInfo &TII = *ST.getInstrInfo(); - - if (!ST.is64Bit()) +bool RISCVOptWInstrs::removeSExtWInstrs(MachineFunction &MF, + const RISCVInstrInfo &TII, + MachineRegisterInfo &MRI) { + if (DisableSExtWRemoval) return false; bool MadeChange = false; - for (MachineBasicBlock &MBB : MF) { for (auto I = MBB.begin(), IE = MBB.end(); I != IE;) { MachineInstr *MI = &*I++; @@ -375,3 +385,51 @@ return MadeChange; } + +bool RISCVOptWInstrs::stripWSuffixes(MachineFunction &MF, + const RISCVInstrInfo &TII, + MachineRegisterInfo &MRI) { + if (DisableStripWSuffix) + return false; + + bool MadeChange = false; + for (MachineBasicBlock &MBB : MF) { + for (auto I = MBB.begin(), IE = MBB.end(); I != IE; ++I) { + MachineInstr &MI = *I; + + unsigned Opc; + switch (MI.getOpcode()) { + default: + continue; + case RISCV::ADDW: Opc = RISCV::ADD; break; + case RISCV::MULW: Opc = RISCV::MUL; break; + case RISCV::SLLIW: Opc = RISCV::SLLI; break; + } + + if (TII.hasAllWUsers(MI, MRI)) { + MI.setDesc(TII.get(Opc)); + MadeChange = true; + } + } + } + + return MadeChange; +} + +bool RISCVOptWInstrs::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(MF.getFunction())) + return false; + + MachineRegisterInfo &MRI = MF.getRegInfo(); + const RISCVSubtarget &ST = MF.getSubtarget(); + const RISCVInstrInfo &TII = *ST.getInstrInfo(); + + if (!ST.is64Bit()) + return false; + + bool MadeChange = false; + MadeChange |= removeSExtWInstrs(MF, TII, MRI); + MadeChange |= stripWSuffixes(MF, TII, MRI); + + return MadeChange; +} diff --git a/llvm/lib/Target/RISCV/RISCVStripWSuffix.cpp b/llvm/lib/Target/RISCV/RISCVStripWSuffix.cpp deleted file mode 100644 --- a/llvm/lib/Target/RISCV/RISCVStripWSuffix.cpp +++ /dev/null @@ -1,89 +0,0 @@ -//===-------------- RISCVStripWSuffix.cpp - -w Suffix Removal -------------===// -// -// -// 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 pass removes the -w suffix from each addiw and slliw instructions -// whenever all users are dependent only on the lower word of the result of the -// instruction. We do this only for addiw and slliw because the -w forms are -// less compressible. -// -//===---------------------------------------------------------------------===// - -#include "RISCV.h" -#include "RISCVMachineFunctionInfo.h" - -using namespace llvm; - -static cl::opt DisableStripWSuffix("riscv-disable-strip-w-suffix", - cl::desc("Disable strip W suffix"), - cl::init(false), cl::Hidden); - -namespace { - -class RISCVStripWSuffix : public MachineFunctionPass { -public: - static char ID; - - RISCVStripWSuffix() : MachineFunctionPass(ID) { - initializeRISCVStripWSuffixPass(*PassRegistry::getPassRegistry()); - } - - bool runOnMachineFunction(MachineFunction &MF) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - StringRef getPassName() const override { return "RISC-V Strip W Suffix"; } -}; - -} // end anonymous namespace - -char RISCVStripWSuffix::ID = 0; -INITIALIZE_PASS(RISCVStripWSuffix, "riscv-strip-w-suffix", - "RISC-V Strip W Suffix", false, false) - -FunctionPass *llvm::createRISCVStripWSuffixPass() { - return new RISCVStripWSuffix(); -} - -bool RISCVStripWSuffix::runOnMachineFunction(MachineFunction &MF) { - if (skipFunction(MF.getFunction()) || DisableStripWSuffix) - return false; - - MachineRegisterInfo &MRI = MF.getRegInfo(); - const RISCVSubtarget &ST = MF.getSubtarget(); - const RISCVInstrInfo &TII = *ST.getInstrInfo(); - - if (!ST.is64Bit()) - return false; - - bool MadeChange = false; - for (MachineBasicBlock &MBB : MF) { - for (auto I = MBB.begin(), IE = MBB.end(); I != IE; ++I) { - MachineInstr &MI = *I; - - unsigned Opc; - switch (MI.getOpcode()) { - default: - continue; - case RISCV::ADDW: Opc = RISCV::ADD; break; - case RISCV::MULW: Opc = RISCV::MUL; break; - case RISCV::SLLIW: Opc = RISCV::SLLI; break; - } - - if (TII.hasAllWUsers(MI, MRI)) { - MI.setDesc(TII.get(Opc)); - MadeChange = true; - } - } - } - - return MadeChange; -} diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -80,8 +80,7 @@ initializeRISCVGatherScatterLoweringPass(*PR); initializeRISCVCodeGenPreparePass(*PR); initializeRISCVMergeBaseOffsetOptPass(*PR); - initializeRISCVSExtWRemovalPass(*PR); - initializeRISCVStripWSuffixPass(*PR); + initializeRISCVOptWInstrsPass(*PR); initializeRISCVPreRAExpandPseudoPass(*PR); initializeRISCVExpandPseudoPass(*PR); initializeRISCVInsertVSETVLIPass(*PR); @@ -362,8 +361,7 @@ addPass(&MachineCombinerID); if (TM->getTargetTriple().getArch() == Triple::riscv64) { - addPass(createRISCVSExtWRemovalPass()); - addPass(createRISCVStripWSuffixPass()); + addPass(createRISCVOptWInstrsPass()); } } diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -103,8 +103,7 @@ ; CHECK-NEXT: Machine Trace Metrics ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine InstCombiner -; RV64-NEXT: RISC-V sext.w Removal -; RV64-NEXT: RISC-V Strip W Suffix +; RV64-NEXT: RISC-V Optimize W Instructions ; CHECK-NEXT: RISC-V Pre-RA pseudo instruction expansion pass ; CHECK-NEXT: RISC-V Merge Base Offset ; CHECK-NEXT: RISC-V Insert VSETVLI pass