91 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/IR/ConvergenceVerifier.h"10#include "llvm/IR/Dominators.h"11#include "llvm/IR/GenericConvergenceVerifierImpl.h"12#include "llvm/IR/Instructions.h"13#include "llvm/IR/SSAContext.h"14 15using namespace llvm;16 17template <>18auto GenericConvergenceVerifier<SSAContext>::getConvOp(const Instruction &I)19 -> ConvOpKind {20 const auto *CB = dyn_cast<CallBase>(&I);21 if (!CB)22 return CONV_NONE;23 switch (CB->getIntrinsicID()) {24 default:25 return CONV_NONE;26 case Intrinsic::experimental_convergence_anchor:27 return CONV_ANCHOR;28 case Intrinsic::experimental_convergence_entry:29 return CONV_ENTRY;30 case Intrinsic::experimental_convergence_loop:31 return CONV_LOOP;32 }33}34 35template <>36void GenericConvergenceVerifier<SSAContext>::checkConvergenceTokenProduced(37 const Instruction &I) {}38 39template <>40const Instruction *41GenericConvergenceVerifier<SSAContext>::findAndCheckConvergenceTokenUsed(42 const Instruction &I) {43 auto *CB = dyn_cast<CallBase>(&I);44 if (!CB)45 return nullptr;46 47 unsigned Count =48 CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl);49 CheckOrNull(Count <= 1,50 "The 'convergencectrl' bundle can occur at most once on a call",51 {Context.print(CB)});52 if (!Count)53 return nullptr;54 55 auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);56 CheckOrNull(Bundle->Inputs.size() == 1 &&57 Bundle->Inputs[0]->getType()->isTokenTy(),58 "The 'convergencectrl' bundle requires exactly one token use.",59 {Context.print(CB)});60 auto *Token = Bundle->Inputs[0].get();61 auto *Def = dyn_cast<Instruction>(Token);62 63 CheckOrNull(Def && getConvOp(*Def) != CONV_NONE,64 "Convergence control tokens can only be produced by calls to the "65 "convergence control intrinsics.",66 {Context.print(Token), Context.print(&I)});67 68 if (Def)69 Tokens[&I] = Def;70 71 return Def;72}73 74template <>75bool GenericConvergenceVerifier<SSAContext>::isInsideConvergentFunction(76 const Instruction &I) {77 auto *F = I.getFunction();78 return F->isConvergent();79}80 81template <>82bool GenericConvergenceVerifier<SSAContext>::isConvergent(83 const Instruction &I) {84 if (auto *CB = dyn_cast<CallBase>(&I)) {85 return CB->isConvergent();86 }87 return false;88}89 90template class llvm::GenericConvergenceVerifier<SSAContext>;91