Skip to content

Commit 80a1de2

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
1 parent c1a4456 commit 80a1de2

File tree

192 files changed

+8022
-10527
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

192 files changed

+8022
-10527
lines changed

llvm/lib/Target/RISCV/RISCVFoldMasks.cpp

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ class RISCVFoldMasks : public MachineFunctionPass {
5050
bool convertToUnmasked(MachineInstr &MI) const;
5151
bool convertVMergeToVMv(MachineInstr &MI) const;
5252

53-
bool isAllOnesMask(const MachineInstr *MaskDef) const;
54-
55-
/// Maps uses of V0 to the corresponding def of V0.
56-
DenseMap<const MachineInstr *, const MachineInstr *> V0Defs;
53+
bool isAllOnesMask(const MachineOperand& MaskOp) const;
5754
};
5855

5956
} // namespace
@@ -62,12 +59,22 @@ char RISCVFoldMasks::ID = 0;
6259

6360
INITIALIZE_PASS(RISCVFoldMasks, DEBUG_TYPE, "RISC-V Fold Masks", false, false)
6461

65-
bool RISCVFoldMasks::isAllOnesMask(const MachineInstr *MaskDef) const {
66-
assert(MaskDef && MaskDef->isCopy() &&
67-
MaskDef->getOperand(0).getReg() == RISCV::V0);
62+
bool RISCVFoldMasks::isAllOnesMask(const MachineOperand &MaskOp) const {
63+
if (!MaskOp.isReg())
64+
return false;
65+
66+
Register MaskReg = MaskOp.getReg();
67+
if (!MaskReg.isVirtual())
68+
return false;
69+
70+
MachineInstr *MaskDef = MRI->getVRegDef(MaskReg);
71+
if (!MaskDef || !MaskDef->isCopy())
72+
return false;
73+
6874
Register SrcReg = TRI->lookThruCopyLike(MaskDef->getOperand(1).getReg(), MRI);
6975
if (!SrcReg.isVirtual())
7076
return false;
77+
7178
MaskDef = MRI->getVRegDef(SrcReg);
7279
if (!MaskDef)
7380
return false;
@@ -116,8 +123,8 @@ bool RISCVFoldMasks::convertVMergeToVMv(MachineInstr &MI) const {
116123
TRI->lookThruCopyLike(FalseReg, MRI))
117124
return false;
118125

119-
assert(MI.getOperand(4).isReg() && MI.getOperand(4).getReg() == RISCV::V0);
120-
if (!isAllOnesMask(V0Defs.lookup(&MI)))
126+
// assert(MI.getOperand(4).isReg() && MI.getOperand(4).getReg() == RISCV::V0);
127+
if (!isAllOnesMask(MI.getOperand(4)))
121128
return false;
122129

123130
MI.setDesc(TII->get(NewOpc));
@@ -140,7 +147,9 @@ bool RISCVFoldMasks::convertToUnmasked(MachineInstr &MI) const {
140147
if (!I)
141148
return false;
142149

143-
if (!isAllOnesMask(V0Defs.lookup(&MI)))
150+
// TODO: Increment all MaskOpIdxs in tablegen by num of explicit defs?
151+
unsigned MaskOpIdx = I->MaskOpIdx + MI.getNumExplicitDefs();
152+
if (!isAllOnesMask(MI.getOperand(MaskOpIdx)))
144153
return false;
145154

146155
// There are two classes of pseudos in the table - compares and
@@ -160,9 +169,6 @@ bool RISCVFoldMasks::convertToUnmasked(MachineInstr &MI) const {
160169
(void)HasPolicyOp;
161170

162171
MI.setDesc(MCID);
163-
164-
// TODO: Increment all MaskOpIdxs in tablegen by num of explicit defs?
165-
unsigned MaskOpIdx = I->MaskOpIdx + MI.getNumExplicitDefs();
166172
MI.removeOperand(MaskOpIdx);
167173

168174
// The unmasked pseudo will no longer be constrained to the vrnov0 reg class,
@@ -193,24 +199,6 @@ bool RISCVFoldMasks::runOnMachineFunction(MachineFunction &MF) {
193199

194200
bool Changed = false;
195201

196-
// Masked pseudos coming out of isel will have their mask operand in the form:
197-
//
198-
// $v0:vr = COPY %mask:vr
199-
// %x:vr = Pseudo_MASK %a:vr, %b:br, $v0:vr
200-
//
201-
// Because $v0 isn't in SSA, keep track of its definition at each use so we
202-
// can check mask operands.
203-
for (const MachineBasicBlock &MBB : MF) {
204-
const MachineInstr *CurrentV0Def = nullptr;
205-
for (const MachineInstr &MI : MBB) {
206-
if (MI.readsRegister(RISCV::V0, TRI))
207-
V0Defs[&MI] = CurrentV0Def;
208-
209-
if (MI.definesRegister(RISCV::V0, TRI))
210-
CurrentV0Def = &MI;
211-
}
212-
}
213-
214202
for (MachineBasicBlock &MBB : MF) {
215203
for (MachineInstr &MI : MBB) {
216204
Changed |= convertToUnmasked(MI);

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 15 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ void RISCVDAGToDAGISel::addVectorLoadStoreOperands(
296296
bool IsMasked, bool IsStridedOrIndexed, SmallVectorImpl<SDValue> &Operands,
297297
bool IsLoad, MVT *IndexVT) {
298298
SDValue Chain = Node->getOperand(0);
299-
SDValue Glue;
300299

301300
Operands.push_back(Node->getOperand(CurOp++)); // Base pointer.
302301

@@ -307,11 +306,8 @@ void RISCVDAGToDAGISel::addVectorLoadStoreOperands(
307306
}
308307

309308
if (IsMasked) {
310-
// Mask needs to be copied to V0.
311309
SDValue Mask = Node->getOperand(CurOp++);
312-
Chain = CurDAG->getCopyToReg(Chain, DL, RISCV::V0, Mask, SDValue());
313-
Glue = Chain.getValue(1);
314-
Operands.push_back(CurDAG->getRegister(RISCV::V0, Mask.getValueType()));
310+
Operands.push_back(Mask);
315311
}
316312
SDValue VL;
317313
selectVLOp(Node->getOperand(CurOp++), VL);
@@ -333,8 +329,6 @@ void RISCVDAGToDAGISel::addVectorLoadStoreOperands(
333329
}
334330

335331
Operands.push_back(Chain); // Chain.
336-
if (Glue)
337-
Operands.push_back(Glue);
338332
}
339333

340334
void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, bool IsMasked,
@@ -1670,20 +1664,14 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16701664
return;
16711665
}
16721666

1673-
// Mask needs to be copied to V0.
1674-
SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL,
1675-
RISCV::V0, Mask, SDValue());
1676-
SDValue Glue = Chain.getValue(1);
1677-
SDValue V0 = CurDAG->getRegister(RISCV::V0, VT);
1678-
16791667
// Otherwise use
16801668
// vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
16811669
// The result is mask undisturbed.
16821670
// We use the same instructions to emulate mask agnostic behavior, because
16831671
// the agnostic result can be either undisturbed or all 1.
16841672
SDValue Cmp = SDValue(
16851673
CurDAG->getMachineNode(VMSLTMaskOpcode, DL, VT,
1686-
{MaskedOff, Src1, Src2, V0, VL, SEW, Glue}),
1674+
{MaskedOff, Src1, Src2, Mask, VL, SEW}),
16871675
0);
16881676
// vmxor.mm vd, vd, v0 is used to update active value.
16891677
ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT,
@@ -3426,32 +3414,7 @@ bool RISCVDAGToDAGISel::doPeepholeSExtW(SDNode *N) {
34263414
return false;
34273415
}
34283416

3429-
static bool usesAllOnesMask(SDValue MaskOp, SDValue GlueOp) {
3430-
// Check that we're using V0 as a mask register.
3431-
if (!isa<RegisterSDNode>(MaskOp) ||
3432-
cast<RegisterSDNode>(MaskOp)->getReg() != RISCV::V0)
3433-
return false;
3434-
3435-
// The glued user defines V0.
3436-
const auto *Glued = GlueOp.getNode();
3437-
3438-
if (!Glued || Glued->getOpcode() != ISD::CopyToReg)
3439-
return false;
3440-
3441-
// Check that we're defining V0 as a mask register.
3442-
if (!isa<RegisterSDNode>(Glued->getOperand(1)) ||
3443-
cast<RegisterSDNode>(Glued->getOperand(1))->getReg() != RISCV::V0)
3444-
return false;
3445-
3446-
// Check the instruction defining V0; it needs to be a VMSET pseudo.
3447-
SDValue MaskSetter = Glued->getOperand(2);
3448-
3449-
// Sometimes the VMSET is wrapped in a COPY_TO_REGCLASS, e.g. if the mask came
3450-
// from an extract_subvector or insert_subvector.
3451-
if (MaskSetter->isMachineOpcode() &&
3452-
MaskSetter->getMachineOpcode() == RISCV::COPY_TO_REGCLASS)
3453-
MaskSetter = MaskSetter->getOperand(0);
3454-
3417+
static bool usesAllOnesMask(SDValue MaskOp) {
34553418
const auto IsVMSet = [](unsigned Opc) {
34563419
return Opc == RISCV::PseudoVMSET_M_B1 || Opc == RISCV::PseudoVMSET_M_B16 ||
34573420
Opc == RISCV::PseudoVMSET_M_B2 || Opc == RISCV::PseudoVMSET_M_B32 ||
@@ -3462,14 +3425,13 @@ static bool usesAllOnesMask(SDValue MaskOp, SDValue GlueOp) {
34623425
// TODO: Check that the VMSET is the expected bitwidth? The pseudo has
34633426
// undefined behaviour if it's the wrong bitwidth, so we could choose to
34643427
// assume that it's all-ones? Same applies to its VL.
3465-
return MaskSetter->isMachineOpcode() &&
3466-
IsVMSet(MaskSetter.getMachineOpcode());
3428+
return MaskOp->isMachineOpcode() &&
3429+
IsVMSet(MaskOp.getMachineOpcode());
34673430
}
34683431

34693432
// Return true if we can make sure mask of N is all-ones mask.
34703433
static bool usesAllOnesMask(SDNode *N, unsigned MaskOpIdx) {
3471-
return usesAllOnesMask(N->getOperand(MaskOpIdx),
3472-
N->getOperand(N->getNumOperands() - 1));
3434+
return usesAllOnesMask(N->getOperand(MaskOpIdx));
34733435
}
34743436

34753437
static bool isImplicitDef(SDValue V) {
@@ -3515,10 +3477,10 @@ bool RISCVDAGToDAGISel::doPeepholeMaskedRVV(MachineSDNode *N) {
35153477
Ops.push_back(Op);
35163478
}
35173479

3518-
// Transitively apply any node glued to our new node.
3519-
const auto *Glued = N->getGluedNode();
3520-
if (auto *TGlued = Glued->getGluedNode())
3521-
Ops.push_back(SDValue(TGlued, TGlued->getNumValues() - 1));
3480+
// // Transitively apply any node glued to our new node.
3481+
// const auto *Glued = N->getGluedNode();
3482+
// if (auto *TGlued = Glued->getGluedNode())
3483+
// Ops.push_back(SDValue(TGlued, TGlued->getNumValues() - 1));
35223484

35233485
MachineSDNode *Result =
35243486
CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
@@ -3584,7 +3546,7 @@ static unsigned GetVMSetForLMul(RISCVII::VLMUL LMUL) {
35843546
// The resulting policy is the effective policy the vmerge would have had,
35853547
// i.e. whether or not it's merge operand was implicit-def.
35863548
bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
3587-
SDValue Merge, False, True, VL, Mask, Glue;
3549+
SDValue Merge, False, True, VL, Mask;
35883550
// A vmv.v.v is equivalent to a vmerge with an all-ones mask.
35893551
if (IsVMv(N)) {
35903552
Merge = N->getOperand(0);
@@ -3600,11 +3562,7 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
36003562
True = N->getOperand(2);
36013563
Mask = N->getOperand(3);
36023564
VL = N->getOperand(4);
3603-
// We always have a glue node for the mask at v0.
3604-
Glue = N->getOperand(N->getNumOperands() - 1);
36053565
}
3606-
assert(!Mask || cast<RegisterSDNode>(Mask)->getReg() == RISCV::V0);
3607-
assert(!Glue || Glue.getValueType() == MVT::Glue);
36083566

36093567
// We require that either merge and false are the same, or that merge
36103568
// is undefined.
@@ -3639,7 +3597,7 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
36393597

36403598
// When Mask is not a true mask, this transformation is illegal for some
36413599
// operations whose results are affected by mask, like viota.m.
3642-
if (Info->MaskAffectsResult && Mask && !usesAllOnesMask(Mask, Glue))
3600+
if (Info->MaskAffectsResult && Mask && !usesAllOnesMask(Mask))
36433601
return false;
36443602

36453603
// If True has a merge operand then it needs to be the same as vmerge's False,
@@ -3664,7 +3622,7 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
36643622
return false;
36653623
// FIXME: Support mask agnostic True instruction which would have an
36663624
// undef merge operand.
3667-
if (Mask && !usesAllOnesMask(Mask, Glue))
3625+
if (Mask && !usesAllOnesMask(Mask))
36683626
return false;
36693627
}
36703628

@@ -3691,8 +3649,6 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
36913649
if (Mask)
36923650
LoopWorklist.push_back(Mask.getNode());
36933651
LoopWorklist.push_back(VL.getNode());
3694-
if (Glue)
3695-
LoopWorklist.push_back(Glue.getNode());
36963652
if (SDNode::hasPredecessorHelper(True.getNode(), Visited, LoopWorklist))
36973653
return false;
36983654
}
@@ -3737,25 +3693,16 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
37373693

37383694
// From the preconditions we checked above, we know the mask and thus glue
37393695
// for the result node will be taken from True.
3740-
if (IsMasked) {
3696+
if (IsMasked)
37413697
Mask = True->getOperand(Info->MaskOpIdx);
3742-
Glue = True->getOperand(True->getNumOperands() - 1);
3743-
assert(Glue.getValueType() == MVT::Glue);
3744-
}
37453698
// If we end up using the vmerge mask the vmerge is actually a vmv.v.v, create
37463699
// an all-ones mask to use.
37473700
else if (IsVMv(N)) {
37483701
unsigned TSFlags = TII->get(N->getMachineOpcode()).TSFlags;
37493702
unsigned VMSetOpc = GetVMSetForLMul(RISCVII::getLMul(TSFlags));
37503703
ElementCount EC = N->getValueType(0).getVectorElementCount();
37513704
MVT MaskVT = MVT::getVectorVT(MVT::i1, EC);
3752-
3753-
SDValue AllOnesMask =
3754-
SDValue(CurDAG->getMachineNode(VMSetOpc, DL, MaskVT, VL, SEW), 0);
3755-
SDValue MaskCopy = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL,
3756-
RISCV::V0, AllOnesMask, SDValue());
3757-
Mask = CurDAG->getRegister(RISCV::V0, MaskVT);
3758-
Glue = MaskCopy.getValue(1);
3705+
Mask = SDValue(CurDAG->getMachineNode(VMSetOpc, DL, MaskVT, VL, SEW), 0);
37593706
}
37603707

37613708
unsigned MaskedOpc = Info->MaskedPseudo;
@@ -3806,9 +3753,6 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
38063753
if (HasChainOp)
38073754
Ops.push_back(True.getOperand(TrueChainOpIdx));
38083755

3809-
// Add the glue for the CopyToReg of mask->v0.
3810-
Ops.push_back(Glue);
3811-
38123756
MachineSDNode *Result =
38133757
CurDAG->getMachineNode(MaskedOpc, DL, True->getVTList(), Ops);
38143758
Result->setFlags(True->getFlags());

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
279279

280280
unsigned getUndefInitOpcode(unsigned RegClassID) const override {
281281
switch (RegClassID) {
282+
case RISCV::VMV0RegClassID:
282283
case RISCV::VRRegClassID:
283284
return RISCV::PseudoRVVInitUndefM1;
284285
case RISCV::VRM2RegClassID:

0 commit comments

Comments
 (0)