summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/VectorTypeUtils.cpp
blob: 62e39aab90079ccd2b1f82522c5d2a61ac3da231 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//===------- VectorTypeUtils.cpp - Vector type utility functions ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/VectorTypeUtils.h"
#include "llvm/ADT/SmallVectorExtras.h"

using namespace llvm;

/// A helper for converting structs of scalar types to structs of vector types.
/// Note: Only unpacked literal struct types are supported.
Type *llvm::toVectorizedStructTy(StructType *StructTy, ElementCount EC) {
  if (EC.isScalar())
    return StructTy;
  assert(isUnpackedStructLiteral(StructTy) &&
         "expected unpacked struct literal");
  assert(all_of(StructTy->elements(), VectorType::isValidElementType) &&
         "expected all element types to be valid vector element types");
  return StructType::get(
      StructTy->getContext(),
      map_to_vector(StructTy->elements(), [&](Type *ElTy) -> Type * {
        return VectorType::get(ElTy, EC);
      }));
}

/// A helper for converting structs of vector types to structs of scalar types.
/// Note: Only unpacked literal struct types are supported.
Type *llvm::toScalarizedStructTy(StructType *StructTy) {
  assert(isUnpackedStructLiteral(StructTy) &&
         "expected unpacked struct literal");
  return StructType::get(
      StructTy->getContext(),
      map_to_vector(StructTy->elements(), [](Type *ElTy) -> Type * {
        return ElTy->getScalarType();
      }));
}

/// Returns true if `StructTy` is an unpacked literal struct where all elements
/// are vectors of matching element count. This does not include empty structs.
bool llvm::isVectorizedStructTy(StructType *StructTy) {
  if (!isUnpackedStructLiteral(StructTy))
    return false;
  auto ElemTys = StructTy->elements();
  if (ElemTys.empty() || !ElemTys.front()->isVectorTy())
    return false;
  ElementCount VF = cast<VectorType>(ElemTys.front())->getElementCount();
  return all_of(ElemTys, [&](Type *Ty) {
    return Ty->isVectorTy() && cast<VectorType>(Ty)->getElementCount() == VF;
  });
}

/// Returns true if `StructTy` is an unpacked literal struct where all elements
/// are scalars that can be used as vector element types.
bool llvm::canVectorizeStructTy(StructType *StructTy) {
  auto ElemTys = StructTy->elements();
  return !ElemTys.empty() && isUnpackedStructLiteral(StructTy) &&
         all_of(ElemTys, VectorType::isValidElementType);
}