================ @@ -0,0 +1,144 @@ +//===-- TargetVerifier.cpp - LLVM IR Target Verifier ----------------*- C++ -*-===// +//// +///// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +///// See https://llvm.org/LICENSE.txt for license information. +///// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +///// +/////===----------------------------------------------------------------------===// +///// +///// This file defines target verifier interfaces that can be used for some +///// validation of input to the system, and for checking that transformations +///// haven't done something bad. In contrast to the Verifier or Lint, the +///// TargetVerifier looks for constructions invalid to a particular target +///// machine. +///// +///// To see what specifically is checked, look at TargetVerifier.cpp or an +///// individual backend's TargetVerifier. +///// +/////===----------------------------------------------------------------------===// + +#include "llvm/Target/TargetVerifier.h" +#include "llvm/Target/TargetVerify/AMDGPUTargetVerifier.h" + +#include "llvm/InitializePasses.h" +#include "llvm/Analysis/UniformityAnalysis.h" +#include "llvm/Analysis/PostDominators.h" +#include "llvm/Support/Debug.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/IntrinsicsAMDGPU.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" + +namespace llvm { + +bool TargetVerify::run(Function &F) { + if (TT.isAMDGPU()) { + AMDGPUTargetVerify TV(Mod); + TV.run(F); + + dbgs() << TV.MessagesStr.str(); + if (!TV.MessagesStr.str().empty()) { + TV.IsValid = false; + return false; + } + return true; + } + report_fatal_error("Target has no verification method\n"); +} + +bool TargetVerify::run(Function &F, FunctionAnalysisManager &AM) { + if (TT.isAMDGPU()) { + auto *UA = &AM.getResult<UniformityInfoAnalysis>(F); + auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); + auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F); + + AMDGPUTargetVerify TV(Mod, DT, PDT, UA); + TV.run(F); + + dbgs() << TV.MessagesStr.str(); + if (!TV.MessagesStr.str().empty()) { + TV.IsValid = false; + return false; + } + return true; + } + report_fatal_error("Target has no verification method\n"); +} + +PreservedAnalyses TargetVerifierPass::run(Function &F, FunctionAnalysisManager &AM) { + auto TT = F.getParent()->getTargetTriple(); + + if (TT.isAMDGPU()) { + auto *Mod = F.getParent(); + + auto UA = &AM.getResult<UniformityInfoAnalysis>(F); + auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); + auto *PDT = &AM.getResult<PostDominatorTreeAnalysis>(F); + + AMDGPUTargetVerify TV(Mod, DT, PDT, UA); ---------------- shiltian wrote:
I'm confused by how this works. If we are going to use polymorphism , I'd imagine we have a `TargetVerifierPass` as a base/interface class, and then each target creates its own instance. We will create the target specific one wherever we need. On the other hand, if we are going to use call back, there is no need for a dedicated interface class for the verifier. We only need to make a target specific verifier as a module and/or function class. However, what we have here is, a generic pass (at least its name looks like so) includes target specific header, and creates instance inside it. https://github.com/llvm/llvm-project/pull/123609 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits