1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2018-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #include "llvmWrapper/IR/DerivedTypes.h" 10 11 #include "PacketBuilder.h" 12 #include "Probe/Assertion.h" 13 14 using namespace llvm; 15 16 namespace pktz 17 { 18 ////////////////////////////////////////////////////////////////////////// 19 /// @brief Contructor for Builder. 20 /// @param pJitMgr - JitManager which contains modules, function passes, etc. PacketBuilder(Module * pModule,uint32_t width)21 PacketBuilder::PacketBuilder(Module *pModule, uint32_t width) 22 { 23 mVWidth16 = 16; 24 mpModule = static_cast<IGCLLVM::Module*>(pModule); 25 26 // Built in types: scalar 27 LLVMContext& Ctx = getContext(); 28 mpIRBuilder = new IGCLLVM::IRBuilder<>(Ctx); 29 mVoidTy = Type::getVoidTy(Ctx); 30 mFP16Ty = Type::getHalfTy(Ctx); 31 mFP32Ty = Type::getFloatTy(Ctx); 32 mFP32PtrTy = PointerType::get(mFP32Ty, 0); 33 mDoubleTy = Type::getDoubleTy(Ctx); 34 mInt1Ty = Type::getInt1Ty(Ctx); 35 mInt8Ty = Type::getInt8Ty(Ctx); 36 mInt16Ty = Type::getInt16Ty(Ctx); 37 mInt32Ty = Type::getInt32Ty(Ctx); 38 mInt8PtrTy = PointerType::get(mInt8Ty, 0); 39 mInt16PtrTy = PointerType::get(mInt16Ty, 0); 40 mInt32PtrTy = PointerType::get(mInt32Ty, 0); 41 mInt64Ty = Type::getInt64Ty(Ctx); 42 43 mSimd4FP64Ty = IGCLLVM::FixedVectorType::get(mDoubleTy, 4); 44 45 // Built in types: simd16 46 mSimd16Int1Ty = IGCLLVM::FixedVectorType::get(mInt1Ty, mVWidth16); 47 mSimd16Int16Ty = IGCLLVM::FixedVectorType::get(mInt16Ty, mVWidth16); 48 mSimd16Int32Ty = IGCLLVM::FixedVectorType::get(mInt32Ty, mVWidth16); 49 mSimd16Int64Ty = IGCLLVM::FixedVectorType::get(mInt64Ty, mVWidth16); 50 mSimd16FP16Ty = IGCLLVM::FixedVectorType::get(mFP16Ty, mVWidth16); 51 mSimd16FP32Ty = IGCLLVM::FixedVectorType::get(mFP32Ty, mVWidth16); 52 53 mSimd32Int8Ty = IGCLLVM::FixedVectorType::get(mInt8Ty, 32); 54 55 if (sizeof(uint32_t*) == 4) 56 { 57 mIntPtrTy = mInt32Ty; 58 mSimd16IntPtrTy = mSimd16Int32Ty; 59 } 60 else 61 { 62 IGC_ASSERT(sizeof(uint32_t*) == 8); 63 mIntPtrTy = mInt64Ty; 64 mSimd16IntPtrTy = mSimd16Int64Ty; 65 } 66 // Built in types: target simd 67 SetTargetWidth(width); 68 69 } 70 SetTargetWidth(uint32_t width)71 void PacketBuilder::SetTargetWidth(uint32_t width) 72 { 73 mVWidth = width; 74 75 mSimdInt1Ty = IGCLLVM::FixedVectorType::get(mInt1Ty, mVWidth); 76 mSimdInt16Ty = IGCLLVM::FixedVectorType::get(mInt16Ty, mVWidth); 77 mSimdInt32Ty = IGCLLVM::FixedVectorType::get(mInt32Ty, mVWidth); 78 mSimdInt64Ty = IGCLLVM::FixedVectorType::get(mInt64Ty, mVWidth); 79 mSimdFP16Ty = IGCLLVM::FixedVectorType::get(mFP16Ty, mVWidth); 80 mSimdFP32Ty = IGCLLVM::FixedVectorType::get(mFP32Ty, mVWidth); 81 if (sizeof(uint32_t*) == 4) 82 { 83 mSimdIntPtrTy = mSimdInt32Ty; 84 } 85 else 86 { 87 IGC_ASSERT(sizeof(uint32_t*) == 8); 88 mSimdIntPtrTy = mSimdInt64Ty; 89 } 90 } 91 92 /// @brief Mark this alloca as temporary to avoid hoisting later on SetTempAlloca(Value * inst)93 void PacketBuilder::SetTempAlloca(Value* inst) 94 { 95 AllocaInst* pAlloca = dyn_cast<AllocaInst>(inst); 96 IGC_ASSERT_MESSAGE(pAlloca, "Unexpected non-alloca instruction"); 97 MDNode* N = MDNode::get(getContext(), MDString::get(getContext(), "is_temp_alloca")); 98 pAlloca->setMetadata("is_temp_alloca", N); 99 } 100 IsTempAlloca(Value * inst)101 bool PacketBuilder::IsTempAlloca(Value* inst) 102 { 103 AllocaInst* pAlloca = dyn_cast<AllocaInst>(inst); 104 IGC_ASSERT_MESSAGE(pAlloca, "Unexpected non-alloca instruction"); 105 106 return (pAlloca->getMetadata("is_temp_alloca") != nullptr); 107 } 108 109 // Returns true if able to find a call instruction to mark SetNamedMetaDataOnCallInstr(Instruction * inst,StringRef mdName)110 bool PacketBuilder::SetNamedMetaDataOnCallInstr(Instruction* inst, StringRef mdName) 111 { 112 CallInst* pCallInstr = dyn_cast<CallInst>(inst); 113 if (pCallInstr) 114 { 115 MDNode* N = MDNode::get(getContext(), MDString::get(getContext(), mdName)); 116 pCallInstr->setMetadata(mdName, N); 117 return true; 118 } 119 else 120 { 121 // Follow use def chain back up 122 for (Use& u : inst->operands()) 123 { 124 Instruction* srcInst = dyn_cast<Instruction>(u.get()); 125 if (srcInst) 126 { 127 if (SetNamedMetaDataOnCallInstr(srcInst, mdName)) 128 { 129 return true; 130 } 131 } 132 } 133 } 134 135 return false; 136 } 137 HasNamedMetaDataOnCallInstr(Instruction * inst,StringRef mdName)138 bool PacketBuilder::HasNamedMetaDataOnCallInstr(Instruction* inst, StringRef mdName) 139 { 140 CallInst* pCallInstr = dyn_cast<CallInst>(inst); 141 142 if (!pCallInstr) 143 { 144 return false; 145 } 146 147 return (pCallInstr->getMetadata(mdName) != nullptr); 148 } 149 150 ////////////////////////////////////////////////////////////////////////// 151 /// @brief Packetizes the type. Assumes SOA conversion. GetVectorType(Type * pType)152 Type* PacketBuilder::GetVectorType(Type* pType) 153 { 154 if (pType->isVoidTy()) 155 return pType; 156 157 if (auto VecpType = dyn_cast<IGCLLVM::FixedVectorType>(pType)) { 158 uint32_t vectorSize = VecpType->getNumElements(); 159 Type *pElemType = VecpType->getElementType(); 160 Type *pVecType = 161 IGCLLVM::FixedVectorType::get(pElemType, vectorSize * mVWidth); 162 return pVecType; 163 } 164 165 // [N x float] should packetize to [N x <8 x float>] 166 if (pType->isArrayTy()) 167 { 168 uint32_t arraySize = pType->getArrayNumElements(); 169 Type* pArrayType = pType->getArrayElementType(); 170 Type* pVecArrayType = GetVectorType(pArrayType); 171 Type* pVecType = ArrayType::get(pVecArrayType, arraySize); 172 return pVecType; 173 } 174 175 // {float,int} should packetize to {<8 x float>, <8 x int>} 176 if (pType->isAggregateType()) 177 { 178 uint32_t numElems = pType->getStructNumElements(); 179 SmallVector<Type*, 8> vecTypes; 180 for (uint32_t i = 0; i < numElems; ++i) 181 { 182 Type* pElemType = pType->getStructElementType(i); 183 Type* pVecElemType = GetVectorType(pElemType); 184 vecTypes.push_back(pVecElemType); 185 } 186 Type* pVecType = StructType::get(getContext(), vecTypes); 187 return pVecType; 188 } 189 190 // <ty> should packetize to <8 x <ty>> 191 Type *vecType = IGCLLVM::FixedVectorType::get(pType, mVWidth); 192 return vecType; 193 } 194 } // end of namespace pktz 195