LLVM 19.0.0git
MachineConvergenceVerifier.cpp
Go to the documentation of this file.
1//===- MachineConvergenceVerifier.cpp - Verify convergencectrl ------------===//
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
16
17using namespace llvm;
18
19template <>
21 const MachineInstr &MI) -> ConvOpKind {
22 switch (MI.getOpcode()) {
23 default:
24 return CONV_NONE;
25 case TargetOpcode::CONVERGENCECTRL_ENTRY:
26 return CONV_ENTRY;
27 case TargetOpcode::CONVERGENCECTRL_ANCHOR:
28 return CONV_ANCHOR;
29 case TargetOpcode::CONVERGENCECTRL_LOOP:
30 return CONV_LOOP;
31 }
32}
33
34template <>
36 MachineSSAContext>::checkConvergenceTokenProduced(const MachineInstr &MI) {
37 Check(!MI.hasImplicitDef(),
38 "Convergence control tokens are defined explicitly.",
39 {Context.print(&MI)});
40 const MachineOperand &Def = MI.getOperand(0);
41 const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo();
42 Check(MRI.getUniqueVRegDef(Def.getReg()),
43 "Convergence control tokens must have unique definitions.",
44 {Context.print(&MI)});
45}
46
47template <>
48const MachineInstr *
50 const MachineInstr &MI) {
51 const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo();
52 const MachineInstr *TokenDef = nullptr;
53
54 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
55 const MachineOperand &MO = MI.getOperand(I);
56 if (!MO.isReg() || !MO.isUse())
57 continue;
58 Register OpReg = MO.getReg();
59 if (!OpReg.isVirtual())
60 continue;
61
62 const MachineInstr *Def = MRI.getUniqueVRegDef(OpReg);
63 if (!Def)
64 continue;
65 if (getConvOp(*Def) == CONV_NONE)
66 continue;
67
69 MI.isConvergent(),
70 "Convergence control tokens can only be used by convergent operations.",
71 {Context.print(OpReg), Context.print(&MI)});
72
73 CheckOrNull(!TokenDef,
74 "An operation can use at most one convergence control token.",
75 {Context.print(OpReg), Context.print(&MI)});
76
77 TokenDef = Def;
78 }
79
80 if (TokenDef)
81 Tokens[&MI] = TokenDef;
82
83 return TokenDef;
84}
85
86template <>
88 const MachineInstr &MI) {
89 // The class MachineFunction does not have any property to indicate whether it
90 // is convergent. Trivially return true so that the check always passes.
91 return true;
92}
93
94template <>
96 const MachineInstr &MI) {
97 return MI.isConvergent();
98}
99
unsigned const MachineRegisterInfo * MRI
A verifier for the static rules of convergence control tokens that works with both LLVM IR and MIR.
#define Check(C,...)
#define CheckOrNull(C,...)
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MIR specialization of the GenericConvergenceVerifier template.
This file declares a specialization of the GenericSSAContext<X> template class for Machine IR.
LLVMContext & Context
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18