Don't taint relaxed loads that immediately comes before an AcqRel read-modify-write op
[oota-llvm.git] / include / llvm / IR / Instructions.h
index e8171db40051e625745469b18e86cc1429a7c5b0..cc6c25974cd5422ed48a6691a033783ea3fab7aa 100644 (file)
@@ -228,6 +228,14 @@ public:
   LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
            BasicBlock *InsertAtEnd);
 
+  bool getHasSubsequentAcqlRMW() {
+    return hasSubsequentAcqlRMW_;
+  }
+
+  void setHasSubsequentAcqlRMW(bool val) {
+    hasSubsequentAcqlRMW_ = val;
+  }
+
   /// isVolatile - Return true if this is a load from a volatile memory
   /// location.
   ///
@@ -306,6 +314,8 @@ private:
   void setInstructionSubclassData(unsigned short D) {
     Instruction::setInstructionSubclassData(D);
   }
+
+  bool hasSubsequentAcqlRMW_;
 };
 
 //===----------------------------------------------------------------------===//
@@ -839,6 +849,8 @@ class GetElementPtrInst : public Instruction {
   Type *SourceElementType;
   Type *ResultElementType;
 
+  void anchor() override;
+
   GetElementPtrInst(const GetElementPtrInst &GEPI);
   void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
 
@@ -1097,6 +1109,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
 /// must be identical types.
 /// \brief Represent an integer comparison operator.
 class ICmpInst: public CmpInst {
+  void anchor() override;
+
   void AssertOK() {
     assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE &&
            getPredicate() <= CmpInst::LAST_ICMP_PREDICATE &&
@@ -2426,6 +2440,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
 // scientist's overactive imagination.
 //
 class PHINode : public Instruction {
+  void anchor() override;
+
   void *operator new(size_t, unsigned) = delete;
   /// ReservedSpace - The number of operands actually allocated.  NumOperands is
   /// the number actually in use.
@@ -2506,6 +2522,14 @@ public:
     return block_begin() + getNumOperands();
   }
 
+  iterator_range<block_iterator> blocks() {
+    return make_range(block_begin(), block_end());
+  }
+
+  iterator_range<const_block_iterator> blocks() const {
+    return make_range(block_begin(), block_end());
+  }
+
   op_range incoming_values() { return operands(); }
 
   const_op_range incoming_values() const { return operands(); }
@@ -3544,6 +3568,11 @@ public:
     return hasFnAttrImpl(A);
   }
 
+  /// \brief Determine whether this call has the given attribute.
+  bool hasFnAttr(StringRef A) const {
+    return hasFnAttrImpl(A);
+  }
+
   /// \brief Determine whether the call or the callee has the given attributes.
   bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;
 
@@ -3728,7 +3757,19 @@ private:
   unsigned getNumSuccessorsV() const override;
   void setSuccessorV(unsigned idx, BasicBlock *B) override;
 
-  bool hasFnAttrImpl(Attribute::AttrKind A) const;
+  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 invoke instruction.
+    if (isFnAttrDisallowedByOpBundle(A))
+      return false;
+
+    if (const Function *F = getCalledFunction())
+      return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A);
+    return false;
+  }
 
   // Shadow Instruction::setInstructionSubclassData with a private forwarding
   // method so that subclasses cannot accidentally use it.
@@ -3960,6 +4001,8 @@ public:
   /// point to the added handler.
   void addHandler(BasicBlock *Dest);
 
+  void removeHandler(handler_iterator HI);
+
   unsigned getNumSuccessors() const { return getNumOperands() - 1; }
   BasicBlock *getSuccessor(unsigned Idx) const {
     assert(Idx < getNumSuccessors() &&
@@ -3991,143 +4034,6 @@ struct OperandTraits<CatchSwitchInst> : public HungoffOperandTraits<2> {};
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value)
 
-//===----------------------------------------------------------------------===//
-//                           TerminatePadInst Class
-//===----------------------------------------------------------------------===//
-
-class TerminatePadInst : public TerminatorInst {
-private:
-  void init(Value *ParentPad, BasicBlock *BB, ArrayRef<Value *> Args);
-
-  TerminatePadInst(const TerminatePadInst &TPI);
-
-  explicit TerminatePadInst(Value *ParentPad, BasicBlock *BB,
-                            ArrayRef<Value *> Args, unsigned Values,
-                            Instruction *InsertBefore);
-  explicit TerminatePadInst(Value *ParentPad, BasicBlock *BB,
-                            ArrayRef<Value *> Args, unsigned Values,
-                            BasicBlock *InsertAtEnd);
-
-protected:
-  // Note: Instruction needs to be a friend here to call cloneImpl.
-  friend class Instruction;
-  TerminatePadInst *cloneImpl() const;
-
-public:
-  static TerminatePadInst *Create(Value *ParentPad, BasicBlock *BB = nullptr,
-                                  ArrayRef<Value *> Args = None,
-                                  Instruction *InsertBefore = nullptr) {
-    unsigned Values = unsigned(Args.size()) + 1;
-    if (BB)
-      ++Values;
-    return new (Values)
-        TerminatePadInst(ParentPad, BB, Args, Values, InsertBefore);
-  }
-  static TerminatePadInst *Create(Value *ParentPad, BasicBlock *BB,
-                                  ArrayRef<Value *> Args,
-                                  BasicBlock *InsertAtEnd) {
-    unsigned Values = unsigned(Args.size()) + 1;
-    if (BB)
-      ++Values;
-    return new (Values)
-        TerminatePadInst(ParentPad, BB, Args, Values, InsertAtEnd);
-  }
-
-  /// Provide fast operand accessors
-  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
-  bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
-  bool unwindsToCaller() const { return !hasUnwindDest(); }
-
-  /// getNumArgOperands - Return the number of terminatepad arguments.
-  ///
-  unsigned getNumArgOperands() const {
-    unsigned NumOperands = getNumOperands();
-    if (hasUnwindDest())
-      return NumOperands - 2;
-    return NumOperands - 1;
-  }
-
-  /// Convenience accessors
-  Value *getParentPad() const { return Op<-1>(); }
-  void setParentPad(Value *ParentPad) {
-    assert(ParentPad);
-    Op<-1>() = ParentPad;
-  }
-
-  /// getArgOperand/setArgOperand - Return/set the i-th terminatepad argument.
-  ///
-  Value *getArgOperand(unsigned i) const { return getOperand(i); }
-  void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
-
-  const_op_iterator arg_begin() const { return op_begin(); }
-  op_iterator arg_begin() { return op_begin(); }
-
-  const_op_iterator arg_end() const {
-    if (hasUnwindDest())
-      return op_end() - 2;
-    return op_end() - 1;
-  }
-
-  op_iterator arg_end() {
-    if (hasUnwindDest())
-      return op_end() - 2;
-    return op_end() - 1;
-  }
-
-  /// arg_operands - iteration adapter for range-for loops.
-  iterator_range<op_iterator> arg_operands() {
-    return make_range(arg_begin(), arg_end());
-  }
-
-  /// arg_operands - iteration adapter for range-for loops.
-  iterator_range<const_op_iterator> arg_operands() const {
-    return make_range(arg_begin(), arg_end());
-  }
-
-  /// \brief Wrappers for getting the \c Use of a terminatepad argument.
-  const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
-  Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
-
-  // get*Dest - Return the destination basic blocks...
-  BasicBlock *getUnwindDest() const {
-    if (!hasUnwindDest())
-      return nullptr;
-    return cast<BasicBlock>(Op<-2>());
-  }
-  void setUnwindDest(BasicBlock *B) {
-    assert(B && hasUnwindDest());
-    Op<-2>() = B;
-  }
-
-  unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
-
-  // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::TerminatePad;
-  }
-  static inline bool classof(const Value *V) {
-    return isa<Instruction>(V) && classof(cast<Instruction>(V));
-  }
-
-private:
-  BasicBlock *getSuccessorV(unsigned idx) const override;
-  unsigned getNumSuccessorsV() const override;
-  void setSuccessorV(unsigned idx, BasicBlock *B) override;
-
-  // Shadow Instruction::setInstructionSubclassData with a private forwarding
-  // method so that subclasses cannot accidentally use it.
-  void setInstructionSubclassData(unsigned short D) {
-    Instruction::setInstructionSubclassData(D);
-  }
-};
-
-template <>
-struct OperandTraits<TerminatePadInst>
-    : public VariadicOperandTraits<TerminatePadInst, /*MINARITY=*/1> {};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value)
-
 //===----------------------------------------------------------------------===//
 //                               CleanupPadInst Class
 //===----------------------------------------------------------------------===//