llvm-6502/include/llvm/IR/Intrinsics.h
Elena Demikhovsky 8be39c81b0 Masked Gather and Scatter Intrinsics.
Gather and Scatter are new introduced intrinsics, comming after recently implemented masked load and store.
This is the first patch for Gather and Scatter intrinsics. It includes only the syntax, parsing and verification.

Gather and Scatter intrinsics allow to perform multiple memory accesses (read/write) in one vector instruction.
The intrinsics are not target specific and will have the following syntax:
Gather:
declare <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> <vector of ptrs>, i32 <alignment>, <16 x i1> <mask>, <16 x i32> <passthru>)
declare <8 x float> @llvm.masked.gather.v8f32(<8 x float*><vector of ptrs>, i32 <alignment>, <8 x i1> <mask>, <8 x float><passthru>)

Scatter:
declare void @llvm.masked.scatter.v8i32(<8 x i32><vector value to be stored> , <8 x i32*><vector of ptrs> , i32 <alignment>, <8 x i1> <mask>)
declare void @llvm.masked.scatter.v16i32(<16 x i32> <vector value to be stored> , <16 x i32*> <vector of ptrs>, i32 <alignment>, <16 x i1><mask> )

Vector of ptrs - a set of source/destination addresses, to load/store the value. 
Mask - switches on/off vector lanes to prevent memory access for switched-off lanes
vector of ptrs, value and mask should have the same vector width.

These are code examples where gather / scatter should be used and will allow function vectorization
;void foo1(int * restrict A, int * restrict B, int * restrict C) {
; for (int i=0; i<SIZE; i++) {
; A[i] = B[C[i]];
; }
;}

;void foo3(int * restrict A, int * restrict B) {
; for (int i=0; i<SIZE; i++) {
; A[B[i]] = i+5;
; }
;}

Tests will come in the following patches, with CodeGen and Vectorizer.

http://reviews.llvm.org/D7433



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228521 91177308-0d34-0410-b5e6-96231b3b80d8
2015-02-08 08:27:19 +00:00

129 lines
4.1 KiB
C++

//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- 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 a set of enums which allow processing of intrinsic
// functions. Values of these enum types are returned by
// Function::getIntrinsicID.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_INTRINSICS_H
#define LLVM_IR_INTRINSICS_H
#include "llvm/ADT/ArrayRef.h"
#include <string>
namespace llvm {
class Type;
class FunctionType;
class Function;
class LLVMContext;
class Module;
class AttributeSet;
/// This namespace contains an enum with a value for every intrinsic/builtin
/// function known by LLVM. The enum values are returned by
/// Function::getIntrinsicID().
namespace Intrinsic {
enum ID {
not_intrinsic = 0, // Must be zero
// Get the intrinsic enums generated from Intrinsics.td
#define GET_INTRINSIC_ENUM_VALUES
#include "llvm/IR/Intrinsics.gen"
#undef GET_INTRINSIC_ENUM_VALUES
, num_intrinsics
};
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
std::string getName(ID id, ArrayRef<Type*> Tys = None);
/// Return the function type for an intrinsic.
FunctionType *getType(LLVMContext &Context, ID id,
ArrayRef<Type*> Tys = None);
/// Returns true if the intrinsic can be overloaded.
bool isOverloaded(ID id);
/// Return the attributes for an intrinsic.
AttributeSet getAttributes(LLVMContext &C, ID id);
/// Create or insert an LLVM Function declaration for an intrinsic, and return
/// it.
///
/// The Tys parameter is for intrinsics with overloaded types (e.g., those
/// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
/// intrinsic, Tys must provide exactly one type for each overloaded type in
/// the intrinsic.
Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
/// Map a GCC builtin name to an intrinsic ID.
ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
/// Map a MS builtin name to an intrinsic ID.
ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
/// This is a type descriptor which explains the type requirements of an
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
struct IITDescriptor {
enum IITDescriptorKind {
Void, VarArg, MMX, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
SameVecWidthArgument, PtrToArgument, VecOfPtrsToElt
} Kind;
union {
unsigned Integer_Width;
unsigned Float_Width;
unsigned Vector_Width;
unsigned Pointer_AddressSpace;
unsigned Struct_NumElements;
unsigned Argument_Info;
};
enum ArgKind {
AK_Any,
AK_AnyInteger,
AK_AnyFloat,
AK_AnyVector,
AK_AnyPointer
};
unsigned getArgumentNumber() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
Kind == VecOfPtrsToElt);
return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
Kind == VecOfPtrsToElt);
return (ArgKind)(Argument_Info & 7);
}
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
}
};
/// Return the IIT table descriptor for the specified intrinsic into an array
/// of IITDescriptors.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
} // End Intrinsic namespace
} // End llvm namespace
#endif