File: GenXVerify.cpp

package info (click to toggle)
intel-graphics-compiler2 2.28.4-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 792,744 kB
  • sloc: cpp: 5,761,745; ansic: 466,928; lisp: 312,143; python: 114,790; asm: 44,736; pascal: 10,930; sh: 8,033; perl: 7,914; ml: 3,625; awk: 3,523; yacc: 2,747; javascript: 2,667; lex: 1,898; f90: 1,028; cs: 573; xml: 474; makefile: 344; objc: 162
file content (124 lines) | stat: -rw-r--r-- 4,042 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*========================== begin_copyright_notice ============================

Copyright (C) 2023-2024 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

//===----------------------------------------------------------------------===//
// GenXVerify
//===----------------------------------------------------------------------===//
//
// This pass contains GenX-specific IR validity checks.
//
#include "GenXVerify.h"
#if LLVM_VERSION_MAJOR >= 16
#include "vc/GenXCodeGen/GenXVerify.h"
#endif

bool GenXVerify::doInitialization(Module &M) {
  Ctx = &M.getContext();
  return false;
}

StringRef GenXVerify::getPassName() const {
  return "GenX IR verification pass.";
}

void GenXVerify::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
}

bool GenXVerify::ensure(const bool Cond, const Twine &Msg, const Value &V,
                        const IsFatal IsFatal_) {
  if (LLVM_LIKELY(Cond))
    return true;
  if (IsFatal_ == IsFatal::Yes || OptAllFatal || !OptQuietNonFatal)
    vc::diagnose(V.getContext(),
                 DbgPrefix + "[stage:" +
                     OptStage.getParser().getOption(
                         static_cast<int>(OptStage.getValue())) +
                     "]" +
                     (IsFatal_ == IsFatal::No
                          ? " (non-fatal, spec review required)"
                          : ""),
                 Msg, DS_Warning, vc::WarningName::Generic, &V);
  if (IsFatal_ == IsFatal::Yes || OptAllFatal) {
    IsBroken = true;
    if (OptTerminationPolicy == Terminate::OnFirstError)
      terminate();
  }
  return false;
}

[[noreturn]] void GenXVerify::terminate() {
  llvm::report_fatal_error(DbgPrefix + "failed, check log for details.");
}

bool GenXVerify::runOnModule(Module &M) {
  visit(M);
  if (Stage == GenXVerifyStage::PostIrAdaptors)
    for (const auto &GV : M.globals())
      visitGlobalVariable(GV);
  if (OptTerminationPolicy != Terminate::No && IsBroken)
    terminate();
  return false;
}

void GenXVerify::visitGlobalVariable(const GlobalVariable &GV) {
  if (!GV.hasAttribute(genx::FunctionMD::GenXVolatile))
    return;
  ensure(GV.getAddressSpace() == vc::AddrSpace::Private,
         "a volatile variable must reside in private address space", GV);
  auto InvalidUser = llvm::find_if(GV.users(), [](const User *U) {
    const auto *I =
        dyn_cast<Instruction>(genx::peelBitCastsWhileSingleUserChain(U));
    return !I || !(genx::isAVStore(I) || genx::isAVLoad(I));
  });
  if (InvalidUser == GV.user_end())
    return;
  ensure(false,
         "a volatile variable may only be used in genx.vload/genx.vstore "
         "intrinsics and volatile loads/stores instructions",
         **InvalidUser);
};

void GenXVerify::visitCallInst(const CallInst &CI) {
  const unsigned IntrinsicId = vc::getAnyIntrinsicID(&CI);
  switch (IntrinsicId) {
  case GenXIntrinsic::genx_rdregionf:
  case GenXIntrinsic::genx_rdregioni:
  case GenXIntrinsic::genx_rdpredregion:
  case GenXIntrinsic::genx_wrregionf:
  case GenXIntrinsic::genx_wrregioni:
  case GenXIntrinsic::genx_wrpredregion:
  case GenXIntrinsic::genx_wrconstregion:
  case GenXIntrinsic::genx_wrpredpredregion:
    verifyRegioning(CI, IntrinsicId);
    break;
  };
}

namespace llvm {
void initializeGenXVerifyPass(PassRegistry &);
} // namespace llvm

INITIALIZE_PASS_BEGIN(GenXVerify, "GenXVerify", "GenX IR verification", false,
                      false)
INITIALIZE_PASS_END(GenXVerify, "GenXVerify", "GenX IR verification", false,
                    false)

ModulePass *llvm::createGenXVerifyPass(GenXVerifyStage ValidityInvariantsSet) {
  initializeGenXVerifyPass(*PassRegistry::getPassRegistry());
  return new GenXVerify(ValidityInvariantsSet);
}

#if LLVM_VERSION_MAJOR >= 16
PreservedAnalyses GenXVerifyPass::run(llvm::Module &M,
                                      llvm::AnalysisManager<llvm::Module> &) {
  GenXVerify GenXVer;
  GenXVer.runOnModule(M);
  return PreservedAnalyses::all();
}
#endif