From: Sanjoy Das Date: Fri, 4 Dec 2015 20:34:37 +0000 (+0000) Subject: [OperandBundles] Allow operand-specific attributes in operand bundles X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=fb25c75967e3b30f6687737616613a56c9d442ca [OperandBundles] Allow operand-specific attributes in operand bundles Currently `OperandBundleUse::operandsHaveAttr` computes its result without being given a specific operand. This is problematic because it forces us to say that, e.g., even non-pointer operands in `"deopt"` operand bundles are `readonly`, which doesn't make sense. This commit changes `operandsHaveAttr` to work in the context of a specific operand, so that we can give the operand attributes that make sense for the operands's `llvm::Type`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254764 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 81de6999cdb..58bc7c1ee10 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -1121,14 +1121,12 @@ struct OperandBundleUse { explicit OperandBundleUse(StringMapEntry *Tag, ArrayRef Inputs) : Inputs(Inputs), Tag(Tag) {} - /// \brief Return true if all the operands in this operand bundle have the - /// attribute A. - /// - /// Currently there is no way to have attributes on operand bundles differ on - /// a per operand granularity. - bool operandsHaveAttr(Attribute::AttrKind A) const { + /// \brief Return true if the operand at index \p Idx in this operand bundle + /// has the attribute A. + bool operandHasAttr(unsigned Idx, Attribute::AttrKind A) const { if (isDeoptOperandBundle()) - return A == Attribute::ReadOnly || A == Attribute::NoCapture; + if (A == Attribute::ReadOnly || A == Attribute::NoCapture) + return Inputs[Idx]->getType()->isPointerTy(); // Conservative answer: no operands have any attributes. return false; @@ -1351,11 +1349,7 @@ public: /// It is an error to call this with an OpIdx that does not correspond to an /// bundle operand. OperandBundleUse getOperandBundleForOperand(unsigned OpIdx) const { - for (auto &BOI : bundle_op_infos()) - if (BOI.Begin <= OpIdx && OpIdx < BOI.End) - return operandBundleFromBundleOpInfo(BOI); - - llvm_unreachable("Did not find operand bundle for operand!"); + return operandBundleFromBundleOpInfo(getBundleOpInfoForOperand(OpIdx)); } /// \brief Return true if this operand bundle user has operand bundles that @@ -1382,6 +1376,14 @@ public: return false; } + /// \brief Return true if the bundle operand at index \p OpIdx has the + /// attribute \p A. + bool bundleOperandHasAttr(unsigned OpIdx, Attribute::AttrKind A) const { + auto &BOI = getBundleOpInfoForOperand(OpIdx); + auto OBU = operandBundleFromBundleOpInfo(BOI); + return OBU.operandHasAttr(OpIdx - BOI.Begin, A); + } + protected: /// \brief Is the function attribute S disallowed by some operand bundle on /// this operand bundle user? @@ -1518,6 +1520,18 @@ protected: return It; } + /// \brief Return the BundleOpInfo for the operand at index OpIdx. + /// + /// It is an error to call this with an OpIdx that does not correspond to an + /// bundle operand. + const BundleOpInfo &getBundleOpInfoForOperand(unsigned OpIdx) const { + for (auto &BOI : bundle_op_infos()) + if (BOI.Begin <= OpIdx && OpIdx < BOI.End) + return BOI; + + llvm_unreachable("Did not find operand bundle for operand!"); + } + /// \brief Return the total number of values used in \p Bundles. static unsigned CountBundleInputs(ArrayRef Bundles) { unsigned Total = 0; diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index b8c72dd7e39..bba0ef2d7d3 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -369,7 +369,7 @@ bool CallInst::dataOperandHasImpliedAttr(unsigned i, assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) && "Must be either a call argument or an operand bundle!"); - return getOperandBundleForOperand(i - 1).operandsHaveAttr(A); + return bundleOperandHasAttr(i - 1, A); } /// IsConstantOne - Return true only if val is constant int 1 @@ -646,7 +646,7 @@ bool InvokeInst::dataOperandHasImpliedAttr(unsigned i, assert(hasOperandBundles() && i >= (getBundleOperandsStartIndex() + 1) && "Must be either an invoke argument or an operand bundle!"); - return getOperandBundleForOperand(i - 1).operandsHaveAttr(A); + return bundleOperandHasAttr(i - 1, A); } void InvokeInst::addAttribute(unsigned i, Attribute::AttrKind attr) {