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