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 10 #include "llvm/CodeGen/MachineConvergenceVerifier.h" 11 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" 12 #include "llvm/CodeGen/MachineDominators.h" 13 #include "llvm/CodeGen/MachineRegisterInfo.h" 14 #include "llvm/CodeGen/MachineSSAContext.h" 15 #include "llvm/IR/GenericConvergenceVerifierImpl.h" 16 17 using namespace llvm; 18 19 template <> 20 auto GenericConvergenceVerifier<MachineSSAContext>::getConvOp( 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 34 template <> 35 void GenericConvergenceVerifier< 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 47 template <> 48 const MachineInstr * 49 GenericConvergenceVerifier<MachineSSAContext>::findAndCheckConvergenceTokenUsed( 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 67 CheckOrNull( 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 85 template <> 86 bool GenericConvergenceVerifier<MachineSSAContext>::isInsideConvergentFunction( 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 93 template <> 94 bool GenericConvergenceVerifier<MachineSSAContext>::isConvergent( 95 const MachineInstr &MI) { 96 return MI.isConvergent(); 97 } 98 99 template class llvm::GenericConvergenceVerifier<MachineSSAContext>; 100