277 lines
12 KiB
C++
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
|