1 | //===-- TargetLibraryInfo.h - Library information ---------------*- 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 | #ifndef LLVM_ANALYSIS_TARGETLIBRARYINFO_H |

10 | #define LLVM_ANALYSIS_TARGETLIBRARYINFO_H |

11 | |

12 | #include "llvm/ADT/BitVector.h" |

13 | #include "llvm/ADT/DenseMap.h" |

14 | #include "llvm/ADT/Optional.h" |

15 | #include "llvm/IR/Function.h" |

16 | #include "llvm/IR/InstrTypes.h" |

17 | #include "llvm/IR/Module.h" |

18 | #include "llvm/IR/PassManager.h" |

19 | #include "llvm/Pass.h" |

20 | |

21 | namespace llvm { |

22 | template <typename T> class ArrayRef; |

23 | class Triple; |

24 | |

25 | /// Describes a possible vectorization of a function. |

26 | /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized |

27 | /// by a factor 'VectorizationFactor'. |

28 | struct VecDesc { |

29 | StringRef ScalarFnName; |

30 | StringRef VectorFnName; |

31 | ElementCount VectorizationFactor; |

32 | }; |

33 | |

34 | enum LibFunc : unsigned { |

35 | #define TLI_DEFINE_ENUM |

36 | #include "llvm/Analysis/TargetLibraryInfo.def" |

37 | |

38 | NumLibFuncs, |

39 | NotLibFunc |

40 | }; |

41 | |

42 | /// Implementation of the target library information. |

43 | /// |

44 | /// This class constructs tables that hold the target library information and |

45 | /// make it available. However, it is somewhat expensive to compute and only |

46 | /// depends on the triple. So users typically interact with the \c |

47 | /// TargetLibraryInfo wrapper below. |

48 | class TargetLibraryInfoImpl { |

49 | friend class TargetLibraryInfo; |

50 | |

51 | unsigned char AvailableArray[(NumLibFuncs+3)/4]; |

52 | llvm::DenseMap<unsigned, std::string> CustomNames; |

53 | static StringLiteral const StandardNames[NumLibFuncs]; |

54 | bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param; |

55 | |

56 | enum AvailabilityState { |

57 | StandardName = 3, // (memset to all ones) |

58 | CustomName = 1, |

59 | Unavailable = 0 // (memset to all zeros) |

60 | }; |

61 | void setState(LibFunc F, AvailabilityState State) { |

62 | AvailableArray[F/4] &= ~(3 << 2*(F&3)); |

63 | AvailableArray[F/4] |= State << 2*(F&3); |

64 | } |

65 | AvailabilityState getState(LibFunc F) const { |

66 | return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3); |

67 | } |

68 | |

69 | /// Vectorization descriptors - sorted by ScalarFnName. |

70 | std::vector<VecDesc> VectorDescs; |

71 | /// Scalarization descriptors - same content as VectorDescs but sorted based |

72 | /// on VectorFnName rather than ScalarFnName. |

73 | std::vector<VecDesc> ScalarDescs; |

74 | |

75 | /// Return true if the function type FTy is valid for the library function |

76 | /// F, regardless of whether the function is available. |

77 | bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, |

78 | const DataLayout *DL) const; |

79 | |

80 | public: |

81 | /// List of known vector-functions libraries. |

82 | /// |

83 | /// The vector-functions library defines, which functions are vectorizable |

84 | /// and with which factor. The library can be specified by either frontend, |

85 | /// or a commandline option, and then used by |

86 | /// addVectorizableFunctionsFromVecLib for filling up the tables of |

87 | /// vectorizable functions. |

88 | enum VectorLibrary { |

89 | NoLibrary, // Don't use any vector library. |

90 | Accelerate, // Use Accelerate framework. |

91 | LIBMVEC_X86,// GLIBC Vector Math library. |

92 | MASSV, // IBM MASS vector library. |

93 | SVML // Intel short vector math library. |

94 | }; |

95 | |

96 | TargetLibraryInfoImpl(); |

97 | explicit TargetLibraryInfoImpl(const Triple &T); |

98 | |

99 | // Provide value semantics. |

100 | TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI); |

101 | TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI); |

102 | TargetLibraryInfoImpl &operator=(const TargetLibraryInfoImpl &TLI); |

103 | TargetLibraryInfoImpl &operator=(TargetLibraryInfoImpl &&TLI); |

104 | |

105 | /// Searches for a particular function name. |

106 | /// |

107 | /// If it is one of the known library functions, return true and set F to the |

108 | /// corresponding value. |

109 | bool getLibFunc(StringRef funcName, LibFunc &F) const; |

110 | |

111 | /// Searches for a particular function name, also checking that its type is |

112 | /// valid for the library function matching that name. |

113 | /// |

114 | /// If it is one of the known library functions, return true and set F to the |

115 | /// corresponding value. |

116 | bool getLibFunc(const Function &FDecl, LibFunc &F) const; |

117 | |

118 | /// Forces a function to be marked as unavailable. |

119 | void setUnavailable(LibFunc F) { |

120 | setState(F, Unavailable); |

121 | } |

122 | |

123 | /// Forces a function to be marked as available. |

124 | void setAvailable(LibFunc F) { |

125 | setState(F, StandardName); |

126 | } |

127 | |

128 | /// Forces a function to be marked as available and provide an alternate name |

129 | /// that must be used. |

130 | void setAvailableWithName(LibFunc F, StringRef Name) { |

131 | if (StandardNames[F] != Name) { |

132 | setState(F, CustomName); |

133 | CustomNames[F] = std::string(Name); |

134 | assert(CustomNames.find(F) != CustomNames.end()); |

135 | } else { |

136 | setState(F, StandardName); |

137 | } |

138 | } |

139 | |

140 | /// Disables all builtins. |

141 | /// |

142 | /// This can be used for options like -fno-builtin. |

143 | void disableAllFunctions(); |

144 | |

145 | /// Add a set of scalar -> vector mappings, queryable via |

146 | /// getVectorizedFunction and getScalarizedFunction. |

147 | void addVectorizableFunctions(ArrayRef<VecDesc> Fns); |

148 | |

149 | /// Calls addVectorizableFunctions with a known preset of functions for the |

150 | /// given vector library. |

151 | void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib); |

152 | |

153 | /// Return true if the function F has a vector equivalent with vectorization |

154 | /// factor VF. |

155 | bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { |

156 | return !getVectorizedFunction(F, VF).empty(); |

157 | } |

158 | |

159 | /// Return true if the function F has a vector equivalent with any |

160 | /// vectorization factor. |

161 | bool isFunctionVectorizable(StringRef F) const; |

162 | |

163 | /// Return the name of the equivalent of F, vectorized with factor VF. If no |

164 | /// such mapping exists, return the empty string. |

165 | StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const; |

166 | |

167 | /// Set to true iff i32 parameters to library functions should have signext |

168 | /// or zeroext attributes if they correspond to C-level int or unsigned int, |

169 | /// respectively. |

170 | void setShouldExtI32Param(bool Val) { |

171 | ShouldExtI32Param = Val; |

172 | } |

173 | |

174 | /// Set to true iff i32 results from library functions should have signext |

175 | /// or zeroext attributes if they correspond to C-level int or unsigned int, |

176 | /// respectively. |

177 | void setShouldExtI32Return(bool Val) { |

178 | ShouldExtI32Return = Val; |

179 | } |

180 | |

181 | /// Set to true iff i32 parameters to library functions should have signext |

182 | /// attribute if they correspond to C-level int or unsigned int. |

183 | void setShouldSignExtI32Param(bool Val) { |

184 | ShouldSignExtI32Param = Val; |

185 | } |

186 | |

187 | /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. |

188 | /// This queries the 'wchar_size' metadata. |

189 | unsigned getWCharSize(const Module &M) const; |

190 | |

191 | /// Returns the largest vectorization factor used in the list of |

192 | /// vector functions. |

193 | void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, |

194 | ElementCount &Scalable) const; |

195 | |

196 | /// Returns true if call site / callee has cdecl-compatible calling |

197 | /// conventions. |

198 | static bool isCallingConvCCompatible(CallBase *CI); |

199 | static bool isCallingConvCCompatible(Function *Callee); |

200 | }; |

201 | |

202 | /// Provides information about what library functions are available for |

203 | /// the current target. |

204 | /// |

205 | /// This both allows optimizations to handle them specially and frontends to |

206 | /// disable such optimizations through -fno-builtin etc. |

207 | class TargetLibraryInfo { |

208 | friend class TargetLibraryAnalysis; |

209 | friend class TargetLibraryInfoWrapperPass; |

210 | |

211 | /// The global (module level) TLI info. |

212 | const TargetLibraryInfoImpl *Impl; |

213 | |

214 | /// Support for -fno-builtin* options as function attributes, overrides |

215 | /// information in global TargetLibraryInfoImpl. |

216 | BitVector OverrideAsUnavailable; |

217 | |

218 | public: |

219 | explicit TargetLibraryInfo(const TargetLibraryInfoImpl &Impl, |

220 | Optional<const Function *> F = None) |

221 | : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) { |

222 | if (!F) |

223 | return; |

224 | if ((*F)->hasFnAttribute("no-builtins")) |

225 | disableAllFunctions(); |

226 | else { |

227 | // Disable individual libc/libm calls in TargetLibraryInfo. |

228 | LibFunc LF; |

229 | AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes(); |

230 | for (const Attribute &Attr : FnAttrs) { |

231 | if (!Attr.isStringAttribute()) |

232 | continue; |

233 | auto AttrStr = Attr.getKindAsString(); |

234 | if (!AttrStr.consume_front("no-builtin-")) |

235 | continue; |

236 | if (getLibFunc(AttrStr, LF)) |

237 | setUnavailable(LF); |

238 | } |

239 | } |

240 | } |

241 | |

242 | // Provide value semantics. |

243 | TargetLibraryInfo(const TargetLibraryInfo &TLI) |

244 | : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {} |

245 | TargetLibraryInfo(TargetLibraryInfo &&TLI) |

246 | : Impl(TLI.Impl), OverrideAsUnavailable(TLI.OverrideAsUnavailable) {} |

247 | TargetLibraryInfo &operator=(const TargetLibraryInfo &TLI) { |

248 | Impl = TLI.Impl; |

249 | OverrideAsUnavailable = TLI.OverrideAsUnavailable; |

250 | return *this; |

251 | } |

252 | TargetLibraryInfo &operator=(TargetLibraryInfo &&TLI) { |

253 | Impl = TLI.Impl; |

254 | OverrideAsUnavailable = TLI.OverrideAsUnavailable; |

255 | return *this; |

256 | } |

257 | |

258 | /// Determine whether a callee with the given TLI can be inlined into |

259 | /// caller with this TLI, based on 'nobuiltin' attributes. When requested, |

260 | /// allow inlining into a caller with a superset of the callee's nobuiltin |

261 | /// attributes, which is conservatively correct. |

262 | bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI, |

263 | bool AllowCallerSuperset) const { |

264 | if (!AllowCallerSuperset) |

265 | return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable; |

266 | BitVector B = OverrideAsUnavailable; |

267 | B |= CalleeTLI.OverrideAsUnavailable; |

268 | // We can inline if the union of the caller and callee's nobuiltin |

269 | // attributes is no stricter than the caller's nobuiltin attributes. |

270 | return B == OverrideAsUnavailable; |

271 | } |

272 | |

273 | /// Searches for a particular function name. |

274 | /// |

275 | /// If it is one of the known library functions, return true and set F to the |

276 | /// corresponding value. |

277 | bool getLibFunc(StringRef funcName, LibFunc &F) const { |

278 | return Impl->getLibFunc(funcName, F); |

279 | } |

280 | |

281 | bool getLibFunc(const Function &FDecl, LibFunc &F) const { |

282 | return Impl->getLibFunc(FDecl, F); |

283 | } |

284 | |

285 | /// If a callbase does not have the 'nobuiltin' attribute, return if the |

286 | /// called function is a known library function and set F to that function. |

287 | bool getLibFunc(const CallBase &CB, LibFunc &F) const { |

288 | return !CB.isNoBuiltin() && CB.getCalledFunction() && |

289 | getLibFunc(*(CB.getCalledFunction()), F); |

290 | } |

291 | |

292 | /// Disables all builtins. |

293 | /// |

294 | /// This can be used for options like -fno-builtin. |

295 | void disableAllFunctions() LLVM_ATTRIBUTE_UNUSED { |

296 | OverrideAsUnavailable.set(); |

297 | } |

298 | |

299 | /// Forces a function to be marked as unavailable. |

300 | void setUnavailable(LibFunc F) LLVM_ATTRIBUTE_UNUSED { |

301 | OverrideAsUnavailable.set(F); |

302 | } |

303 | |

304 | TargetLibraryInfoImpl::AvailabilityState getState(LibFunc F) const { |

305 | if (OverrideAsUnavailable[F]) |

306 | return TargetLibraryInfoImpl::Unavailable; |

307 | return Impl->getState(F); |

308 | } |

309 | |

310 | /// Tests whether a library function is available. |

311 | bool has(LibFunc F) const { |

312 | return getState(F) != TargetLibraryInfoImpl::Unavailable; |

313 | } |

314 | bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const { |

315 | return Impl->isFunctionVectorizable(F, VF); |

316 | } |

317 | bool isFunctionVectorizable(StringRef F) const { |

318 | return Impl->isFunctionVectorizable(F); |

319 | } |

320 | StringRef getVectorizedFunction(StringRef F, const ElementCount &VF) const { |

321 | return Impl->getVectorizedFunction(F, VF); |

322 | } |

323 | |

324 | /// Tests if the function is both available and a candidate for optimized code |

325 | /// generation. |

326 | bool hasOptimizedCodeGen(LibFunc F) const { |

327 | if (getState(F) == TargetLibraryInfoImpl::Unavailable) |

328 | return false; |

329 | switch (F) { |

330 | default: break; |

331 | case LibFunc_copysign: case LibFunc_copysignf: case LibFunc_copysignl: |

332 | case LibFunc_fabs: case LibFunc_fabsf: case LibFunc_fabsl: |

333 | case LibFunc_sin: case LibFunc_sinf: case LibFunc_sinl: |

334 | case LibFunc_cos: case LibFunc_cosf: case LibFunc_cosl: |

335 | case LibFunc_sqrt: case LibFunc_sqrtf: case LibFunc_sqrtl: |

336 | case LibFunc_sqrt_finite: case LibFunc_sqrtf_finite: |

337 | case LibFunc_sqrtl_finite: |

338 | case LibFunc_fmax: case LibFunc_fmaxf: case LibFunc_fmaxl: |

339 | case LibFunc_fmin: case LibFunc_fminf: case LibFunc_fminl: |

340 | case LibFunc_floor: case LibFunc_floorf: case LibFunc_floorl: |

341 | case LibFunc_nearbyint: case LibFunc_nearbyintf: case LibFunc_nearbyintl: |

342 | case LibFunc_ceil: case LibFunc_ceilf: case LibFunc_ceill: |

343 | case LibFunc_rint: case LibFunc_rintf: case LibFunc_rintl: |

344 | case LibFunc_round: case LibFunc_roundf: case LibFunc_roundl: |

345 | case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl: |

346 | case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l: |

347 | case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l: |

348 | case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove: |

349 | case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp: |

350 | case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen: |

351 | case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy: |

352 | return true; |

353 | } |

354 | return false; |

355 | } |

356 | |

357 | StringRef getName(LibFunc F) const { |

358 | auto State = getState(F); |

359 | if (State == TargetLibraryInfoImpl::Unavailable) |

360 | return StringRef(); |

361 | if (State == TargetLibraryInfoImpl::StandardName) |

362 | return Impl->StandardNames[F]; |

363 | assert(State == TargetLibraryInfoImpl::CustomName); |

364 | return Impl->CustomNames.find(F)->second; |

365 | } |

366 | |

367 | /// Returns extension attribute kind to be used for i32 parameters |

368 | /// corresponding to C-level int or unsigned int. May be zeroext, signext, |

369 | /// or none. |

370 | Attribute::AttrKind getExtAttrForI32Param(bool Signed = true) const { |

371 | if (Impl->ShouldExtI32Param) |

372 | return Signed ? Attribute::SExt : Attribute::ZExt; |

373 | if (Impl->ShouldSignExtI32Param) |

374 | return Attribute::SExt; |

375 | return Attribute::None; |

376 | } |

377 | |

378 | /// Returns extension attribute kind to be used for i32 return values |

379 | /// corresponding to C-level int or unsigned int. May be zeroext, signext, |

380 | /// or none. |

381 | Attribute::AttrKind getExtAttrForI32Return(bool Signed = true) const { |

382 | if (Impl->ShouldExtI32Return) |

383 | return Signed ? Attribute::SExt : Attribute::ZExt; |

384 | return Attribute::None; |

385 | } |

386 | |

387 | /// \copydoc TargetLibraryInfoImpl::getWCharSize() |

388 | unsigned getWCharSize(const Module &M) const { |

389 | return Impl->getWCharSize(M); |

390 | } |

391 | |

392 | /// Handle invalidation from the pass manager. |

393 | /// |

394 | /// If we try to invalidate this info, just return false. It cannot become |

395 | /// invalid even if the module or function changes. |

396 | bool invalidate(Module &, const PreservedAnalyses &, |

397 | ModuleAnalysisManager::Invalidator &) { |

398 | return false; |

399 | } |

400 | bool invalidate(Function &, const PreservedAnalyses &, |

401 | FunctionAnalysisManager::Invalidator &) { |

402 | return false; |

403 | } |

404 | /// Returns the largest vectorization factor used in the list of |

405 | /// vector functions. |

406 | void getWidestVF(StringRef ScalarF, ElementCount &FixedVF, |

407 | ElementCount &ScalableVF) const { |

408 | Impl->getWidestVF(ScalarF, FixedVF, ScalableVF); |

409 | } |

410 | |

411 | /// Check if the function "F" is listed in a library known to LLVM. |

412 | bool isKnownVectorFunctionInLibrary(StringRef F) const { |

413 | return this->isFunctionVectorizable(F); |

414 | } |

415 | }; |

416 | |

417 | /// Analysis pass providing the \c TargetLibraryInfo. |

418 | /// |

419 | /// Note that this pass's result cannot be invalidated, it is immutable for the |

420 | /// life of the module. |

421 | class TargetLibraryAnalysis : public AnalysisInfoMixin<TargetLibraryAnalysis> { |

422 | public: |

423 | typedef TargetLibraryInfo Result; |

424 | |

425 | /// Default construct the library analysis. |

426 | /// |

427 | /// This will use the module's triple to construct the library info for that |

428 | /// module. |

429 | TargetLibraryAnalysis() {} |

430 | |

431 | /// Construct a library analysis with baseline Module-level info. |

432 | /// |

433 | /// This will be supplemented with Function-specific info in the Result. |

434 | TargetLibraryAnalysis(TargetLibraryInfoImpl BaselineInfoImpl) |

435 | : BaselineInfoImpl(std::move(BaselineInfoImpl)) {} |

436 | |

437 | TargetLibraryInfo run(const Function &F, FunctionAnalysisManager &); |

438 | |

439 | private: |

440 | friend AnalysisInfoMixin<TargetLibraryAnalysis>; |

441 | static AnalysisKey Key; |

442 | |

443 | Optional<TargetLibraryInfoImpl> BaselineInfoImpl; |

444 | }; |

445 | |

446 | class TargetLibraryInfoWrapperPass : public ImmutablePass { |

447 | TargetLibraryAnalysis TLA; |

448 | Optional<TargetLibraryInfo> TLI; |

449 | |

450 | virtual void anchor(); |

451 | |

452 | public: |

453 | static char ID; |

454 | TargetLibraryInfoWrapperPass(); |

455 | explicit TargetLibraryInfoWrapperPass(const Triple &T); |

456 | explicit TargetLibraryInfoWrapperPass(const TargetLibraryInfoImpl &TLI); |

457 | |

458 | TargetLibraryInfo &getTLI(const Function &F) { |

459 | FunctionAnalysisManager DummyFAM; |

460 | TLI = TLA.run(F, DummyFAM); |

461 | return *TLI; |

462 | } |

463 | }; |

464 | |

465 | } // end namespace llvm |

466 | |

467 | #endif |

468 |