|
|
@@ -1,32 +1,32 @@ |
|
|
|
/**************************************************************************** |
|
|
|
* Copyright (C) 2014-2015 Intel Corporation. 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 in 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: |
|
|
|
* |
|
|
|
* The above copyright notice and this permission notice (including the next |
|
|
|
* paragraph) shall be included in all copies or substantial portions of the |
|
|
|
* Software. |
|
|
|
* |
|
|
|
* 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 AUTHORS 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 |
|
|
|
* IN THE SOFTWARE. |
|
|
|
* |
|
|
|
* @file builder.h |
|
|
|
* |
|
|
|
* @brief Includes all the builder related functionality |
|
|
|
* |
|
|
|
* Notes: |
|
|
|
* |
|
|
|
******************************************************************************/ |
|
|
|
* Copyright (C) 2014-2015 Intel Corporation. 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 in 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: |
|
|
|
* |
|
|
|
* The above copyright notice and this permission notice (including the next |
|
|
|
* paragraph) shall be included in all copies or substantial portions of the |
|
|
|
* Software. |
|
|
|
* |
|
|
|
* 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 AUTHORS 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 |
|
|
|
* IN THE SOFTWARE. |
|
|
|
* |
|
|
|
* @file builder.h |
|
|
|
* |
|
|
|
* @brief Includes all the builder related functionality |
|
|
|
* |
|
|
|
* Notes: |
|
|
|
* |
|
|
|
******************************************************************************/ |
|
|
|
|
|
|
|
#include "jit_pch.hpp" |
|
|
|
#include "builder.h" |
|
|
@@ -38,11 +38,9 @@ namespace SwrJit |
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
/// @brief Contructor for Builder. |
|
|
|
/// @param pJitMgr - JitManager which contains modules, function passes, etc. |
|
|
|
Builder::Builder(JitManager *pJitMgr) |
|
|
|
: mpJitMgr(pJitMgr), |
|
|
|
mpPrivateContext(nullptr) |
|
|
|
Builder::Builder(JitManager *pJitMgr) : mpJitMgr(pJitMgr), mpPrivateContext(nullptr) |
|
|
|
{ |
|
|
|
mVWidth = pJitMgr->mVWidth; |
|
|
|
mVWidth = pJitMgr->mVWidth; |
|
|
|
mVWidth16 = 16; |
|
|
|
|
|
|
|
mpIRBuilder = &pJitMgr->mBuilder; |
|
|
@@ -70,29 +68,29 @@ namespace SwrJit |
|
|
|
|
|
|
|
// Built in types: simd16 |
|
|
|
|
|
|
|
mSimd16Int1Ty = VectorType::get(mInt1Ty, mVWidth16); |
|
|
|
mSimd16Int16Ty = VectorType::get(mInt16Ty, mVWidth16); |
|
|
|
mSimd16Int32Ty = VectorType::get(mInt32Ty, mVWidth16); |
|
|
|
mSimd16Int64Ty = VectorType::get(mInt64Ty, mVWidth16); |
|
|
|
mSimd16FP16Ty = VectorType::get(mFP16Ty, mVWidth16); |
|
|
|
mSimd16FP32Ty = VectorType::get(mFP32Ty, mVWidth16); |
|
|
|
mSimd16VectorTy = ArrayType::get(mSimd16FP32Ty, 4); |
|
|
|
mSimd16VectorTRTy = ArrayType::get(mSimd16FP32Ty, 5); |
|
|
|
mSimd16Int1Ty = VectorType::get(mInt1Ty, mVWidth16); |
|
|
|
mSimd16Int16Ty = VectorType::get(mInt16Ty, mVWidth16); |
|
|
|
mSimd16Int32Ty = VectorType::get(mInt32Ty, mVWidth16); |
|
|
|
mSimd16Int64Ty = VectorType::get(mInt64Ty, mVWidth16); |
|
|
|
mSimd16FP16Ty = VectorType::get(mFP16Ty, mVWidth16); |
|
|
|
mSimd16FP32Ty = VectorType::get(mFP32Ty, mVWidth16); |
|
|
|
mSimd16VectorTy = ArrayType::get(mSimd16FP32Ty, 4); |
|
|
|
mSimd16VectorTRTy = ArrayType::get(mSimd16FP32Ty, 5); |
|
|
|
|
|
|
|
mSimd32Int8Ty = VectorType::get(mInt8Ty, 32); |
|
|
|
mSimd32Int8Ty = VectorType::get(mInt8Ty, 32); |
|
|
|
|
|
|
|
if (sizeof(uint32_t*) == 4) |
|
|
|
if (sizeof(uint32_t *) == 4) |
|
|
|
{ |
|
|
|
mIntPtrTy = mInt32Ty; |
|
|
|
mSimdIntPtrTy = mSimdInt32Ty; |
|
|
|
mIntPtrTy = mInt32Ty; |
|
|
|
mSimdIntPtrTy = mSimdInt32Ty; |
|
|
|
mSimd16IntPtrTy = mSimd16Int32Ty; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
SWR_ASSERT(sizeof(uint32_t*) == 8); |
|
|
|
SWR_ASSERT(sizeof(uint32_t *) == 8); |
|
|
|
|
|
|
|
mIntPtrTy = mInt64Ty; |
|
|
|
mSimdIntPtrTy = mSimdInt64Ty; |
|
|
|
mIntPtrTy = mInt64Ty; |
|
|
|
mSimdIntPtrTy = mSimdInt64Ty; |
|
|
|
mSimd16IntPtrTy = mSimd16Int64Ty; |
|
|
|
} |
|
|
|
} |
|
|
@@ -101,53 +99,53 @@ namespace SwrJit |
|
|
|
{ |
|
|
|
mVWidth = width; |
|
|
|
|
|
|
|
mSimdInt1Ty = VectorType::get(mInt1Ty, mVWidth); |
|
|
|
mSimdInt16Ty = VectorType::get(mInt16Ty, mVWidth); |
|
|
|
mSimdInt32Ty = VectorType::get(mInt32Ty, mVWidth); |
|
|
|
mSimdInt64Ty = VectorType::get(mInt64Ty, mVWidth); |
|
|
|
mSimdFP16Ty = VectorType::get(mFP16Ty, mVWidth); |
|
|
|
mSimdFP32Ty = VectorType::get(mFP32Ty, mVWidth); |
|
|
|
mSimdVectorTy = ArrayType::get(mSimdFP32Ty, 4); |
|
|
|
mSimdInt1Ty = VectorType::get(mInt1Ty, mVWidth); |
|
|
|
mSimdInt16Ty = VectorType::get(mInt16Ty, mVWidth); |
|
|
|
mSimdInt32Ty = VectorType::get(mInt32Ty, mVWidth); |
|
|
|
mSimdInt64Ty = VectorType::get(mInt64Ty, mVWidth); |
|
|
|
mSimdFP16Ty = VectorType::get(mFP16Ty, mVWidth); |
|
|
|
mSimdFP32Ty = VectorType::get(mFP32Ty, mVWidth); |
|
|
|
mSimdVectorTy = ArrayType::get(mSimdFP32Ty, 4); |
|
|
|
mSimdVectorIntTy = ArrayType::get(mSimdInt32Ty, 4); |
|
|
|
mSimdVectorTRTy = ArrayType::get(mSimdFP32Ty, 5); |
|
|
|
mSimdVectorTRTy = ArrayType::get(mSimdFP32Ty, 5); |
|
|
|
} |
|
|
|
|
|
|
|
/// @brief Mark this alloca as temporary to avoid hoisting later on |
|
|
|
void Builder::SetTempAlloca(Value* inst) |
|
|
|
void Builder::SetTempAlloca(Value *inst) |
|
|
|
{ |
|
|
|
AllocaInst* pAlloca = dyn_cast<AllocaInst>(inst); |
|
|
|
AllocaInst *pAlloca = dyn_cast<AllocaInst>(inst); |
|
|
|
SWR_ASSERT(pAlloca, "Unexpected non-alloca instruction"); |
|
|
|
MDNode* N = MDNode::get(JM()->mContext, MDString::get(JM()->mContext, "is_temp_alloca")); |
|
|
|
MDNode *N = MDNode::get(JM()->mContext, MDString::get(JM()->mContext, "is_temp_alloca")); |
|
|
|
pAlloca->setMetadata("is_temp_alloca", N); |
|
|
|
} |
|
|
|
|
|
|
|
bool Builder::IsTempAlloca(Value* inst) |
|
|
|
bool Builder::IsTempAlloca(Value *inst) |
|
|
|
{ |
|
|
|
AllocaInst* pAlloca = dyn_cast<AllocaInst>(inst); |
|
|
|
AllocaInst *pAlloca = dyn_cast<AllocaInst>(inst); |
|
|
|
SWR_ASSERT(pAlloca, "Unexpected non-alloca instruction"); |
|
|
|
|
|
|
|
return (pAlloca->getMetadata("is_temp_alloca") != nullptr); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns true if able to find an intrinsic to mark |
|
|
|
bool Builder::SetTexelMaskEvaluate(Instruction* inst) |
|
|
|
// Returns true if able to find a call instruction to mark |
|
|
|
bool Builder::SetNamedMetaDataOnCallInstr(Instruction *inst, StringRef mdName) |
|
|
|
{ |
|
|
|
CallInst* pGenIntrin = dyn_cast<CallInst>(inst); |
|
|
|
if (pGenIntrin) |
|
|
|
CallInst *pCallInstr = dyn_cast<CallInst>(inst); |
|
|
|
if (pCallInstr) |
|
|
|
{ |
|
|
|
MDNode* N = MDNode::get(JM()->mContext, MDString::get(JM()->mContext, "is_evaluate")); |
|
|
|
pGenIntrin->setMetadata("is_evaluate", N); |
|
|
|
MDNode *N = MDNode::get(JM()->mContext, MDString::get(JM()->mContext, mdName)); |
|
|
|
pCallInstr->setMetadata(mdName, N); |
|
|
|
return true; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// Follow use def chain back up |
|
|
|
for (Use& u : inst->operands()) |
|
|
|
for (Use &u : inst->operands()) |
|
|
|
{ |
|
|
|
Instruction* srcInst = dyn_cast<Instruction>(u.get()); |
|
|
|
Instruction *srcInst = dyn_cast<Instruction>(u.get()); |
|
|
|
if (srcInst) |
|
|
|
{ |
|
|
|
if (SetTexelMaskEvaluate(srcInst)) |
|
|
|
if (SetNamedMetaDataOnCallInstr(srcInst, mdName)) |
|
|
|
{ |
|
|
|
return true; |
|
|
|
} |
|
|
@@ -158,21 +156,22 @@ namespace SwrJit |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
bool Builder::IsTexelMaskEvaluate(Instruction* genSampleOrLoadIntrinsic) |
|
|
|
bool Builder::HasNamedMetaDataOnCallInstr(Instruction *inst, |
|
|
|
StringRef mdName) |
|
|
|
{ |
|
|
|
CallInst* pGenIntrin = dyn_cast<CallInst>(genSampleOrLoadIntrinsic); |
|
|
|
CallInst *pCallInstr = dyn_cast<CallInst>(inst); |
|
|
|
|
|
|
|
if (!pGenIntrin) |
|
|
|
if (!pCallInstr) |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return (pGenIntrin->getMetadata("is_evaluate") != nullptr); |
|
|
|
return (pCallInstr->getMetadata(mdName) != nullptr); |
|
|
|
} |
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
/// @brief Packetizes the type. Assumes SOA conversion. |
|
|
|
Type* Builder::GetVectorType(Type* pType) |
|
|
|
Type *Builder::GetVectorType(Type *pType) |
|
|
|
{ |
|
|
|
if (pType->isVectorTy()) |
|
|
|
{ |
|
|
@@ -182,36 +181,37 @@ namespace SwrJit |
|
|
|
// [N x float] should packetize to [N x <8 x float>] |
|
|
|
if (pType->isArrayTy()) |
|
|
|
{ |
|
|
|
uint32_t arraySize = pType->getArrayNumElements(); |
|
|
|
Type* pArrayType = pType->getArrayElementType(); |
|
|
|
Type* pVecArrayType = GetVectorType(pArrayType); |
|
|
|
Type* pVecType = ArrayType::get(pVecArrayType, arraySize); |
|
|
|
uint32_t arraySize = pType->getArrayNumElements(); |
|
|
|
Type * pArrayType = pType->getArrayElementType(); |
|
|
|
Type * pVecArrayType = GetVectorType(pArrayType); |
|
|
|
Type * pVecType = ArrayType::get(pVecArrayType, arraySize); |
|
|
|
return pVecType; |
|
|
|
} |
|
|
|
|
|
|
|
// {float,int} should packetize to {<8 x float>, <8 x int>} |
|
|
|
if (pType->isAggregateType()) |
|
|
|
{ |
|
|
|
uint32_t numElems = pType->getStructNumElements(); |
|
|
|
SmallVector<Type*, 8> vecTypes; |
|
|
|
uint32_t numElems = pType->getStructNumElements(); |
|
|
|
SmallVector<Type *, 8> vecTypes; |
|
|
|
for (uint32_t i = 0; i < numElems; ++i) |
|
|
|
{ |
|
|
|
Type* pElemType = pType->getStructElementType(i); |
|
|
|
Type* pVecElemType = GetVectorType(pElemType); |
|
|
|
Type *pElemType = pType->getStructElementType(i); |
|
|
|
Type *pVecElemType = GetVectorType(pElemType); |
|
|
|
vecTypes.push_back(pVecElemType); |
|
|
|
} |
|
|
|
Type* pVecType = StructType::get(JM()->mContext, vecTypes); |
|
|
|
Type *pVecType = StructType::get(JM()->mContext, vecTypes); |
|
|
|
return pVecType; |
|
|
|
} |
|
|
|
|
|
|
|
// [N x float]* should packetize to [N x <8 x float>]* |
|
|
|
if (pType->isPointerTy() && pType->getPointerElementType()->isArrayTy()) |
|
|
|
{ |
|
|
|
return PointerType::get(GetVectorType(pType->getPointerElementType()), pType->getPointerAddressSpace()); |
|
|
|
return PointerType::get(GetVectorType(pType->getPointerElementType()), |
|
|
|
pType->getPointerAddressSpace()); |
|
|
|
} |
|
|
|
|
|
|
|
// <ty> should packetize to <8 x <ty>> |
|
|
|
Type* vecType = VectorType::get(pType, JM()->mVWidth); |
|
|
|
Type *vecType = VectorType::get(pType, JM()->mVWidth); |
|
|
|
return vecType; |
|
|
|
} |
|
|
|
} |