summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-10-22 03:12:22 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-10-22 03:12:22 +0000
commit98a341bc0cbc66a7f1456f834fea565541721087 (patch)
treea3344b02230b9487345f609a6339715ce5877598 /llvm/include
parentf2364bf129b533f99c4b9251fa60e720346223c8 (diff)
downloadbcm5719-llvm-98a341bc0cbc66a7f1456f834fea565541721087.tar.gz
bcm5719-llvm-98a341bc0cbc66a7f1456f834fea565541721087.zip
[OperandBundles] Make function attributes conservatively correct
Summary: This makes attribute accessors on `CallInst` and `InvokeInst` do the (conservatively) right thing. This essentially involves, in some cases, *not* falling back querying the attributes on the called `llvm::Function` when operand bundles are present. Attributes locally present on the `CallInst` or `InvokeInst` will still override operand bundle semantics. The LangRef has been amended to reflect this. Note: this change does not do anything prevent `-function-attrs` from inferring `CallSite` local attributes after inspecting the called function -- that will be done as a separate change. I've used `-adce` and `-early-cse` to test these changes. There is nothing special about these passes (and they did not require any changes) except that they seemed be the easiest way to write the tests. This change does not add deal with `argmemonly`. That's a later change because alias analysis requires a related fix before `argmemonly` can be tested. Reviewers: reames, chandlerc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D13961 llvm-svn: 250973
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/IR/InstrTypes.h43
-rw-r--r--llvm/include/llvm/IR/Instructions.h6
2 files changed, 49 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index c3bbe22069c..136a6c3f457 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/OperandTraits.h"
@@ -1232,8 +1233,50 @@ public:
return None;
}
+ /// \brief Return true if this operand bundle user has operand bundles that
+ /// may read from the heap.
+ bool hasReadingOperandBundles() const {
+ // Implementation note: this is a conservative implementation of operand
+ // bundle semantics, where *any* operand bundle forces a callsite to be at
+ // least readonly.
+ return hasOperandBundles();
+ }
+
+ /// \brief Return true if this operand bundle user has operand bundles that
+ /// may write to the heap.
+ bool hasClobberingOperandBundles() const {
+ // Implementation note: this is a conservative implementation of operand
+ // bundle semantics, where *any* operand bundle forces a callsite to be
+ // read-write.
+ return hasOperandBundles();
+ }
protected:
+ /// \brief Is the function attribute S disallowed by some operand bundle on
+ /// this operand bundle user?
+ bool isFnAttrDisallowedByOpBundle(StringRef S) const {
+ // Operand bundles only possibly disallow readnone and readonly attributes.
+ // All String attributes are fine.
+ return false;
+ }
+
+ /// \brief Is the function attribute A disallowed by some operand bundle on
+ /// this operand bundle user?
+ bool isFnAttrDisallowedByOpBundle(Attribute::AttrKind A) const {
+ switch (A) {
+ default:
+ return false;
+
+ case Attribute::ReadNone:
+ return hasReadingOperandBundles();
+
+ case Attribute::ReadOnly:
+ return hasClobberingOperandBundles();
+ }
+
+ llvm_unreachable("switch has a default case!");
+ }
+
/// \brief Used to keep track of an operand bundle. See the main comment on
/// OperandBundleUser above.
struct BundleOpInfo {
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 9fb44ca07a6..cb3a260e0d5 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -1742,6 +1742,12 @@ private:
template <typename AttrKind> bool hasFnAttrImpl(AttrKind A) const {
if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))
return true;
+
+ // Operand bundles override attributes on the called function, but don't
+ // override attributes directly present on the call instruction.
+ if (isFnAttrDisallowedByOpBundle(A))
+ return false;
+
if (const Function *F = getCalledFunction())
return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A);
return false;
OpenPOWER on IntegriCloud