aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp b/contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp
new file mode 100644
index 000000000000..e7be7a98a593
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/IR/VectorBuilder.cpp
@@ -0,0 +1,103 @@
+//===- 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