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