LLVM 24.0.0git
SLPCompatibilityAnalysis.h
Go to the documentation of this file.
1//===- SLPCompatibilityAnalysis.h - SLP same-opcode helpers ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Internal header used by SLPVectorizer.cpp. It declares the same-opcode
10// compatibility primitives that decide whether a group of values can be
11// treated as sharing the same (or an interchangeable/alternate) opcode. These
12// do not depend on BoUpSLP or any other SLP-private type.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPCOMPATIBILITYANALYSIS_H
17#define LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPCOMPATIBILITYANALYSIS_H
18
20#include "llvm/ADT/STLExtras.h"
22#include "llvm/IR/Instruction.h"
23
24#include <cstdint>
25#include <utility>
26
27namespace llvm {
28class Constant;
29class Value;
30} // namespace llvm
31
32namespace llvm::slpvectorizer {
33
34/// \returns true if \p Opcode is allowed as part of the main/alternate
35/// instruction for SLP vectorization.
36///
37/// Example of unsupported opcode is SDIV that can potentially cause UB if the
38/// "shuffled out" lane would result in division by zero.
39bool isValidForAlternation(unsigned Opcode);
40
41/// Helper class that determines VL can use the same opcode.
42/// Alternate instruction is supported. In addition, it supports interchangeable
43/// instruction. An interchangeable instruction is an instruction that can be
44/// converted to another instruction with same semantics. For example, x << 1 is
45/// equal to x * 2. x * 1 is equal to x | 0.
47 using MaskType = std::uint_fast32_t;
48 /// Sort SupportedOp because it is used by binary_search.
49 constexpr static unsigned SupportedOp[] = {
50 Instruction::Add, Instruction::FAdd, Instruction::Sub, Instruction::FSub,
51 Instruction::Mul, Instruction::Shl, Instruction::AShr, Instruction::And,
52 Instruction::Or, Instruction::Xor};
53 static_assert(llvm::is_sorted_constexpr(SupportedOp) &&
54 "SupportedOp is not sorted.");
55 enum : MaskType {
56 ShlBIT = 1,
57 AShrBIT = 1 << 1,
58 MulBIT = 1 << 2,
59 AddBIT = 1 << 3,
60 SubBIT = 1 << 4,
61 AndBIT = 1 << 5,
62 OrBIT = 1 << 6,
63 XorBIT = 1 << 7,
64 FAddBIT = 1 << 8,
65 FSubBIT = 1 << 9,
66 MainOpBIT = 1 << 10,
68 };
69 /// Return a non-nullptr if either operand of I is a ConstantInt (for the
70 /// integer opcodes) or a ConstantFP (for FAdd/FSub).
71 /// The second return value represents the operand position. We check the
72 /// right-hand side first (1). If the right hand side is not a constant and
73 /// the instruction is neither Sub, FSub, Shl, nor AShr, we then check the
74 /// left hand side (0).
75 static std::pair<Constant *, unsigned>
76 isBinOpWithConstant(const Instruction *I);
77 struct InterchangeableInfo {
78 const Instruction *I = nullptr;
79 /// The bit it sets represents whether MainOp can be converted to.
80 MaskType Mask = MainOpBIT | XorBIT | OrBIT | AndBIT | SubBIT | AddBIT |
81 MulBIT | AShrBIT | ShlBIT | FSubBIT | FAddBIT;
82 /// We cannot create an interchangeable instruction that does not exist in
83 /// VL. For example, VL [x + 0, y * 1] can be converted to [x << 0, y << 0],
84 /// but << does not exist in VL. In the end, we convert VL to [x * 1, y *
85 /// 1]. SeenBefore is used to know what operations have been seen before.
86 MaskType SeenBefore = 0;
87 InterchangeableInfo(const Instruction *I) : I(I) {}
88 /// Return false allows BinOpSameOpcodeHelper to find an alternate
89 /// instruction. Directly setting the mask will destroy the mask state,
90 /// preventing us from determining which instruction it should convert to.
91 bool trySet(MaskType OpcodeInMaskForm, MaskType InterchangeableMask);
92 bool equal(unsigned Opcode) {
93 return Opcode == I->getOpcode() && trySet(MainOpBIT, MainOpBIT);
94 }
95 unsigned getOpcode() const;
96 bool hasDefinedOpcode() const { return (Mask & SeenBefore) > 0; }
97 /// Return true if the instruction can be converted to \p Opcode.
98 bool hasCandidateOpcode(unsigned Opcode) const;
100 };
101 InterchangeableInfo MainOp;
102 InterchangeableInfo AltOp;
103 bool isValidForAlternation(const Instruction *I) const;
104 bool initializeAltOp(const Instruction *I);
105
106public:
108 const Instruction *AltOp = nullptr)
109 : MainOp(MainOp), AltOp(AltOp) {}
110 bool add(const Instruction *I);
111 unsigned getMainOpcode() const { return MainOp.getOpcode(); }
112 bool hasDefinedMainOpcode() const { return MainOp.hasDefinedOpcode(); }
113 /// Checks if the list of potential opcodes includes \p Opcode.
114 bool hasCandidateOpcode(unsigned Opcode) const {
115 return MainOp.hasCandidateOpcode(Opcode);
116 }
117 bool hasAltOp() const { return AltOp.I; }
118 unsigned getAltOpcode() const {
119 return hasAltOp() ? AltOp.getOpcode() : getMainOpcode();
120 }
121 bool hasDefinedAltOpcode() const {
122 return !hasAltOp() || AltOp.hasDefinedOpcode();
123 }
125 return MainOp.getOperand(I);
126 }
127};
128
129} // namespace llvm::slpvectorizer
130
131#endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPCOMPATIBILITYANALYSIS_H
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
This is an important base class in LLVM.
Definition Constant.h:43
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Definition Value.h:75
SmallVector< Value * > getOperand(const Instruction *I) const
bool hasCandidateOpcode(unsigned Opcode) const
Checks if the list of potential opcodes includes Opcode.
BinOpSameOpcodeHelper(const Instruction *MainOp, const Instruction *AltOp=nullptr)
A private "module" namespace for types and utilities used by this pass.
bool isValidForAlternation(unsigned Opcode)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool is_sorted_constexpr(R &&Range, Cmp C=Cmp{})
Check if elements in a range R are sorted with respect to a comparator C.
Definition STLExtras.h:1984
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2146