1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file defines a set of enums which allow processing of intrinsic
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// functions.  Values of these enum types are returned by
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// Function::getIntrinsicID.
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_IR_INTRINSICS_H
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_IR_INTRINSICS_H
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/ArrayRef.h"
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/None.h"
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/Optional.h"
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <string>
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Type;
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass FunctionType;
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Function;
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass LLVMContext;
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Module;
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AttributeList;
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This namespace contains an enum with a value for every intrinsic/builtin
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// function known by LLVM. The enum values are returned by
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Function::getIntrinsicID().
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace Intrinsic {
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum ID : unsigned {
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    not_intrinsic = 0,   // Must be zero
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // Get the intrinsic enums generated from Intrinsics.td
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define GET_INTRINSIC_ENUM_VALUES
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Intrinsics.gen"
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#undef GET_INTRINSIC_ENUM_VALUES
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    , num_intrinsics
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Note, this version is for intrinsics with no overloads.  Use the other
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// version of getName if overloads are required.
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  StringRef getName(ID id);
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Note, this version of getName supports overloads, but is less efficient
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// than the StringRef version of this function.  If no overloads are
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// requried, it is safe to use this version, but better to use the StringRef
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// version.
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::string getName(ID id, ArrayRef<Type*> Tys);
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the function type for an intrinsic.
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  FunctionType *getType(LLVMContext &Context, ID id,
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                        ArrayRef<Type*> Tys = None);
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns true if the intrinsic can be overloaded.
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isOverloaded(ID id);
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// itself.  Most intrinsics are leafs, the exceptions being the patchpoint
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// and statepoint intrinsics. These call (or invoke) their "target" argument.
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isLeaf(ID id);
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the attributes for an intrinsic.
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AttributeList getAttributes(LLVMContext &C, ID id);
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Create or insert an LLVM Function declaration for an intrinsic, and return
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// it.
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The Tys parameter is for intrinsics with overloaded types (e.g., those
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// intrinsic, Tys must provide exactly one type for each overloaded type in
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the intrinsic.
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Looks up Name in NameTable via binary search. NameTable must be sorted
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// and all entries must start with "llvm.".  If NameTable contains an exact
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// match for Name or a prefix of Name followed by a dot, its index in
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// NameTable is returned. Otherwise, -1 is returned.
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                StringRef Name);
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Map a GCC builtin name to an intrinsic ID.
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName);
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Map a MS builtin name to an intrinsic ID.
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This is a type descriptor which explains the type requirements of an
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct IITDescriptor {
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    enum IITDescriptorKind {
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Void, VarArg, MMX, Token, Metadata, Half, Float, Double,
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Integer, Vector, Pointer, Struct,
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Argument, ExtendArgument, TruncArgument, HalfVecArgument,
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    } Kind;
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    union {
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Integer_Width;
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Float_Width;
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Vector_Width;
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Pointer_AddressSpace;
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Struct_NumElements;
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Argument_Info;
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    };
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    enum ArgKind {
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AK_Any,
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AK_AnyInteger,
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AK_AnyFloat,
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AK_AnyVector,
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AK_AnyPointer
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    };
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned getArgumentNumber() const {
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(Kind == Argument || Kind == ExtendArgument ||
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             Kind == TruncArgument || Kind == HalfVecArgument ||
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             Kind == SameVecWidthArgument || Kind == PtrToArgument ||
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             Kind == PtrToElt);
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return Argument_Info >> 3;
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ArgKind getArgumentKind() const {
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(Kind == Argument || Kind == ExtendArgument ||
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             Kind == TruncArgument || Kind == HalfVecArgument ||
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot             Kind == SameVecWidthArgument || Kind == PtrToArgument);
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return (ArgKind)(Argument_Info & 7);
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    // and a reference argument (for matching vector width and element types)
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned getOverloadArgNumber() const {
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(Kind == VecOfAnyPtrsToElt);
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return Argument_Info >> 16;
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    unsigned getRefArgNumber() const {
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(Kind == VecOfAnyPtrsToElt);
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return Argument_Info & 0xFFFF;
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      IITDescriptor Result = { K, { Field } };
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return Result;
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                             unsigned short Lo) {
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      unsigned Field = Hi << 16 | Lo;
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      IITDescriptor Result = {K, {Field}};
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return Result;
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the IIT table descriptor for the specified intrinsic into an array
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// of IITDescriptors.
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Match the specified type (which comes from an intrinsic argument or return
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// value) with the type constraints specified by the .td file. If the given
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// type is an overloaded type it is pushed to the ArgTys vector.
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Returns false if the given type matches with the constraints, true
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// otherwise.
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool matchIntrinsicType(Type *Ty, ArrayRef<IITDescriptor> &Infos,
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                          SmallVectorImpl<Type*> &ArgTys);
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Verify if the intrinsic has variable arguments. This method is intended to
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// be called after all the fixed arguments have been matched first.
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This method returns true on error.
178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Checks if the intrinsic name matches with its signature and if not
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // returns the declaration with the same signature and remangled name.
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // End Intrinsic namespace
185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // End llvm namespace
187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif
189