File: InternalIntrinsics.h

package info (click to toggle)
intel-graphics-compiler 1.0.17791.18-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 102,312 kB
  • sloc: cpp: 935,343; lisp: 286,143; ansic: 16,196; python: 3,279; yacc: 2,487; lex: 1,642; pascal: 300; sh: 174; makefile: 27
file content (210 lines) | stat: -rw-r--r-- 6,944 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*========================== begin_copyright_notice ============================

Copyright (C) 2022-2024 Intel Corporation

SPDX-License-Identifier: MIT

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

//===----------------------------------------------------------------------===//
//
// This file defines a set of enums which allow processing of intrinsic
// functions.  Values of these enum types are returned by
// InternalIntrinsic::getInternalIntrinsicID.
//
//===----------------------------------------------------------------------===//

#ifndef INTERNAL_INTRINSIC_INTERFACE_H
#define INTERNAL_INTRINSIC_INTERFACE_H

#include <llvm/IR/Module.h>
#include <llvm/IR/Attributes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/Intrinsics.h>

#include "llvm/GenXIntrinsics/GenXIntrinsics.h"

#include "Probe/Assertion.h"

namespace vc::InternalIntrinsic {

enum ID : unsigned {
  // TODO: check start, later may be GenXIntrinsic::num_genx_intrinsics
  not_internal_intrinsic = llvm::GenXIntrinsic::not_any_intrinsic + 1,
#define GET_INTRINSIC_ENUM_VALUES
#include "vc/InternalIntrinsics/InternalIntrinsicDescription.gen"
#undef GET_INTRINSIC_ENUM_VALUES
  num_internal_intrinsics,
  not_any_intrinsic,
};

inline const char *getInternalIntrinsicPrefix() { return "llvm.vc.internal."; }

ID getInternalIntrinsicID(const llvm::Function *F);

/// Utility function to get the internal_intrinsic ID if V is a
/// InternalIntrinsic call. V is allowed to be 0.
inline ID getInternalIntrinsicID(const llvm::Value *V) {
  if (!V)
    return InternalIntrinsic::not_any_intrinsic;
  const llvm::CallInst *CI = llvm::dyn_cast<llvm::CallInst>(V);
  if (!CI)
    return InternalIntrinsic::not_any_intrinsic;
  llvm::Function *Callee = CI->getCalledFunction();
  if (!Callee)
    return InternalIntrinsic::not_any_intrinsic;
  return getInternalIntrinsicID(Callee);
}

/// InternalIntrinsic::isInternalIntrinsic(ID) - Is Internal intrinsic
/// NOTE that this is include not_internal_intrinsic
inline bool isInternalIntrinsic(unsigned ID) {
  return ID >= not_internal_intrinsic && ID < num_internal_intrinsics;
}

/// InternalIntrinsic::isInternalIntrinsic(CF) - Returns true if
/// the function's name starts with "llvm.vc.internal.".
/// It's possible for this function to return true while
/// getInternalIntrinsicID() returns InternalIntrinsic::not_internal_intrinsic!
inline bool isInternalIntrinsic(const llvm::Function *CF) {
  IGC_ASSERT(CF);
  return CF->getName().startswith(getInternalIntrinsicPrefix());
}

inline bool isInternalIntrinsic(const llvm::Value *V) {
  if (!V)
    return false;
  const llvm::CallInst *CI = llvm::dyn_cast<llvm::CallInst>(V);
  if (!CI)
    return false;
  llvm::Function *Callee = CI->getCalledFunction();
  if (!Callee)
    return false;
  return isInternalIntrinsic(Callee);
}

/// InternalIntrinsic::isInternalNonTrivialIntrinsic(ID) - Is Internal
/// intrinsic, which is not equal to not_internal_intrinsic or
/// not_internal_intrinsic
inline bool isInternalNonTrivialIntrinsic(unsigned ID) {
  return ID > not_internal_intrinsic && ID < num_internal_intrinsics;
}

inline bool isInternalNonTrivialIntrinsic(const llvm::Function *CF) {
  return isInternalNonTrivialIntrinsic(getInternalIntrinsicID(CF));
}

inline bool isInternalNonTrivialIntrinsic(const llvm::Value *V) {
  return isInternalNonTrivialIntrinsic(getInternalIntrinsicID(V));
}

/// InternalIntrinsic::getInternalDeclaration(M, ID) - Create or insert a
/// Internal LLVM Function declaration for an intrinsic, and return it.
///
/// The Tys parameter is for intrinsics with overloaded types (e.g., those
/// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
/// intrinsic, Tys must provide exactly one type for each overloaded type in
/// the intrinsic.
llvm::Function *
getInternalDeclaration(llvm::Module *M, ID id,
                       llvm::ArrayRef<llvm::Type *> Tys = llvm::None);

/// InternalIntrinsic::isOverloadedArg(ID, ArgNum) - Return true if ArgNum
/// in intrinsic overloaded
bool isOverloadedArg(unsigned IntrinID, unsigned ArgNum);

/// InternalIntrinsic::isOverloadedRet(ID) - Return true if return type
/// in intrinsic is overloaded
bool isOverloadedRet(unsigned IntrinID);

std::string getInternalName(ID id,
                            llvm::ArrayRef<llvm::Type *> Tys = llvm::None);

bool isInternalMemoryIntrinsic(ID id);

inline bool isInternalMemoryIntrinsic(const llvm::Value *V) {
  return isInternalMemoryIntrinsic(getInternalIntrinsicID(V));
}

inline bool isInternalMemoryIntrinsic(const llvm::Function *F) {
  return isInternalMemoryIntrinsic(getInternalIntrinsicID(F));
}

bool isStatelessIntrinsic(ID IID);

inline bool isStatelessIntrinsic(const llvm::Value *V) {
  return isStatelessIntrinsic(getInternalIntrinsicID(V));
}

inline bool isStatelessIntrinsic(const llvm::Function *F) {
  return isStatelessIntrinsic(getInternalIntrinsicID(F));
}

bool isSlmIntrinsic(ID IID);

inline bool isSlmIntrinsic(const llvm::Value *V) {
  return isSlmIntrinsic(getInternalIntrinsicID(V));
}

inline bool isSlmIntrinsic(const llvm::Function *F) {
  return isSlmIntrinsic(getInternalIntrinsicID(F));
}

bool isInternalSamplerIntrinsic(ID IID);

inline bool isInternalSamplerIntrinsic(const llvm::Value *V) {
  return isInternalSamplerIntrinsic(getInternalIntrinsicID(V));
}

inline bool isInternalSamplerIntrinsic(const llvm::Function *F) {
  return isInternalSamplerIntrinsic(getInternalIntrinsicID(F));
}

bool isMemoryBlockIntrinsic(const llvm::Instruction *I);

unsigned getMemoryVectorSizePerLane(const llvm::Instruction *I);
unsigned getMemorySimdWidth(const llvm::Instruction *I);
unsigned getMemoryRegisterElementSize(const llvm::Instruction *I);

int getMemorySurfaceOperandIndex(unsigned IID);
int getMemorySamplerOperandIndex(unsigned IID);

int getMemoryCacheControlOperandIndex(unsigned IID);

inline int getMemoryCacheControlOperandIndex(const llvm::Value *V) {
  return getMemoryCacheControlOperandIndex(getInternalIntrinsicID(V));
}

inline llvm::Value *getMemoryCacheControlOperand(const llvm::Instruction *I) {
  const auto Index = getMemoryCacheControlOperandIndex(I);
  if (Index < 0)
    return nullptr;
  return I->getOperand(Index);
}

int getMemoryAddressOperandIndex(unsigned IID);

inline llvm::Value *getMemoryAddressOperand(const llvm::Instruction *I) {
  auto IID = getInternalIntrinsicID(I);
  const auto Index = getMemoryAddressOperandIndex(IID);
  if (Index < 0)
    return nullptr;
  return I->getOperand(Index);
}

int getMemoryBaseOperandIndex(unsigned IID);

inline llvm::Value *getMemoryBaseOperand(const llvm::Instruction *I) {
  auto IID = getInternalIntrinsicID(I);
  const auto Index = getMemoryBaseOperandIndex(IID);
  if (Index < 0)
    return nullptr;
  return I->getOperand(Index);
}

int getTwoAddrOpIndex(const llvm::CallInst *CI);

} // namespace vc::InternalIntrinsic

#endif