Commit 4259a90b authored by Jurek, Pawel's avatar Jurek, Pawel Committed by gbsbuild

Changing VME types to opaque.

In new Clang versions VME types are built-in. They will be declared as opaque structure types. This change prepares IGC for this change without breaking compatibility with Clang based on LLVM4.
This is achieved by adding conversion helpers that are resolved on LLVM level.

In CShader.cpp optimisation for GRF size of VME payload is reverted, as it was not fully functionally correct. This will be addressed in future commits

Change-Id: I5f085adf9e9732da5a3511c98f9f23e25ba7e528
parent 3246f772
......@@ -1490,27 +1490,17 @@ SPIRVToLLVM::transType(SPIRVType *T) {
}
default: {
auto OC = T->getOpCode();
if (isOpaqueGenericTypeOpCode(OC))
if (isOpaqueGenericTypeOpCode(OC) ||
isSubgroupAvcINTELTypeOpCode(OC))
{
auto name = BuiltinOpaqueGenericTypeOpCodeMap::rmap(OC);
auto name = isSubgroupAvcINTELTypeOpCode(OC) ?
OCLSubgroupINTELTypeOpCodeMap::rmap(OC) :
BuiltinOpaqueGenericTypeOpCodeMap::rmap(OC);
auto *pST = M->getTypeByName(name);
pST = pST ? pST : StructType::create(*Context, name);
return mapType(T, PointerType::get(pST, getOCLOpaqueTypeAddrSpace(OC)));
}
else if (isSubgroupAvcINTELTypeOpCode(OC)) {
StructType* avcType = nullptr;
std::string typeName = OCLSubgroupINTELTypeOpCodeMap::rmap(T->getOpCode());
unsigned vectorWidth = getSubgroupAvcINTELTypeVectorWidth(OC);
if (vectorWidth == 1) {
avcType = StructType::create({ Type::getInt32Ty(*Context) }, typeName);
}
else {
spirv_assert(vectorWidth > 1);
avcType = StructType::create({ VectorType::get(Type::getInt32Ty(*Context), vectorWidth) }, typeName);
}
return mapType(T, avcType);
}
llvm_unreachable("Not implemented");
}
}
......@@ -3140,6 +3130,22 @@ SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB) {
std::string builtinName(getSPIRVBuiltinName(OC, BI, ArgTys, suffix));
// Fix mangling of VME builtins.
if (isIntelVMEOpCode(OC)) {
decltype(ArgTys) ArgTysWithVME_WA;
for (auto t : ArgTys) {
if (isa<PointerType>(t) &&
t->getPointerElementType()->isStructTy()) {
ArgTysWithVME_WA.push_back(t->getPointerElementType());
}
else {
ArgTysWithVME_WA.push_back(t);
}
}
builtinName = getSPIRVBuiltinName(OC, BI, ArgTysWithVME_WA, suffix);
}
if (hasReturnTypeInTypeList)
{
ArgTys.erase(ArgTys.begin());
......
......@@ -232,6 +232,11 @@ inline bool isIntelSubgroupOpCode(Op OpCode) {
return OpSubgroupShuffleINTEL <= OC && OC <= OpSubgroupImageMediaBlockWriteINTEL;
}
inline bool isIntelVMEOpCode(Op OpCode) {
unsigned OC = OpCode;
return OpVmeImageINTEL <= OC && OC <= OpSubgroupAvcSicGetInterRawSadsINTEL;
}
}
#endif /* SPIRVOPCODE_HPP_ */
......@@ -690,7 +690,7 @@ class SPIRVTypeSubgroupINTEL;
template<> inline void
SPIRVMap<std::string, Op, SPIRVTypeSubgroupINTEL>::init() {
#define _SPIRV_OP(x,y) \
add("opencl.intel_sub_group_avc_"#x, OpTypeAvc##y##INTEL);
add("struct.intel_sub_group_avc_"#x, OpTypeAvc##y##INTEL);
_SPIRV_OP(mce_payload_t, McePayload)
_SPIRV_OP(mce_result_t, MceResult)
_SPIRV_OP(sic_payload_t, SicPayload)
......
......@@ -59,8 +59,7 @@ float __attribute__((overloadable)) atomic_cmpxchg(volatile __local float *p, fl
#define CLK_AVC_ME_SEARCH_WINDOW_4x4_RADIUS_INTEL 0x2
#define CLK_AVC_ME_SEARCH_WINDOW_2x2_RADIUS_INTEL 0xa
// These types are built-in in Clang 5.0
#ifndef __CLANG_50__
#ifndef __VME_TYPES_DEFINED__
// Externally exposed device side VME.
// ... Defines ...
......@@ -221,71 +220,45 @@ float __attribute__((overloadable)) atomic_cmpxchg(volatile __local float *p, fl
// ... Types ...
typedef struct
{
uint4 x;
} intel_sub_group_avc_mce_payload_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_ime_payload_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_ref_payload_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_sic_payload_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_idm_payload_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_mce_result_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_ime_result_t;
typedef struct
{
uint8 x;
} intel_sub_group_avc_ime_result_single_reference_streamout_t;
typedef struct
{
uint8 x;
} intel_sub_group_avc_ime_result_dual_reference_streamout_t;
typedef struct
{
uint x;
} intel_sub_group_avc_ime_single_reference_streamin_t;
typedef struct
{
uint2 x;
} intel_sub_group_avc_ime_dual_reference_streamin_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_ref_result_t;
typedef struct
{
uint4 x;
} intel_sub_group_avc_sic_result_t;
#endif // !__CLANG_50__
struct intel_sub_group_avc_mce_payload_t;
typedef __private struct intel_sub_group_avc_mce_payload_t* intel_sub_group_avc_mce_payload_t;
struct intel_sub_group_avc_ime_payload_t;
typedef __private struct intel_sub_group_avc_ime_payload_t* intel_sub_group_avc_ime_payload_t;
struct intel_sub_group_avc_ref_payload_t;
typedef __private struct intel_sub_group_avc_ref_payload_t* intel_sub_group_avc_ref_payload_t;
struct intel_sub_group_avc_sic_payload_t;
typedef __private struct intel_sub_group_avc_sic_payload_t* intel_sub_group_avc_sic_payload_t;
struct intel_sub_group_avc_idm_payload_t;
typedef __private struct intel_sub_group_avc_idm_payload_t* intel_sub_group_avc_idm_payload_t;
struct intel_sub_group_avc_mce_result_t;
typedef __private struct intel_sub_group_avc_mce_result_t* intel_sub_group_avc_mce_result_t;
struct intel_sub_group_avc_ime_result_t;
typedef __private struct intel_sub_group_avc_ime_result_t* intel_sub_group_avc_ime_result_t;
struct intel_sub_group_avc_ime_result_single_reference_streamout_t;
typedef __private struct intel_sub_group_avc_ime_result_single_reference_streamout_t* intel_sub_group_avc_ime_result_single_reference_streamout_t;
struct intel_sub_group_avc_ime_result_dual_reference_streamout_t;
typedef __private struct intel_sub_group_avc_ime_result_dual_reference_streamout_t* intel_sub_group_avc_ime_result_dual_reference_streamout_t;
struct intel_sub_group_avc_ime_single_reference_streamin_t;
typedef __private struct intel_sub_group_avc_ime_single_reference_streamin_t* intel_sub_group_avc_ime_single_reference_streamin_t;
struct intel_sub_group_avc_ime_dual_reference_streamin_t;
typedef __private struct intel_sub_group_avc_ime_dual_reference_streamin_t* intel_sub_group_avc_ime_dual_reference_streamin_t;
struct intel_sub_group_avc_ref_result_t;
typedef __private struct intel_sub_group_avc_ref_result_t* intel_sub_group_avc_ref_result_t;
struct intel_sub_group_avc_sic_result_t;
typedef __private struct intel_sub_group_avc_sic_result_t* intel_sub_group_avc_sic_result_t;
#endif // !__VME_TYPES_DEFINED__
// ... Common VME operations ...
#pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable
......
......@@ -1056,14 +1056,6 @@ uint CShader::GetNbElementAndMask(llvm::Value* value, uint32_t& mask)
GenISAIntrinsic::ID IID = inst->getIntrinsicID();
switch (IID)
{
// The VME intrinsics can have sizes that don't correspond
// to a legal llvm type (i.e., an 11 GRF payload).
case GenISAIntrinsic::GenISA_vmeSendIME2:
// Number elements = {num GRFs} * {num DWords in GRF} = {num GRFs} * 8;
return GetIMEReturnPayloadSize(inst) * (SIZE_GRF / SIZE_DWORD);
case GenISAIntrinsic::GenISA_vmeSendFBR2:
case GenISAIntrinsic::GenISA_vmeSendSIC2:
return 7 * (SIZE_GRF / SIZE_DWORD);
case GenISAIntrinsic::GenISA_createMessagePhases:
case GenISAIntrinsic::GenISA_createMessagePhasesNoInit:
case GenISAIntrinsic::GenISA_createMessagePhasesV:
......@@ -1100,9 +1092,6 @@ uint CShader::GetNbElementAndMask(llvm::Value* value, uint32_t& mask)
case GenISAIntrinsic::GenISA_createMessagePhasesNoInit:
case GenISAIntrinsic::GenISA_createMessagePhasesV:
case GenISAIntrinsic::GenISA_createMessagePhasesNoInitV:
case GenISAIntrinsic::GenISA_vmeSendIME2:
case GenISAIntrinsic::GenISA_vmeSendFBR2:
case GenISAIntrinsic::GenISA_vmeSendSIC2:
return GetNbElementAndMask(inst, mask);
default:
break;
......
......@@ -335,7 +335,7 @@ static Type* GetBaseType(Type* pType)
if(pType->isStructTy())
{
int num_elements = pType->getStructNumElements();
if(num_elements > 1)
if(num_elements != 1)
return nullptr;
pType = pType->getStructElementType(0);
......
......@@ -87,6 +87,34 @@ void ExtensionFuncsResolution::visitCallInst(CallInst &CI)
{
argType = ImplicitArg::VME_SEARCH_PATH_TYPE;
}
else if (funcName.startswith(ExtensionFuncsAnalysis::VME_HELPER_GET_HANDLE)) {
// Load from the opaque vme pointer and return the a vector with values.
assert(CI.getNumArgOperands() == 1);
IRBuilder<> builder(&CI);
Type* retType = CI.getType();
assert(retType->isVectorTy() || retType->isIntegerTy());
PointerType* ptrType = PointerType::get(retType, 0);
auto bitcastInst = builder.CreateBitCast(CI.getArgOperand(0), ptrType);
auto ret = builder.CreateLoad(bitcastInst);
CI.replaceAllUsesWith(ret);
CI.eraseFromParent();
return;
}
else if (funcName.startswith(ExtensionFuncsAnalysis::VME_HELPER_GET_AS)) {
// Store the VME values and return an opaque vme pointer.
assert(CI.getNumArgOperands() == 1);
IRBuilder<> builder(&*CI.getParent()->getParent()->begin()->getFirstInsertionPt());
Type* retType = CI.getType();
Value* arg = CI.getArgOperand(0);
assert(arg->getType()->isVectorTy() || arg->getType()->isIntegerTy());
AllocaInst* allocaInst = builder.CreateAlloca(arg->getType());
builder.SetInsertPoint(&CI);
builder.CreateStore(arg, allocaInst);
Value* bitcastInst = builder.CreateBitCast(allocaInst, retType);
CI.replaceAllUsesWith(bitcastInst);
CI.eraseFromParent();
return;
}
else {
// Non VME function, do nothing
return;
......
......@@ -51,6 +51,8 @@ const StringRef ExtensionFuncsAnalysis::VME_MB_BLOCK_TYPE = "__builtin_IB_vme_mb
const StringRef ExtensionFuncsAnalysis::VME_SUBPIXEL_MODE = "__builtin_IB_vme_subpixel_mode";
const StringRef ExtensionFuncsAnalysis::VME_SAD_ADJUST_MODE = "__builtin_IB_vme_sad_adjust_mode";
const StringRef ExtensionFuncsAnalysis::VME_SEARCH_PATH_TYPE = "__builtin_IB_vme_search_path_type";
const StringRef ExtensionFuncsAnalysis::VME_HELPER_GET_HANDLE = "__builtin_IB_vme_helper_get_handle";
const StringRef ExtensionFuncsAnalysis::VME_HELPER_GET_AS = "__builtin_IB_vme_helper_get_as";
bool ExtensionFuncsAnalysis::runOnModule(Module &M)
{
......@@ -103,7 +105,9 @@ void ExtensionFuncsAnalysis::visitCallInst(CallInst &CI)
if (funcName.equals(VME_MB_BLOCK_TYPE) ||
funcName.equals(VME_SUBPIXEL_MODE) ||
funcName.equals(VME_SAD_ADJUST_MODE) ||
funcName.equals(VME_SEARCH_PATH_TYPE))
funcName.equals(VME_SEARCH_PATH_TYPE) ||
funcName.startswith(VME_HELPER_GET_HANDLE) ||
funcName.startswith(VME_HELPER_GET_AS))
{
m_hasVME = true;
}
......
......@@ -85,6 +85,8 @@ namespace IGC
static const llvm::StringRef VME_SUBPIXEL_MODE;
static const llvm::StringRef VME_SAD_ADJUST_MODE;
static const llvm::StringRef VME_SEARCH_PATH_TYPE;
static const llvm::StringRef VME_HELPER_GET_HANDLE;
static const llvm::StringRef VME_HELPER_GET_AS;
private:
/// @brief Marks whether VME information is needed by the current function
......
......@@ -804,6 +804,23 @@ namespace TC
#endif
}
/*****************************************************************************\
Function:
AreVMETypesDefined
Description:
Returns true if Clang used on current OS has VME types defined.
\*****************************************************************************/
bool AreVMETypesDefined()
{
#if defined __linux__
return false;
#endif
return true;
}
/*****************************************************************************\
Function:
......@@ -1319,6 +1336,10 @@ namespace TC
break;
}
if (AreVMETypesDefined()) {
optionsEx += " -D__VME_TYPES_DEFINED__";
}
if (options.find("-triple") == std::string::npos) {
// if target triple not explicitly set
if (pInputArgs->b32bit)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment