1e8d8bef9SDimitry Andric //===- Assumptions.cpp ------ Collection of helpers for assumptions -------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric // 9*349cc55cSDimitry Andric // This file implements helper functions for accessing assumption infomration 10*349cc55cSDimitry Andric // inside of the "llvm.assume" metadata. 11*349cc55cSDimitry Andric // 12e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 13e8d8bef9SDimitry Andric 14e8d8bef9SDimitry Andric #include "llvm/IR/Assumptions.h" 15*349cc55cSDimitry Andric #include "llvm/ADT/SetOperations.h" 16*349cc55cSDimitry Andric #include "llvm/ADT/StringExtras.h" 17e8d8bef9SDimitry Andric #include "llvm/IR/Attributes.h" 18e8d8bef9SDimitry Andric #include "llvm/IR/Function.h" 19*349cc55cSDimitry Andric #include "llvm/IR/InstrTypes.h" 20e8d8bef9SDimitry Andric 21e8d8bef9SDimitry Andric using namespace llvm; 22e8d8bef9SDimitry Andric 23*349cc55cSDimitry Andric namespace { 24*349cc55cSDimitry Andric bool hasAssumption(const Attribute &A, 25e8d8bef9SDimitry Andric const KnownAssumptionString &AssumptionStr) { 26e8d8bef9SDimitry Andric if (!A.isValid()) 27e8d8bef9SDimitry Andric return false; 28e8d8bef9SDimitry Andric assert(A.isStringAttribute() && "Expected a string attribute!"); 29e8d8bef9SDimitry Andric 30e8d8bef9SDimitry Andric SmallVector<StringRef, 8> Strings; 31e8d8bef9SDimitry Andric A.getValueAsString().split(Strings, ","); 32e8d8bef9SDimitry Andric 33*349cc55cSDimitry Andric return llvm::is_contained(Strings, AssumptionStr); 34*349cc55cSDimitry Andric } 35*349cc55cSDimitry Andric 36*349cc55cSDimitry Andric DenseSet<StringRef> getAssumptions(const Attribute &A) { 37*349cc55cSDimitry Andric if (!A.isValid()) 38*349cc55cSDimitry Andric return DenseSet<StringRef>(); 39*349cc55cSDimitry Andric assert(A.isStringAttribute() && "Expected a string attribute!"); 40*349cc55cSDimitry Andric 41*349cc55cSDimitry Andric DenseSet<StringRef> Assumptions; 42*349cc55cSDimitry Andric SmallVector<StringRef, 8> Strings; 43*349cc55cSDimitry Andric A.getValueAsString().split(Strings, ","); 44*349cc55cSDimitry Andric 45*349cc55cSDimitry Andric for (StringRef Str : Strings) 46*349cc55cSDimitry Andric Assumptions.insert(Str); 47*349cc55cSDimitry Andric return Assumptions; 48*349cc55cSDimitry Andric } 49*349cc55cSDimitry Andric 50*349cc55cSDimitry Andric template <typename AttrSite> 51*349cc55cSDimitry Andric bool addAssumptionsImpl(AttrSite &Site, 52*349cc55cSDimitry Andric const DenseSet<StringRef> &Assumptions) { 53*349cc55cSDimitry Andric if (Assumptions.empty()) 54*349cc55cSDimitry Andric return false; 55*349cc55cSDimitry Andric 56*349cc55cSDimitry Andric DenseSet<StringRef> CurAssumptions = getAssumptions(Site); 57*349cc55cSDimitry Andric 58*349cc55cSDimitry Andric if (!set_union(CurAssumptions, Assumptions)) 59*349cc55cSDimitry Andric return false; 60*349cc55cSDimitry Andric 61*349cc55cSDimitry Andric LLVMContext &Ctx = Site.getContext(); 62*349cc55cSDimitry Andric Site.addFnAttr(llvm::Attribute::get( 63*349cc55cSDimitry Andric Ctx, llvm::AssumptionAttrKey, 64*349cc55cSDimitry Andric llvm::join(CurAssumptions.begin(), CurAssumptions.end(), ","))); 65*349cc55cSDimitry Andric 66*349cc55cSDimitry Andric return true; 67*349cc55cSDimitry Andric } 68*349cc55cSDimitry Andric } // namespace 69*349cc55cSDimitry Andric 70*349cc55cSDimitry Andric bool llvm::hasAssumption(const Function &F, 71*349cc55cSDimitry Andric const KnownAssumptionString &AssumptionStr) { 72*349cc55cSDimitry Andric const Attribute &A = F.getFnAttribute(AssumptionAttrKey); 73*349cc55cSDimitry Andric return ::hasAssumption(A, AssumptionStr); 74*349cc55cSDimitry Andric } 75*349cc55cSDimitry Andric 76*349cc55cSDimitry Andric bool llvm::hasAssumption(const CallBase &CB, 77*349cc55cSDimitry Andric const KnownAssumptionString &AssumptionStr) { 78*349cc55cSDimitry Andric if (Function *F = CB.getCalledFunction()) 79*349cc55cSDimitry Andric if (hasAssumption(*F, AssumptionStr)) 80*349cc55cSDimitry Andric return true; 81*349cc55cSDimitry Andric 82*349cc55cSDimitry Andric const Attribute &A = CB.getFnAttr(AssumptionAttrKey); 83*349cc55cSDimitry Andric return ::hasAssumption(A, AssumptionStr); 84*349cc55cSDimitry Andric } 85*349cc55cSDimitry Andric 86*349cc55cSDimitry Andric DenseSet<StringRef> llvm::getAssumptions(const Function &F) { 87*349cc55cSDimitry Andric const Attribute &A = F.getFnAttribute(AssumptionAttrKey); 88*349cc55cSDimitry Andric return ::getAssumptions(A); 89*349cc55cSDimitry Andric } 90*349cc55cSDimitry Andric 91*349cc55cSDimitry Andric DenseSet<StringRef> llvm::getAssumptions(const CallBase &CB) { 92*349cc55cSDimitry Andric const Attribute &A = CB.getFnAttr(AssumptionAttrKey); 93*349cc55cSDimitry Andric return ::getAssumptions(A); 94*349cc55cSDimitry Andric } 95*349cc55cSDimitry Andric 96*349cc55cSDimitry Andric bool llvm::addAssumptions(Function &F, const DenseSet<StringRef> &Assumptions) { 97*349cc55cSDimitry Andric return ::addAssumptionsImpl(F, Assumptions); 98*349cc55cSDimitry Andric } 99*349cc55cSDimitry Andric 100*349cc55cSDimitry Andric bool llvm::addAssumptions(CallBase &CB, 101*349cc55cSDimitry Andric const DenseSet<StringRef> &Assumptions) { 102*349cc55cSDimitry Andric return ::addAssumptionsImpl(CB, Assumptions); 103e8d8bef9SDimitry Andric } 104e8d8bef9SDimitry Andric 105e8d8bef9SDimitry Andric StringSet<> llvm::KnownAssumptionStrings({ 106e8d8bef9SDimitry Andric "omp_no_openmp", // OpenMP 5.1 107e8d8bef9SDimitry Andric "omp_no_openmp_routines", // OpenMP 5.1 108e8d8bef9SDimitry Andric "omp_no_parallelism", // OpenMP 5.1 109fe6060f1SDimitry Andric "ompx_spmd_amenable", // OpenMPOpt extension 110e8d8bef9SDimitry Andric }); 111