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