cobalt / cobalt / ac9ac065c5083565917b15e7a672a79599f2f00b / . / src / third_party / llvm-project / llvm / include / llvm / Analysis / VectorUtils.h

//===- llvm/Analysis/VectorUtils.h - Vector utilities -----------*- C++ -*-===// | |

// | |

// The LLVM Compiler Infrastructure | |

// | |

// This file is distributed under the University of Illinois Open Source | |

// License. See LICENSE.TXT for details. | |

// | |

//===----------------------------------------------------------------------===// | |

// | |

// This file defines some vectorizer utilities. | |

// | |

//===----------------------------------------------------------------------===// | |

#ifndef LLVM_ANALYSIS_VECTORUTILS_H | |

#define LLVM_ANALYSIS_VECTORUTILS_H | |

#include "llvm/ADT/MapVector.h" | |

#include "llvm/Analysis/TargetLibraryInfo.h" | |

#include "llvm/IR/IRBuilder.h" | |

namespace llvm { | |

template <typename T> class ArrayRef; | |

class DemandedBits; | |

class GetElementPtrInst; | |

class Loop; | |

class ScalarEvolution; | |

class TargetTransformInfo; | |

class Type; | |

class Value; | |

namespace Intrinsic { | |

enum ID : unsigned; | |

} | |

/// Identify if the intrinsic is trivially vectorizable. | |

/// This method returns true if the intrinsic's argument types are all | |

/// scalars for the scalar form of the intrinsic and all vectors for | |

/// the vector form of the intrinsic. | |

bool isTriviallyVectorizable(Intrinsic::ID ID); | |

/// Identifies if the intrinsic has a scalar operand. It checks for | |

/// ctlz,cttz and powi special intrinsics whose argument is scalar. | |

bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, unsigned ScalarOpdIdx); | |

/// Returns intrinsic ID for call. | |

/// For the input call instruction it finds mapping intrinsic and returns | |

/// its intrinsic ID, in case it does not found it return not_intrinsic. | |

Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, | |

const TargetLibraryInfo *TLI); | |

/// Find the operand of the GEP that should be checked for consecutive | |

/// stores. This ignores trailing indices that have no effect on the final | |

/// pointer. | |

unsigned getGEPInductionOperand(const GetElementPtrInst *Gep); | |

/// If the argument is a GEP, then returns the operand identified by | |

/// getGEPInductionOperand. However, if there is some other non-loop-invariant | |

/// operand, it returns that instead. | |

Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp); | |

/// If a value has only one user that is a CastInst, return it. | |

Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty); | |

/// Get the stride of a pointer access in a loop. Looks for symbolic | |

/// strides "a[i*stride]". Returns the symbolic stride, or null otherwise. | |

Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp); | |

/// Given a vector and an element number, see if the scalar value is | |

/// already around as a register, for example if it were inserted then extracted | |

/// from the vector. | |

Value *findScalarElement(Value *V, unsigned EltNo); | |

/// Get splat value if the input is a splat vector or return nullptr. | |

/// The value may be extracted from a splat constants vector or from | |

/// a sequence of instructions that broadcast a single value into a vector. | |

const Value *getSplatValue(const Value *V); | |

/// Compute a map of integer instructions to their minimum legal type | |

/// size. | |

/// | |

/// C semantics force sub-int-sized values (e.g. i8, i16) to be promoted to int | |

/// type (e.g. i32) whenever arithmetic is performed on them. | |

/// | |

/// For targets with native i8 or i16 operations, usually InstCombine can shrink | |

/// the arithmetic type down again. However InstCombine refuses to create | |

/// illegal types, so for targets without i8 or i16 registers, the lengthening | |

/// and shrinking remains. | |

/// | |

/// Most SIMD ISAs (e.g. NEON) however support vectors of i8 or i16 even when | |

/// their scalar equivalents do not, so during vectorization it is important to | |

/// remove these lengthens and truncates when deciding the profitability of | |

/// vectorization. | |

/// | |

/// This function analyzes the given range of instructions and determines the | |

/// minimum type size each can be converted to. It attempts to remove or | |

/// minimize type size changes across each def-use chain, so for example in the | |

/// following code: | |

/// | |

/// %1 = load i8, i8* | |

/// %2 = add i8 %1, 2 | |

/// %3 = load i16, i16* | |

/// %4 = zext i8 %2 to i32 | |

/// %5 = zext i16 %3 to i32 | |

/// %6 = add i32 %4, %5 | |

/// %7 = trunc i32 %6 to i16 | |

/// | |

/// Instruction %6 must be done at least in i16, so computeMinimumValueSizes | |

/// will return: {%1: 16, %2: 16, %3: 16, %4: 16, %5: 16, %6: 16, %7: 16}. | |

/// | |

/// If the optional TargetTransformInfo is provided, this function tries harder | |

/// to do less work by only looking at illegal types. | |

MapVector<Instruction*, uint64_t> | |

computeMinimumValueSizes(ArrayRef<BasicBlock*> Blocks, | |

DemandedBits &DB, | |

const TargetTransformInfo *TTI=nullptr); | |

/// Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath, | |

/// MD_nontemporal]. For K in Kinds, we get the MDNode for K from each of the | |

/// elements of VL, compute their "intersection" (i.e., the most generic | |

/// metadata value that covers all of the individual values), and set I's | |

/// metadata for M equal to the intersection value. | |

/// | |

/// This function always sets a (possibly null) value for each K in Kinds. | |

Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL); | |

/// Create an interleave shuffle mask. | |

/// | |

/// This function creates a shuffle mask for interleaving \p NumVecs vectors of | |

/// vectorization factor \p VF into a single wide vector. The mask is of the | |

/// form: | |

/// | |

/// <0, VF, VF * 2, ..., VF * (NumVecs - 1), 1, VF + 1, VF * 2 + 1, ...> | |

/// | |

/// For example, the mask for VF = 4 and NumVecs = 2 is: | |

/// | |

/// <0, 4, 1, 5, 2, 6, 3, 7>. | |

Constant *createInterleaveMask(IRBuilder<> &Builder, unsigned VF, | |

unsigned NumVecs); | |

/// Create a stride shuffle mask. | |

/// | |

/// This function creates a shuffle mask whose elements begin at \p Start and | |

/// are incremented by \p Stride. The mask can be used to deinterleave an | |

/// interleaved vector into separate vectors of vectorization factor \p VF. The | |

/// mask is of the form: | |

/// | |

/// <Start, Start + Stride, ..., Start + Stride * (VF - 1)> | |

/// | |

/// For example, the mask for Start = 0, Stride = 2, and VF = 4 is: | |

/// | |

/// <0, 2, 4, 6> | |

Constant *createStrideMask(IRBuilder<> &Builder, unsigned Start, | |

unsigned Stride, unsigned VF); | |

/// Create a sequential shuffle mask. | |

/// | |

/// This function creates shuffle mask whose elements are sequential and begin | |

/// at \p Start. The mask contains \p NumInts integers and is padded with \p | |

/// NumUndefs undef values. The mask is of the form: | |

/// | |

/// <Start, Start + 1, ... Start + NumInts - 1, undef_1, ... undef_NumUndefs> | |

/// | |

/// For example, the mask for Start = 0, NumInsts = 4, and NumUndefs = 4 is: | |

/// | |

/// <0, 1, 2, 3, undef, undef, undef, undef> | |

Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start, | |

unsigned NumInts, unsigned NumUndefs); | |

/// Concatenate a list of vectors. | |

/// | |

/// This function generates code that concatenate the vectors in \p Vecs into a | |

/// single large vector. The number of vectors should be greater than one, and | |

/// their element types should be the same. The number of elements in the | |

/// vectors should also be the same; however, if the last vector has fewer | |

/// elements, it will be padded with undefs. | |

Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs); | |

} // llvm namespace | |

#endif |