123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- //===- VectorBuilder.cpp - Builder for VP Intrinsics ----------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements the VectorBuilder class, which is used as a convenient
- // way to create VP intrinsics as if they were LLVM instructions with a
- // consistent and simplified interface.
- //
- //===----------------------------------------------------------------------===//
- #include <llvm/ADT/SmallVector.h>
- #include <llvm/IR/FPEnv.h>
- #include <llvm/IR/Instructions.h>
- #include <llvm/IR/IntrinsicInst.h>
- #include <llvm/IR/Intrinsics.h>
- #include <llvm/IR/VectorBuilder.h>
- namespace llvm {
- void VectorBuilder::handleError(const char *ErrorMsg) const {
- if (ErrorHandling == Behavior::SilentlyReturnNone)
- return;
- report_fatal_error(ErrorMsg);
- }
- Module &VectorBuilder::getModule() const {
- return *Builder.GetInsertBlock()->getModule();
- }
- Value *VectorBuilder::getAllTrueMask() {
- auto *BoolTy = Builder.getInt1Ty();
- auto *MaskTy = VectorType::get(BoolTy, StaticVectorLength);
- return ConstantInt::getAllOnesValue(MaskTy);
- }
- Value &VectorBuilder::requestMask() {
- if (Mask)
- return *Mask;
- return *getAllTrueMask();
- }
- Value &VectorBuilder::requestEVL() {
- if (ExplicitVectorLength)
- return *ExplicitVectorLength;
- assert(!StaticVectorLength.isScalable() && "TODO vscale lowering");
- auto *IntTy = Builder.getInt32Ty();
- return *ConstantInt::get(IntTy, StaticVectorLength.getFixedValue());
- }
- Value *VectorBuilder::createVectorInstruction(unsigned Opcode, Type *ReturnTy,
- ArrayRef<Value *> InstOpArray,
- const Twine &Name) {
- auto VPID = VPIntrinsic::getForOpcode(Opcode);
- if (VPID == Intrinsic::not_intrinsic)
- return returnWithError<Value *>("No VPIntrinsic for this opcode");
- auto MaskPosOpt = VPIntrinsic::getMaskParamPos(VPID);
- auto VLenPosOpt = VPIntrinsic::getVectorLengthParamPos(VPID);
- size_t NumInstParams = InstOpArray.size();
- size_t NumVPParams =
- NumInstParams + MaskPosOpt.has_value() + VLenPosOpt.has_value();
- SmallVector<Value *, 6> IntrinParams;
- // Whether the mask and vlen parameter are at the end of the parameter list.
- bool TrailingMaskAndVLen =
- std::min<size_t>(MaskPosOpt.value_or(NumInstParams),
- VLenPosOpt.value_or(NumInstParams)) >= NumInstParams;
- if (TrailingMaskAndVLen) {
- // Fast path for trailing mask, vector length.
- IntrinParams.append(InstOpArray.begin(), InstOpArray.end());
- IntrinParams.resize(NumVPParams);
- } else {
- IntrinParams.resize(NumVPParams);
- // Insert mask and evl operands in between the instruction operands.
- for (size_t VPParamIdx = 0, ParamIdx = 0; VPParamIdx < NumVPParams;
- ++VPParamIdx) {
- if ((MaskPosOpt && MaskPosOpt.value_or(NumVPParams) == VPParamIdx) ||
- (VLenPosOpt && VLenPosOpt.value_or(NumVPParams) == VPParamIdx))
- continue;
- assert(ParamIdx < NumInstParams);
- IntrinParams[VPParamIdx] = InstOpArray[ParamIdx++];
- }
- }
- if (MaskPosOpt)
- IntrinParams[*MaskPosOpt] = &requestMask();
- if (VLenPosOpt)
- IntrinParams[*VLenPosOpt] = &requestEVL();
- auto *VPDecl = VPIntrinsic::getDeclarationForParams(&getModule(), VPID,
- ReturnTy, IntrinParams);
- return Builder.CreateCall(VPDecl, IntrinParams, Name);
- }
- } // namespace llvm
|