Skip to content

Commit

Permalink
[LLVM][XTHeadVector] Add RedundantVSETVLIElimination pass to remove…
Browse files Browse the repository at this point in the history
… unnecessary vtype-preserving sequences (llvm#99)

* [LLVM][XTHeadVector] Initial `RedundantVSETVLIElimination` pass

* [LLVM][XTHeadVector] `RedundantVSETVLIElimination`

This pass removes code sequences like:

```
csrr <r1>, vl
csrr <r2>, vtype
<a lot of th.vsetvl/th.vsetvli>
th.vsetvl zero, <r1>, <r2>
```

* [LLVM][XTHeadVector] Update tests

* [LLVM][XTHeadVector] Update tests

* [LLVM][XTHeadVector] Fix comments

* [LLVM][XTHeadVector] Fix comments

* [LLVM][XTHeadVector] More comments

* [LLVM][XTHeadVector] Update tests

* [LLVM][XTHeadVector] add option `riscv-enable-vsetvli-elim`
  • Loading branch information
imkiva authored Apr 15, 2024
1 parent 63b7539 commit b0d2834
Show file tree
Hide file tree
Showing 153 changed files with 1,825 additions and 76,571 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ add_llvm_target(RISCVCodeGen
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
RISCVRedundantCopyElimination.cpp
RISCVRedundantVSETVLIElimination.cpp
RISCVMoveMerger.cpp
RISCVPushPopOptimizer.cpp
RISCVRegisterInfo.cpp
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ void initializeRISCVInsertReadWriteCSRPass(PassRegistry &);
FunctionPass *createRISCVRedundantCopyEliminationPass();
void initializeRISCVRedundantCopyEliminationPass(PassRegistry &);

FunctionPass *createRISCVRedundantVSETVLIEliminationPass();
void initializeRISCVRedundantVSETVLIEliminationPass(PassRegistry &);

FunctionPass *createRISCVInitUndefPass();
void initializeRISCVInitUndefPass(PassRegistry &);
extern char &RISCVInitUndefID;
Expand Down
189 changes: 189 additions & 0 deletions llvm/lib/Target/RISCV/RISCVRedundantVSETVLIElimination.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
//=- RISCVRedundantVSETVLIElimination.cpp - Remove useless vsetvl for RISC-V =//
//
// 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
//

#include "RISCV.h"
#include "RISCVInstrInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

#define DEBUG_TYPE "riscv-th-vsetvli-elim"

STATISTIC(NumVSETVLIRemoved, "Number of vsetvli removed.");

namespace {
class RISCVRedundantVSETVLIElimination : public MachineFunctionPass {
const MachineRegisterInfo *MRI;
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;

public:
static char ID;
RISCVRedundantVSETVLIElimination() : MachineFunctionPass(ID) {
initializeRISCVRedundantVSETVLIEliminationPass(
*PassRegistry::getPassRegistry());
}

bool runOnMachineFunction(MachineFunction &MF) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
}

StringRef getPassName() const override {
return "RISC-V Redundant VSETVLI Elimination";
}

private:
bool optimizeBlock(MachineBasicBlock &MBB);
};

} // end anonymous namespace

char RISCVRedundantVSETVLIElimination::ID = 0;

INITIALIZE_PASS(RISCVRedundantVSETVLIElimination, "riscv-th-vsetvli-elim",
"RISC-V Redundant VSETVLI Elimination", false, false)

bool RISCVRedundantVSETVLIElimination::optimizeBlock(MachineBasicBlock &MBB) {
// Delete the following backup-action-restore patterns where action is empty.
// ; CHECK-NEXT: csrr a1, vl
// ; CHECK-NEXT: csrr a2, vtype
// ; CHECK-NEXT: <a lot of th.vsetvl/vsetvli>
// ; CHECK-NEXT: th.vsetvl zero, a1, a2

enum State {
OTHER,
BACKUP_VL,
BACKUP_VTYPE,
SEQUENCE,
};

State NowState = OTHER;
MachineBasicBlock::iterator FoundBegin = MBB.end();
Register SavedVL = RISCV::NoRegister;
Register SavedVTYPE = RISCV::NoRegister;

const auto VLEncoding = RISCVSysReg::lookupSysRegByName("VL")->Encoding;
const auto VTYPEEncoding = RISCVSysReg::lookupSysRegByName("VTYPE")->Encoding;

bool Changed = false;

// Remove redundant VTYPE preserving blocks unless it has some side effects.
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E;) {
MachineInstr *MI = &*I;
++I;

// CSRRS saved_vl, VL, x0
if (NowState == OTHER) {
if (MI->getOpcode() == RISCV::CSRRS) {
if (MI->getOperand(1).getImm() == VLEncoding) {
NowState = BACKUP_VL;
SavedVL = MI->getOperand(0).getReg();
FoundBegin = MI;
continue;
}
NowState = OTHER;
}
}

// CSRRS saved_vtype, VTYPE, x0
if (NowState == BACKUP_VL) {
if (MI->getOpcode() == RISCV::CSRRS) {
if (MI->getOperand(1).getImm() == VTYPEEncoding) {
NowState = BACKUP_VTYPE;
SavedVTYPE = MI->getOperand(0).getReg();
continue;
}
NowState = OTHER;
}
}

if (NowState == BACKUP_VTYPE) {
// Ok, the backup is done. We should be changing the VL and VTYPE to
// the desired values. Let's see if we can find the sequence that
// depends on the new VL and VTYPE.
if (MI->getOpcode() == RISCV::TH_VSETVL ||
MI->getOpcode() == RISCV::TH_VSETVLI ||
MI->getOpcode() == RISCV::PseudoTH_VSETVLI ||
MI->getOpcode() == RISCV::PseudoTH_VSETVLIX0) {
NowState = SEQUENCE;
continue;
}
NowState = OTHER;
}

if (NowState == SEQUENCE) {
// Currently, we believe vsetvl and vsetvli do not depend on
// the new VL or VTYPE. Let's see if we can find more vsetvl/vsetvli.
if (MI->getOpcode() == RISCV::TH_VSETVLI ||
MI->getOpcode() == RISCV::PseudoTH_VSETVLI ||
MI->getOpcode() == RISCV::PseudoTH_VSETVLIX0) {
continue;
}

// If this is the restoring instruction?
// See also: RISCVInsertVSETVLI::insertVSETVLIForCOPY
// See also: RISCVISelLowering::emitXWholeLoadStore
if (MI->getOpcode() == RISCV::TH_VSETVL) {
// Check if this is a restore point
if (MI->getOperand(0).getReg() == RISCV::X0 &&
MI->getOperand(1).getReg() == SavedVL &&
MI->getOperand(2).getReg() == SavedVTYPE) {
assert(FoundBegin != MBB.end() &&
"FoundBegin is not set but restore point is found");
// Now erase the sequence from the FoundBegin to MI
while (FoundBegin != MI) {
MachineInstr *ToErase = &*FoundBegin;
++FoundBegin;
ToErase->eraseFromParent();
++NumVSETVLIRemoved;
Changed = true;
}
// Don't forget to erase the restoring vsetvl
MI->eraseFromParent();
++NumVSETVLIRemoved;
// Now try to find more
NowState = OTHER;
}

// If this is not a restore point, wait and see if the next instruction
// is a restore point.
continue;
}

// Oops, VL or VTYPE may affect instructions in this sequence.
// Do not touch anything here!
NowState = OTHER;
}
}

return Changed;
}

bool RISCVRedundantVSETVLIElimination::runOnMachineFunction(
MachineFunction &MF) {
if (skipFunction(MF.getFunction()))
return false;

TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();

bool Changed = false;
for (MachineBasicBlock &MBB : MF)
Changed |= optimizeBlock(MBB);

return Changed;
}

FunctionPass *llvm::createRISCVRedundantVSETVLIEliminationPass() {
return new RISCVRedundantVSETVLIElimination();
}
12 changes: 11 additions & 1 deletion llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ static cl::opt<bool> EnableRedundantCopyElimination(
cl::desc("Enable the redundant copy elimination pass"), cl::init(true),
cl::Hidden);

static cl::opt<bool> EnableRedundantVSEVLIElimination(
"riscv-enable-vsetvli-elim",
cl::desc("Enable the redundant VSETVLI elimination pass"), cl::init(true),
cl::Hidden);

// FIXME: Unify control over GlobalMerge.
static cl::opt<cl::boolOrDefault>
EnableGlobalMerge("riscv-enable-global-merge", cl::Hidden,
Expand Down Expand Up @@ -399,8 +404,13 @@ void RISCVPassConfig::addOptimizedRegAlloc() {
}

void RISCVPassConfig::addPostRegAlloc() {
if (TM->getOptLevel() != CodeGenOpt::None && EnableRedundantCopyElimination)
if (TM->getOptLevel() != CodeGenOpt::None && EnableRedundantCopyElimination) {
addPass(createRISCVRedundantCopyEliminationPass());
}
if (TM->getOptLevel() != CodeGenOpt::None &&
EnableRedundantVSEVLIElimination) {
addPass(createRISCVRedundantVSETVLIEliminationPass());
}
}

yaml::MachineFunctionInfo *
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/RISCV/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
; CHECK-NEXT: Machine Copy Propagation Pass
; CHECK-NEXT: Machine Loop Invariant Code Motion
; CHECK-NEXT: RISC-V Redundant Copy Elimination
; CHECK-NEXT: RISC-V Redundant VSETVLI Elimination
; CHECK-NEXT: Remove Redundant DEBUG_VALUE analysis
; CHECK-NEXT: Fixup Statepoint Caller Saved
; CHECK-NEXT: PostRA Machine Sink
Expand Down
Loading

0 comments on commit b0d2834

Please sign in to comment.