Fixed/added namespace ending comments using clang-tidy. NFC
[oota-llvm.git] / include / llvm / Transforms / Utils / VectorUtils.h
1 //===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- C++ -*-=====//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines some vectorizer utilities.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
15 #define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
16
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/IR/Intrinsics.h"
20
21 namespace llvm {
22
23 /// \brief Identify if the intrinsic is trivially vectorizable.
24 ///
25 /// This method returns true if the intrinsic's argument types are all
26 /// scalars for the scalar form of the intrinsic and all vectors for
27 /// the vector form of the intrinsic.
28 static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
29   switch (ID) {
30   case Intrinsic::sqrt:
31   case Intrinsic::sin:
32   case Intrinsic::cos:
33   case Intrinsic::exp:
34   case Intrinsic::exp2:
35   case Intrinsic::log:
36   case Intrinsic::log10:
37   case Intrinsic::log2:
38   case Intrinsic::fabs:
39   case Intrinsic::minnum:
40   case Intrinsic::maxnum:
41   case Intrinsic::copysign:
42   case Intrinsic::floor:
43   case Intrinsic::ceil:
44   case Intrinsic::trunc:
45   case Intrinsic::rint:
46   case Intrinsic::nearbyint:
47   case Intrinsic::round:
48   case Intrinsic::bswap:
49   case Intrinsic::ctpop:
50   case Intrinsic::pow:
51   case Intrinsic::fma:
52   case Intrinsic::fmuladd:
53   case Intrinsic::ctlz:
54   case Intrinsic::cttz:
55   case Intrinsic::powi:
56     return true;
57   default:
58     return false;
59   }
60 }
61
62 static inline bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
63                                          unsigned ScalarOpdIdx) {
64   switch (ID) {
65     case Intrinsic::ctlz:
66     case Intrinsic::cttz:
67     case Intrinsic::powi:
68       return (ScalarOpdIdx == 1);
69     default:
70       return false;
71   }
72 }
73
74 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
75                                               Intrinsic::ID ValidIntrinsicID) {
76   if (I.getNumArgOperands() != 1 ||
77       !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
78       I.getType() != I.getArgOperand(0)->getType() ||
79       !I.onlyReadsMemory())
80     return Intrinsic::not_intrinsic;
81
82   return ValidIntrinsicID;
83 }
84
85 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
86                                                Intrinsic::ID ValidIntrinsicID) {
87   if (I.getNumArgOperands() != 2 ||
88       !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
89       !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
90       I.getType() != I.getArgOperand(0)->getType() ||
91       I.getType() != I.getArgOperand(1)->getType() ||
92       !I.onlyReadsMemory())
93     return Intrinsic::not_intrinsic;
94
95   return ValidIntrinsicID;
96 }
97
98 static Intrinsic::ID
99 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
100   // If we have an intrinsic call, check if it is trivially vectorizable.
101   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
102     Intrinsic::ID ID = II->getIntrinsicID();
103     if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
104         ID == Intrinsic::lifetime_end || ID == Intrinsic::assume)
105       return ID;
106     else
107       return Intrinsic::not_intrinsic;
108   }
109
110   if (!TLI)
111     return Intrinsic::not_intrinsic;
112
113   LibFunc::Func Func;
114   Function *F = CI->getCalledFunction();
115   // We're going to make assumptions on the semantics of the functions, check
116   // that the target knows that it's available in this environment and it does
117   // not have local linkage.
118   if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
119     return Intrinsic::not_intrinsic;
120
121   // Otherwise check if we have a call to a function that can be turned into a
122   // vector intrinsic.
123   switch (Func) {
124   default:
125     break;
126   case LibFunc::sin:
127   case LibFunc::sinf:
128   case LibFunc::sinl:
129     return checkUnaryFloatSignature(*CI, Intrinsic::sin);
130   case LibFunc::cos:
131   case LibFunc::cosf:
132   case LibFunc::cosl:
133     return checkUnaryFloatSignature(*CI, Intrinsic::cos);
134   case LibFunc::exp:
135   case LibFunc::expf:
136   case LibFunc::expl:
137     return checkUnaryFloatSignature(*CI, Intrinsic::exp);
138   case LibFunc::exp2:
139   case LibFunc::exp2f:
140   case LibFunc::exp2l:
141     return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
142   case LibFunc::log:
143   case LibFunc::logf:
144   case LibFunc::logl:
145     return checkUnaryFloatSignature(*CI, Intrinsic::log);
146   case LibFunc::log10:
147   case LibFunc::log10f:
148   case LibFunc::log10l:
149     return checkUnaryFloatSignature(*CI, Intrinsic::log10);
150   case LibFunc::log2:
151   case LibFunc::log2f:
152   case LibFunc::log2l:
153     return checkUnaryFloatSignature(*CI, Intrinsic::log2);
154   case LibFunc::fabs:
155   case LibFunc::fabsf:
156   case LibFunc::fabsl:
157     return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
158   case LibFunc::fmin:
159   case LibFunc::fminf:
160   case LibFunc::fminl:
161     return checkBinaryFloatSignature(*CI, Intrinsic::minnum);
162   case LibFunc::fmax:
163   case LibFunc::fmaxf:
164   case LibFunc::fmaxl:
165     return checkBinaryFloatSignature(*CI, Intrinsic::maxnum);
166   case LibFunc::copysign:
167   case LibFunc::copysignf:
168   case LibFunc::copysignl:
169     return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
170   case LibFunc::floor:
171   case LibFunc::floorf:
172   case LibFunc::floorl:
173     return checkUnaryFloatSignature(*CI, Intrinsic::floor);
174   case LibFunc::ceil:
175   case LibFunc::ceilf:
176   case LibFunc::ceill:
177     return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
178   case LibFunc::trunc:
179   case LibFunc::truncf:
180   case LibFunc::truncl:
181     return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
182   case LibFunc::rint:
183   case LibFunc::rintf:
184   case LibFunc::rintl:
185     return checkUnaryFloatSignature(*CI, Intrinsic::rint);
186   case LibFunc::nearbyint:
187   case LibFunc::nearbyintf:
188   case LibFunc::nearbyintl:
189     return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
190   case LibFunc::round:
191   case LibFunc::roundf:
192   case LibFunc::roundl:
193     return checkUnaryFloatSignature(*CI, Intrinsic::round);
194   case LibFunc::pow:
195   case LibFunc::powf:
196   case LibFunc::powl:
197     return checkBinaryFloatSignature(*CI, Intrinsic::pow);
198   }
199
200   return Intrinsic::not_intrinsic;
201 }
202
203 } // namespace llvm
204
205 #endif