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 (const MachineOperand &MO : MI.operands()) {
55 if (!MO.isReg() || !MO.isUse())
56 continue;
57 Register OpReg = MO.getReg();
58 if (!OpReg.isVirtual())
59 continue;
60
61 const MachineInstr *Def = MRI.getUniqueVRegDef(OpReg);
62 if (!Def)
63 continue;
64 if (getConvOp(*Def) == CONV_NONE)
65 continue;
66
68 MI.isConvergent(),
69 "Convergence control tokens can only be used by convergent operations.",
70 {Context.print(OpReg), Context.print(&MI)});
71
72 CheckOrNull(!TokenDef,
73 "An operation can use at most one convergence control token.",
74 {Context.print(OpReg), Context.print(&MI)});
75
76 TokenDef = Def;
77 }
78
79 if (TokenDef)
80 Tokens[&MI] = TokenDef;
81
82 return TokenDef;
83}
84
85template <>
87 const MachineInstr &MI) {
88 // The class MachineFunction does not have any property to indicate whether it
89 // is convergent. Trivially return true so that the check always passes.
90 return true;
91}
92
93template <>
95 const MachineInstr &MI) {
96 return MI.isConvergent();
97}
98
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
This file declares the MIR specialization of the GenericConvergenceVerifier template.
This file declares a specialization of the GenericSSAContext<X> template class for Machine IR.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
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