Path: blob/main/contrib/llvm-project/llvm/lib/IR/ConvergenceVerifier.cpp
35233 views
//===- ConvergenceVerifier.cpp - Verify convergence control -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/IR/ConvergenceVerifier.h"9#include "llvm/IR/Dominators.h"10#include "llvm/IR/GenericConvergenceVerifierImpl.h"11#include "llvm/IR/Instructions.h"12#include "llvm/IR/SSAContext.h"1314using namespace llvm;1516template <>17auto GenericConvergenceVerifier<SSAContext>::getConvOp(const Instruction &I)18-> ConvOpKind {19const auto *CB = dyn_cast<CallBase>(&I);20if (!CB)21return CONV_NONE;22switch (CB->getIntrinsicID()) {23default:24return CONV_NONE;25case Intrinsic::experimental_convergence_anchor:26return CONV_ANCHOR;27case Intrinsic::experimental_convergence_entry:28return CONV_ENTRY;29case Intrinsic::experimental_convergence_loop:30return CONV_LOOP;31}32}3334template <>35void GenericConvergenceVerifier<SSAContext>::checkConvergenceTokenProduced(36const Instruction &I) {37return;38}3940template <>41const Instruction *42GenericConvergenceVerifier<SSAContext>::findAndCheckConvergenceTokenUsed(43const Instruction &I) {44auto *CB = dyn_cast<CallBase>(&I);45if (!CB)46return nullptr;4748unsigned Count =49CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl);50CheckOrNull(Count <= 1,51"The 'convergencectrl' bundle can occur at most once on a call",52{Context.print(CB)});53if (!Count)54return nullptr;5556auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);57CheckOrNull(Bundle->Inputs.size() == 1 &&58Bundle->Inputs[0]->getType()->isTokenTy(),59"The 'convergencectrl' bundle requires exactly one token use.",60{Context.print(CB)});61auto *Token = Bundle->Inputs[0].get();62auto *Def = dyn_cast<Instruction>(Token);6364CheckOrNull(Def && getConvOp(*Def) != CONV_NONE,65"Convergence control tokens can only be produced by calls to the "66"convergence control intrinsics.",67{Context.print(Token), Context.print(&I)});6869if (Def)70Tokens[&I] = Def;7172return Def;73}7475template <>76bool GenericConvergenceVerifier<SSAContext>::isInsideConvergentFunction(77const Instruction &I) {78auto *F = I.getFunction();79return F->isConvergent();80}8182template <>83bool GenericConvergenceVerifier<SSAContext>::isConvergent(84const Instruction &I) {85if (auto *CB = dyn_cast<CallBase>(&I)) {86return CB->isConvergent();87}88return false;89}9091template class llvm::GenericConvergenceVerifier<SSAContext>;929394