diff options
Diffstat (limited to 'include/llvm/IR')
-rw-r--r-- | include/llvm/IR/Attributes.h | 46 | ||||
-rw-r--r-- | include/llvm/IR/BasicBlock.h | 45 | ||||
-rw-r--r-- | include/llvm/IR/IntrinsicInst.h | 13 | ||||
-rw-r--r-- | include/llvm/IR/Intrinsics.td | 58 | ||||
-rw-r--r-- | include/llvm/IR/IntrinsicsAMDGPU.td | 10 | ||||
-rw-r--r-- | include/llvm/IR/Metadata.h | 1 | ||||
-rw-r--r-- | include/llvm/IR/Module.h | 5 |
7 files changed, 148 insertions, 30 deletions
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index d4a896c01867..ace309ed95a4 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -322,7 +322,7 @@ template <> struct DenseMapInfo<AttributeSet> { /// the AttributeList object. The function attributes are at index /// `AttributeList::FunctionIndex', the return value is at index /// `AttributeList::ReturnIndex', and the attributes for the parameters start at -/// index `1'. +/// index `AttributeList::FirstArgIndex'. class AttributeList { public: enum AttrIndex : unsigned { @@ -347,8 +347,8 @@ public: /// \brief Create an AttributeList with the specified parameters in it. static AttributeList get(LLVMContext &C, ArrayRef<std::pair<unsigned, Attribute>> Attrs); - static AttributeList - get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); + static AttributeList get(LLVMContext &C, + ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); /// \brief Create an AttributeList from attribute sets for a function, its /// return value, and all of its arguments. @@ -356,13 +356,11 @@ public: AttributeSet RetAttrs, ArrayRef<AttributeSet> ArgAttrs); - static AttributeList - getImpl(LLVMContext &C, - ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); - private: explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} + static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets); + public: AttributeList() = default; @@ -521,39 +519,31 @@ public: /// \brief Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; - using iterator = ArrayRef<Attribute>::iterator; + //===--------------------------------------------------------------------===// + // AttributeList Introspection + //===--------------------------------------------------------------------===// + + typedef const AttributeSet *iterator; + iterator begin() const; + iterator end() const; + + unsigned getNumAttrSets() const; - iterator begin(unsigned Slot) const; - iterator end(unsigned Slot) const; + /// Use these to iterate over the valid attribute indices. + unsigned index_begin() const { return AttributeList::FunctionIndex; } + unsigned index_end() const { return getNumAttrSets() - 1; } /// operator==/!= - Provide equality predicates. bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } - //===--------------------------------------------------------------------===// - // AttributeList Introspection - //===--------------------------------------------------------------------===// - /// \brief Return a raw pointer that uniquely identifies this attribute list. void *getRawPointer() const { return pImpl; } /// \brief Return true if there are no attributes. - bool isEmpty() const { - return getNumSlots() == 0; - } - - /// \brief Return the number of slots used in this attribute list. This is - /// the number of arguments that have an attribute set on them (including the - /// function itself). - unsigned getNumSlots() const; - - /// \brief Return the index for the given slot. - unsigned getSlotIndex(unsigned Slot) const; - - /// \brief Return the attributes at the given slot. - AttributeSet getSlotAttributes(unsigned Slot) const; + bool isEmpty() const { return pImpl == nullptr; } void dump() const; }; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index c917b1f2cada..235cb57cfd09 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -33,6 +33,7 @@ class Function; class LandingPadInst; class LLVMContext; class Module; +class PHINode; class TerminatorInst; class ValueSymbolTable; @@ -261,6 +262,50 @@ public: inline const Instruction &back() const { return InstList.back(); } inline Instruction &back() { return InstList.back(); } + /// Iterator to walk just the phi nodes in the basic block. + template <typename PHINodeT = PHINode, typename BBIteratorT = iterator> + class phi_iterator_impl + : public iterator_facade_base<phi_iterator_impl<PHINodeT, BBIteratorT>, + std::forward_iterator_tag, PHINodeT> { + friend BasicBlock; + + PHINodeT *PN; + + phi_iterator_impl(PHINodeT *PN) : PN(PN) {} + + public: + // Allow default construction to build variables, but this doesn't build + // a useful iterator. + phi_iterator_impl() = default; + + // Allow conversion between instantiations where valid. + template <typename PHINodeU, typename BBIteratorU> + phi_iterator_impl(const phi_iterator_impl<PHINodeU, BBIteratorU> &Arg) + : PN(Arg.PN) {} + + bool operator==(const phi_iterator_impl &Arg) const { return PN == Arg.PN; } + + PHINodeT &operator*() const { return *PN; } + + using phi_iterator_impl::iterator_facade_base::operator++; + phi_iterator_impl &operator++() { + assert(PN && "Cannot increment the end iterator!"); + PN = dyn_cast<PHINodeT>(std::next(BBIteratorT(PN))); + return *this; + } + }; + typedef phi_iterator_impl<> phi_iterator; + typedef phi_iterator_impl<const PHINode, BasicBlock::const_iterator> + const_phi_iterator; + + /// Returns a range that iterates over the phis in the basic block. + /// + /// Note that this cannot be used with basic blocks that have no terminator. + iterator_range<const_phi_iterator> phis() const { + return const_cast<BasicBlock *>(this)->phis(); + } + iterator_range<phi_iterator> phis(); + /// \brief Return the underlying instruction list container. /// /// Currently you need to access the underlying instruction list container diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index 05e3315cbab2..2ae98d9e35b0 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -171,6 +171,7 @@ namespace llvm { ebStrict }; + bool isUnaryOp() const; RoundingMode getRoundingMode() const; ExceptionBehavior getExceptionBehavior() const; @@ -182,6 +183,18 @@ namespace llvm { case Intrinsic::experimental_constrained_fmul: case Intrinsic::experimental_constrained_fdiv: case Intrinsic::experimental_constrained_frem: + case Intrinsic::experimental_constrained_sqrt: + case Intrinsic::experimental_constrained_pow: + case Intrinsic::experimental_constrained_powi: + case Intrinsic::experimental_constrained_sin: + case Intrinsic::experimental_constrained_cos: + case Intrinsic::experimental_constrained_exp: + case Intrinsic::experimental_constrained_exp2: + case Intrinsic::experimental_constrained_log: + case Intrinsic::experimental_constrained_log10: + case Intrinsic::experimental_constrained_log2: + case Intrinsic::experimental_constrained_rint: + case Intrinsic::experimental_constrained_nearbyint: return true; default: return false; } diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 19f6045568f4..291d16fb0d9b 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -489,8 +489,64 @@ let IntrProperties = [IntrInaccessibleMemOnly] in { LLVMMatchType<0>, llvm_metadata_ty, llvm_metadata_ty ]>; + + // These intrinsics are sensitive to the rounding mode so we need constrained + // versions of each of them. When strict rounding and exception control are + // not required the non-constrained versions of these intrinsics should be + // used. + def int_experimental_constrained_sqrt : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_powi : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_i32_ty, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_sin : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_cos : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_pow : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_log : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_log10: Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_log2 : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_exp : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_exp2 : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_rint : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; + def int_experimental_constrained_nearbyint : Intrinsic<[ llvm_anyfloat_ty ], + [ LLVMMatchType<0>, + llvm_metadata_ty, + llvm_metadata_ty ]>; } -// FIXME: Add intrinsic for fcmp, fptrunc, fpext, fptoui and fptosi. +// FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi. +// FIXME: Add intrinsics for fabs, copysign, floor, ceil, trunc and round? //===------------------------- Expect Intrinsics --------------------------===// diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index d7413fe9e56f..e1928546607a 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -566,6 +566,16 @@ def int_amdgcn_s_getreg : [IntrReadMem, IntrSpeculatable] >; +// int_amdgcn_s_getpc is provided to allow a specific style of position +// independent code to determine the high part of its address when it is +// known (through convention) that the code and any data of interest does +// not cross a 4Gb address boundary. Use for any other purpose may not +// produce the desired results as optimizations may cause code movement, +// especially as we explicitly use IntrNoMem to allow optimizations. +def int_amdgcn_s_getpc : + GCCBuiltin<"__builtin_amdgcn_s_getpc">, + Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>; + // __builtin_amdgcn_interp_mov <param>, <attr_chan>, <attr>, <m0> // param values: 0 = P10, 1 = P20, 2 = P0 def int_amdgcn_interp_mov : diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 92f701e01ff3..3c753260190e 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -1223,6 +1223,7 @@ public: // FIXME: Fix callers and remove condition on N. unsigned size() const { return N ? N->getNumOperands() : 0u; } + bool empty() const { return N ? N->getNumOperands() == 0 : true; } T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); } // FIXME: Fix callers and remove condition on N. diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 3024d9e27a2f..5e1f680c5b36 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -139,9 +139,12 @@ public: /// during the append operation. AppendUnique = 6, + /// Takes the max of the two values, which are required to be integers. + Max = 7, + // Markers: ModFlagBehaviorFirstVal = Error, - ModFlagBehaviorLastVal = AppendUnique + ModFlagBehaviorLastVal = Max }; /// Checks if Metadata represents a valid ModFlagBehavior, and stores the |