1 //===- ConvergenceVerifier.cpp - Verify convergence control -----*- C++ -*-===// 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 const MachineInstr * 36 GenericConvergenceVerifier<MachineSSAContext>::findAndCheckConvergenceTokenUsed( 37 const MachineInstr &MI) { 38 const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo(); 39 const MachineInstr *TokenDef = nullptr; 40 41 for (const MachineOperand &MO : MI.uses()) { 42 if (!MO.isReg()) 43 continue; 44 Register OpReg = MO.getReg(); 45 if (!OpReg.isVirtual()) 46 continue; 47 48 const MachineInstr *Def = MRI.getVRegDef(OpReg); 49 if (!Def) 50 continue; 51 if (getConvOp(*Def) == CONV_NONE) 52 continue; 53 54 CheckOrNull( 55 MI.isConvergent(), 56 "Convergence control tokens can only be used by convergent operations.", 57 {Context.print(OpReg), Context.print(&MI)}); 58 59 CheckOrNull(!TokenDef, 60 "An operation can use at most one convergence control token.", 61 {Context.print(OpReg), Context.print(&MI)}); 62 63 TokenDef = Def; 64 } 65 66 if (TokenDef) 67 Tokens[&MI] = TokenDef; 68 69 return TokenDef; 70 } 71 72 template <> 73 bool GenericConvergenceVerifier<MachineSSAContext>::isInsideConvergentFunction( 74 const MachineInstr &MI) { 75 // The class MachineFunction does not have any property to indicate whether it 76 // is convergent. Trivially return true so that the check always passes. 77 return true; 78 } 79 80 template <> 81 bool GenericConvergenceVerifier<MachineSSAContext>::isConvergent( 82 const MachineInstr &MI) { 83 return MI.isConvergent(); 84 } 85 86 template class llvm::GenericConvergenceVerifier<MachineSSAContext>; 87