Teach PeepholeOpt to eliminate redundant copy from constant physreg (e.g VLENB on...
authorPhilip Reames <preames@rivosinc.com>
Mon, 16 May 2022 23:27:39 +0000 (16:27 -0700)
committerPhilip Reames <preames@rivosinc.com>
Mon, 16 May 2022 23:38:30 +0000 (16:38 -0700)
The existing redundant copy elimination required a virtual register source, but the same logic works for any physreg where we don't have to worry about clobbers.  On RISCV, this helps eliminate redundant CSR reads from VLENB.

Differential Revision: https://reviews.llvm.org/D125564

llvm/lib/CodeGen/PeepholeOptimizer.cpp
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
llvm/test/CodeGen/RISCV/vlenb.ll

index 1b04748..31e37c4 100644 (file)
@@ -213,8 +213,9 @@ namespace {
                               const SmallSet<Register, 2> &TargetReg,
                               RecurrenceCycle &RC);
 
-    /// If copy instruction \p MI is a virtual register copy, track it in
-    /// the set \p CopyMIs. If this virtual register was previously seen as a
+    /// If copy instruction \p MI is a virtual register copy or a copy of a
+    /// constant physical register to a virtual register, track it in the
+    /// set \p CopyMIs. If this virtual register was previously seen as a
     /// copy, replace the uses of this copy with the previously seen copy's
     /// destination register.
     bool foldRedundantCopy(MachineInstr &MI,
@@ -1411,7 +1412,7 @@ bool PeepholeOptimizer::foldRedundantCopy(
 
   Register SrcReg = MI.getOperand(1).getReg();
   unsigned SrcSubReg = MI.getOperand(1).getSubReg();
-  if (!SrcReg.isVirtual())
+  if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
     return false;
 
   Register DstReg = MI.getOperand(0).getReg();
@@ -1642,8 +1643,8 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
     // without any intervening re-definition of $physreg.
     DenseMap<Register, MachineInstr *> NAPhysToVirtMIs;
 
-    // Set of pairs of virtual registers and their subregs that are copied
-    // from.
+    // Set of copies to virtual registers keyed by source register.  Never
+    // holds any physreg which requires def tracking.
     DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
 
     bool IsLoopHeader = MLI->isLoopHeader(&MBB);
index bcbaf5b..eb32332 100644 (file)
@@ -118,7 +118,7 @@ bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF,
 }
 
 bool RISCVRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
-  return PhysReg == RISCV::X0;
+  return PhysReg == RISCV::X0 || PhysReg == RISCV::VLENB;
 }
 
 const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const {
index b53d02a..6ce7f53 100644 (file)
@@ -16,8 +16,7 @@ define i32 @simple_cse() {
 ; CHECK-LABEL: simple_cse:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    csrr a0, vlenb
-; CHECK-NEXT:    csrr a1, vlenb
-; CHECK-NEXT:    sub a0, a0, a1
+; CHECK-NEXT:    sub a0, a0, a0
 ; CHECK-NEXT:    ret
 entry:
   %v1 = call i32 @llvm.read_register.i32(metadata !0)