15f621567SSimon Moll //===- VectorBuilder.cpp - Builder for VP Intrinsics ----------------------===// 25f621567SSimon Moll // 35f621567SSimon Moll // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f621567SSimon Moll // See https://llvm.org/LICENSE.txt for license information. 55f621567SSimon Moll // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f621567SSimon Moll // 75f621567SSimon Moll //===----------------------------------------------------------------------===// 85f621567SSimon Moll // 95f621567SSimon Moll // This file implements the VectorBuilder class, which is used as a convenient 105f621567SSimon Moll // way to create VP intrinsics as if they were LLVM instructions with a 115f621567SSimon Moll // consistent and simplified interface. 125f621567SSimon Moll // 135f621567SSimon Moll //===----------------------------------------------------------------------===// 145f621567SSimon Moll 155f621567SSimon Moll #include <llvm/ADT/SmallVector.h> 165f621567SSimon Moll #include <llvm/IR/FPEnv.h> 175f621567SSimon Moll #include <llvm/IR/Instructions.h> 185f621567SSimon Moll #include <llvm/IR/IntrinsicInst.h> 195f621567SSimon Moll #include <llvm/IR/Intrinsics.h> 205f621567SSimon Moll #include <llvm/IR/VectorBuilder.h> 215f621567SSimon Moll 225f621567SSimon Moll namespace llvm { 235f621567SSimon Moll 245f621567SSimon Moll void VectorBuilder::handleError(const char *ErrorMsg) const { 255f621567SSimon Moll if (ErrorHandling == Behavior::SilentlyReturnNone) 265f621567SSimon Moll return; 275f621567SSimon Moll report_fatal_error(ErrorMsg); 285f621567SSimon Moll } 295f621567SSimon Moll 305f621567SSimon Moll Module &VectorBuilder::getModule() const { 315f621567SSimon Moll return *Builder.GetInsertBlock()->getModule(); 325f621567SSimon Moll } 335f621567SSimon Moll 345f621567SSimon Moll Value *VectorBuilder::getAllTrueMask() { 359959cdb6SPhilip Reames return Builder.getAllOnesMask(StaticVectorLength); 365f621567SSimon Moll } 375f621567SSimon Moll 385f621567SSimon Moll Value &VectorBuilder::requestMask() { 395f621567SSimon Moll if (Mask) 405f621567SSimon Moll return *Mask; 415f621567SSimon Moll 425f621567SSimon Moll return *getAllTrueMask(); 435f621567SSimon Moll } 445f621567SSimon Moll 455f621567SSimon Moll Value &VectorBuilder::requestEVL() { 465f621567SSimon Moll if (ExplicitVectorLength) 475f621567SSimon Moll return *ExplicitVectorLength; 485f621567SSimon Moll 495f621567SSimon Moll assert(!StaticVectorLength.isScalable() && "TODO vscale lowering"); 505f621567SSimon Moll auto *IntTy = Builder.getInt32Ty(); 515f621567SSimon Moll return *ConstantInt::get(IntTy, StaticVectorLength.getFixedValue()); 525f621567SSimon Moll } 535f621567SSimon Moll 545f621567SSimon Moll Value *VectorBuilder::createVectorInstruction(unsigned Opcode, Type *ReturnTy, 555f621567SSimon Moll ArrayRef<Value *> InstOpArray, 565f621567SSimon Moll const Twine &Name) { 575f621567SSimon Moll auto VPID = VPIntrinsic::getForOpcode(Opcode); 585f621567SSimon Moll if (VPID == Intrinsic::not_intrinsic) 595f621567SSimon Moll return returnWithError<Value *>("No VPIntrinsic for this opcode"); 604eb30cfbSMel Chen return createVectorInstructionImpl(VPID, ReturnTy, InstOpArray, Name); 614eb30cfbSMel Chen } 625f621567SSimon Moll 633e8840baSPhilip Reames Value *VectorBuilder::createSimpleReduction(Intrinsic::ID RdxID, 646d12b3f6SMel Chen Type *ValTy, 654eb30cfbSMel Chen ArrayRef<Value *> InstOpArray, 664eb30cfbSMel Chen const Twine &Name) { 676d12b3f6SMel Chen auto VPID = VPIntrinsic::getForIntrinsic(RdxID); 686d12b3f6SMel Chen assert(VPReductionIntrinsic::isVPReduction(VPID) && 696d12b3f6SMel Chen "No VPIntrinsic for this reduction"); 704eb30cfbSMel Chen return createVectorInstructionImpl(VPID, ValTy, InstOpArray, Name); 714eb30cfbSMel Chen } 724eb30cfbSMel Chen 734eb30cfbSMel Chen Value *VectorBuilder::createVectorInstructionImpl(Intrinsic::ID VPID, 744eb30cfbSMel Chen Type *ReturnTy, 754eb30cfbSMel Chen ArrayRef<Value *> InstOpArray, 764eb30cfbSMel Chen const Twine &Name) { 775f621567SSimon Moll auto MaskPosOpt = VPIntrinsic::getMaskParamPos(VPID); 785f621567SSimon Moll auto VLenPosOpt = VPIntrinsic::getVectorLengthParamPos(VPID); 795f621567SSimon Moll size_t NumInstParams = InstOpArray.size(); 805f621567SSimon Moll size_t NumVPParams = 810916d96dSKazu Hirata NumInstParams + MaskPosOpt.has_value() + VLenPosOpt.has_value(); 825f621567SSimon Moll 835f621567SSimon Moll SmallVector<Value *, 6> IntrinParams; 845f621567SSimon Moll 855f621567SSimon Moll // Whether the mask and vlen parameter are at the end of the parameter list. 865f621567SSimon Moll bool TrailingMaskAndVLen = 87129b531cSKazu Hirata std::min<size_t>(MaskPosOpt.value_or(NumInstParams), 88129b531cSKazu Hirata VLenPosOpt.value_or(NumInstParams)) >= NumInstParams; 895f621567SSimon Moll 905f621567SSimon Moll if (TrailingMaskAndVLen) { 915f621567SSimon Moll // Fast path for trailing mask, vector length. 925f621567SSimon Moll IntrinParams.append(InstOpArray.begin(), InstOpArray.end()); 935f621567SSimon Moll IntrinParams.resize(NumVPParams); 945f621567SSimon Moll } else { 955f621567SSimon Moll IntrinParams.resize(NumVPParams); 965f621567SSimon Moll // Insert mask and evl operands in between the instruction operands. 975f621567SSimon Moll for (size_t VPParamIdx = 0, ParamIdx = 0; VPParamIdx < NumVPParams; 985f621567SSimon Moll ++VPParamIdx) { 99b2cd81c9SKazu Hirata if (MaskPosOpt == VPParamIdx || VLenPosOpt == VPParamIdx) 1005f621567SSimon Moll continue; 1015f621567SSimon Moll assert(ParamIdx < NumInstParams); 1025f621567SSimon Moll IntrinParams[VPParamIdx] = InstOpArray[ParamIdx++]; 1035f621567SSimon Moll } 1045f621567SSimon Moll } 1055f621567SSimon Moll 106a7938c74SKazu Hirata if (MaskPosOpt) 1075f621567SSimon Moll IntrinParams[*MaskPosOpt] = &requestMask(); 108a7938c74SKazu Hirata if (VLenPosOpt) 1095f621567SSimon Moll IntrinParams[*VLenPosOpt] = &requestEVL(); 1105f621567SSimon Moll 111*fa789dffSRahul Joshi auto *VPDecl = VPIntrinsic::getOrInsertDeclarationForParams( 112*fa789dffSRahul Joshi &getModule(), VPID, ReturnTy, IntrinParams); 1135f621567SSimon Moll return Builder.CreateCall(VPDecl, IntrinParams, Name); 1145f621567SSimon Moll } 1155f621567SSimon Moll 1165f621567SSimon Moll } // namespace llvm 117