1 //===- MachineConvergenceVerifier.cpp - Verify convergencectrl ------------===//
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
7 //===----------------------------------------------------------------------===//
8 //===----------------------------------------------------------------------===//
10 #include "llvm/CodeGen/MachineConvergenceVerifier.h"
11 #include "llvm/CodeGen/MachineDominators.h"
12 #include "llvm/CodeGen/MachineRegisterInfo.h"
13 #include "llvm/CodeGen/MachineSSAContext.h"
14 #include "llvm/IR/GenericConvergenceVerifierImpl.h"
19 auto GenericConvergenceVerifier
<MachineSSAContext
>::getConvOp(
20 const MachineInstr
&MI
) -> ConvOpKind
{
21 switch (MI
.getOpcode()) {
24 case TargetOpcode::CONVERGENCECTRL_ENTRY
:
26 case TargetOpcode::CONVERGENCECTRL_ANCHOR
:
28 case TargetOpcode::CONVERGENCECTRL_LOOP
:
34 void GenericConvergenceVerifier
<
35 MachineSSAContext
>::checkConvergenceTokenProduced(const MachineInstr
&MI
) {
36 Check(!MI
.hasImplicitDef(),
37 "Convergence control tokens are defined explicitly.",
38 {Context
.print(&MI
)});
39 const MachineOperand
&Def
= MI
.getOperand(0);
40 const MachineRegisterInfo
&MRI
= Context
.getFunction()->getRegInfo();
41 Check(MRI
.getUniqueVRegDef(Def
.getReg()),
42 "Convergence control tokens must have unique definitions.",
43 {Context
.print(&MI
)});
48 GenericConvergenceVerifier
<MachineSSAContext
>::findAndCheckConvergenceTokenUsed(
49 const MachineInstr
&MI
) {
50 const MachineRegisterInfo
&MRI
= Context
.getFunction()->getRegInfo();
51 const MachineInstr
*TokenDef
= nullptr;
53 for (const MachineOperand
&MO
: MI
.operands()) {
54 if (!MO
.isReg() || !MO
.isUse())
56 Register OpReg
= MO
.getReg();
57 if (!OpReg
.isVirtual())
60 const MachineInstr
*Def
= MRI
.getUniqueVRegDef(OpReg
);
63 if (getConvOp(*Def
) == CONV_NONE
)
68 "Convergence control tokens can only be used by convergent operations.",
69 {Context
.print(OpReg
), Context
.print(&MI
)});
71 CheckOrNull(!TokenDef
,
72 "An operation can use at most one convergence control token.",
73 {Context
.print(OpReg
), Context
.print(&MI
)});
79 Tokens
[&MI
] = TokenDef
;
85 bool GenericConvergenceVerifier
<MachineSSAContext
>::isInsideConvergentFunction(
86 const MachineInstr
&MI
) {
87 // The class MachineFunction does not have any property to indicate whether it
88 // is convergent. Trivially return true so that the check always passes.
93 bool GenericConvergenceVerifier
<MachineSSAContext
>::isConvergent(
94 const MachineInstr
&MI
) {
95 return MI
.isConvergent();
98 template class llvm::GenericConvergenceVerifier
<MachineSSAContext
>;