LLVM 20.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
15
16using namespace llvm;
17
18template <>
20 const MachineInstr &MI) -> ConvOpKind {
21 switch (MI.getOpcode()) {
22 default:
23 return CONV_NONE;
24 case TargetOpcode::CONVERGENCECTRL_ENTRY:
25 return CONV_ENTRY;
26 case TargetOpcode::CONVERGENCECTRL_ANCHOR:
27 return CONV_ANCHOR;
28 case TargetOpcode::CONVERGENCECTRL_LOOP:
29 return CONV_LOOP;
30 }
31}
32
33template <>
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)});
44}
45
46template <>
47const MachineInstr *
49 const MachineInstr &MI) {
50 const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo();
51 const MachineInstr *TokenDef = nullptr;
52
53 for (const MachineOperand &MO : MI.operands()) {
54 if (!MO.isReg() || !MO.isUse())
55 continue;
56 Register OpReg = MO.getReg();
57 if (!OpReg.isVirtual())
58 continue;
59
60 const MachineInstr *Def = MRI.getUniqueVRegDef(OpReg);
61 if (!Def)
62 continue;
63 if (getConvOp(*Def) == CONV_NONE)
64 continue;
65
67 MI.isConvergent(),
68 "Convergence control tokens can only be used by convergent operations.",
69 {Context.print(OpReg), Context.print(&MI)});
70
71 CheckOrNull(!TokenDef,
72 "An operation can use at most one convergence control token.",
73 {Context.print(OpReg), Context.print(&MI)});
74
75 TokenDef = Def;
76 }
77
78 if (TokenDef)
79 Tokens[&MI] = TokenDef;
80
81 return TokenDef;
82}
83
84template <>
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.
89 return true;
90}
91
92template <>
94 const MachineInstr &MI) {
95 return MI.isConvergent();
96}
97
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,...)
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