Files
RedBear-OS/local/recipes/dev/spirv-llvm-translator/source/lib/SPIRV/SPIRVReader.h
T

277 lines
12 KiB
C++

//===- SPIRVReader.h - Converts SPIR-V to LLVM ------------------*- C++ -*-===//
//
// The LLVM/SPIR-V Translator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal with the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
// Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimers in the documentation
// and/or other materials provided with the distribution.
// Neither the names of Advanced Micro Devices, Inc., nor the names of its
// contributors may be used to endorse or promote products derived from this
// Software without specific prior written permission.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
// THE SOFTWARE.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file contains declaration of SPIRVToLLVM class which implements
/// conversion of SPIR-V binary to LLVM IR.
///
//===----------------------------------------------------------------------===//
#ifndef SPIRVREADER_H
#define SPIRVREADER_H
#include "SPIRVBuiltinHelper.h"
#include "SPIRVInternal.h"
#include "SPIRVModule.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/GlobalValue.h" // llvm::GlobalValue::LinkageTypes
namespace llvm {
class Metadata;
class Module;
class Type;
class Instruction;
class CallInst;
class BasicBlock;
class Loop;
class Function;
class GlobalVariable;
class LLVMContext;
class MDString;
class IntrinsicInst;
class LoadInst;
class BranchInst;
class BinaryOperator;
class Value;
} // namespace llvm
using namespace llvm;
namespace SPIRV {
class SPIRVFunctionParameter;
class SPIRVConstantSampler;
class SPIRVConstantPipeStorage;
class SPIRVLoopMerge;
class SPIRVToLLVMDbgTran;
class SPIRVToLLVM : private BuiltinCallHelper {
public:
SPIRVToLLVM(Module *LLVMModule, SPIRVModule *TheSPIRVModule);
static const StringSet<> BuiltInConstFunc;
/// Translate the SPIR-V type into an LLVM type. If UseTypedPointerTypes is
/// true, then generate a TypedPointerType instead of a PointerType. The
/// intended use of TypedPointerTypes is for name mangling, so pointer types
/// that occur as array members or struct members will not be represented with
/// TypedPointerType, even when UseTypedPointerTypes is true.
Type *transType(SPIRVType *BT, bool UseTypedPointerTypes = false);
std::string transTypeToOCLTypeName(SPIRVType *BT, bool IsSigned = true);
std::vector<Type *> transTypeVector(const std::vector<SPIRVType *> &,
bool UseTypedPointerTypes = false);
bool translate();
bool transAddressingModel();
Value *transValue(SPIRVValue *, Function *F, BasicBlock *,
bool CreatePlaceHolder = true);
Value *transValueWithoutDecoration(SPIRVValue *, Function *F, BasicBlock *,
bool CreatePlaceHolder = true);
bool transDecoration(SPIRVValue *, Value *);
bool transAlign(SPIRVValue *, Value *);
Instruction *transOCLBuiltinFromExtInst(SPIRVExtInst *BC, BasicBlock *BB);
void transAuxDataInst(SPIRVExtInst *BC);
std::vector<Value *> transValue(const std::vector<SPIRVValue *> &,
Function *F, BasicBlock *);
Function *transFunction(SPIRVFunction *F, unsigned AS = SPIRAS_Private);
void transFunctionAttrs(SPIRVFunction *BF, Function *F);
Value *transBlockInvoke(SPIRVValue *Invoke, BasicBlock *BB);
Instruction *transWGSizeQueryBI(SPIRVInstruction *BI, BasicBlock *BB);
Instruction *transSGSizeQueryBI(SPIRVInstruction *BI, BasicBlock *BB);
bool transFPContractMetadata();
bool transMetadata();
bool transOCLMetadata(SPIRVFunction *BF);
bool transVectorComputeMetadata(SPIRVFunction *BF);
bool transFPGAFunctionMetadata(SPIRVFunction *BF, Function *F);
Value *transAsmINTEL(SPIRVAsmINTEL *BA);
CallInst *transAsmCallINTEL(SPIRVAsmCallINTEL *BI, Function *F,
BasicBlock *BB);
Value *transFixedPointInst(SPIRVInstruction *BI, BasicBlock *BB);
Value *transArbFloatInst(SPIRVInstruction *BI, BasicBlock *BB,
bool IsBinaryInst = false);
bool transNonTemporalMetadata(Instruction *I);
template <typename SPIRVInstType>
void transAliasingMemAccess(SPIRVInstType *BI, Instruction *I);
void addMemAliasMetadata(Instruction *I, SPIRVId AliasListId,
uint32_t AliasMDKind);
void transSourceLanguage();
bool transSourceExtension();
void transGeneratorMD();
Value *transConvertInst(SPIRVValue *BV, Function *F, BasicBlock *BB);
Instruction *transBuiltinFromInst(const std::string &FuncName,
SPIRVInstruction *BI, BasicBlock *BB);
Instruction *transSPIRVBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB);
/// \brief Expand OCL builtin functions with scalar argument, e.g.
/// step, smoothstep.
/// gentype func (fp edge, gentype x)
/// =>
/// gentype func (gentype edge, gentype x)
/// \return transformed call instruction.
CallInst *expandOCLBuiltinWithScalarArg(CallInst *CI,
const std::string &FuncName);
typedef DenseMap<SPIRVType *, Type *> SPIRVToLLVMTypeMap;
typedef DenseMap<SPIRVValue *, Value *> SPIRVToLLVMValueMap;
typedef DenseMap<SPIRVValue *, Value *> SPIRVBlockToLLVMStructMap;
typedef DenseMap<SPIRVFunction *, Function *> SPIRVToLLVMFunctionMap;
typedef DenseMap<GlobalVariable *, SPIRVBuiltinVariableKind> BuiltinVarMap;
typedef std::unordered_map<SPIRVId, MDNode *> SPIRVToLLVMMDAliasInstMap;
// A SPIRV value may be translated to a load instruction of a placeholder
// global variable. This map records load instruction of these placeholders
// which are supposed to be replaced by the real values later.
typedef std::unordered_map<SPIRVValue *, LoadInst *>
SPIRVToLLVMPlaceholderMap;
typedef std::unordered_map<const BasicBlock *, const SPIRVValue *>
SPIRVToLLVMLoopMetadataMap;
// Store all the allocations to Struct Types that are further
// accessed inside GetElementPtr instruction or in ptr.annotation intrinsics.
// For every structure we save the accessed structure field index and the
// last corresponding translated LLVM instruction.
typedef std::unordered_map<Value *,
std::unordered_map<SPIRVWord, Instruction *>>
TypeToGEPOrUseMap;
private:
Module *M;
LLVMContext *Context;
SPIRVModule *BM;
SPIRVToLLVMTypeMap TypeMap;
SPIRVToLLVMValueMap ValueMap;
SPIRVToLLVMFunctionMap FuncMap;
SPIRVBlockToLLVMStructMap BlockMap;
SPIRVToLLVMPlaceholderMap PlaceholderMap;
std::unique_ptr<SPIRVToLLVMDbgTran> DbgTran;
// GlobalAnnotations collects array of annotation entries for global variables
// and functions. They are used in translation of llvm.global.annotations
// instruction.
std::vector<Constant *> GlobalAnnotations;
// AnnotationsMap helps to translate annotation strings for local variables.
// Map values are pointers on global strings in LLVM-IR. It is used to avoid
// duplication of these annotation strings in LLVM-IR, which can be caused by
// multiple translation of UserSemantic decorations with the same literal.
std::unordered_map<std::string, Constant *> AnnotationsMap;
// Loops metadata is translated in the end of a function translation.
// This storage contains pairs of translated loop header basic block and loop
// metadata SPIR-V instruction in SPIR-V representation of this basic block.
SPIRVToLLVMLoopMetadataMap FuncLoopMetadataMap;
// These storages are used to prevent duplication of alias.scope/noalias
// metadata
SPIRVToLLVMMDAliasInstMap MDAliasDomainMap;
SPIRVToLLVMMDAliasInstMap MDAliasScopeMap;
SPIRVToLLVMMDAliasInstMap MDAliasListMap;
TypeToGEPOrUseMap GEPOrUseMap;
Type *mapType(SPIRVType *BT, Type *T);
// If a value is mapped twice, the existing mapped value is a placeholder,
// which must be a load instruction of a global variable whose name starts
// with kPlaceholderPrefix.
Value *mapValue(SPIRVValue *BV, Value *V);
// OpenCL function always has NoUnwind attribute.
// Change this if it is no longer true.
bool isFuncNoUnwind() const { return true; }
bool isFuncReadNone(const std::string &Name) const {
return BuiltInConstFunc.count(Name);
}
bool isDirectlyTranslatedToOCL(Op OpCode) const;
MDString *transOCLKernelArgTypeName(SPIRVFunctionParameter *);
// Attempt to translate Id as a (specialization) constant.
std::optional<uint64_t> transIdAsConstant(SPIRVId Id);
// Return the value of an Alignment or AlignmentId decoration for V.
std::optional<uint64_t> getAlignment(SPIRVValue *V);
Value *mapFunction(SPIRVFunction *BF, Function *F);
Value *getTranslatedValue(SPIRVValue *BV);
IntrinsicInst *getLifetimeStartIntrinsic(Instruction *I);
SPIRVErrorLog &getErrorLog();
void setCallingConv(CallInst *Call);
Type *transFPType(SPIRVType *T);
Value *transShiftLogicalBitwiseInst(SPIRVValue *BV, BasicBlock *BB,
Function *F);
Value *transCmpInst(SPIRVValue *BV, BasicBlock *BB, Function *F);
void transOCLBuiltinFromInstPreproc(SPIRVInstruction *BI, Type *&RetTy,
std::vector<SPIRVValue *> &Args);
Instruction *transOCLBuiltinPostproc(SPIRVInstruction *BI, CallInst *CI,
BasicBlock *BB,
const std::string &DemangledName);
std::string transOCLImageTypeAccessQualifier(SPIRV::SPIRVTypeImage *ST);
std::string transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe *ST);
std::string transVCTypeName(SPIRVTypeBufferSurfaceINTEL *PST);
Value *oclTransConstantSampler(SPIRV::SPIRVConstantSampler *BCS,
BasicBlock *BB);
Value *oclTransConstantPipeStorage(SPIRV::SPIRVConstantPipeStorage *BCPS);
void setName(llvm::Value *V, SPIRVValue *BV);
template <typename LoopInstType>
void setLLVMLoopMetadata(const LoopInstType *LM, const Loop *LoopObj);
void transLLVMLoopMetadata(const Function *F);
inline llvm::Metadata *getMetadataFromName(std::string Name);
inline std::vector<llvm::Metadata *>
getMetadataFromNameAndParameter(std::string Name, SPIRVWord Parameter);
inline MDNode *getMetadataFromNameAndParameter(std::string Name,
int64_t Parameter);
template <class Source, class Func> bool foreachFuncCtlMask(Source, Func);
llvm::GlobalValue::LinkageTypes transLinkageType(const SPIRVValue *V);
Instruction *transAllAny(SPIRVInstruction *BI, BasicBlock *BB);
Instruction *transRelational(SPIRVInstruction *BI, BasicBlock *BB);
void transUserSemantic(SPIRV::SPIRVFunction *Fun);
void transGlobalAnnotations();
void transGlobalCtorDtors(SPIRVVariableBase *BV);
void createCXXStructor(const char *ListName,
SmallVectorImpl<Function *> &Funcs);
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
void transMemAliasingINTELDecorations(SPIRVValue *BV, Value *V);
void transDecorationsToMetadata(SPIRVValue *BV, Value *V);
void transFunctionDecorationsToMetadata(SPIRVFunction *BF, Function *F);
void
transFunctionPointerCallArgumentAttributes(SPIRVValue *BV, CallInst *CI,
SPIRVTypeFunction *CalledFnTy);
}; // class SPIRVToLLVM
} // namespace SPIRV
#endif // SPIRVREADER_H