xref: /llvm-project/llvm/lib/IR/VectorBuilder.cpp (revision fa789dffb1e12c2aece0187aeacc48dfb1768340)
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