1//===--- SPIRVUtils.h ---- SPIR-V Utility Functions -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains miscellaneous utility functions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
14#define LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
15
16#include "MCTargetDesc/SPIRVBaseInfo.h"
17#include "llvm/IR/IRBuilder.h"
18#include "llvm/IR/TypedPointerType.h"
19#include <string>
20
21namespace llvm {
22class MCInst;
23class MachineFunction;
24class MachineInstr;
25class MachineInstrBuilder;
26class MachineIRBuilder;
27class MachineRegisterInfo;
28class Register;
29class StringRef;
30class SPIRVInstrInfo;
31class SPIRVSubtarget;
32
33// Add the given string as a series of integer operand, inserting null
34// terminators and padding to make sure the operands all have 32-bit
35// little-endian words.
36void addStringImm(const StringRef &Str, MCInst &Inst);
37void addStringImm(const StringRef &Str, MachineInstrBuilder &MIB);
38void addStringImm(const StringRef &Str, IRBuilder<> &B,
39 std::vector<Value *> &Args);
40
41// Read the series of integer operands back as a null-terminated string using
42// the reverse of the logic in addStringImm.
43std::string getStringImm(const MachineInstr &MI, unsigned StartIndex);
44
45// Add the given numerical immediate to MIB.
46void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB);
47
48// Add an OpName instruction for the given target register.
49void buildOpName(Register Target, const StringRef &Name,
50 MachineIRBuilder &MIRBuilder);
51
52// Add an OpDecorate instruction for the given Reg.
53void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder,
54 SPIRV::Decoration::Decoration Dec,
55 const std::vector<uint32_t> &DecArgs,
56 StringRef StrImm = "");
57void buildOpDecorate(Register Reg, MachineInstr &I, const SPIRVInstrInfo &TII,
58 SPIRV::Decoration::Decoration Dec,
59 const std::vector<uint32_t> &DecArgs,
60 StringRef StrImm = "");
61
62// Convert a SPIR-V storage class to the corresponding LLVM IR address space.
63unsigned storageClassToAddressSpace(SPIRV::StorageClass::StorageClass SC);
64
65// Convert an LLVM IR address space to a SPIR-V storage class.
66SPIRV::StorageClass::StorageClass
67addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI);
68
69SPIRV::MemorySemantics::MemorySemantics
70getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC);
71
72SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord);
73
74// Find def instruction for the given ConstReg, walking through
75// spv_track_constant and ASSIGN_TYPE instructions. Updates ConstReg by def
76// of OpConstant instruction.
77MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
78 const MachineRegisterInfo *MRI);
79
80// Get constant integer value of the given ConstReg.
81uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI);
82
83// Check if MI is a SPIR-V specific intrinsic call.
84bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID);
85
86// Get type of i-th operand of the metadata node.
87Type *getMDOperandAsType(const MDNode *N, unsigned I);
88
89// If OpenCL or SPIR-V builtin function name is recognized, return a demangled
90// name, otherwise return an empty string.
91std::string getOclOrSpirvBuiltinDemangledName(StringRef Name);
92
93// Check if a string contains a builtin prefix.
94bool hasBuiltinTypePrefix(StringRef Name);
95
96// Check if given LLVM type is a special opaque builtin type.
97bool isSpecialOpaqueType(const Type *Ty);
98
99// Check if the function is an SPIR-V entry point
100bool isEntryPoint(const Function &F);
101
102// Parse basic scalar type name, substring TypeName, and return LLVM type.
103Type *parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx);
104
105// True if this is an instance of TypedPointerType.
106inline bool isTypedPointerTy(const Type *T) {
107 return T->getTypeID() == Type::TypedPointerTyID;
108}
109
110// True if this is an instance of PointerType.
111inline bool isUntypedPointerTy(const Type *T) {
112 return T->getTypeID() == Type::PointerTyID;
113}
114
115// True if this is an instance of PointerType or TypedPointerType.
116inline bool isPointerTy(const Type *T) {
117 return isUntypedPointerTy(T) || isTypedPointerTy(T);
118}
119
120// Get the address space of this pointer or pointer vector type for instances of
121// PointerType or TypedPointerType.
122inline unsigned getPointerAddressSpace(const Type *T) {
123 Type *SubT = T->getScalarType();
124 return SubT->getTypeID() == Type::PointerTyID
125 ? cast<PointerType>(Val: SubT)->getAddressSpace()
126 : cast<TypedPointerType>(Val: SubT)->getAddressSpace();
127}
128
129// Return true if the Argument is decorated with a pointee type
130inline bool hasPointeeTypeAttr(Argument *Arg) {
131 return Arg->hasByValAttr() || Arg->hasByRefAttr() || Arg->hasStructRetAttr();
132}
133
134// Return the pointee type of the argument or nullptr otherwise
135inline Type *getPointeeTypeByAttr(Argument *Arg) {
136 if (Arg->hasByValAttr())
137 return Arg->getParamByValType();
138 if (Arg->hasStructRetAttr())
139 return Arg->getParamStructRetType();
140 if (Arg->hasByRefAttr())
141 return Arg->getParamByRefType();
142 return nullptr;
143}
144
145inline Type *reconstructFunctionType(Function *F) {
146 SmallVector<Type *> ArgTys;
147 for (unsigned i = 0; i < F->arg_size(); ++i)
148 ArgTys.push_back(Elt: F->getArg(i)->getType());
149 return FunctionType::get(Result: F->getReturnType(), Params: ArgTys, isVarArg: F->isVarArg());
150}
151
152inline Type *toTypedPointer(Type *Ty, LLVMContext &Ctx) {
153 return isUntypedPointerTy(T: Ty)
154 ? TypedPointerType::get(ElementType: IntegerType::getInt8Ty(C&: Ctx),
155 AddressSpace: getPointerAddressSpace(T: Ty))
156 : Ty;
157}
158
159} // namespace llvm
160#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
161

source code of llvm/lib/Target/SPIRV/SPIRVUtils.h