File: PredefinedVariable.h

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (136 lines) | stat: -rw-r--r-- 4,686 bytes parent folder | download | duplicates (2)
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
125
126
127
128
129
130
131
132
133
134
135
136
/*========================== begin_copyright_notice ============================

Copyright (C) 2022 Intel Corporation

SPDX-License-Identifier: MIT

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

#ifndef VC_UTILS_GENX_PREDEFINEDVARIABLE_H
#define VC_UTILS_GENX_PREDEFINEDVARIABLE_H

//===----------------------------------------------------------------------===//
//
/// Predefined Variables
///
/// vISA predefined variables (aka registers) are represented in LLVM IR as
/// global variables. This header provides utilities for working with such
/// variables.
///
/// Note that there are another approaches for the same idea in VC backend. The
/// main one is based on adding specific read/write intrinsics for every
/// predefined variable. This approach is considered obsolete. New predefined
/// variables should be represented via predefined variables and accessed via
/// common read/write instrinsics. The legacy approaches are to be replaced with
/// the new one.
//===----------------------------------------------------------------------===//

#include "Probe/Assertion.h"

#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Module.h>

namespace vc {
namespace PredefVar {

// The attribute that defines that a global variable is a predefined variable.
// Don't use this attribute directly, use interfaces below to create and
// identify predefined variables.
constexpr const char Attribute[] = "VCPredefinedVariable";

// The name of a global variable that represents predefined VISA variable BSS.
constexpr const char BSSName[] = "llvm.vc.predef.var.bss";

// The name of a global variable that represents predefined VISA variable
// IMPL_ARG_BUF_PTR.
constexpr const char ImplicitArgsBufferName[] =
    "llvm.vc.predef.var.impl.args.buf";

// The name of a global variable that represents predefined VISA variable
// LOCAL_ID_BUF_PTR.
constexpr const char LocalIDBufferName[] = "llvm.vc.predef.var.loc.id.buf";

enum class ID {
  BSS,
  ImplicitArgsBuffer,
  LocalIDBuffer,
};

// Get the name of a predefined variable defined by the provided ID.
template <enum ID PVID> const char *getName();

template <> inline const char *getName<ID::BSS>() { return BSSName; }

template <> inline const char *getName<ID::ImplicitArgsBuffer>() {
  return ImplicitArgsBufferName;
}

template <> inline const char *getName<ID::LocalIDBuffer>() {
  return LocalIDBufferName;
}

// Get the type of a predefined variable defined by the provided ID.
template <enum ID PVID> llvm::Type *getType(llvm::LLVMContext &C);

template <> inline llvm::Type *getType<ID::BSS>(llvm::LLVMContext &C) {
  return llvm::Type::getInt32Ty(C);
}

template <>
inline llvm::Type *getType<ID::ImplicitArgsBuffer>(llvm::LLVMContext &C) {
  return llvm::Type::getInt64Ty(C);
}

template <>
inline llvm::Type *getType<ID::LocalIDBuffer>(llvm::LLVMContext &C) {
  return llvm::Type::getInt64Ty(C);
}

// Checks whether a global variable \p GV is a predefined variable.
inline bool isPV(const llvm::GlobalVariable &GV) {
  return GV.hasAttribute(Attribute);
}

// Checks whether a value \p V is a predefined variable.
inline bool isPV(const llvm::Value &V) {
  if (!llvm::isa<llvm::GlobalVariable>(V))
    return false;
  return isPV(llvm::cast<llvm::GlobalVariable>(V));
}

// Creates a predefined varaible defined by the provided ID.
// The predefined variable must not have been created before.
// The reference to the created global variable is returned.
template <enum ID PVID> llvm::GlobalVariable &createPV(llvm::Module &M) {
  auto *Name = getName<PVID>();
  IGC_ASSERT_MESSAGE(M.getNamedGlobal(Name) == nullptr,
                     "Unexpected BSS global already created");
  auto *PVTy = getType<PVID>(M.getContext());
  auto *PV = new llvm::GlobalVariable(M, PVTy, /*isConstant=*/false,
                                      llvm::GlobalValue::ExternalLinkage,
                                      /*Initializer=*/nullptr, Name);
  PV->addAttribute(Attribute);
  return *PV;
}

// Creates BSS predefined variable. Matches \p createPV restrictions.
inline llvm::GlobalVariable &createBSS(llvm::Module &M) {
  return createPV<ID::BSS>(M);
}

// Creates ImplicitArgsBuffer predefined variable. Matches \p createPV
// restrictions.
inline llvm::GlobalVariable &createImplicitArgsBuffer(llvm::Module &M) {
  return createPV<ID::ImplicitArgsBuffer>(M);
}

// Creates LocalIDBuffer predefined variable. Matches \p createPV restrictions.
inline llvm::GlobalVariable &createLocalIDBuffer(llvm::Module &M) {
  return createPV<ID::LocalIDBuffer>(M);
}

} // namespace PredefVar
} // namespace vc

#endif // VC_UTILS_GENX_PREDEFINEDVARIABLE_H