| //===- llvm/BundleAttributes.cpp - LLVM Bundle Attributes -------*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/IR/BundleAttributes.h" | |
| #include "llvm/IR/Constants.h" | |
| using namespace llvm; | |
| StringRef llvm::getNameFromBundleAttr(BundleAttr BA) { | |
| switch (BA) { | |
| #define ATTR(Name, Str) \ | |
| case BundleAttr::Name: \ | |
| return #Str; | |
| #include "llvm/IR/BundleAttributes.def" | |
| case BundleAttr::None: | |
| return "none"; | |
| } | |
| llvm_unreachable("unknonwn bundle attribute"); | |
| } | |
| BundleAttr llvm::getBundleAttrFromID(uint32_t ID) { | |
| switch (ID) { | |
| #define ATTR(Name, Str) \ | |
| case LLVMContext::OB_##Name: \ | |
| return BundleAttr::Name; | |
| #include "llvm/IR/BundleAttributes.def" | |
| default: | |
| return BundleAttr::None; | |
| } | |
| } | |
| AssumeAlignInfo llvm::getAssumeAlignInfo(OperandBundleUse OBU) { | |
| assert(OBU.getTagID() == LLVMContext::OB_Align && OBU.Inputs.size() >= 2 && | |
| OBU.Inputs.size() <= 3); | |
| AssumeAlignInfo Ret{OBU.Inputs[0], OBU.Inputs[1], nullptr, std::nullopt, | |
| std::nullopt}; | |
| if (auto *Align = dyn_cast<ConstantInt>(OBU.Inputs[1])) | |
| Ret.AlignmentVal = Align->getZExtValue(); | |
| if (OBU.Inputs.size() == 3) { | |
| Ret.Offset = &OBU.Inputs[2]; | |
| if (auto *Offset = dyn_cast<ConstantInt>(OBU.Inputs[2])) | |
| Ret.OffsetVal = Offset->getZExtValue(); | |
| } else { | |
| Ret.OffsetVal = 0; | |
| } | |
| return Ret; | |
| } | |
| AssumeNoUndefInfo llvm::getAssumeNoUndefInfo(OperandBundleUse OBU) { | |
| assert(OBU.getTagID() == LLVMContext::OB_NoUndef && OBU.Inputs.size() == 1); | |
| return {OBU.Inputs[0]}; | |
| } | |
| AssumeSeparateStorageInfo | |
| llvm::getAssumeSeparateStorageInfo(OperandBundleUse OBU) { | |
| assert(OBU.getTagID() == LLVMContext::OB_SeparateStorage && | |
| OBU.Inputs.size() == 2); | |
| return {OBU.Inputs[0], OBU.Inputs[1]}; | |
| } | |
| AssumeNonNullInfo llvm::getAssumeNonNullInfo(OperandBundleUse OBU) { | |
| assert(OBU.getTagID() == LLVMContext::OB_NonNull && OBU.Inputs.size() == 1); | |
| return {OBU.Inputs[0]}; | |
| } | |
| AssumeDereferenceableInfo | |
| llvm::getAssumeDereferenceableInfo(OperandBundleUse OBU) { | |
| assert(OBU.getTagID() == LLVMContext::OB_Dereferenceable && | |
| OBU.Inputs.size() == 2); | |
| AssumeDereferenceableInfo Ret{OBU.Inputs[0], OBU.Inputs[1], std::nullopt}; | |
| if (auto *Size = dyn_cast<ConstantInt>(OBU.Inputs[1])) | |
| Ret.CountVal = Size->getZExtValue(); | |
| return Ret; | |
| } | |
| bool llvm::assumeBundleImpliesNonNull(const Value *Val, const Function *Context, | |
| OperandBundleUse OBU) { | |
| switch (getBundleAttrFromOBU(OBU)) { | |
| case BundleAttr::Align: { | |
| auto [Ptr, _, _2, Alignment, Offset] = getAssumeAlignInfo(OBU); | |
| return Ptr == Val && Alignment && Offset && isPowerOf2_64(*Alignment) && | |
| *Offset % *Alignment != 0; | |
| } | |
| case BundleAttr::Dereferenceable: { | |
| auto [Ptr, _, Count] = getAssumeDereferenceableInfo(OBU); | |
| return Ptr == Val && Count && *Count != 0 && | |
| !NullPointerIsDefined(Context, | |
| Val->getType()->getPointerAddressSpace()); | |
| } | |
| case BundleAttr::NonNull: | |
| return getAssumeNonNullInfo(OBU).Ptr == Val; | |
| default: | |
| return false; | |
| } | |
| } |