Assumptions.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //===- Assumptions.cpp ------ Collection of helpers for assumptions -------===//
  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. // This file implements helper functions for accessing assumption infomration
  10. // inside of the "llvm.assume" metadata.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/IR/Assumptions.h"
  14. #include "llvm/ADT/SetOperations.h"
  15. #include "llvm/ADT/StringExtras.h"
  16. #include "llvm/IR/Attributes.h"
  17. #include "llvm/IR/Function.h"
  18. #include "llvm/IR/InstrTypes.h"
  19. using namespace llvm;
  20. namespace {
  21. bool hasAssumption(const Attribute &A,
  22. const KnownAssumptionString &AssumptionStr) {
  23. if (!A.isValid())
  24. return false;
  25. assert(A.isStringAttribute() && "Expected a string attribute!");
  26. SmallVector<StringRef, 8> Strings;
  27. A.getValueAsString().split(Strings, ",");
  28. return llvm::is_contained(Strings, AssumptionStr);
  29. }
  30. DenseSet<StringRef> getAssumptions(const Attribute &A) {
  31. if (!A.isValid())
  32. return DenseSet<StringRef>();
  33. assert(A.isStringAttribute() && "Expected a string attribute!");
  34. DenseSet<StringRef> Assumptions;
  35. SmallVector<StringRef, 8> Strings;
  36. A.getValueAsString().split(Strings, ",");
  37. for (StringRef Str : Strings)
  38. Assumptions.insert(Str);
  39. return Assumptions;
  40. }
  41. template <typename AttrSite>
  42. bool addAssumptionsImpl(AttrSite &Site,
  43. const DenseSet<StringRef> &Assumptions) {
  44. if (Assumptions.empty())
  45. return false;
  46. DenseSet<StringRef> CurAssumptions = getAssumptions(Site);
  47. if (!set_union(CurAssumptions, Assumptions))
  48. return false;
  49. LLVMContext &Ctx = Site.getContext();
  50. Site.addFnAttr(llvm::Attribute::get(
  51. Ctx, llvm::AssumptionAttrKey,
  52. llvm::join(CurAssumptions.begin(), CurAssumptions.end(), ",")));
  53. return true;
  54. }
  55. } // namespace
  56. bool llvm::hasAssumption(const Function &F,
  57. const KnownAssumptionString &AssumptionStr) {
  58. const Attribute &A = F.getFnAttribute(AssumptionAttrKey);
  59. return ::hasAssumption(A, AssumptionStr);
  60. }
  61. bool llvm::hasAssumption(const CallBase &CB,
  62. const KnownAssumptionString &AssumptionStr) {
  63. if (Function *F = CB.getCalledFunction())
  64. if (hasAssumption(*F, AssumptionStr))
  65. return true;
  66. const Attribute &A = CB.getFnAttr(AssumptionAttrKey);
  67. return ::hasAssumption(A, AssumptionStr);
  68. }
  69. DenseSet<StringRef> llvm::getAssumptions(const Function &F) {
  70. const Attribute &A = F.getFnAttribute(AssumptionAttrKey);
  71. return ::getAssumptions(A);
  72. }
  73. DenseSet<StringRef> llvm::getAssumptions(const CallBase &CB) {
  74. const Attribute &A = CB.getFnAttr(AssumptionAttrKey);
  75. return ::getAssumptions(A);
  76. }
  77. bool llvm::addAssumptions(Function &F, const DenseSet<StringRef> &Assumptions) {
  78. return ::addAssumptionsImpl(F, Assumptions);
  79. }
  80. bool llvm::addAssumptions(CallBase &CB,
  81. const DenseSet<StringRef> &Assumptions) {
  82. return ::addAssumptionsImpl(CB, Assumptions);
  83. }
  84. StringSet<> llvm::KnownAssumptionStrings({
  85. "omp_no_openmp", // OpenMP 5.1
  86. "omp_no_openmp_routines", // OpenMP 5.1
  87. "omp_no_parallelism", // OpenMP 5.1
  88. "ompx_spmd_amenable", // OpenMPOpt extension
  89. "ompx_no_call_asm", // OpenMPOpt extension
  90. });