blob: 12e2766c21127961389768326298b944bbc3de45 [file] [log] [blame] [edit]
///////////////////////////////////////////////////////////////////////////////
// //
// HLOperations.h //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// Implentation of High Level DXIL operations. //
// //
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include "llvm/IR/IRBuilder.h"
#include <string>
namespace llvm {
class Argument;
template <typename T> class ArrayRef;
class AttributeSet;
class CallInst;
class Function;
class FunctionType;
class Module;
class StringRef;
class Type;
class Value;
} // namespace llvm
namespace hlsl {
enum class HLOpcodeGroup {
NotHL,
HLExtIntrinsic,
HLIntrinsic,
HLCast,
HLInit,
HLBinOp,
HLUnOp,
HLSubscript,
HLMatLoadStore,
HLSelect,
HLCreateHandle,
// FIXME: Change the way these groups are being proliferated/used for each
// new generated op.
// Suggestion: Add an opcode and reuse CreateHandle/AnnotateHandle groups, and
// add an IndexHandle group.
HLCreateNodeOutputHandle,
HLIndexNodeHandle,
HLCreateNodeInputRecordHandle,
HLAnnotateHandle,
HLWaveMatrix_Annotate,
HLAnnotateNodeHandle,
HLAnnotateNodeRecordHandle,
NumOfHLOps
};
enum class HLBinaryOpcode {
Invalid,
Mul,
Div,
Rem,
Add,
Sub,
Shl,
Shr,
LT,
GT,
LE,
GE,
EQ,
NE,
And,
Xor,
Or,
LAnd,
LOr,
UDiv,
URem,
UShr,
ULT,
UGT,
ULE,
UGE,
NumOfBO,
};
enum class HLUnaryOpcode {
Invalid,
PostInc,
PostDec,
PreInc,
PreDec,
Plus,
Minus,
Not,
LNot,
NumOfUO,
};
enum class HLSubscriptOpcode {
DefaultSubscript,
ColMatSubscript,
RowMatSubscript,
ColMatElement,
RowMatElement,
DoubleSubscript,
CBufferSubscript,
VectorSubscript, // Only for bool vector, other vector type will use GEP
// directly.
};
enum class HLCastOpcode {
DefaultCast,
UnsignedUnsignedCast,
FromUnsignedCast,
ToUnsignedCast,
ColMatrixToVecCast,
RowMatrixToVecCast,
ColMatrixToRowMatrix,
RowMatrixToColMatrix,
HandleToResCast,
HandleToNodeOutputCast,
NodeOutputToHandleCast,
HandleToNodeRecordCast,
NodeRecordToHandleCast,
};
enum class HLMatLoadStoreOpcode {
ColMatLoad,
ColMatStore,
RowMatLoad,
RowMatStore,
};
extern const char *const HLPrefix;
HLOpcodeGroup GetHLOpcodeGroup(llvm::Function *F);
HLOpcodeGroup GetHLOpcodeGroupByName(const llvm::Function *F);
llvm::StringRef GetHLOpcodeGroupNameByAttr(llvm::Function *F);
llvm::StringRef GetHLLowerStrategy(llvm::Function *F);
unsigned GetHLOpcode(const llvm::CallInst *CI);
unsigned GetRowMajorOpcode(HLOpcodeGroup group, unsigned opcode);
void SetHLLowerStrategy(llvm::Function *F, llvm::StringRef S);
void SetHLWaveSensitive(llvm::Function *F);
bool IsHLWaveSensitive(llvm::Function *F);
// For intrinsic opcode.
unsigned GetUnsignedOpcode(unsigned opcode);
// For HLBinaryOpcode.
bool HasUnsignedOpcode(HLBinaryOpcode opcode);
HLBinaryOpcode GetUnsignedOpcode(HLBinaryOpcode opcode);
llvm::StringRef GetHLOpcodeGroupName(HLOpcodeGroup op);
namespace HLOperandIndex {
// Opcode parameter.
const unsigned kOpcodeIdx = 0;
// Used to initialize values that have no valid index in the HL overload.
const unsigned kInvalidIdx = UINT32_MAX;
// Matrix store.
const unsigned kMatStoreDstPtrOpIdx = 1;
const unsigned kMatStoreValOpIdx = 2;
// Matrix load.
const unsigned kMatLoadPtrOpIdx = 1;
// Normal subscipts.
const unsigned kSubscriptObjectOpIdx = 1;
const unsigned kSubscriptIndexOpIdx = 2;
// Double subscripts.
const unsigned kDoubleSubscriptMipLevelOpIdx = 3;
// Matrix subscripts.
const unsigned kMatSubscriptMatOpIdx = 1;
const unsigned kMatSubscriptSubOpIdx = 2;
// Matrix init.
const unsigned kMatArrayInitMatOpIdx = 1;
const unsigned kMatArrayInitFirstArgOpIdx = 2;
// Array Init.
const unsigned kArrayInitPtrOpIdx = 1;
const unsigned kArrayInitFirstArgOpIdx = 2;
// Normal Init.
const unsigned kInitFirstArgOpIdx = 1;
// Unary operators.
const unsigned kUnaryOpSrc0Idx = 1;
// Binary operators.
const unsigned kBinaryOpSrc0Idx = 1;
const unsigned kBinaryOpSrc1Idx = 2;
// Trinary operators.
const unsigned kTrinaryOpSrc0Idx = 1;
const unsigned kTrinaryOpSrc1Idx = 2;
const unsigned kTrinaryOpSrc2Idx = 3;
// Interlocked.
const unsigned kInterlockedDestOpIndex = 1;
const unsigned kInterlockedValueOpIndex = 2;
const unsigned kInterlockedOriginalValueOpIndex = 3;
// Interlocked method
const unsigned kInterlockedMethodValueOpIndex = 3;
// InterlockedCompareExchange.
const unsigned kInterlockedCmpDestOpIndex = 1;
const unsigned kInterlockedCmpCompareValueOpIndex = 2;
const unsigned kInterlockedCmpValueOpIndex = 3;
const unsigned kInterlockedCmpOriginalValueOpIndex = 4;
// Lerp.
const unsigned kLerpOpXIdx = 1;
const unsigned kLerpOpYIdx = 2;
const unsigned kLerpOpSIdx = 3;
// ProcessTessFactorIsoline.
const unsigned kProcessTessFactorRawDetailFactor = 1;
const unsigned kProcessTessFactorRawDensityFactor = 2;
const unsigned kProcessTessFactorRoundedDetailFactor = 3;
const unsigned kProcessTessFactorRoundedDensityFactor = 4;
// ProcessTessFactor.
const unsigned kProcessTessFactorRawEdgeFactor = 1;
const unsigned kProcessTessFactorInsideScale = 2;
const unsigned kProcessTessFactorRoundedEdgeFactor = 3;
const unsigned kProcessTessFactorRoundedInsideFactor = 4;
const unsigned kProcessTessFactorUnRoundedInsideFactor = 5;
// Reflect.
const unsigned kReflectOpIIdx = 1;
const unsigned kReflectOpNIdx = 2;
// Refract
const unsigned kRefractOpIIdx = 1;
const unsigned kRefractOpNIdx = 2;
const unsigned kRefractOpEtaIdx = 3;
// SmoothStep.
const unsigned kSmoothStepOpMinIdx = 1;
const unsigned kSmoothStepOpMaxIdx = 2;
const unsigned kSmoothStepOpXIdx = 3;
// Clamp
const unsigned kClampOpXIdx = 1;
const unsigned kClampOpMinIdx = 2;
const unsigned kClampOpMaxIdx = 3;
// Object functions.
const unsigned kHandleOpIdx = 1;
// Store.
const unsigned kStoreOffsetOpIdx = 2;
const unsigned kStoreValOpIdx = 3;
// Load.
const unsigned kBufLoadAddrOpIdx = 2;
const unsigned kBufLoadStatusOpIdx = 3;
const unsigned kRWTexLoadStatusOpIdx = 3;
const unsigned kTexLoadOffsetOpIdx = 3;
const unsigned kTexLoadStatusOpIdx = 4;
// Load for Texture2DMS
const unsigned kTex2DMSLoadSampleIdxOpIdx = 3;
const unsigned kTex2DMSLoadOffsetOpIdx = 4;
const unsigned kTex2DMSLoadStatusOpIdx = 5;
// mips.Operator.
const unsigned kMipLoadAddrOpIdx = 3;
const unsigned kMipLoadOffsetOpIdx = 4;
const unsigned kMipLoadStatusOpIdx = 5;
// Sample.
const unsigned kSampleSamplerArgIndex = 2;
const unsigned kSampleCoordArgIndex = 3;
const unsigned kSampleOffsetArgIndex = 4;
const unsigned kSampleClampArgIndex = 5;
const unsigned kSampleStatusArgIndex = 6;
// SampleG.
const unsigned kSampleGDDXArgIndex = 4;
const unsigned kSampleGDDYArgIndex = 5;
const unsigned kSampleGOffsetArgIndex = 6;
const unsigned kSampleGClampArgIndex = 7;
const unsigned kSampleGStatusArgIndex = 8;
// SampleCmp.
const unsigned kSampleCmpCmpValArgIndex = 4;
const unsigned kSampleCmpOffsetArgIndex = 5;
const unsigned kSampleCmpClampArgIndex = 6;
const unsigned kSampleCmpStatusArgIndex = 7;
// SampleCmpBias.
const unsigned kSampleCmpBCmpValArgIndex = 4;
const unsigned kSampleCmpBBiasArgIndex = 5;
const unsigned kSampleCmpBOffsetArgIndex = 6;
const unsigned kSampleCmpBClampArgIndex = 7;
const unsigned kSampleCmpBStatusArgIndex = 8;
// SampleCmpGrad.
const unsigned kSampleCmpGCmpValArgIndex = 4;
const unsigned kSampleCmpGDDXArgIndex = 5;
const unsigned kSampleCmpGDDYArgIndex = 6;
const unsigned kSampleCmpGOffsetArgIndex = 7;
const unsigned kSampleCmpGClampArgIndex = 8;
const unsigned kSampleCmpGStatusArgIndex = 9;
// SampleBias.
const unsigned kSampleBBiasArgIndex = 4;
const unsigned kSampleBOffsetArgIndex = 5;
const unsigned kSampleBClampArgIndex = 6;
const unsigned kSampleBStatusArgIndex = 7;
// SampleLevel.
const unsigned kSampleLLevelArgIndex = 4;
const unsigned kSampleLOffsetArgIndex = 5;
const unsigned kSampleLStatusArgIndex = 6;
// SampleCmpLevel
// the rest are the same as SampleCmp
const unsigned kSampleCmpLLevelArgIndex = 5;
const unsigned kSampleCmpLOffsetArgIndex = 6;
// SampleCmpLevelZero.
const unsigned kSampleCmpLZCmpValArgIndex = 4;
const unsigned kSampleCmpLZOffsetArgIndex = 5;
const unsigned kSampleCmpLZStatusArgIndex = 6;
// Gather.
const unsigned kGatherSamplerArgIndex = 2;
const unsigned kGatherCoordArgIndex = 3;
const unsigned kGatherOffsetArgIndex = 4;
const unsigned kGatherStatusArgIndex = 5;
const unsigned kGatherSampleOffsetArgIndex = 5;
const unsigned kGatherStatusWithSampleOffsetArgIndex = 8;
const unsigned kGatherCubeStatusArgIndex = 4;
// GatherCmp.
const unsigned kGatherCmpCmpValArgIndex = 4;
const unsigned kGatherCmpOffsetArgIndex = 5;
const unsigned kGatherCmpStatusArgIndex = 6;
const unsigned kGatherCmpSampleOffsetArgIndex = 6;
const unsigned kGatherCmpStatusWithSampleOffsetArgIndex = 9;
const unsigned kGatherCmpCubeStatusArgIndex = 5;
// WriteSamplerFeedback.
const unsigned kWriteSamplerFeedbackSampledArgIndex = 2;
const unsigned kWriteSamplerFeedbackSamplerArgIndex = 3;
const unsigned kWriteSamplerFeedbackCoordArgIndex = 4;
const unsigned kWriteSamplerFeedbackBias_BiasArgIndex = 5;
const unsigned kWriteSamplerFeedbackLevel_LodArgIndex = 5;
const unsigned kWriteSamplerFeedbackGrad_DdxArgIndex = 5;
const unsigned kWriteSamplerFeedbackGrad_DdyArgIndex = 6;
const unsigned kWriteSamplerFeedback_ClampArgIndex = 5;
const unsigned kWriteSamplerFeedbackBias_ClampArgIndex = 6;
const unsigned kWriteSamplerFeedbackGrad_ClampArgIndex = 7;
// StreamAppend.
const unsigned kStreamAppendStreamOpIndex = 1;
const unsigned kStreamAppendDataOpIndex = 2;
// Append.
const unsigned kAppendValOpIndex = 2;
// Interlocked.
const unsigned kObjectInterlockedDestOpIndex = 2;
const unsigned kObjectInterlockedValueOpIndex = 3;
const unsigned kObjectInterlockedOriginalValueOpIndex = 4;
// InterlockedCompareExchange.
const unsigned kObjectInterlockedCmpDestOpIndex = 2;
const unsigned kObjectInterlockedCmpCompareValueOpIndex = 3;
const unsigned kObjectInterlockedCmpValueOpIndex = 4;
const unsigned kObjectInterlockedCmpOriginalValueOpIndex = 5;
// GetSamplePosition.
const unsigned kGetSamplePositionSampleIdxOpIndex = 2;
// GetDimensions.
const unsigned kGetDimensionsMipLevelOpIndex = 2;
const unsigned kGetDimensionsMipWidthOpIndex = 3;
const unsigned kGetDimensionsNoMipWidthOpIndex = 2;
// WaveAllEqual.
const unsigned kWaveAllEqualValueOpIdx = 1;
// CreateHandle.
const unsigned kCreateHandleResourceOpIdx = 1;
const unsigned kCreateHandleIndexOpIdx = 2; // Only for array of cbuffer.
// Annotate(Node)(Record)Handle.
const unsigned kAnnotateHandleResourcePropertiesOpIdx = 2;
const unsigned kAnnotateHandleResourceTypeOpIdx = 3;
// AnnotateWaveMatrix.
const unsigned kAnnotateWaveMatrixPtrOpIdx = 1;
const unsigned kAnnotateWaveMatrixPropertiesOpIdx = 2;
// TraceRay.
const unsigned kTraceRayRayDescOpIdx = 7;
const unsigned kTraceRayPayLoadOpIdx = 8;
// CallShader.
const unsigned kCallShaderPayloadOpIdx = 2;
// TraceRayInline.
const unsigned kTraceRayInlineRayDescOpIdx = 5;
// ReportIntersection.
const unsigned kReportIntersectionAttributeOpIdx = 3;
// DispatchMesh
const unsigned kDispatchMeshOpThreadX = 1;
const unsigned kDispatchMeshOpThreadY = 2;
const unsigned kDispatchMeshOpThreadZ = 3;
const unsigned kDispatchMeshOpPayload = 4;
// WaveMatrix
const unsigned kWaveMatThisOpIdx = 1;
const unsigned kWaveMatFillScalarOpIdx = 2;
const unsigned kWaveMatScalarOpOpIdx = 2;
const unsigned kWaveMatOther1OpIdx = 2;
const unsigned kWaveMatOther2OpIdx = 3;
const unsigned kWaveMatLoadStoreBufOpIdx = 2;
const unsigned kWaveMatLoadStoreStartOpIdx = 3;
const unsigned kWaveMatLoadStoreStrideOpIdx = 4;
// Note: No ColMajor arg for fragments, so align idx is one less.
const unsigned kWaveMatLoadStoreColMajorOpIdx = 5;
const unsigned kWaveMatFragLoadStoreAlignmentOpIdx = 5;
const unsigned kWaveMatLoadStoreAlignmentOpIdx = 6;
// Work Graph
const unsigned kIncrementOutputCountCountIdx = 2;
const unsigned kBarrierMemoryTypeFlagsOpIdx = 1;
const unsigned kBarrierSemanticFlagsOpIdx = 2;
// Node Handles
const unsigned kAllocateRecordNumRecordsIdx = 2;
const unsigned kNodeOutputMetadataIDIdx = 1;
const unsigned kIndexNodeHandleArrayIDIdx = 2;
const unsigned kNodeInputRecordMetadataIDIdx = 1;
const unsigned kNodeHandleToResCastOpIdx = 1;
const unsigned kAnnotateNodeHandleNodePropIdx = 2;
const unsigned kAnnotateNodeRecordHandleNodeRecordPropIdx = 2;
} // namespace HLOperandIndex
llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
llvm::FunctionType *funcTy,
HLOpcodeGroup group, unsigned opcode);
llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
llvm::FunctionType *funcTy,
HLOpcodeGroup group,
llvm::StringRef *groupName,
llvm::StringRef *fnName, unsigned opcode);
llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
llvm::FunctionType *funcTy,
HLOpcodeGroup group, unsigned opcode,
const llvm::AttributeSet &attribs);
llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
llvm::FunctionType *funcTy,
HLOpcodeGroup group,
llvm::StringRef *groupName,
llvm::StringRef *fnName, unsigned opcode,
const llvm::AttributeSet &attribs);
llvm::Function *GetOrCreateHLFunctionWithBody(llvm::Module &M,
llvm::FunctionType *funcTy,
HLOpcodeGroup group,
unsigned opcode,
llvm::StringRef name);
llvm::Value *callHLFunction(llvm::Module &Module, HLOpcodeGroup OpcodeGroup,
unsigned Opcode, llvm::Type *RetTy,
llvm::ArrayRef<llvm::Value *> Args,
const llvm::AttributeSet &attribs,
llvm::IRBuilder<> &Builder);
llvm::Value *callHLFunction(llvm::Module &Module, HLOpcodeGroup OpcodeGroup,
unsigned Opcode, llvm::Type *RetTy,
llvm::ArrayRef<llvm::Value *> Args,
llvm::IRBuilder<> &Builder);
} // namespace hlsl