160822637SSameer Sahasrabuddhe //===- MachineConvergenceVerifier.cpp - Verify convergencectrl ------------===// 260822637SSameer Sahasrabuddhe // 360822637SSameer Sahasrabuddhe // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 460822637SSameer Sahasrabuddhe // See https://llvm.org/LICENSE.txt for license information. 560822637SSameer Sahasrabuddhe // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 660822637SSameer Sahasrabuddhe // 760822637SSameer Sahasrabuddhe //===----------------------------------------------------------------------===// 860822637SSameer Sahasrabuddhe //===----------------------------------------------------------------------===// 960822637SSameer Sahasrabuddhe 1060822637SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineConvergenceVerifier.h" 1160822637SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineDominators.h" 1260822637SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineRegisterInfo.h" 1360822637SSameer Sahasrabuddhe #include "llvm/CodeGen/MachineSSAContext.h" 1460822637SSameer Sahasrabuddhe #include "llvm/IR/GenericConvergenceVerifierImpl.h" 1560822637SSameer Sahasrabuddhe 1660822637SSameer Sahasrabuddhe using namespace llvm; 1760822637SSameer Sahasrabuddhe 1860822637SSameer Sahasrabuddhe template <> 1960822637SSameer Sahasrabuddhe auto GenericConvergenceVerifier<MachineSSAContext>::getConvOp( 2060822637SSameer Sahasrabuddhe const MachineInstr &MI) -> ConvOpKind { 2160822637SSameer Sahasrabuddhe switch (MI.getOpcode()) { 2260822637SSameer Sahasrabuddhe default: 2360822637SSameer Sahasrabuddhe return CONV_NONE; 2460822637SSameer Sahasrabuddhe case TargetOpcode::CONVERGENCECTRL_ENTRY: 2560822637SSameer Sahasrabuddhe return CONV_ENTRY; 2660822637SSameer Sahasrabuddhe case TargetOpcode::CONVERGENCECTRL_ANCHOR: 2760822637SSameer Sahasrabuddhe return CONV_ANCHOR; 2860822637SSameer Sahasrabuddhe case TargetOpcode::CONVERGENCECTRL_LOOP: 2960822637SSameer Sahasrabuddhe return CONV_LOOP; 3060822637SSameer Sahasrabuddhe } 3160822637SSameer Sahasrabuddhe } 3260822637SSameer Sahasrabuddhe 3360822637SSameer Sahasrabuddhe template <> 3460822637SSameer Sahasrabuddhe void GenericConvergenceVerifier< 3560822637SSameer Sahasrabuddhe MachineSSAContext>::checkConvergenceTokenProduced(const MachineInstr &MI) { 3660822637SSameer Sahasrabuddhe Check(!MI.hasImplicitDef(), 3760822637SSameer Sahasrabuddhe "Convergence control tokens are defined explicitly.", 3860822637SSameer Sahasrabuddhe {Context.print(&MI)}); 3960822637SSameer Sahasrabuddhe const MachineOperand &Def = MI.getOperand(0); 4060822637SSameer Sahasrabuddhe const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo(); 4160822637SSameer Sahasrabuddhe Check(MRI.getUniqueVRegDef(Def.getReg()), 4260822637SSameer Sahasrabuddhe "Convergence control tokens must have unique definitions.", 4360822637SSameer Sahasrabuddhe {Context.print(&MI)}); 4460822637SSameer Sahasrabuddhe } 4560822637SSameer Sahasrabuddhe 4660822637SSameer Sahasrabuddhe template <> 4760822637SSameer Sahasrabuddhe const MachineInstr * 4860822637SSameer Sahasrabuddhe GenericConvergenceVerifier<MachineSSAContext>::findAndCheckConvergenceTokenUsed( 4960822637SSameer Sahasrabuddhe const MachineInstr &MI) { 5060822637SSameer Sahasrabuddhe const MachineRegisterInfo &MRI = Context.getFunction()->getRegInfo(); 5160822637SSameer Sahasrabuddhe const MachineInstr *TokenDef = nullptr; 5260822637SSameer Sahasrabuddhe 53*02813391SVitaly Buka for (const MachineOperand &MO : MI.operands()) { 54*02813391SVitaly Buka if (!MO.isReg() || !MO.isUse()) 55*02813391SVitaly Buka continue; 5660822637SSameer Sahasrabuddhe Register OpReg = MO.getReg(); 5760822637SSameer Sahasrabuddhe if (!OpReg.isVirtual()) 5860822637SSameer Sahasrabuddhe continue; 5960822637SSameer Sahasrabuddhe 6060822637SSameer Sahasrabuddhe const MachineInstr *Def = MRI.getUniqueVRegDef(OpReg); 6160822637SSameer Sahasrabuddhe if (!Def) 6260822637SSameer Sahasrabuddhe continue; 6360822637SSameer Sahasrabuddhe if (getConvOp(*Def) == CONV_NONE) 6460822637SSameer Sahasrabuddhe continue; 6560822637SSameer Sahasrabuddhe 6660822637SSameer Sahasrabuddhe CheckOrNull( 6760822637SSameer Sahasrabuddhe MI.isConvergent(), 6860822637SSameer Sahasrabuddhe "Convergence control tokens can only be used by convergent operations.", 6960822637SSameer Sahasrabuddhe {Context.print(OpReg), Context.print(&MI)}); 7060822637SSameer Sahasrabuddhe 7160822637SSameer Sahasrabuddhe CheckOrNull(!TokenDef, 7260822637SSameer Sahasrabuddhe "An operation can use at most one convergence control token.", 7360822637SSameer Sahasrabuddhe {Context.print(OpReg), Context.print(&MI)}); 7460822637SSameer Sahasrabuddhe 7560822637SSameer Sahasrabuddhe TokenDef = Def; 7660822637SSameer Sahasrabuddhe } 7760822637SSameer Sahasrabuddhe 7860822637SSameer Sahasrabuddhe if (TokenDef) 7960822637SSameer Sahasrabuddhe Tokens[&MI] = TokenDef; 8060822637SSameer Sahasrabuddhe 8160822637SSameer Sahasrabuddhe return TokenDef; 8260822637SSameer Sahasrabuddhe } 8360822637SSameer Sahasrabuddhe 8460822637SSameer Sahasrabuddhe template <> 8560822637SSameer Sahasrabuddhe bool GenericConvergenceVerifier<MachineSSAContext>::isInsideConvergentFunction( 8660822637SSameer Sahasrabuddhe const MachineInstr &MI) { 8760822637SSameer Sahasrabuddhe // The class MachineFunction does not have any property to indicate whether it 8860822637SSameer Sahasrabuddhe // is convergent. Trivially return true so that the check always passes. 8960822637SSameer Sahasrabuddhe return true; 9060822637SSameer Sahasrabuddhe } 9160822637SSameer Sahasrabuddhe 9260822637SSameer Sahasrabuddhe template <> 9360822637SSameer Sahasrabuddhe bool GenericConvergenceVerifier<MachineSSAContext>::isConvergent( 9460822637SSameer Sahasrabuddhe const MachineInstr &MI) { 9560822637SSameer Sahasrabuddhe return MI.isConvergent(); 9660822637SSameer Sahasrabuddhe } 9760822637SSameer Sahasrabuddhe 9860822637SSameer Sahasrabuddhe template class llvm::GenericConvergenceVerifier<MachineSSAContext>; 99