Skip to content

Commit 327d658

Browse files
committed
[RISCV] Set a barrier between mask producer and user of V0
Here we add a scheduling mutation in pre-ra scheduling, which will adds an artificial dependency edge between mask producer and its previous nearest instruction that uses V0 register. This prevents making live intervals of mask registers longer and as a consequence we can reduce some spills/moves. From the test changes, we can see some improvements and also some regressions (more vtype toggles). Partially fixes #113489.
1 parent a1d31ca commit 327d658

33 files changed

+2470
-2562
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ add_llvm_target(RISCVCodeGen
5858
RISCVTargetMachine.cpp
5959
RISCVTargetObjectFile.cpp
6060
RISCVTargetTransformInfo.cpp
61+
RISCVVectorMaskDAGMutation.cpp
6162
RISCVVectorPeephole.cpp
6263
RISCVVLOptimizer.cpp
6364
RISCVZacasABIFix.cpp

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,12 @@ class RISCVPassConfig : public TargetPassConfig {
360360
DAG->addMutation(createStoreClusterDAGMutation(
361361
DAG->TII, DAG->TRI, /*ReorderWhileClustering=*/true));
362362
}
363+
364+
const RISCVSubtarget &ST = C->MF->getSubtarget<RISCVSubtarget>();
365+
if (ST.hasVInstructions()) {
366+
DAG = DAG ? DAG : createGenericSchedLive(C);
367+
DAG->addMutation(createRISCVVectorMaskDAGMutation(DAG->TRI));
368+
}
363369
return DAG;
364370
}
365371

llvm/lib/Target/RISCV/RISCVTargetMachine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class RISCVTargetMachine : public LLVMTargetMachine {
6161
SMRange &SourceRange) const override;
6262
void registerPassBuilderCallbacks(PassBuilder &PB) override;
6363
};
64+
65+
std::unique_ptr<ScheduleDAGMutation>
66+
createRISCVVectorMaskDAGMutation(const TargetRegisterInfo *TRI);
67+
6468
} // namespace llvm
6569

6670
#endif
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//===- RISCVVectorMaskDAGMutation.cpp - RISCV Vector Mask DAGMutation -----===//
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+
// A schedule mutation that add a dependency between masks producing
10+
// instructions and masked instructions, so that we will not extend the live
11+
// interval of mask register.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "MCTargetDesc/RISCVMCTargetDesc.h"
16+
#include "RISCVTargetMachine.h"
17+
#include "llvm/CodeGen/MachineInstr.h"
18+
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
19+
#include "llvm/CodeGen/ScheduleDAGMutation.h"
20+
21+
#define DEBUG_TYPE "machine-scheduler"
22+
23+
namespace llvm {
24+
25+
static inline bool isVectorMaskProducer(const MachineInstr *MI) {
26+
switch (RISCV::getRVVMCOpcode(MI->getOpcode())) {
27+
// Vector Mask Instructions
28+
case RISCV::VMAND_MM:
29+
case RISCV::VMNAND_MM:
30+
case RISCV::VMANDN_MM:
31+
case RISCV::VMXOR_MM:
32+
case RISCV::VMOR_MM:
33+
case RISCV::VMNOR_MM:
34+
case RISCV::VMORN_MM:
35+
case RISCV::VMXNOR_MM:
36+
case RISCV::VMSBF_M:
37+
case RISCV::VMSIF_M:
38+
case RISCV::VMSOF_M:
39+
case RISCV::VIOTA_M:
40+
// Vector Integer Compare Instructions
41+
case RISCV::VMSEQ_VV:
42+
case RISCV::VMSEQ_VX:
43+
case RISCV::VMSEQ_VI:
44+
case RISCV::VMSNE_VV:
45+
case RISCV::VMSNE_VX:
46+
case RISCV::VMSNE_VI:
47+
case RISCV::VMSLT_VV:
48+
case RISCV::VMSLT_VX:
49+
case RISCV::VMSLTU_VV:
50+
case RISCV::VMSLTU_VX:
51+
case RISCV::VMSLE_VV:
52+
case RISCV::VMSLE_VX:
53+
case RISCV::VMSLE_VI:
54+
case RISCV::VMSLEU_VV:
55+
case RISCV::VMSLEU_VX:
56+
case RISCV::VMSLEU_VI:
57+
case RISCV::VMSGTU_VX:
58+
case RISCV::VMSGTU_VI:
59+
case RISCV::VMSGT_VX:
60+
case RISCV::VMSGT_VI:
61+
// Vector Floating-Point Compare Instructions
62+
case RISCV::VMFEQ_VV:
63+
case RISCV::VMFEQ_VF:
64+
case RISCV::VMFNE_VV:
65+
case RISCV::VMFNE_VF:
66+
case RISCV::VMFLT_VV:
67+
case RISCV::VMFLT_VF:
68+
case RISCV::VMFLE_VV:
69+
case RISCV::VMFLE_VF:
70+
case RISCV::VMFGT_VF:
71+
case RISCV::VMFGE_VF:
72+
return true;
73+
}
74+
return false;
75+
}
76+
77+
class RISCVVectorMaskDAGMutation : public ScheduleDAGMutation {
78+
private:
79+
const TargetRegisterInfo *TRI;
80+
81+
public:
82+
RISCVVectorMaskDAGMutation(const TargetRegisterInfo *TRI) : TRI(TRI) {}
83+
84+
void apply(ScheduleDAGInstrs *DAG) override {
85+
SUnit *NearestUseV0SU = nullptr;
86+
for (SUnit &SU : DAG->SUnits) {
87+
const MachineInstr *MI = SU.getInstr();
88+
if (MI->findRegisterUseOperand(RISCV::V0, TRI))
89+
NearestUseV0SU = &SU;
90+
91+
if (NearestUseV0SU && NearestUseV0SU != &SU && isVectorMaskProducer(MI))
92+
DAG->addEdge(&SU, SDep(NearestUseV0SU, SDep::Artificial));
93+
}
94+
}
95+
};
96+
97+
std::unique_ptr<ScheduleDAGMutation>
98+
createRISCVVectorMaskDAGMutation(const TargetRegisterInfo *TRI) {
99+
return std::make_unique<RISCVVectorMaskDAGMutation>(TRI);
100+
}
101+
102+
} // namespace llvm

llvm/test/CodeGen/RISCV/rvv/constant-folding-crash.ll

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,18 @@ define void @constant_folding_crash(ptr %v54, <4 x ptr> %lanes.a, <4 x ptr> %lan
1919
; RV32-LABEL: constant_folding_crash:
2020
; RV32: # %bb.0: # %entry
2121
; RV32-NEXT: lw a0, 8(a0)
22+
; RV32-NEXT: vmv1r.v v10, v0
2223
; RV32-NEXT: andi a0, a0, 1
2324
; RV32-NEXT: seqz a0, a0
2425
; RV32-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
25-
; RV32-NEXT: vmv.v.x v10, a0
26-
; RV32-NEXT: vmsne.vi v10, v10, 0
27-
; RV32-NEXT: vmv1r.v v11, v0
28-
; RV32-NEXT: vmv1r.v v0, v10
26+
; RV32-NEXT: vmv.v.x v11, a0
27+
; RV32-NEXT: vmsne.vi v0, v11, 0
2928
; RV32-NEXT: vsetvli zero, zero, e32, m1, ta, ma
3029
; RV32-NEXT: vmerge.vvm v8, v9, v8, v0
3130
; RV32-NEXT: vmv.x.s a0, v8
3231
; RV32-NEXT: vsetvli zero, zero, e8, mf4, ta, ma
3332
; RV32-NEXT: vmv.v.i v8, 0
34-
; RV32-NEXT: vmv1r.v v0, v11
33+
; RV32-NEXT: vmv1r.v v0, v10
3534
; RV32-NEXT: vmerge.vim v8, v8, 1, v0
3635
; RV32-NEXT: vrgather.vi v9, v8, 0
3736
; RV32-NEXT: vmsne.vi v0, v9, 0
@@ -43,19 +42,18 @@ define void @constant_folding_crash(ptr %v54, <4 x ptr> %lanes.a, <4 x ptr> %lan
4342
; RV64-LABEL: constant_folding_crash:
4443
; RV64: # %bb.0: # %entry
4544
; RV64-NEXT: ld a0, 8(a0)
45+
; RV64-NEXT: vmv1r.v v12, v0
4646
; RV64-NEXT: andi a0, a0, 1
4747
; RV64-NEXT: seqz a0, a0
4848
; RV64-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
49-
; RV64-NEXT: vmv.v.x v12, a0
50-
; RV64-NEXT: vmsne.vi v12, v12, 0
51-
; RV64-NEXT: vmv1r.v v13, v0
52-
; RV64-NEXT: vmv1r.v v0, v12
49+
; RV64-NEXT: vmv.v.x v13, a0
50+
; RV64-NEXT: vmsne.vi v0, v13, 0
5351
; RV64-NEXT: vsetvli zero, zero, e64, m2, ta, ma
5452
; RV64-NEXT: vmerge.vvm v8, v10, v8, v0
5553
; RV64-NEXT: vmv.x.s a0, v8
5654
; RV64-NEXT: vsetvli zero, zero, e8, mf4, ta, ma
5755
; RV64-NEXT: vmv.v.i v8, 0
58-
; RV64-NEXT: vmv1r.v v0, v13
56+
; RV64-NEXT: vmv1r.v v0, v12
5957
; RV64-NEXT: vmerge.vim v8, v8, 1, v0
6058
; RV64-NEXT: vrgather.vi v9, v8, 0
6159
; RV64-NEXT: vmsne.vi v0, v9, 0

0 commit comments

Comments
 (0)