summaryrefslogtreecommitdiff
path: root/include/llvm/IR
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR')
-rw-r--r--include/llvm/IR/Argument.h5
-rw-r--r--include/llvm/IR/Attributes.h71
-rw-r--r--include/llvm/IR/BasicBlock.h75
-rw-r--r--include/llvm/IR/CFG.h30
-rw-r--r--include/llvm/IR/CallSite.h51
-rw-r--r--include/llvm/IR/Comdat.h2
-rw-r--r--include/llvm/IR/Constant.h4
-rw-r--r--include/llvm/IR/ConstantFolder.h25
-rw-r--r--include/llvm/IR/ConstantRange.h33
-rw-r--r--include/llvm/IR/Constants.h94
-rw-r--r--include/llvm/IR/DIBuilder.h474
-rw-r--r--include/llvm/IR/DataLayout.h52
-rw-r--r--include/llvm/IR/DebugInfo.h1021
-rw-r--r--include/llvm/IR/DebugInfoFlags.def36
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h2227
-rw-r--r--include/llvm/IR/DebugLoc.h117
-rw-r--r--include/llvm/IR/DerivedTypes.h27
-rw-r--r--include/llvm/IR/DiagnosticInfo.h1
-rw-r--r--include/llvm/IR/Function.h139
-rw-r--r--include/llvm/IR/GVMaterializer.h7
-rw-r--r--include/llvm/IR/GetElementPtrTypeIterator.h50
-rw-r--r--include/llvm/IR/GlobalAlias.h24
-rw-r--r--include/llvm/IR/GlobalObject.h4
-rw-r--r--include/llvm/IR/GlobalValue.h37
-rw-r--r--include/llvm/IR/GlobalVariable.h8
-rw-r--r--include/llvm/IR/IRBuilder.h217
-rw-r--r--include/llvm/IR/IRPrintingPasses.h7
-rw-r--r--include/llvm/IR/InlineAsm.h60
-rw-r--r--include/llvm/IR/InstIterator.h29
-rw-r--r--include/llvm/IR/InstVisitor.h2
-rw-r--r--include/llvm/IR/InstrTypes.h25
-rw-r--r--include/llvm/IR/Instruction.h64
-rw-r--r--include/llvm/IR/Instructions.h345
-rw-r--r--include/llvm/IR/IntrinsicInst.h42
-rw-r--r--include/llvm/IR/Intrinsics.h29
-rw-r--r--include/llvm/IR/Intrinsics.td62
-rw-r--r--include/llvm/IR/IntrinsicsBPF.td24
-rw-r--r--include/llvm/IR/IntrinsicsHexagon.td463
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td387
-rw-r--r--include/llvm/IR/IntrinsicsSystemZ.td376
-rw-r--r--include/llvm/IR/IntrinsicsX86.td707
-rw-r--r--include/llvm/IR/LLVMContext.h8
-rw-r--r--include/llvm/IR/LegacyPassManager.h4
-rw-r--r--include/llvm/IR/LegacyPassNameParser.h12
-rw-r--r--include/llvm/IR/MDBuilder.h6
-rw-r--r--include/llvm/IR/Metadata.def73
-rw-r--r--include/llvm/IR/Metadata.h658
-rw-r--r--include/llvm/IR/Module.h42
-rw-r--r--include/llvm/IR/NoFolder.h25
-rw-r--r--include/llvm/IR/Operator.h70
-rw-r--r--include/llvm/IR/PassManager.h34
-rw-r--r--include/llvm/IR/PassManagerInternal.h1
-rw-r--r--include/llvm/IR/PatternMatch.h49
-rw-r--r--include/llvm/IR/PredIteratorCache.h87
-rw-r--r--include/llvm/IR/Statepoint.h255
-rw-r--r--include/llvm/IR/Type.h7
-rw-r--r--include/llvm/IR/TypeBuilder.h10
-rw-r--r--include/llvm/IR/Use.h2
-rw-r--r--include/llvm/IR/UseListOrder.h10
-rw-r--r--include/llvm/IR/User.h8
-rw-r--r--include/llvm/IR/Value.h33
-rw-r--r--include/llvm/IR/ValueHandle.h2
-rw-r--r--include/llvm/IR/ValueMap.h21
-rw-r--r--include/llvm/IR/Verifier.h13
64 files changed, 6275 insertions, 2608 deletions
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index dd76a90aa5ea..fc04fe71cbf0 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -64,6 +64,11 @@ public:
/// containing function, return the number of bytes known to be
/// dereferenceable. Otherwise, zero is returned.
uint64_t getDereferenceableBytes() const;
+
+ /// \brief If this argument has the dereferenceable_or_null attribute on
+ /// it in its containing function, return the number of bytes known to be
+ /// dereferenceable. Otherwise, zero is returned.
+ uint64_t getDereferenceableOrNullBytes() const;
/// \brief Return true if this argument has the byval attribute on it in its
/// containing function.
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 5ff48d688918..e2a0a7ee395a 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -73,6 +73,7 @@ public:
ByVal, ///< Pass structure by value
InAlloca, ///< Pass structure in an alloca
Cold, ///< Marks function as being in a cold path.
+ Convergent, ///< Can only be moved to control-equivalent blocks
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
JumpTable, ///< Build jump-instruction tables and replace refs.
@@ -89,6 +90,7 @@ public:
///< often, so lazy binding isn't worthwhile
NonNull, ///< Pointer is known to be not null
Dereferenceable, ///< Pointer is known to be dereferenceable
+ DereferenceableOrNull, ///< Pointer is either null or dereferenceable
NoRedZone, ///< Disable redzone
NoReturn, ///< Mark the function as not returning
NoUnwind, ///< Function doesn't unwind stack
@@ -136,6 +138,8 @@ public:
static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
static Attribute getWithDereferenceableBytes(LLVMContext &Context,
uint64_t Bytes);
+ static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context,
+ uint64_t Bytes);
//===--------------------------------------------------------------------===//
// Attribute Accessors
@@ -185,6 +189,10 @@ public:
/// dereferenceable attribute (or zero if unknown).
uint64_t getDereferenceableBytes() const;
+ /// \brief Returns the number of dereferenceable_or_null bytes from the
+ /// dereferenceable_or_null attribute (or zero if unknown).
+ uint64_t getDereferenceableOrNullBytes() const;
+
/// \brief The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
std::string getAsString(bool InAttrGrp = false) const;
@@ -253,35 +261,52 @@ public:
ArrayRef<Attribute::AttrKind> Kind);
static AttributeSet get(LLVMContext &C, unsigned Index, const AttrBuilder &B);
- /// \brief Add an attribute to the attribute set at the given index. Since
+ /// \brief Add an attribute to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Attr) const;
- /// \brief Add an attribute to the attribute set at the given index. Since
+ /// \brief Add an attribute to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
StringRef Kind) const;
AttributeSet addAttribute(LLVMContext &C, unsigned Index,
StringRef Kind, StringRef Value) const;
- /// \brief Add attributes to the attribute set at the given index. Since
+ /// \brief Add attributes to the attribute set at the given index. Because
/// attribute sets are immutable, this returns a new set.
AttributeSet addAttributes(LLVMContext &C, unsigned Index,
AttributeSet Attrs) const;
/// \brief Remove the specified attribute at the specified index from this
- /// attribute list. Since attribute lists are immutable, this returns the new
- /// list.
+ /// attribute list. Because attribute lists are immutable, this returns the
+ /// new list.
AttributeSet removeAttribute(LLVMContext &C, unsigned Index,
Attribute::AttrKind Attr) const;
/// \brief Remove the specified attributes at the specified index from this
- /// attribute list. Since attribute lists are immutable, this returns the new
- /// list.
+ /// attribute list. Because attribute lists are immutable, this returns the
+ /// new list.
AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
AttributeSet Attrs) const;
+ /// \brief Remove the specified attributes at the specified index from this
+ /// attribute list. Because attribute lists are immutable, this returns the
+ /// new list.
+ AttributeSet removeAttributes(LLVMContext &C, unsigned Index,
+ const AttrBuilder &Attrs) const;
+
+ /// \brief Add the dereferenceable attribute to the attribute set at the given
+ /// index. Because attribute sets are immutable, this returns a new set.
+ AttributeSet addDereferenceableAttr(LLVMContext &C, unsigned Index,
+ uint64_t Bytes) const;
+
+ /// \brief Add the dereferenceable_or_null attribute to the attribute set at
+ /// the given index. Because attribute sets are immutable, this returns a new
+ /// set.
+ AttributeSet addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
+ uint64_t Bytes) const;
+
//===--------------------------------------------------------------------===//
// AttributeSet Accessors
//===--------------------------------------------------------------------===//
@@ -326,6 +351,10 @@ public:
/// \brief Get the number of dereferenceable bytes (or zero if unknown).
uint64_t getDereferenceableBytes(unsigned Index) const;
+ /// \brief Get the number of dereferenceable_or_null bytes (or zero if
+ /// unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned Index) const;
+
/// \brief Return the attributes at the index as a string.
std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
@@ -406,14 +435,19 @@ class AttrBuilder {
uint64_t Alignment;
uint64_t StackAlignment;
uint64_t DerefBytes;
+ uint64_t DerefOrNullBytes;
public:
- AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {}
+ AttrBuilder()
+ : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
+ DerefOrNullBytes(0) {}
explicit AttrBuilder(uint64_t Val)
- : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+ : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
+ DerefOrNullBytes(0) {
addRawValue(Val);
}
AttrBuilder(const Attribute &A)
- : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) {
+ : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
+ DerefOrNullBytes(0) {
addAttribute(A);
}
AttrBuilder(AttributeSet AS, unsigned Idx);
@@ -441,6 +475,13 @@ public:
/// \brief Add the attributes from the builder.
AttrBuilder &merge(const AttrBuilder &B);
+ /// \brief Remove the attributes from the builder.
+ AttrBuilder &remove(const AttrBuilder &B);
+
+ /// \brief Return true if the builder has any attribute that's in the
+ /// specified builder.
+ bool overlaps(const AttrBuilder &B) const;
+
/// \brief Return true if the builder has the specified attribute.
bool contains(Attribute::AttrKind A) const {
assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
@@ -471,6 +512,10 @@ public:
/// attribute exists (zero is returned otherwise).
uint64_t getDereferenceableBytes() const { return DerefBytes; }
+ /// \brief Retrieve the number of dereferenceable_or_null bytes, if the
+ /// dereferenceable_or_null attribute exists (zero is returned otherwise).
+ uint64_t getDereferenceableOrNullBytes() const { return DerefOrNullBytes; }
+
/// \brief This turns an int alignment (which must be a power of 2) into the
/// form used internally in Attribute.
AttrBuilder &addAlignmentAttr(unsigned Align);
@@ -483,6 +528,10 @@ public:
/// internally in Attribute.
AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
+ /// \brief This turns the number of dereferenceable_or_null bytes into the
+ /// form used internally in Attribute.
+ AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);
+
/// \brief Return true if the builder contains no target-independent
/// attributes.
bool empty() const { return Attrs.none(); }
@@ -521,7 +570,7 @@ public:
namespace AttributeFuncs {
/// \brief Which attributes cannot be applied to a type.
-AttributeSet typeIncompatible(Type *Ty, uint64_t Index);
+AttrBuilder typeIncompatible(const Type *Ty);
} // end AttributeFuncs namespace
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 7c7dd2ca5643..66581bfedbe6 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -28,33 +28,25 @@ class LandingPadInst;
class TerminatorInst;
class LLVMContext;
class BlockAddress;
+class Function;
-template<> struct ilist_traits<Instruction>
- : public SymbolTableListTraits<Instruction, BasicBlock> {
+// Traits for intrusive list of basic blocks...
+template<> struct ilist_traits<BasicBlock>
+ : public SymbolTableListTraits<BasicBlock, Function> {
- /// \brief Return a node that marks the end of a list.
- ///
- /// The sentinel is relative to this instance, so we use a non-static
- /// method.
- Instruction *createSentinel() const {
- // Since i(p)lists always publicly derive from their corresponding traits,
- // placing a data member in this class will augment the i(p)list. But since
- // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
- // there is a legal viable downcast from it to NodeTy. We use this trick to
- // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
- // sentinel. Dereferencing the sentinel is forbidden (save the
- // ilist_node<NodeTy>), so no one will ever notice the superposition.
- return static_cast<Instruction*>(&Sentinel);
- }
- static void destroySentinel(Instruction*) {}
+ BasicBlock *createSentinel() const;
+ static void destroySentinel(BasicBlock*) {}
- Instruction *provideInitialHead() const { return createSentinel(); }
- Instruction *ensureHead(Instruction*) const { return createSentinel(); }
- static void noteHead(Instruction*, Instruction*) {}
+ BasicBlock *provideInitialHead() const { return createSentinel(); }
+ BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
+ static void noteHead(BasicBlock*, BasicBlock*) {}
+
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
private:
- mutable ilist_half_node<Instruction> Sentinel;
+ mutable ilist_half_node<BasicBlock> Sentinel;
};
+
/// \brief LLVM Basic Block Representation
///
/// This represents a single basic block in LLVM. A basic block is simply a
@@ -82,8 +74,8 @@ private:
void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock, Function>;
- BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
- void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
+ BasicBlock(const BasicBlock &) = delete;
+ void operator=(const BasicBlock &) = delete;
/// \brief Constructor.
///
@@ -113,13 +105,18 @@ public:
BasicBlock *InsertBefore = nullptr) {
return new BasicBlock(Context, Name, Parent, InsertBefore);
}
- ~BasicBlock();
+ ~BasicBlock() override;
/// \brief Return the enclosing method, or null if none.
const Function *getParent() const { return Parent; }
Function *getParent() { return Parent; }
- const DataLayout *getDataLayout() const;
+ /// \brief Return the module owning the function this basic block belongs to,
+ /// or nullptr it the function does not have a module.
+ ///
+ /// Note: this is undefined behavior if the block does not have a parent.
+ const Module *getModule() const;
+ Module *getModule();
/// \brief Returns the terminator instruction if the block is well formed or
/// null if the block is not well formed.
@@ -172,7 +169,9 @@ public:
void removeFromParent();
/// \brief Unlink 'this' from the containing function and delete it.
- void eraseFromParent();
+ ///
+ // \returns an iterator pointing to the element after the erased one.
+ iplist<BasicBlock>::iterator eraseFromParent();
/// \brief Unlink this basic block from its current function and insert it
/// into the function that \p MovePos lives in, right before \p MovePos.
@@ -208,6 +207,24 @@ public:
return const_cast<BasicBlock*>(this)->getUniquePredecessor();
}
+ /// \brief Return the successor of this block if it has a single successor.
+ /// Otherwise return a null pointer.
+ ///
+ /// This method is analogous to getSinglePredecessor above.
+ BasicBlock *getSingleSuccessor();
+ const BasicBlock *getSingleSuccessor() const {
+ return const_cast<BasicBlock*>(this)->getSingleSuccessor();
+ }
+
+ /// \brief Return the successor of this block if it has a unique successor.
+ /// Otherwise return a null pointer.
+ ///
+ /// This method is analogous to getUniquePredecessor above.
+ BasicBlock *getUniqueSuccessor();
+ const BasicBlock *getUniqueSuccessor() const {
+ return const_cast<BasicBlock*>(this)->getUniqueSuccessor();
+ }
+
//===--------------------------------------------------------------------===//
/// Instruction iterator methods
///
@@ -320,6 +337,12 @@ private:
}
};
+// createSentinel is used to get hold of the node that marks the end of the
+// list... (same trick used here as in ilist_traits<Instruction>)
+inline BasicBlock *ilist_traits<BasicBlock>::createSentinel() const {
+ return static_cast<BasicBlock*>(&Sentinel);
+}
+
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h
index 5400d2384868..f78220a52033 100644
--- a/include/llvm/IR/CFG.h
+++ b/include/llvm/IR/CFG.h
@@ -16,6 +16,7 @@
#define LLVM_IR_CFG_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
@@ -84,6 +85,8 @@ public:
typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
typedef PredIterator<const BasicBlock,
Value::const_user_iterator> const_pred_iterator;
+typedef llvm::iterator_range<pred_iterator> pred_range;
+typedef llvm::iterator_range<const_pred_iterator> pred_const_range;
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
@@ -96,8 +99,12 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) {
inline bool pred_empty(const BasicBlock *BB) {
return pred_begin(BB) == pred_end(BB);
}
-
-
+inline pred_range predecessors(BasicBlock *BB) {
+ return pred_range(pred_begin(BB), pred_end(BB));
+}
+inline pred_const_range predecessors(const BasicBlock *BB) {
+ return pred_const_range(pred_begin(BB), pred_end(BB));
+}
//===----------------------------------------------------------------------===//
// BasicBlock succ_iterator definition
@@ -114,7 +121,7 @@ public:
typedef typename super::reference reference;
private:
- const Term_ Term;
+ Term_ Term;
unsigned idx;
typedef SuccIterator<Term_, BB_> Self;
@@ -129,6 +136,8 @@ private:
public:
explicit SuccessorProxy(const Self &it) : it(it) {}
+ SuccessorProxy(const SuccessorProxy&) = default;
+
SuccessorProxy &operator=(SuccessorProxy r) {
*this = reference(r);
return *this;
@@ -158,12 +167,6 @@ public:
idx = 0;
}
- inline const Self &operator=(const Self &I) {
- assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
- idx = I.idx;
- return *this;
- }
-
/// getSuccessorIndex - This is used to interface between code that wants to
/// operate on terminator instructions directly.
unsigned getSuccessorIndex() const { return idx; }
@@ -247,6 +250,8 @@ public:
typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
typedef SuccIterator<const TerminatorInst*,
const BasicBlock> succ_const_iterator;
+typedef llvm::iterator_range<succ_iterator> succ_range;
+typedef llvm::iterator_range<succ_const_iterator> succ_const_range;
inline succ_iterator succ_begin(BasicBlock *BB) {
return succ_iterator(BB->getTerminator());
@@ -263,6 +268,13 @@ inline succ_const_iterator succ_end(const BasicBlock *BB) {
inline bool succ_empty(const BasicBlock *BB) {
return succ_begin(BB) == succ_end(BB);
}
+inline succ_range successors(BasicBlock *BB) {
+ return succ_range(succ_begin(BB), succ_end(BB));
+}
+inline succ_const_range successors(const BasicBlock *BB) {
+ return succ_const_range(succ_begin(BB), succ_end(BB));
+}
+
template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > {
static const bool value = isPodLike<T>::value;
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index df082577a0e2..170d263dfc79 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -46,12 +46,13 @@ template <typename FunTy = const Function,
class CallSiteBase {
protected:
PointerIntPair<InstrTy*, 1, bool> I;
-public:
+
CallSiteBase() : I(nullptr, false) {}
CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
- CallSiteBase(ValTy *II) { *this = get(II); }
-protected:
+ explicit CallSiteBase(ValTy *II) { *this = get(II); }
+
+private:
/// CallSiteBase::get - This static method is sort of like a constructor. It
/// will create an appropriate call site for a Call or Invoke instruction, but
/// it can also create a null initialized CallSiteBase object for something
@@ -78,7 +79,7 @@ public:
InstrTy *getInstruction() const { return I.getPointer(); }
InstrTy *operator->() const { return I.getPointer(); }
- LLVM_EXPLICIT operator bool() const { return I.getPointer(); }
+ explicit operator bool() const { return I.getPointer(); }
/// getCalledValue - Return the pointer to function that is being called.
///
@@ -151,7 +152,7 @@ public:
IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
bool arg_empty() const { return arg_end() == arg_begin(); }
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
-
+
/// getType - Return the type of the instruction that generated this call site
///
Type *getType() const { return (*this)->getType(); }
@@ -193,6 +194,14 @@ public:
CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
}
+ FunctionType *getFunctionType() const {
+ CALLSITE_DELEGATE_GETTER(getFunctionType());
+ }
+
+ void mutateFunctionType(FunctionType *Ty) const {
+ CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty));
+ }
+
/// getAttributes/setAttributes - get or set the parameter attributes of
/// the call.
const AttributeSet &getAttributes() const {
@@ -222,7 +231,13 @@ public:
uint64_t getDereferenceableBytes(uint16_t i) const {
CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
}
-
+
+ /// @brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(uint16_t i) const {
+ CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
+ }
+
/// \brief Return true if the call should not be treated as a call to a
/// builtin.
bool isNoBuiltin() const {
@@ -349,15 +364,13 @@ private:
class CallSite : public CallSiteBase<Function, Value, User, Instruction,
CallInst, InvokeInst, User::op_iterator> {
- typedef CallSiteBase<Function, Value, User, Instruction,
- CallInst, InvokeInst, User::op_iterator> Base;
public:
CallSite() {}
- CallSite(Base B) : Base(B) {}
- CallSite(Value* V) : Base(V) {}
- CallSite(CallInst *CI) : Base(CI) {}
- CallSite(InvokeInst *II) : Base(II) {}
- CallSite(Instruction *II) : Base(II) {}
+ CallSite(CallSiteBase B) : CallSiteBase(B) {}
+ CallSite(CallInst *CI) : CallSiteBase(CI) {}
+ CallSite(InvokeInst *II) : CallSiteBase(II) {}
+ explicit CallSite(Instruction *II) : CallSiteBase(II) {}
+ explicit CallSite(Value *V) : CallSiteBase(V) {}
bool operator==(const CallSite &CS) const { return I == CS.I; }
bool operator!=(const CallSite &CS) const { return I != CS.I; }
@@ -371,13 +384,13 @@ private:
/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
- typedef CallSiteBase<> Base;
public:
- ImmutableCallSite(const Value* V) : Base(V) {}
- ImmutableCallSite(const CallInst *CI) : Base(CI) {}
- ImmutableCallSite(const InvokeInst *II) : Base(II) {}
- ImmutableCallSite(const Instruction *II) : Base(II) {}
- ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
+ ImmutableCallSite() {}
+ ImmutableCallSite(const CallInst *CI) : CallSiteBase(CI) {}
+ ImmutableCallSite(const InvokeInst *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Instruction *II) : CallSiteBase(II) {}
+ explicit ImmutableCallSite(const Value *V) : CallSiteBase(V) {}
+ ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {}
};
} // End llvm namespace
diff --git a/include/llvm/IR/Comdat.h b/include/llvm/IR/Comdat.h
index 3e77a7709d5c..4d4c15fb68cd 100644
--- a/include/llvm/IR/Comdat.h
+++ b/include/llvm/IR/Comdat.h
@@ -49,7 +49,7 @@ private:
friend class Module;
Comdat();
Comdat(SelectionKind SK, StringMapEntry<Comdat> *Name);
- Comdat(const Comdat &) LLVM_DELETED_FUNCTION;
+ Comdat(const Comdat &) = delete;
// Points to the map in Module.
StringMapEntry<Comdat> *Name;
diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h
index d26991eaab75..75499e0a4db3 100644
--- a/include/llvm/IR/Constant.h
+++ b/include/llvm/IR/Constant.h
@@ -39,8 +39,8 @@ namespace llvm {
/// don't have to worry about the lifetime of the objects.
/// @brief LLVM Constant Representation
class Constant : public User {
- void operator=(const Constant &) LLVM_DELETED_FUNCTION;
- Constant(const Constant &) LLVM_DELETED_FUNCTION;
+ void operator=(const Constant &) = delete;
+ Constant(const Constant &) = delete;
void anchor() override;
protected:
diff --git a/include/llvm/IR/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h
index e271a1482117..fb6ca3b3184c 100644
--- a/include/llvm/IR/ConstantFolder.h
+++ b/include/llvm/IR/ConstantFolder.h
@@ -118,34 +118,35 @@ public:
// Memory Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
+ return ConstantExpr::getGetElementPtr(Ty, C, Idx);
}
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h
index 5e8cd34c4d69..9ded3ca36a70 100644
--- a/include/llvm/IR/ConstantRange.h
+++ b/include/llvm/IR/ConstantRange.h
@@ -33,6 +33,7 @@
#define LLVM_IR_CONSTANTRANGE_H
#include "llvm/ADT/APInt.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -59,15 +60,27 @@ public:
/// assert out if the two APInt's are not the same bit width.
ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
- /// Produce the smallest range that contains all values that
- /// might satisfy the comparison specified by Pred when compared to any value
- /// contained within Other.
+ /// Produce the smallest range such that all values that may satisfy the given
+ /// predicate with any value contained within Other is contained in the
+ /// returned range. Formally, this returns a superset of
+ /// 'union over all y in Other . { x : icmp op x y is true }'. If the exact
+ /// answer is not representable as a ConstantRange, the return value will be a
+ /// proper superset of the above.
///
- /// Solves for range X in 'for all x in X, there exists a y in Y such that
- /// icmp op x, y is true'. Every value that might make the comparison true
- /// is included in the resulting range.
- static ConstantRange makeICmpRegion(unsigned Pred,
- const ConstantRange &Other);
+ /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4)
+ static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred,
+ const ConstantRange &Other);
+
+ /// Produce the largest range such that all values in the returned range
+ /// satisfy the given predicate with all values contained within Other.
+ /// Formally, this returns a subset of
+ /// 'intersection over all y in Other . { x : icmp op x y is true }'. If the
+ /// exact answer is not representable as a ConstantRange, the return value
+ /// will be a proper subset of the above.
+ ///
+ /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2)
+ static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
+ const ConstantRange &Other);
/// Return the lower value for this range.
///
@@ -208,8 +221,8 @@ public:
ConstantRange sub(const ConstantRange &Other) const;
/// Return a new range representing the possible values resulting
- /// from a multiplication of a value in this range and a value in \p Other.
- /// TODO: This isn't fully implemented yet.
+ /// from a multiplication of a value in this range and a value in \p Other,
+ /// treating both this and \p Other as unsigned ranges.
ConstantRange multiply(const ConstantRange &Other) const;
/// Return a new range representing the possible values resulting
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index 5b098b4f51d6..e97bda54e8f0 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -12,7 +12,7 @@
/// which represent the different flavors of constant values that live in LLVM.
/// Note that Constants are immutable (once created they never change) and are
/// fully shared by structural equivalence. This means that two structurally
-/// equivalent constants will always have the same address. Constant's are
+/// equivalent constants will always have the same address. Constants are
/// created on demand as needed and never deleted: thus clients don't have to
/// worry about the lifetime of the objects.
//
@@ -46,8 +46,8 @@ template <class ConstantClass> struct ConstantAggrKeyType;
/// @brief Class for constant integers.
class ConstantInt : public Constant {
void anchor() override;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantInt(const ConstantInt &) = delete;
ConstantInt(IntegerType *Ty, const APInt& V);
APInt Val;
protected:
@@ -228,8 +228,8 @@ public:
class ConstantFP : public Constant {
APFloat Val;
void anchor() override;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantFP(const ConstantFP &) = delete;
friend class LLVMContextImpl;
protected:
ConstantFP(Type *Ty, const APFloat& V);
@@ -251,6 +251,7 @@ public:
static Constant *get(Type* Ty, double V);
static Constant *get(Type* Ty, StringRef Str);
static ConstantFP *get(LLVMContext &Context, const APFloat &V);
+ static Constant *getNaN(Type *Ty, bool Negative = false, unsigned type = 0);
static Constant *getNegativeZero(Type *Ty);
static Constant *getInfinity(Type *Ty, bool Negative = false);
@@ -294,8 +295,8 @@ public:
/// ConstantAggregateZero - All zero aggregate value
///
class ConstantAggregateZero : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantAggregateZero(const ConstantAggregateZero &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantAggregateZero(const ConstantAggregateZero &) = delete;
protected:
explicit ConstantAggregateZero(Type *ty)
: Constant(ty, ConstantAggregateZeroVal, nullptr, 0) {}
@@ -341,7 +342,7 @@ public:
///
class ConstantArray : public Constant {
friend struct ConstantAggrKeyType<ConstantArray>;
- ConstantArray(const ConstantArray &) LLVM_DELETED_FUNCTION;
+ ConstantArray(const ConstantArray &) = delete;
protected:
ConstantArray(ArrayType *T, ArrayRef<Constant *> Val);
public:
@@ -383,7 +384,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
//
class ConstantStruct : public Constant {
friend struct ConstantAggrKeyType<ConstantStruct>;
- ConstantStruct(const ConstantStruct &) LLVM_DELETED_FUNCTION;
+ ConstantStruct(const ConstantStruct &) = delete;
protected:
ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
public:
@@ -442,7 +443,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
///
class ConstantVector : public Constant {
friend struct ConstantAggrKeyType<ConstantVector>;
- ConstantVector(const ConstantVector &) LLVM_DELETED_FUNCTION;
+ ConstantVector(const ConstantVector &) = delete;
protected:
ConstantVector(VectorType *T, ArrayRef<Constant *> Val);
public:
@@ -491,8 +492,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant)
/// ConstantPointerNull - a constant pointer value that points to null
///
class ConstantPointerNull : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantPointerNull(const ConstantPointerNull &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantPointerNull(const ConstantPointerNull &) = delete;
protected:
explicit ConstantPointerNull(PointerType *T)
: Constant(T,
@@ -542,12 +543,12 @@ class ConstantDataSequential : public Constant {
/// element array of i8, or a 1-element array of i32. They'll both end up in
/// the same StringMap bucket, linked up.
ConstantDataSequential *Next;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataSequential(const ConstantDataSequential &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataSequential(const ConstantDataSequential &) = delete;
protected:
explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
: Constant(ty, VT, nullptr, 0), DataElements(Data), Next(nullptr) {}
- ~ConstantDataSequential() { delete Next; }
+ ~ConstantDataSequential() override { delete Next; }
static Constant *getImpl(StringRef Bytes, Type *Ty);
@@ -653,8 +654,8 @@ private:
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataArray : public ConstantDataSequential {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataArray(const ConstantDataArray &) = delete;
void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataArray(Type *ty, const char *Data)
@@ -676,6 +677,15 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+ /// getFP() constructors - Return a constant with array type with an element
+ /// count and element type of float with precision matching the number of
+ /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+ /// double for 64bits) Note that this can return a ConstantAggregateZero
+ /// object.
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+
/// getString - This method constructs a CDS and initializes it with a text
/// string. The default behavior (AddNull==true) causes a null terminator to
/// be placed at the end of the array (increasing the length of the string by
@@ -705,8 +715,8 @@ public:
/// operands because it stores all of the elements of the constant as densely
/// packed data, instead of as Value*'s.
class ConstantDataVector : public ConstantDataSequential {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ ConstantDataVector(const ConstantDataVector &) = delete;
void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataVector(Type *ty, const char *Data)
@@ -728,6 +738,15 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
+ /// getFP() constructors - Return a constant with vector type with an element
+ /// count and element type of float with the precision matching the number of
+ /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
+ /// double for 64bits) Note that this can return a ConstantAggregateZero
+ /// object.
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+
/// getSplat - Return a ConstantVector with the specified constant in each
/// element. The specified constant has to be a of a compatible type (i8/i16/
/// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
@@ -756,7 +775,7 @@ public:
/// BlockAddress - The address of a basic block.
///
class BlockAddress : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
void *operator new(size_t s) { return User::operator new(s, 2); }
BlockAddress(Function *F, BasicBlock *BB);
public:
@@ -1036,44 +1055,46 @@ public:
bool OnlyIfReduced = false);
/// Getelementptr form. Value* is only accepted for convenience;
- /// all elements must be Constant's.
+ /// all elements must be Constants.
///
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
- static Constant *getGetElementPtr(Constant *C, ArrayRef<Constant *> IdxList,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Constant *> IdxList,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) {
return getGetElementPtr(
- C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
+ Ty, C, makeArrayRef((Value * const *)IdxList.data(), IdxList.size()),
InBounds, OnlyIfReducedTy);
}
- static Constant *getGetElementPtr(Constant *C, Constant *Idx,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C, Constant *Idx,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
+ return getGetElementPtr(Ty, C, cast<Value>(Idx), InBounds, OnlyIfReducedTy);
}
- static Constant *getGetElementPtr(Constant *C, ArrayRef<Value *> IdxList,
+ static Constant *getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Value *> IdxList,
bool InBounds = false,
Type *OnlyIfReducedTy = nullptr);
/// Create an "inbounds" getelementptr. See the documentation for the
/// "inbounds" flag in LangRef.html for details.
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
Constant *Idx) {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return getGetElementPtr(C, Idx, true);
+ return getGetElementPtr(Ty, C, Idx, true);
}
- static Constant *getInBoundsGetElementPtr(Constant *C,
+ static Constant *getInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) {
- return getGetElementPtr(C, IdxList, true);
+ return getGetElementPtr(Ty, C, IdxList, true);
}
static Constant *getExtractElement(Constant *Vec, Constant *Idx,
@@ -1125,8 +1146,9 @@ public:
Constant *getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
bool OnlyIfReduced = false) const;
- /// getAsInstruction - Returns an Instruction which implements the same operation
- /// as this ConstantExpr. The instruction is not linked to any basic block.
+ /// getAsInstruction - Returns an Instruction which implements the same
+ /// operation as this ConstantExpr. The instruction is not linked to any basic
+ /// block.
///
/// A better approach to this could be to have a constructor for Instruction
/// which would take a ConstantExpr parameter, but that would have spread
@@ -1168,8 +1190,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
/// LangRef.html#undefvalues for details.
///
class UndefValue : public Constant {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- UndefValue(const UndefValue &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ UndefValue(const UndefValue &) = delete;
protected:
explicit UndefValue(Type *T) : Constant(T, UndefValueVal, nullptr, 0) {}
protected:
diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index ae1ac650a9ec..997113191d19 100644
--- a/include/llvm/IR/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -30,38 +30,17 @@ namespace llvm {
class Value;
class Constant;
class LLVMContext;
- class MDNode;
class StringRef;
- class DIBasicType;
- class DICompileUnit;
- class DICompositeType;
- class DIDerivedType;
- class DIDescriptor;
- class DIFile;
- class DIEnumerator;
- class DIType;
- class DIGlobalVariable;
- class DIImportedEntity;
- class DINameSpace;
- class DIVariable;
- class DISubrange;
- class DILexicalBlockFile;
- class DILexicalBlock;
- class DIScope;
- class DISubprogram;
- class DITemplateTypeParameter;
- class DITemplateValueParameter;
- class DIObjCProperty;
class DIBuilder {
Module &M;
LLVMContext &VMContext;
- MDNode *TempEnumTypes;
- MDNode *TempRetainTypes;
- MDNode *TempSubprograms;
- MDNode *TempGVs;
- MDNode *TempImportedModules;
+ TempMDTuple TempEnumTypes;
+ TempMDTuple TempRetainTypes;
+ TempMDTuple TempSubprograms;
+ TempMDTuple TempGVs;
+ TempMDTuple TempImportedModules;
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
@@ -80,12 +59,12 @@ namespace llvm {
/// Each subprogram's preserved local variables.
DenseMap<MDNode *, std::vector<TrackingMDNodeRef>> PreservedVariables;
- DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;
- void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;
+ DIBuilder(const DIBuilder &) = delete;
+ void operator=(const DIBuilder &) = delete;
/// \brief Create a temporary.
///
- /// Create an \a MDNodeFwdDecl and track it in \a UnresolvedNodes.
+ /// Create an \a temporary node and track it in \a UnresolvedNodes.
void trackIfUnresolved(MDNode *N);
public:
@@ -116,6 +95,7 @@ namespace llvm {
/// @param SplitName The name of the file that we'll split debug info out
/// into.
/// @param Kind The kind of debug information to generate.
+ /// @param DWOId The DWOId if this is a split skeleton compile unit.
/// @param EmitDebugInfo A boolean flag which indicates whether debug
/// information should be written to the final
/// output or not. When this is false, debug
@@ -125,26 +105,25 @@ namespace llvm {
/// source location information in the back end
/// without actually changing the output (e.g.,
/// when using optimization remarks).
- DICompileUnit createCompileUnit(unsigned Lang, StringRef File,
- StringRef Dir, StringRef Producer,
- bool isOptimized, StringRef Flags,
- unsigned RV,
- StringRef SplitName = StringRef(),
- DebugEmissionKind Kind = FullDebug,
- bool EmitDebugInfo = true);
+ DICompileUnit *
+ createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
+ StringRef Producer, bool isOptimized, StringRef Flags,
+ unsigned RV, StringRef SplitName = StringRef(),
+ DebugEmissionKind Kind = FullDebug, uint64_t DWOId = 0,
+ bool EmitDebugInfo = true);
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
- DIFile createFile(StringRef Filename, StringRef Directory);
+ DIFile *createFile(StringRef Filename, StringRef Directory);
/// createEnumerator - Create a single enumerator value.
- DIEnumerator createEnumerator(StringRef Name, int64_t Val);
+ DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
/// \brief Create a DWARF unspecified type.
- DIBasicType createUnspecifiedType(StringRef Name);
+ DIBasicType *createUnspecifiedType(StringRef Name);
/// \brief Create C++11 nullptr type.
- DIBasicType createNullPtrType();
+ DIBasicType *createNullPtrType();
/// createBasicType - Create debugging information entry for a basic
/// type.
@@ -152,36 +131,36 @@ namespace llvm {
/// @param SizeInBits Size of the type.
/// @param AlignInBits Type alignment.
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
- DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Encoding);
+ DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding);
/// createQualifiedType - Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
/// @param FromTy Base Type.
- DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy);
+ DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy);
/// createPointerType - Create debugging information entry for a pointer.
/// @param PointeeTy Type pointed by this pointer.
/// @param SizeInBits Size.
/// @param AlignInBits Alignment. (optional)
/// @param Name Pointer type name. (optional)
- DIDerivedType
- createPointerType(DIType PointeeTy, uint64_t SizeInBits,
- uint64_t AlignInBits = 0, StringRef Name = StringRef());
+ DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0,
+ StringRef Name = "");
/// \brief Create debugging information entry for a pointer to member.
/// @param PointeeTy Type pointed to by this pointer.
/// @param SizeInBits Size.
/// @param AlignInBits Alignment. (optional)
/// @param Class Type for which this pointer points to members of.
- DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class,
- uint64_t SizeInBits,
- uint64_t AlignInBits = 0);
+ DIDerivedType *createMemberPointerType(DIType *PointeeTy, DIType *Class,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits = 0);
/// createReferenceType - Create debugging information entry for a c++
/// style reference or rvalue reference type.
- DIDerivedType createReferenceType(unsigned Tag, DIType RTy);
+ DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy);
/// createTypedef - Create debugging information entry for a typedef.
/// @param Ty Original type.
@@ -189,11 +168,11 @@ namespace llvm {
/// @param File File where this type is defined.
/// @param LineNo Line number.
/// @param Context The surrounding context for the typedef.
- DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File,
- unsigned LineNo, DIDescriptor Context);
+ DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File,
+ unsigned LineNo, DIScope *Context);
/// createFriend - Create debugging information entry for a 'friend'.
- DIDerivedType createFriend(DIType Ty, DIType FriendTy);
+ DIDerivedType *createFriend(DIType *Ty, DIType *FriendTy);
/// createInheritance - Create debugging information entry to establish
/// inheritance relationship between two types.
@@ -202,8 +181,8 @@ namespace llvm {
/// @param BaseOffset Base offset.
/// @param Flags Flags to describe inheritance attribute,
/// e.g. private
- DIDerivedType createInheritance(DIType Ty, DIType BaseTy,
- uint64_t BaseOffset, unsigned Flags);
+ DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy,
+ uint64_t BaseOffset, unsigned Flags);
/// createMemberType - Create debugging information entry for a member.
/// @param Scope Member scope.
@@ -215,10 +194,11 @@ namespace llvm {
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
- DIDerivedType
- createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags, DIType Ty);
+ DIDerivedType *createMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType *Ty);
/// createStaticMemberType - Create debugging information entry for a
/// C++ static data member.
@@ -229,10 +209,10 @@ namespace llvm {
/// @param Ty Type of the static member.
/// @param Flags Flags to encode member attribute, e.g. private.
/// @param Val Const initializer of the member.
- DIDerivedType createStaticMemberType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNo,
- DIType Ty, unsigned Flags,
- llvm::Constant *Val);
+ DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNo,
+ DIType *Ty, unsigned Flags,
+ llvm::Constant *Val);
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
@@ -245,11 +225,10 @@ namespace llvm {
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
/// @param PropertyNode Property associated with this ivar.
- DIDerivedType createObjCIVar(StringRef Name, DIFile File,
- unsigned LineNo, uint64_t SizeInBits,
- uint64_t AlignInBits, uint64_t OffsetInBits,
- unsigned Flags, DIType Ty,
- MDNode *PropertyNode);
+ DIDerivedType *createObjCIVar(StringRef Name, DIFile *File, unsigned LineNo,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType *Ty, MDNode *PropertyNode);
/// createObjCProperty - Create debugging information entry for Objective-C
/// property.
@@ -260,12 +239,11 @@ namespace llvm {
/// @param SetterName Name of the Objective C property setter selector.
/// @param PropertyAttributes Objective C property attributes.
/// @param Ty Type.
- DIObjCProperty createObjCProperty(StringRef Name,
- DIFile File, unsigned LineNumber,
- StringRef GetterName,
- StringRef SetterName,
- unsigned PropertyAttributes,
- DIType Ty);
+ DIObjCProperty *createObjCProperty(StringRef Name, DIFile *File,
+ unsigned LineNumber,
+ StringRef GetterName,
+ StringRef SetterName,
+ unsigned PropertyAttributes, DIType *Ty);
/// createClassType - Create debugging information entry for a class.
/// @param Scope Scope in which this class is defined.
@@ -283,14 +261,14 @@ namespace llvm {
/// for more info.
/// @param TemplateParms Template type parameters.
/// @param UniqueIdentifier A unique identifier for the class.
- DICompositeType createClassType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- uint64_t OffsetInBits, unsigned Flags,
- DIType DerivedFrom, DIArray Elements,
- DIType VTableHolder = DIType(),
- MDNode *TemplateParms = nullptr,
- StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createClassType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ DIType *DerivedFrom, DINodeArray Elements,
+ DIType *VTableHolder = nullptr,
+ MDNode *TemplateParms = nullptr,
+ StringRef UniqueIdentifier = "");
/// createStructType - Create debugging information entry for a struct.
/// @param Scope Scope in which this struct is defined.
@@ -303,13 +281,11 @@ namespace llvm {
/// @param Elements Struct elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
/// @param UniqueIdentifier A unique identifier for the struct.
- DICompositeType createStructType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- unsigned Flags, DIType DerivedFrom,
- DIArray Elements, unsigned RunTimeLang = 0,
- DIType VTableHolder = DIType(),
- StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createStructType(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+ DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
+ DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "");
/// createUnionType - Create debugging information entry for an union.
/// @param Scope Scope in which this union is defined.
@@ -322,24 +298,20 @@ namespace llvm {
/// @param Elements Union elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
/// @param UniqueIdentifier A unique identifier for the union.
- DICompositeType createUnionType(
- DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
- DIArray Elements, unsigned RunTimeLang = 0,
- StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createUnionType(DIScope *Scope, StringRef Name,
+ DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ unsigned Flags, DINodeArray Elements,
+ unsigned RunTimeLang = 0,
+ StringRef UniqueIdentifier = "");
/// createTemplateTypeParameter - Create debugging information for template
/// type parameter.
/// @param Scope Scope in which this type is defined.
/// @param Name Type parameter name.
/// @param Ty Parameter type.
- /// @param File File where this type parameter is defined.
- /// @param LineNo Line number.
- /// @param ColumnNo Column Number.
- DITemplateTypeParameter
- createTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
- MDNode *File = nullptr, unsigned LineNo = 0,
- unsigned ColumnNo = 0);
+ DITemplateTypeParameter *
+ createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty);
/// createTemplateValueParameter - Create debugging information for template
/// value parameter.
@@ -347,56 +319,46 @@ namespace llvm {
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val Constant parameter value.
- /// @param File File where this type parameter is defined.
- /// @param LineNo Line number.
- /// @param ColumnNo Column Number.
- DITemplateValueParameter
- createTemplateValueParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
- Constant *Val, MDNode *File = nullptr,
- unsigned LineNo = 0, unsigned ColumnNo = 0);
+ DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope,
+ StringRef Name,
+ DIType *Ty,
+ Constant *Val);
/// \brief Create debugging information for a template template parameter.
/// @param Scope Scope in which this type is defined.
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val The fully qualified name of the template.
- /// @param File File where this type parameter is defined.
- /// @param LineNo Line number.
- /// @param ColumnNo Column Number.
- DITemplateValueParameter
- createTemplateTemplateParameter(DIDescriptor Scope, StringRef Name,
- DIType Ty, StringRef Val,
- MDNode *File = nullptr, unsigned LineNo = 0,
- unsigned ColumnNo = 0);
+ DITemplateValueParameter *createTemplateTemplateParameter(DIScope *Scope,
+ StringRef Name,
+ DIType *Ty,
+ StringRef Val);
/// \brief Create debugging information for a template parameter pack.
/// @param Scope Scope in which this type is defined.
/// @param Name Value parameter name.
/// @param Ty Parameter type.
/// @param Val An array of types in the pack.
- /// @param File File where this type parameter is defined.
- /// @param LineNo Line number.
- /// @param ColumnNo Column Number.
- DITemplateValueParameter
- createTemplateParameterPack(DIDescriptor Scope, StringRef Name,
- DIType Ty, DIArray Val, MDNode *File = nullptr,
- unsigned LineNo = 0, unsigned ColumnNo = 0);
+ DITemplateValueParameter *createTemplateParameterPack(DIScope *Scope,
+ StringRef Name,
+ DIType *Ty,
+ DINodeArray Val);
/// createArrayType - Create debugging information entry for an array.
/// @param Size Array size.
/// @param AlignInBits Alignment.
/// @param Ty Element type.
/// @param Subscripts Subscripts.
- DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts);
+ DICompositeType *createArrayType(uint64_t Size, uint64_t AlignInBits,
+ DIType *Ty, DINodeArray Subscripts);
/// createVectorType - Create debugging information entry for a vector type.
/// @param Size Array size.
/// @param AlignInBits Alignment.
/// @param Ty Element type.
/// @param Subscripts Subscripts.
- DICompositeType createVectorType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts);
+ DICompositeType *createVectorType(uint64_t Size, uint64_t AlignInBits,
+ DIType *Ty, DINodeArray Subscripts);
/// createEnumerationType - Create debugging information entry for an
/// enumeration.
@@ -409,10 +371,10 @@ namespace llvm {
/// @param Elements Enumeration elements.
/// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
/// @param UniqueIdentifier A unique identifier for the enum.
- DICompositeType createEnumerationType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType,
- StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createEnumerationType(
+ DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, DINodeArray Elements,
+ DIType *UnderlyingType, StringRef UniqueIdentifier = "");
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
@@ -420,49 +382,49 @@ namespace llvm {
/// includes return type at 0th index.
/// @param Flags E.g.: LValueReference.
/// These flags are used to emit dwarf attributes.
- DISubroutineType createSubroutineType(DIFile File,
- DITypeArray ParameterTypes,
- unsigned Flags = 0);
+ DISubroutineType *createSubroutineType(DIFile *File,
+ DITypeRefArray ParameterTypes,
+ unsigned Flags = 0);
- /// createArtificialType - Create a new DIType with "artificial" flag set.
- DIType createArtificialType(DIType Ty);
+ /// createArtificialType - Create a new DIType* with "artificial" flag set.
+ DIType *createArtificialType(DIType *Ty);
- /// createObjectPointerType - Create a new DIType with the "object pointer"
+ /// createObjectPointerType - Create a new DIType* with the "object pointer"
/// flag set.
- DIType createObjectPointerType(DIType Ty);
+ DIType *createObjectPointerType(DIType *Ty);
/// \brief Create a permanent forward-declared type.
- DICompositeType createForwardDecl(unsigned Tag, StringRef Name,
- DIDescriptor Scope, DIFile F,
- unsigned Line, unsigned RuntimeLang = 0,
- uint64_t SizeInBits = 0,
- uint64_t AlignInBits = 0,
- StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
+ DIScope *Scope, DIFile *F, unsigned Line,
+ unsigned RuntimeLang = 0,
+ uint64_t SizeInBits = 0,
+ uint64_t AlignInBits = 0,
+ StringRef UniqueIdentifier = "");
/// \brief Create a temporary forward-declared type.
- DICompositeType createReplaceableForwardDecl(
- unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F,
- unsigned Line, unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
- uint64_t AlignInBits = 0, StringRef UniqueIdentifier = StringRef());
+ DICompositeType *createReplaceableCompositeType(
+ unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
+ unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
+ uint64_t AlignInBits = 0, unsigned Flags = DINode::FlagFwdDecl,
+ StringRef UniqueIdentifier = "");
- /// retainType - Retain DIType in a module even if it is not referenced
+ /// retainType - Retain DIType* in a module even if it is not referenced
/// through debug info anchors.
- void retainType(DIType T);
+ void retainType(DIType *T);
/// createUnspecifiedParameter - Create unspecified parameter type
/// for a subroutine type.
- DIBasicType createUnspecifiedParameter();
+ DIBasicType *createUnspecifiedParameter();
- /// getOrCreateArray - Get a DIArray, create one if required.
- DIArray getOrCreateArray(ArrayRef<Metadata *> Elements);
+ /// getOrCreateArray - Get a DINodeArray, create one if required.
+ DINodeArray getOrCreateArray(ArrayRef<Metadata *> Elements);
- /// getOrCreateTypeArray - Get a DITypeArray, create one if required.
- DITypeArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements);
+ /// getOrCreateTypeArray - Get a DITypeRefArray, create one if required.
+ DITypeRefArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements);
/// getOrCreateSubrange - Create a descriptor for a value range. This
/// implicitly uniques the values returned.
- DISubrange getOrCreateSubrange(int64_t Lo, int64_t Count);
-
+ DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
/// createGlobalVariable - Create a new descriptor for the specified
/// variable.
@@ -476,19 +438,19 @@ namespace llvm {
/// externally visible or not.
/// @param Val llvm::Value of the variable.
/// @param Decl Reference to the corresponding declaration.
- DIGlobalVariable createGlobalVariable(DIDescriptor Context, StringRef Name,
- StringRef LinkageName, DIFile File,
- unsigned LineNo, DITypeRef Ty,
- bool isLocalToUnit,
- llvm::Constant *Val,
- MDNode *Decl = nullptr);
+ DIGlobalVariable *createGlobalVariable(DIScope *Context, StringRef Name,
+ StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DIType *Ty,
+ bool isLocalToUnit,
+ llvm::Constant *Val,
+ MDNode *Decl = nullptr);
/// createTempGlobalVariableFwdDecl - Identical to createGlobalVariable
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
- DIGlobalVariable createTempGlobalVariableFwdDecl(
- DIDescriptor Context, StringRef Name, StringRef LinkageName,
- DIFile File, unsigned LineNo, DITypeRef Ty, bool isLocalToUnit,
- llvm::Constant *Val, MDNode *Decl = nullptr);
+ DIGlobalVariable *createTempGlobalVariableFwdDecl(
+ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val,
+ MDNode *Decl = nullptr);
/// createLocalVariable - Create a new descriptor for the specified
/// local variable.
@@ -504,28 +466,29 @@ namespace llvm {
/// @param Flags Flags, e.g. artificial variable.
/// @param ArgNo If this variable is an argument then this argument's
/// number. 1 indicates 1st argument.
- DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
- StringRef Name,
- DIFile File, unsigned LineNo,
- DITypeRef Ty, bool AlwaysPreserve = false,
- unsigned Flags = 0,
- unsigned ArgNo = 0);
+ DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope,
+ StringRef Name, DIFile *File,
+ unsigned LineNo, DIType *Ty,
+ bool AlwaysPreserve = false,
+ unsigned Flags = 0,
+ unsigned ArgNo = 0);
/// createExpression - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
/// @param Addr An array of complex address operations.
- DIExpression createExpression(ArrayRef<int64_t> Addr = None);
+ DIExpression *createExpression(ArrayRef<uint64_t> Addr = None);
+ DIExpression *createExpression(ArrayRef<int64_t> Addr);
- /// createPieceExpression - Create a descriptor to describe one part
+ /// createBitPieceExpression - Create a descriptor to describe one part
/// of aggregate variable that is fragmented across multiple Values.
///
- /// @param OffsetInBytes Offset of the piece in bytes.
- /// @param SizeInBytes Size of the piece in bytes.
- DIExpression createPieceExpression(unsigned OffsetInBytes,
- unsigned SizeInBytes);
+ /// @param OffsetInBits Offset of the piece in bits.
+ /// @param SizeInBits Size of the piece in bits.
+ DIExpression *createBitPieceExpression(unsigned OffsetInBits,
+ unsigned SizeInBits);
/// createFunction - Create a new descriptor for the specified subprogram.
- /// See comments in DISubprogram for descriptions of these fields.
+ /// See comments in DISubprogram* for descriptions of these fields.
/// @param Scope Function scope.
/// @param Name Function name.
/// @param LinkageName Mangled function name.
@@ -540,49 +503,35 @@ namespace llvm {
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
- DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
+ DISubprogram *
+ createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName,
+ DIFile *File, unsigned LineNo, DISubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned ScopeLine,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr,
+ MDNode *Decl = nullptr);
/// createTempFunctionFwdDecl - Identical to createFunction,
/// except that the resulting DbgNode is meant to be RAUWed.
- DISubprogram createTempFunctionFwdDecl(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
-
+ DISubprogram *createTempFunctionFwdDecl(
+ DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags = 0,
+ bool isOptimized = false, Function *Fn = nullptr,
+ MDNode *TParam = nullptr, MDNode *Decl = nullptr);
/// FIXME: this is added for dragonegg. Once we update dragonegg
/// to call resolve function, this will be removed.
- DISubprogram createFunction(DIScopeRef Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned ScopeLine,
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr,
- MDNode *Decl = nullptr);
+ DISubprogram *
+ createFunction(DIScopeRef Scope, StringRef Name, StringRef LinkageName,
+ DIFile *File, unsigned LineNo, DISubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned ScopeLine,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr,
+ MDNode *Decl = nullptr);
/// createMethod - Create a new descriptor for the specified C++ method.
- /// See comments in DISubprogram for descriptions of these fields.
+ /// See comments in DISubprogram* for descriptions of these fields.
/// @param Scope Function scope.
/// @param Name Function name.
/// @param LinkageName Mangled function name.
@@ -600,17 +549,13 @@ namespace llvm {
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
- DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
- StringRef LinkageName,
- DIFile File, unsigned LineNo,
- DICompositeType Ty, bool isLocalToUnit,
- bool isDefinition,
- unsigned Virtuality = 0, unsigned VTableIndex = 0,
- DIType VTableHolder = DIType(),
- unsigned Flags = 0,
- bool isOptimized = false,
- Function *Fn = nullptr,
- MDNode *TParam = nullptr);
+ DISubprogram *
+ createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
+ DIFile *File, unsigned LineNo, DISubroutineType *Ty,
+ bool isLocalToUnit, bool isDefinition, unsigned Virtuality = 0,
+ unsigned VTableIndex = 0, DIType *VTableHolder = nullptr,
+ unsigned Flags = 0, bool isOptimized = false,
+ Function *Fn = nullptr, MDNode *TParam = nullptr);
/// createNameSpace - This creates new descriptor for a namespace
/// with the specified parent scope.
@@ -618,9 +563,8 @@ namespace llvm {
/// @param Name Name of this namespace
/// @param File Source file
/// @param LineNo Line number
- DINameSpace createNameSpace(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNo);
-
+ DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
+ unsigned LineNo);
/// createLexicalBlockFile - This creates a descriptor for a lexical
/// block with a new file attached. This merely extends the existing
@@ -628,8 +572,8 @@ namespace llvm {
/// @param Scope Lexical block.
/// @param File Source file.
/// @param Discriminator DWARF path discriminator value.
- DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope, DIFile File,
- unsigned Discriminator = 0);
+ DILexicalBlockFile *createLexicalBlockFile(DIScope *Scope, DIFile *File,
+ unsigned Discriminator = 0);
/// createLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context.
@@ -637,60 +581,63 @@ namespace llvm {
/// @param File Source file.
/// @param Line Line number.
/// @param Col Column number.
- DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
- unsigned Line, unsigned Col);
+ DILexicalBlock *createLexicalBlock(DIScope *Scope, DIFile *File,
+ unsigned Line, unsigned Col);
/// \brief Create a descriptor for an imported module.
/// @param Context The scope this module is imported into
/// @param NS The namespace being imported here
/// @param Line Line number
- DIImportedEntity createImportedModule(DIScope Context, DINameSpace NS,
- unsigned Line);
+ DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS,
+ unsigned Line);
/// \brief Create a descriptor for an imported module.
/// @param Context The scope this module is imported into
/// @param NS An aliased namespace
/// @param Line Line number
- DIImportedEntity createImportedModule(DIScope Context, DIImportedEntity NS,
- unsigned Line);
+ DIImportedEntity *createImportedModule(DIScope *Context,
+ DIImportedEntity *NS, unsigned Line);
/// \brief Create a descriptor for an imported function.
/// @param Context The scope this module is imported into
/// @param Decl The declaration (or definition) of a function, type, or
/// variable
/// @param Line Line number
- DIImportedEntity createImportedDeclaration(DIScope Context, DIDescriptor Decl,
- unsigned Line,
- StringRef Name = StringRef());
- DIImportedEntity createImportedDeclaration(DIScope Context,
- DIImportedEntity NS,
- unsigned Line,
- StringRef Name = StringRef());
+ DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl,
+ unsigned Line,
+ StringRef Name = "");
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
/// @param Storage llvm::Value of the variable
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertAtEnd Location for the new intrinsic.
- Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
- DIExpression Expr, BasicBlock *InsertAtEnd);
+ Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
+ DIExpression *Expr, const DILocation *DL,
+ BasicBlock *InsertAtEnd);
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
/// @param Storage llvm::Value of the variable
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertBefore Location for the new intrinsic.
- Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
- DIExpression Expr, Instruction *InsertBefore);
+ Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
+ DIExpression *Expr, const DILocation *DL,
+ Instruction *InsertBefore);
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
/// @param Val llvm::Value of the variable
/// @param Offset Offset
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertAtEnd Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
- DIVariable VarInfo, DIExpression Expr,
+ DILocalVariable *VarInfo,
+ DIExpression *Expr,
+ const DILocation *DL,
BasicBlock *InsertAtEnd);
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
@@ -698,24 +645,45 @@ namespace llvm {
/// @param Offset Offset
/// @param VarInfo Variable's debug info descriptor.
/// @param Expr A complex location expression.
+ /// @param DL Debug info location.
/// @param InsertBefore Location for the new intrinsic.
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
- DIVariable VarInfo, DIExpression Expr,
+ DILocalVariable *VarInfo,
+ DIExpression *Expr,
+ const DILocation *DL,
Instruction *InsertBefore);
/// \brief Replace the vtable holder in the given composite type.
///
/// If this creates a self reference, it may orphan some unresolved cycles
/// in the operands of \c T, so \a DIBuilder needs to track that.
- void replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder);
+ void replaceVTableHolder(DICompositeType *&T,
+ DICompositeType *VTableHolder);
/// \brief Replace arrays on a composite type.
///
/// If \c T is resolved, but the arrays aren't -- which can happen if \c T
/// has a self-reference -- \a DIBuilder needs to track the array to
/// resolve cycles.
- void replaceArrays(DICompositeType &T, DIArray Elements,
- DIArray TParems = DIArray());
+ void replaceArrays(DICompositeType *&T, DINodeArray Elements,
+ DINodeArray TParems = DINodeArray());
+
+ /// \brief Replace a temporary node.
+ ///
+ /// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c
+ /// Replacement.
+ ///
+ /// If \c Replacement is the same as \c N.get(), instead call \a
+ /// MDNode::replaceWithUniqued(). In this case, the uniqued node could
+ /// have a different address, so we return the final address.
+ template <class NodeTy>
+ NodeTy *replaceTemporary(TempMDNode &&N, NodeTy *Replacement) {
+ if (N.get() == Replacement)
+ return cast<NodeTy>(MDNode::replaceWithUniqued(std::move(N)));
+
+ N->replaceAllUsesWith(Replacement);
+ return Replacement;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index a9e75955ce74..3e1f9744f9e8 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -53,6 +53,11 @@ enum AlignTypeEnum {
AGGREGATE_ALIGN = 'a'
};
+// FIXME: Currently the DataLayout string carries a "preferred alignment"
+// for types. As the DataLayout is module/global, this should likely be
+// sunk down to an FTTI element that is queried rather than a global
+// preference.
+
/// \brief Layout alignment element.
///
/// Stores the alignment data associated with a given alignment type (integer,
@@ -103,7 +108,14 @@ private:
unsigned StackNaturalAlign;
- enum ManglingModeT { MM_None, MM_ELF, MM_MachO, MM_WINCOFF, MM_Mips };
+ enum ManglingModeT {
+ MM_None,
+ MM_ELF,
+ MM_MachO,
+ MM_WinCOFF,
+ MM_WinCOFFX86,
+ MM_Mips
+ };
ManglingModeT ManglingMode;
SmallVector<unsigned char, 8> LegalIntWidths;
@@ -111,6 +123,9 @@ private:
/// \brief Primitive type alignment data.
SmallVector<LayoutAlignElem, 16> Alignments;
+ /// \brief The string representation used to create this DataLayout
+ std::string StringRepresentation;
+
typedef SmallVector<PointerAlignElem, 8> PointersTy;
PointersTy Pointers;
@@ -180,6 +195,7 @@ public:
DataLayout &operator=(const DataLayout &DL) {
clear();
+ StringRepresentation = DL.StringRepresentation;
BigEndian = DL.isBigEndian();
StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode;
@@ -204,8 +220,12 @@ public:
/// \brief Returns the string representation of the DataLayout.
///
/// This representation is in the same format accepted by the string
- /// constructor above.
- std::string getStringRepresentation() const;
+ /// constructor above. This should not be used to compare two DataLayout as
+ /// different string can represent the same layout.
+ std::string getStringRepresentation() const { return StringRepresentation; }
+
+ /// \brief Test if the DataLayout was constructed from an empty string.
+ bool isDefault() const { return StringRepresentation.empty(); }
/// \brief Returns true if the specified type is known to be a native integer
/// type supported by the CPU.
@@ -231,7 +251,7 @@ public:
unsigned getStackAlignment() const { return StackNaturalAlign; }
bool hasMicrosoftFastStdCallMangling() const {
- return ManglingMode == MM_WINCOFF;
+ return ManglingMode == MM_WinCOFFX86;
}
bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; }
@@ -239,7 +259,7 @@ public:
const char *getLinkerPrivateGlobalPrefix() const {
if (ManglingMode == MM_MachO)
return "l";
- return getPrivateGlobalPrefix();
+ return "";
}
char getGlobalPrefix() const {
@@ -247,9 +267,10 @@ public:
case MM_None:
case MM_ELF:
case MM_Mips:
+ case MM_WinCOFF:
return '\0';
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFFX86:
return '_';
}
llvm_unreachable("invalid mangling mode");
@@ -264,7 +285,8 @@ public:
case MM_Mips:
return "$";
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFF:
+ case MM_WinCOFFX86:
return "L";
}
llvm_unreachable("invalid mangling mode");
@@ -446,22 +468,6 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P));
}
-class DataLayoutPass : public ImmutablePass {
- DataLayout DL;
-
-public:
- /// This has to exist, because this is a pass, but it should never be used.
- DataLayoutPass();
- ~DataLayoutPass();
-
- const DataLayout &getDataLayout() const { return DL; }
-
- static char ID; // Pass identification, replacement for typeid
-
- bool doFinalization(Module &M) override;
- bool doInitialization(Module &M) override;
-};
-
/// Used to lazily calculate structure layout information for a target machine,
/// based on the DataLayout structure.
class StructLayout {
diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h
index 5c85d6d52824..5429648ade2c 100644
--- a/include/llvm/IR/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -22,990 +22,30 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/Metadata.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include <iterator>
namespace llvm {
-class BasicBlock;
-class Constant;
-class Function;
-class GlobalVariable;
class Module;
-class Type;
-class Value;
class DbgDeclareInst;
class DbgValueInst;
-class Instruction;
-class Metadata;
-class MDNode;
-class MDString;
-class NamedMDNode;
-class LLVMContext;
-class raw_ostream;
-
-class DIFile;
-class DISubprogram;
-class DILexicalBlock;
-class DILexicalBlockFile;
-class DIVariable;
-class DIType;
-class DIScope;
-class DIObjCProperty;
/// \brief Maps from type identifier to the actual MDNode.
-typedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
-
-class DIHeaderFieldIterator
- : public std::iterator<std::input_iterator_tag, StringRef, std::ptrdiff_t,
- const StringRef *, StringRef> {
- StringRef Header;
- StringRef Current;
-
-public:
- DIHeaderFieldIterator() {}
- DIHeaderFieldIterator(StringRef Header)
- : Header(Header), Current(Header.slice(0, Header.find('\0'))) {}
- StringRef operator*() const { return Current; }
- const StringRef * operator->() const { return &Current; }
- DIHeaderFieldIterator &operator++() {
- increment();
- return *this;
- }
- DIHeaderFieldIterator operator++(int) {
- DIHeaderFieldIterator X(*this);
- increment();
- return X;
- }
- bool operator==(const DIHeaderFieldIterator &X) const {
- return Current.data() == X.Current.data();
- }
- bool operator!=(const DIHeaderFieldIterator &X) const {
- return !(*this == X);
- }
-
- StringRef getHeader() const { return Header; }
- StringRef getCurrent() const { return Current; }
- StringRef getPrefix() const {
- if (Current.begin() == Header.begin())
- return StringRef();
- return Header.slice(0, Current.begin() - Header.begin() - 1);
- }
- StringRef getSuffix() const {
- if (Current.end() == Header.end())
- return StringRef();
- return Header.slice(Current.end() - Header.begin() + 1, StringRef::npos);
- }
-
-private:
- void increment() {
- assert(Current.data() != nullptr && "Cannot increment past the end");
- StringRef Suffix = getSuffix();
- Current = Suffix.slice(0, Suffix.find('\0'));
- }
-};
-
-/// \brief A thin wraper around MDNode to access encoded debug info.
-///
-/// This should not be stored in a container, because the underlying MDNode may
-/// change in certain situations.
-class DIDescriptor {
- // Befriends DIRef so DIRef can befriend the protected member
- // function: getFieldAs<DIRef>.
- template <typename T> friend class DIRef;
-
-public:
- /// \brief Accessibility flags.
- ///
- /// The three accessibility flags are mutually exclusive and rolled together
- /// in the first two bits.
- enum {
- FlagAccessibility = 1 << 0 | 1 << 1,
- FlagPrivate = 1,
- FlagProtected = 2,
- FlagPublic = 3,
-
- FlagFwdDecl = 1 << 2,
- FlagAppleBlock = 1 << 3,
- FlagBlockByrefStruct = 1 << 4,
- FlagVirtual = 1 << 5,
- FlagArtificial = 1 << 6,
- FlagExplicit = 1 << 7,
- FlagPrototyped = 1 << 8,
- FlagObjcClassComplete = 1 << 9,
- FlagObjectPointer = 1 << 10,
- FlagVector = 1 << 11,
- FlagStaticMember = 1 << 12,
- FlagIndirectVariable = 1 << 13,
- FlagLValueReference = 1 << 14,
- FlagRValueReference = 1 << 15
- };
-
-protected:
- const MDNode *DbgNode;
-
- StringRef getStringField(unsigned Elt) const;
- unsigned getUnsignedField(unsigned Elt) const {
- return (unsigned)getUInt64Field(Elt);
- }
- uint64_t getUInt64Field(unsigned Elt) const;
- int64_t getInt64Field(unsigned Elt) const;
- DIDescriptor getDescriptorField(unsigned Elt) const;
-
- template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
- return DescTy(getDescriptorField(Elt));
- }
-
- GlobalVariable *getGlobalVariableField(unsigned Elt) const;
- Constant *getConstantField(unsigned Elt) const;
- Function *getFunctionField(unsigned Elt) const;
- void replaceFunctionField(unsigned Elt, Function *F);
-
-public:
- explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {}
-
- bool Verify() const;
-
- MDNode *get() const { return const_cast<MDNode *>(DbgNode); }
- operator MDNode *() const { return get(); }
- MDNode *operator->() const { return get(); }
-
- // An explicit operator bool so that we can do testing of DI values
- // easily.
- // FIXME: This operator bool isn't actually protecting anything at the
- // moment due to the conversion operator above making DIDescriptor nodes
- // implicitly convertable to bool.
- LLVM_EXPLICIT operator bool() const { return DbgNode != nullptr; }
-
- bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; }
- bool operator!=(DIDescriptor Other) const { return !operator==(Other); }
-
- StringRef getHeader() const {
- return getStringField(0);
- }
-
- size_t getNumHeaderFields() const {
- return std::distance(DIHeaderFieldIterator(getHeader()),
- DIHeaderFieldIterator());
- }
-
- StringRef getHeaderField(unsigned Index) const {
- // Since callers expect an empty string for out-of-range accesses, we can't
- // use std::advance() here.
- for (DIHeaderFieldIterator I(getHeader()), E; I != E; ++I, --Index)
- if (!Index)
- return *I;
- return StringRef();
- }
-
- template <class T> T getHeaderFieldAs(unsigned Index) const {
- T Int;
- if (getHeaderField(Index).getAsInteger(0, Int))
- return 0;
- return Int;
- }
-
- uint16_t getTag() const { return getHeaderFieldAs<uint16_t>(0); }
-
- bool isDerivedType() const;
- bool isCompositeType() const;
- bool isSubroutineType() const;
- bool isBasicType() const;
- bool isVariable() const;
- bool isSubprogram() const;
- bool isGlobalVariable() const;
- bool isScope() const;
- bool isFile() const;
- bool isCompileUnit() const;
- bool isNameSpace() const;
- bool isLexicalBlockFile() const;
- bool isLexicalBlock() const;
- bool isSubrange() const;
- bool isEnumerator() const;
- bool isType() const;
- bool isTemplateTypeParameter() const;
- bool isTemplateValueParameter() const;
- bool isObjCProperty() const;
- bool isImportedEntity() const;
- bool isExpression() const;
-
- void print(raw_ostream &OS) const;
- void dump() const;
-
- /// \brief Replace all uses of debug info referenced by this descriptor.
- void replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D);
- void replaceAllUsesWith(MDNode *D);
-};
-
-/// \brief This is used to represent ranges, for array bounds.
-class DISubrange : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- int64_t getLo() const { return getHeaderFieldAs<int64_t>(1); }
- int64_t getCount() const { return getHeaderFieldAs<int64_t>(2); }
- bool Verify() const;
-};
-
-/// \brief This descriptor holds an array of nodes with type T.
-template <typename T> class DITypedArray : public DIDescriptor {
-public:
- explicit DITypedArray(const MDNode *N = nullptr) : DIDescriptor(N) {}
- unsigned getNumElements() const {
- return DbgNode ? DbgNode->getNumOperands() : 0;
- }
- T getElement(unsigned Idx) const {
- return getFieldAs<T>(Idx);
- }
-};
-
-typedef DITypedArray<DIDescriptor> DIArray;
-
-/// \brief A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
-///
-/// FIXME: it seems strange that this doesn't have either a reference to the
-/// type/precision or a file/line pair for location info.
-class DIEnumerator : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- int64_t getEnumValue() const { return getHeaderFieldAs<int64_t>(2); }
- bool Verify() const;
-};
-
-template <typename T> class DIRef;
-typedef DIRef<DIScope> DIScopeRef;
-typedef DIRef<DIType> DITypeRef;
-typedef DITypedArray<DITypeRef> DITypeArray;
-
-/// \brief A base class for various scopes.
-///
-/// Although, implementation-wise, DIScope is the parent class of most
-/// other DIxxx classes, including DIType and its descendants, most of
-/// DIScope's descendants are not a substitutable subtype of
-/// DIScope. The DIDescriptor::isScope() method only is true for
-/// DIScopes that are scopes in the strict lexical scope sense
-/// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType.
-class DIScope : public DIDescriptor {
-protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- /// \brief Get the parent scope.
- ///
- /// Gets the parent scope for this scope node or returns a default
- /// constructed scope.
- DIScopeRef getContext() const;
- /// \brief Get the scope name.
- ///
- /// If the scope node has a name, return that, else return an empty string.
- StringRef getName() const;
- StringRef getFilename() const;
- StringRef getDirectory() const;
-
- /// \brief Generate a reference to this DIScope.
- ///
- /// Uses the type identifier instead of the actual MDNode if possible, to
- /// help type uniquing.
- DIScopeRef getRef() const;
-};
-
-/// \brief Represents reference to a DIDescriptor.
-///
-/// Abstracts over direct and identifier-based metadata references.
-template <typename T> class DIRef {
- template <typename DescTy>
- friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
- friend DIScopeRef DIScope::getContext() const;
- friend DIScopeRef DIScope::getRef() const;
- friend class DIType;
-
- /// \brief Val can be either a MDNode or a MDString.
- ///
- /// In the latter, MDString specifies the type identifier.
- const Metadata *Val;
- explicit DIRef(const Metadata *V);
-
-public:
- T resolve(const DITypeIdentifierMap &Map) const;
- StringRef getName() const;
- operator Metadata *() const { return const_cast<Metadata *>(Val); }
-};
-
-template <typename T>
-T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
- if (!Val)
- return T();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD);
-
- const MDString *MS = cast<MDString>(Val);
- // Find the corresponding MDNode.
- DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
- assert(Iter != Map.end() && "Identifier not in the type map?");
- assert(DIDescriptor(Iter->second).isType() &&
- "MDNode in DITypeIdentifierMap should be a DIType.");
- return T(Iter->second);
-}
-
-template <typename T> StringRef DIRef<T>::getName() const {
- if (!Val)
- return StringRef();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD).getName();
-
- const MDString *MS = cast<MDString>(Val);
- return MS->getString();
-}
-
-/// \brief Handle fields that are references to DIScopes.
-template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIScopeRef.
-template <> DIRef<DIScope>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DITypes.
-template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DITypeRef.
-template <> DIRef<DIType>::DIRef(const Metadata *V);
-
-/// \briefThis is a wrapper for a type.
-///
-/// FIXME: Types should be factored much better so that CV qualifiers and
-/// others do not require a huge and empty descriptor full of zeros.
-class DIType : public DIScope {
-protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIType(const MDNode *N = nullptr) : DIScope(N) {}
- operator DITypeRef () const {
- assert(isType() &&
- "constructing DITypeRef from an MDNode that is not a type");
- return DITypeRef(&*getRef());
- }
-
- bool Verify() const;
-
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const {
- return getHeaderFieldAs<unsigned>(2);
- }
- uint64_t getSizeInBits() const {
- return getHeaderFieldAs<unsigned>(3);
- }
- uint64_t getAlignInBits() const {
- return getHeaderFieldAs<unsigned>(4);
- }
- // FIXME: Offset is only used for DW_TAG_member nodes. Making every type
- // carry this is just plain insane.
- uint64_t getOffsetInBits() const {
- return getHeaderFieldAs<unsigned>(5);
- }
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(6); }
- bool isPrivate() const {
- return (getFlags() & FlagAccessibility) == FlagPrivate;
- }
- bool isProtected() const {
- return (getFlags() & FlagAccessibility) == FlagProtected;
- }
- bool isPublic() const {
- return (getFlags() & FlagAccessibility) == FlagPublic;
- }
- bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
- bool isAppleBlockExtension() const {
- return (getFlags() & FlagAppleBlock) != 0;
- }
- bool isBlockByrefStruct() const {
- return (getFlags() & FlagBlockByrefStruct) != 0;
- }
- bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
- bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
- bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
- bool isObjcClassComplete() const {
- return (getFlags() & FlagObjcClassComplete) != 0;
- }
- bool isVector() const { return (getFlags() & FlagVector) != 0; }
- bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
- bool isLValueReference() const {
- return (getFlags() & FlagLValueReference) != 0;
- }
- bool isRValueReference() const {
- return (getFlags() & FlagRValueReference) != 0;
- }
- bool isValid() const { return DbgNode && isType(); }
-};
-
-/// \brief A basic type, like 'int' or 'float'.
-class DIBasicType : public DIType {
-public:
- explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {}
-
- unsigned getEncoding() const { return getHeaderFieldAs<unsigned>(7); }
-
- bool Verify() const;
-};
-
-/// \brief A simple derived type
-///
-/// Like a const qualified type, a typedef, a pointer or reference, et cetera.
-/// Or, a data member of a class/struct/union.
-class DIDerivedType : public DIType {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {}
-
- DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(3); }
-
- /// \brief Return property node, if this ivar is associated with one.
- MDNode *getObjCProperty() const;
-
- DITypeRef getClassType() const {
- assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- return getFieldAs<DITypeRef>(4);
- }
-
- Constant *getConstant() const {
- assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
- return getConstantField(4);
- }
-
- bool Verify() const;
-};
-
-/// \brief Types that refer to multiple other types.
-///
-/// This descriptor holds a type that can refer to multiple other types, like a
-/// function or struct.
-///
-/// DICompositeType is derived from DIDerivedType because some
-/// composite types (such as enums) can be derived from basic types
-// FIXME: Make this derive from DIType directly & just store the
-// base type in a single DIType field.
-class DICompositeType : public DIDerivedType {
- friend class DIBuilder;
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
- /// \brief Set the array of member DITypes.
- void setArraysHelper(MDNode *Elements, MDNode *TParams);
-
-public:
- explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {}
-
- DIArray getElements() const {
- assert(!isSubroutineType() && "no elements for DISubroutineType");
- return getFieldAs<DIArray>(4);
- }
-
-private:
- template <typename T>
- void setArrays(DITypedArray<T> Elements, DIArray TParams = DIArray()) {
- assert((!TParams || DbgNode->getNumOperands() == 8) &&
- "If you're setting the template parameters this should include a slot "
- "for that!");
- setArraysHelper(Elements, TParams);
- }
-
-public:
- unsigned getRunTimeLang() const {
- return getHeaderFieldAs<unsigned>(7);
- }
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(5); }
-
-private:
- /// \brief Set the containing type.
- void setContainingType(DICompositeType ContainingType);
-
-public:
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); }
- MDString *getIdentifier() const;
-
- bool Verify() const;
-};
-
-class DISubroutineType : public DICompositeType {
-public:
- explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {}
- DITypedArray<DITypeRef> getTypeArray() const {
- return getFieldAs<DITypedArray<DITypeRef>>(4);
- }
-};
-
-/// \brief This is a wrapper for a file.
-class DIFile : public DIScope {
- friend class DIDescriptor;
-
-public:
- explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {}
-
- /// \brief Retrieve the MDNode for the directory/file pair.
- MDNode *getFileNode() const;
- bool Verify() const;
-};
-
-/// \brief A wrapper for a compile unit.
-class DICompileUnit : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {}
-
- dwarf::SourceLanguage getLanguage() const {
- return static_cast<dwarf::SourceLanguage>(getHeaderFieldAs<unsigned>(1));
- }
- StringRef getProducer() const { return getHeaderField(2); }
-
- bool isOptimized() const { return getHeaderFieldAs<bool>(3) != 0; }
- StringRef getFlags() const { return getHeaderField(4); }
- unsigned getRunTimeVersion() const { return getHeaderFieldAs<unsigned>(5); }
-
- DIArray getEnumTypes() const;
- DIArray getRetainedTypes() const;
- DIArray getSubprograms() const;
- DIArray getGlobalVariables() const;
- DIArray getImportedEntities() const;
-
- void replaceSubprograms(DIArray Subprograms);
- void replaceGlobalVariables(DIArray GlobalVariables);
-
- StringRef getSplitDebugFilename() const { return getHeaderField(6); }
- unsigned getEmissionKind() const { return getHeaderFieldAs<unsigned>(7); }
-
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a subprogram (e.g. a function).
-class DISubprogram : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- StringRef getDisplayName() const { return getHeaderField(2); }
- StringRef getLinkageName() const { return getHeaderField(3); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); }
-
- /// \brief Check if this is local (like 'static' in C).
- unsigned isLocalToUnit() const { return getHeaderFieldAs<unsigned>(5); }
- unsigned isDefinition() const { return getHeaderFieldAs<unsigned>(6); }
-
- unsigned getVirtuality() const { return getHeaderFieldAs<unsigned>(7); }
- unsigned getVirtualIndex() const { return getHeaderFieldAs<unsigned>(8); }
-
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(9); }
-
- unsigned isOptimized() const { return getHeaderFieldAs<bool>(10); }
-
- /// \brief Get the beginning of the scope of the function (not the name).
- unsigned getScopeLineNumber() const { return getHeaderFieldAs<unsigned>(11); }
-
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- DISubroutineType getType() const { return getFieldAs<DISubroutineType>(3); }
-
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(4); }
-
- bool Verify() const;
-
- /// \brief Check if this provides debugging information for the function F.
- bool describes(const Function *F);
-
- Function *getFunction() const { return getFunctionField(5); }
- void replaceFunction(Function *F) { replaceFunctionField(5, F); }
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); }
- DISubprogram getFunctionDeclaration() const {
- return getFieldAs<DISubprogram>(7);
- }
- MDNode *getVariablesNodes() const;
- DIArray getVariables() const;
-
- unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
- /// \brief Check for the "private" access specifier.
- bool isPrivate() const {
- return (getFlags() & FlagAccessibility) == FlagPrivate;
- }
- /// \brief Check for the "protected" access specifier.
- bool isProtected() const {
- return (getFlags() & FlagAccessibility) == FlagProtected;
- }
- /// \brief Check for the "public" access specifier.
- bool isPublic() const {
- return (getFlags() & FlagAccessibility) == FlagPublic;
- }
- /// \brief Check for "explicit".
- bool isExplicit() const { return (getFlags() & FlagExplicit) != 0; }
- /// \brief Check if this is prototyped.
- bool isPrototyped() const { return (getFlags() & FlagPrototyped) != 0; }
-
- /// \brief Check if this is reference-qualified.
- ///
- /// Return true if this subprogram is a C++11 reference-qualified non-static
- /// member function (void foo() &).
- unsigned isLValueReference() const {
- return (getFlags() & FlagLValueReference) != 0;
- }
-
- /// \brief Check if this is rvalue-reference-qualified.
- ///
- /// Return true if this subprogram is a C++11 rvalue-reference-qualified
- /// non-static member function (void foo() &&).
- unsigned isRValueReference() const {
- return (getFlags() & FlagRValueReference) != 0;
- }
-
-};
-
-/// \brief This is a wrapper for a lexical block.
-class DILexicalBlock : public DIScope {
-public:
- explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- unsigned getLineNumber() const {
- return getHeaderFieldAs<unsigned>(1);
- }
- unsigned getColumnNumber() const {
- return getHeaderFieldAs<unsigned>(2);
- }
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a lexical block with a filename change.
-class DILexicalBlockFile : public DIScope {
-public:
- explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {}
- DIScope getContext() const {
- if (getScope().isSubprogram())
- return getScope();
- return getScope().getContext();
- }
- unsigned getLineNumber() const { return getScope().getLineNumber(); }
- unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
- DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
- unsigned getDiscriminator() const { return getHeaderFieldAs<unsigned>(1); }
- bool Verify() const;
-};
-
-/// \brief A wrapper for a C++ style name space.
-class DINameSpace : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {}
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for template type parameter.
-class DITemplateTypeParameter : public DIDescriptor {
-public:
- explicit DITemplateTypeParameter(const MDNode *N = nullptr)
- : DIDescriptor(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- unsigned getColumnNumber() const { return getHeaderFieldAs<unsigned>(3); }
-
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
- StringRef getFilename() const { return getFieldAs<DIFile>(3).getFilename(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(3).getDirectory();
- }
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for template value parameter.
-class DITemplateValueParameter : public DIDescriptor {
-public:
- explicit DITemplateValueParameter(const MDNode *N = nullptr)
- : DIDescriptor(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- unsigned getColumnNumber() const { return getHeaderFieldAs<unsigned>(3); }
-
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
- Metadata *getValue() const;
- StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(4).getDirectory();
- }
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a global variable.
-class DIGlobalVariable : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- StringRef getDisplayName() const { return getHeaderField(2); }
- StringRef getLinkageName() const { return getHeaderField(3); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); }
- unsigned isLocalToUnit() const { return getHeaderFieldAs<bool>(5); }
- unsigned isDefinition() const { return getHeaderFieldAs<bool>(6); }
-
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getFilename() const { return getFieldAs<DIFile>(2).getFilename(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(2).getDirectory();
- }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
-
- GlobalVariable *getGlobal() const { return getGlobalVariableField(4); }
- Constant *getConstant() const { return getConstantField(4); }
- DIDerivedType getStaticDataMemberDeclaration() const {
- return getFieldAs<DIDerivedType>(5);
- }
-
- bool Verify() const;
-};
-
-/// \brief This is a wrapper for a variable (e.g. parameter, local, global etc).
-class DIVariable : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const {
- // FIXME: Line number and arg number shouldn't be merged together like this.
- return (getHeaderFieldAs<unsigned>(2) << 8) >> 8;
- }
- unsigned getArgNumber() const { return getHeaderFieldAs<unsigned>(2) >> 24; }
-
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIFile getFile() const { return getFieldAs<DIFile>(2); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
-
- /// \brief Return true if this variable is marked as "artificial".
- bool isArtificial() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagArtificial) != 0;
- }
-
- bool isObjectPointer() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0;
- }
-
- /// \brief Return true if this variable is represented as a pointer.
- bool isIndirect() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagIndirectVariable) != 0;
- }
-
- /// \brief If this variable is inlined then return inline location.
- MDNode *getInlinedAt() const;
-
- bool Verify() const;
-
- /// \brief Check if this is a "__block" variable (Apple Blocks).
- bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
- return (getType().resolve(Map)).isBlockByrefStruct();
- }
-
- /// \brief Check if this is an inlined function argument.
- bool isInlinedFnArgument(const Function *CurFn);
-
- /// \brief Return the size reported by the variable's type.
- unsigned getSizeInBits(const DITypeIdentifierMap &Map);
-
- void printExtendedName(raw_ostream &OS) const;
-};
-
-/// \brief A complex location expression.
-class DIExpression : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {}
-
- bool Verify() const;
-
- /// \brief Return the number of elements in the complex expression.
- unsigned getNumElements() const {
- if (!DbgNode)
- return 0;
- unsigned N = getNumHeaderFields();
- assert(N > 0 && "missing tag");
- return N - 1;
- }
-
- /// \brief return the Idx'th complex address element.
- uint64_t getElement(unsigned Idx) const;
-
- /// \brief Return whether this is a piece of an aggregate variable.
- bool isVariablePiece() const;
- /// \brief Return the offset of this piece in bytes.
- uint64_t getPieceOffset() const;
- /// \brief Return the size of this piece in bytes.
- uint64_t getPieceSize() const;
-};
-
-/// \brief This object holds location information.
-///
-/// This object is not associated with any DWARF tag.
-class DILocation : public DIDescriptor {
-public:
- explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
-
- unsigned getLineNumber() const {
- if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
- return L->getLine();
- return 0;
- }
- unsigned getColumnNumber() const {
- if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
- return L->getColumn();
- return 0;
- }
- DIScope getScope() const {
- if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
- return DIScope(dyn_cast_or_null<MDNode>(L->getScope()));
- return DIScope(nullptr);
- }
- DILocation getOrigLocation() const {
- if (auto *L = dyn_cast_or_null<MDLocation>(DbgNode))
- return DILocation(dyn_cast_or_null<MDNode>(L->getInlinedAt()));
- return DILocation(nullptr);
- }
- StringRef getFilename() const { return getScope().getFilename(); }
- StringRef getDirectory() const { return getScope().getDirectory(); }
- bool Verify() const;
- bool atSameLineAs(const DILocation &Other) const {
- return (getLineNumber() == Other.getLineNumber() &&
- getFilename() == Other.getFilename());
- }
- /// \brief Get the DWAF discriminator.
- ///
- /// DWARF discriminators are used to distinguish identical file locations for
- /// instructions that are on different basic blocks. If two instructions are
- /// inside the same lexical block and are in different basic blocks, we
- /// create a new lexical block with identical location as the original but
- /// with a different discriminator value
- /// (lib/Transforms/Util/AddDiscriminators.cpp for details).
- unsigned getDiscriminator() const {
- // Since discriminators are associated with lexical blocks, make
- // sure this location is a lexical block before retrieving its
- // value.
- return getScope().isLexicalBlockFile()
- ? DILexicalBlockFile(
- cast<MDNode>(cast<MDLocation>(DbgNode)->getScope()))
- .getDiscriminator()
- : 0;
- }
-
- /// \brief Generate a new discriminator value for this location.
- unsigned computeNewDiscriminator(LLVMContext &Ctx);
-
- /// \brief Return a copy of this location with a different scope.
- DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlockFile NewScope);
-};
-
-class DIObjCProperty : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
-
- StringRef getObjCPropertyName() const { return getHeaderField(1); }
- DIFile getFile() const { return getFieldAs<DIFile>(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
-
- StringRef getObjCPropertyGetterName() const { return getHeaderField(3); }
- StringRef getObjCPropertySetterName() const { return getHeaderField(4); }
- unsigned getAttributes() const { return getHeaderFieldAs<unsigned>(5); }
- bool isReadOnlyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
- }
- bool isReadWriteObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
- }
- bool isAssignObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_assign) != 0;
- }
- bool isRetainObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_retain) != 0;
- }
- bool isCopyObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_copy) != 0;
- }
- bool isNonAtomicObjCProperty() const {
- return (getAttributes() & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
- }
-
- /// \brief Get the type.
- ///
- /// \note Objective-C doesn't have an ODR, so there is no benefit in storing
- /// the type as a DITypeRef here.
- DIType getType() const { return getFieldAs<DIType>(2); }
-
- bool Verify() const;
-};
-
-/// \brief An imported module (C++ using directive or similar).
-class DIImportedEntity : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIScopeRef getEntity() const { return getFieldAs<DIScopeRef>(2); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); }
- StringRef getName() const { return getHeaderField(2); }
- bool Verify() const;
-};
+typedef DenseMap<const MDString *, DIType *> DITypeIdentifierMap;
/// \brief Find subprogram that is enclosing this scope.
-DISubprogram getDISubprogram(const MDNode *Scope);
+DISubprogram *getDISubprogram(const MDNode *Scope);
/// \brief Find debug info for a given function.
-/// \returns a valid DISubprogram, if found. Otherwise, it returns an empty
-/// DISubprogram.
-DISubprogram getDISubprogram(const Function *F);
-
-/// \brief Find underlying composite type.
-DICompositeType getDICompositeType(DIType T);
-
-/// \brief Create a new inlined variable based on current variable.
///
-/// @param DV Current Variable.
-/// @param InlinedScope Location at current variable is inlined.
-DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
- LLVMContext &VMContext);
+/// \returns a valid subprogram, if found. Otherwise, return \c nullptr.
+DISubprogram *getDISubprogram(const Function *F);
-/// \brief Remove inlined scope from the variable.
-DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
+/// \brief Find underlying composite type.
+DICompositeTypeBase *getDICompositeType(DIType *T);
/// \brief Generate map by visiting all retained types.
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
@@ -1016,6 +56,7 @@ DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
/// metadata for debugging. We also remove debug locations for instructions.
/// Return true if module is modified.
bool StripDebugInfo(Module &M);
+bool stripDebugInfo(Function &F);
/// \brief Return Debug Info Metadata Version by checking module flags.
unsigned getDebugMetadataVersionFromModule(const Module &M);
@@ -1039,8 +80,8 @@ public:
void processDeclare(const Module &M, const DbgDeclareInst *DDI);
/// \brief Process DbgValueInst.
void processValue(const Module &M, const DbgValueInst *DVI);
- /// \brief Process DILocation.
- void processLocation(const Module &M, DILocation Loc);
+ /// \brief Process debug info location.
+ void processLocation(const Module &M, const DILocation *Loc);
/// \brief Clear all lists.
void reset();
@@ -1048,21 +89,23 @@ public:
private:
void InitializeTypeMap(const Module &M);
- void processType(DIType DT);
- void processSubprogram(DISubprogram SP);
- void processScope(DIScope Scope);
- bool addCompileUnit(DICompileUnit CU);
- bool addGlobalVariable(DIGlobalVariable DIG);
- bool addSubprogram(DISubprogram SP);
- bool addType(DIType DT);
- bool addScope(DIScope Scope);
+ void processType(DIType *DT);
+ void processSubprogram(DISubprogram *SP);
+ void processScope(DIScope *Scope);
+ bool addCompileUnit(DICompileUnit *CU);
+ bool addGlobalVariable(DIGlobalVariable *DIG);
+ bool addSubprogram(DISubprogram *SP);
+ bool addType(DIType *DT);
+ bool addScope(DIScope *Scope);
public:
- typedef SmallVectorImpl<DICompileUnit>::const_iterator compile_unit_iterator;
- typedef SmallVectorImpl<DISubprogram>::const_iterator subprogram_iterator;
- typedef SmallVectorImpl<DIGlobalVariable>::const_iterator global_variable_iterator;
- typedef SmallVectorImpl<DIType>::const_iterator type_iterator;
- typedef SmallVectorImpl<DIScope>::const_iterator scope_iterator;
+ typedef SmallVectorImpl<DICompileUnit *>::const_iterator
+ compile_unit_iterator;
+ typedef SmallVectorImpl<DISubprogram *>::const_iterator subprogram_iterator;
+ typedef SmallVectorImpl<DIGlobalVariable *>::const_iterator
+ global_variable_iterator;
+ typedef SmallVectorImpl<DIType *>::const_iterator type_iterator;
+ typedef SmallVectorImpl<DIScope *>::const_iterator scope_iterator;
iterator_range<compile_unit_iterator> compile_units() const {
return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end());
@@ -1091,19 +134,19 @@ public:
unsigned scope_count() const { return Scopes.size(); }
private:
- SmallVector<DICompileUnit, 8> CUs;
- SmallVector<DISubprogram, 8> SPs;
- SmallVector<DIGlobalVariable, 8> GVs;
- SmallVector<DIType, 8> TYs;
- SmallVector<DIScope, 8> Scopes;
- SmallPtrSet<MDNode *, 64> NodesSeen;
+ SmallVector<DICompileUnit *, 8> CUs;
+ SmallVector<DISubprogram *, 8> SPs;
+ SmallVector<DIGlobalVariable *, 8> GVs;
+ SmallVector<DIType *, 8> TYs;
+ SmallVector<DIScope *, 8> Scopes;
+ SmallPtrSet<const MDNode *, 64> NodesSeen;
DITypeIdentifierMap TypeIdentifierMap;
/// \brief Specify if TypeIdentifierMap is initialized.
bool TypeMapInitialized;
};
-DenseMap<const Function *, DISubprogram> makeSubprogramMap(const Module &M);
+DenseMap<const Function *, DISubprogram *> makeSubprogramMap(const Module &M);
} // end namespace llvm
diff --git a/include/llvm/IR/DebugInfoFlags.def b/include/llvm/IR/DebugInfoFlags.def
new file mode 100644
index 000000000000..d5de8683fd3b
--- /dev/null
+++ b/include/llvm/IR/DebugInfoFlags.def
@@ -0,0 +1,36 @@
+//===- llvm/IR/DebugInfoFlags.def - Debug info flag definitions -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Macros for running through debug info flags.
+//
+//===----------------------------------------------------------------------===//
+
+// TODO: Add other DW-based macros.
+#ifndef HANDLE_DI_FLAG
+#error "Missing macro definition of HANDLE_DI_FLAG"
+#endif
+
+HANDLE_DI_FLAG(1, Private)
+HANDLE_DI_FLAG(2, Protected)
+HANDLE_DI_FLAG(3, Public)
+HANDLE_DI_FLAG((1 << 2), FwdDecl)
+HANDLE_DI_FLAG((1 << 3), AppleBlock)
+HANDLE_DI_FLAG((1 << 4), BlockByrefStruct)
+HANDLE_DI_FLAG((1 << 5), Virtual)
+HANDLE_DI_FLAG((1 << 6), Artificial)
+HANDLE_DI_FLAG((1 << 7), Explicit)
+HANDLE_DI_FLAG((1 << 8), Prototyped)
+HANDLE_DI_FLAG((1 << 9), ObjcClassComplete)
+HANDLE_DI_FLAG((1 << 10), ObjectPointer)
+HANDLE_DI_FLAG((1 << 11), Vector)
+HANDLE_DI_FLAG((1 << 12), StaticMember)
+HANDLE_DI_FLAG((1 << 13), LValueReference)
+HANDLE_DI_FLAG((1 << 14), RValueReference)
+
+#undef HANDLE_DI_FLAG
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
new file mode 100644
index 000000000000..0125de5d40f5
--- /dev/null
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -0,0 +1,2227 @@
+//===- llvm/IR/DebugInfoMetadata.h - Debug info metadata --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Declarations for metadata specific to debug info.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DEBUGINFOMETADATA_H
+#define LLVM_IR_DEBUGINFOMETADATA_H
+
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Dwarf.h"
+
+// Helper macros for defining get() overrides.
+#define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__
+#define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS
+#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \
+ static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
+ return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \
+ } \
+ static CLASS *getIfExists(LLVMContext &Context, \
+ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
+ return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \
+ /* ShouldCreate */ false); \
+ } \
+ static CLASS *getDistinct(LLVMContext &Context, \
+ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
+ return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \
+ } \
+ static Temp##CLASS getTemporary(LLVMContext &Context, \
+ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \
+ return Temp##CLASS( \
+ getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \
+ }
+
+namespace llvm {
+
+/// \brief Pointer union between a subclass of DINode and MDString.
+///
+/// \a DICompositeType can be referenced via an \a MDString unique identifier.
+/// This class allows some type safety in the face of that, requiring either a
+/// node of a particular type or an \a MDString.
+template <class T> class TypedDINodeRef {
+ const Metadata *MD = nullptr;
+
+public:
+ TypedDINodeRef() = default;
+ TypedDINodeRef(std::nullptr_t) {}
+
+ /// \brief Construct from a raw pointer.
+ explicit TypedDINodeRef(const Metadata *MD) : MD(MD) {
+ assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
+ }
+
+ template <class U>
+ TypedDINodeRef(
+ const TypedDINodeRef<U> &X,
+ typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : MD(X) {}
+
+ operator Metadata *() const { return const_cast<Metadata *>(MD); }
+
+ bool operator==(const TypedDINodeRef<T> &X) const { return MD == X.MD; };
+ bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; };
+
+ /// \brief Create a reference.
+ ///
+ /// Get a reference to \c N, using an \a MDString reference if available.
+ static TypedDINodeRef get(const T *N);
+
+ template <class MapTy> T *resolve(const MapTy &Map) const {
+ if (!MD)
+ return nullptr;
+
+ if (auto *Typed = dyn_cast<T>(MD))
+ return const_cast<T *>(Typed);
+
+ auto *S = cast<MDString>(MD);
+ auto I = Map.find(S);
+ assert(I != Map.end() && "Missing identifier in type map");
+ return cast<T>(I->second);
+ }
+};
+
+typedef TypedDINodeRef<DINode> DINodeRef;
+typedef TypedDINodeRef<DIScope> DIScopeRef;
+typedef TypedDINodeRef<DIType> DITypeRef;
+
+class DITypeRefArray {
+ const MDTuple *N = nullptr;
+
+public:
+ DITypeRefArray(const MDTuple *N) : N(N) {}
+
+ explicit operator bool() const { return get(); }
+ explicit operator MDTuple *() const { return get(); }
+
+ MDTuple *get() const { return const_cast<MDTuple *>(N); }
+ MDTuple *operator->() const { return get(); }
+ MDTuple &operator*() const { return *get(); }
+
+ // FIXME: Fix callers and remove condition on N.
+ unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ DITypeRef operator[](unsigned I) const { return DITypeRef(N->getOperand(I)); }
+
+ class iterator : std::iterator<std::input_iterator_tag, DITypeRef,
+ std::ptrdiff_t, void, DITypeRef> {
+ MDNode::op_iterator I = nullptr;
+
+ public:
+ iterator() = default;
+ explicit iterator(MDNode::op_iterator I) : I(I) {}
+ DITypeRef operator*() const { return DITypeRef(*I); }
+ iterator &operator++() {
+ ++I;
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator Temp(*this);
+ ++I;
+ return Temp;
+ }
+ bool operator==(const iterator &X) const { return I == X.I; }
+ bool operator!=(const iterator &X) const { return I != X.I; }
+ };
+
+ // FIXME: Fix callers and remove condition on N.
+ iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
+ iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
+};
+
+/// \brief Tagged DWARF-like metadata node.
+///
+/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
+/// defined in llvm/Support/Dwarf.h). Called \a DINode because it's
+/// potentially used for non-DWARF output.
+class DINode : public MDNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+protected:
+ DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None)
+ : MDNode(C, ID, Storage, Ops1, Ops2) {
+ assert(Tag < 1u << 16);
+ SubclassData16 = Tag;
+ }
+ ~DINode() = default;
+
+ template <class Ty> Ty *getOperandAs(unsigned I) const {
+ return cast_or_null<Ty>(getOperand(I));
+ }
+
+ StringRef getStringOperand(unsigned I) const {
+ if (auto *S = getOperandAs<MDString>(I))
+ return S->getString();
+ return StringRef();
+ }
+
+ static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) {
+ if (S.empty())
+ return nullptr;
+ return MDString::get(Context, S);
+ }
+
+public:
+ unsigned getTag() const { return SubclassData16; }
+
+ /// \brief Debug info flags.
+ ///
+ /// The three accessibility flags are mutually exclusive and rolled together
+ /// in the first two bits.
+ enum DIFlags {
+#define HANDLE_DI_FLAG(ID, NAME) Flag##NAME = ID,
+#include "llvm/IR/DebugInfoFlags.def"
+ FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic
+ };
+
+ static unsigned getFlag(StringRef Flag);
+ static const char *getFlagString(unsigned Flag);
+
+ /// \brief Split up a flags bitfield.
+ ///
+ /// Split \c Flags into \c SplitFlags, a vector of its components. Returns
+ /// any remaining (unrecognized) bits.
+ static unsigned splitFlags(unsigned Flags,
+ SmallVectorImpl<unsigned> &SplitFlags);
+
+ DINodeRef getRef() const { return DINodeRef::get(this); }
+
+ static bool classof(const Metadata *MD) {
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case GenericDINodeKind:
+ case DISubrangeKind:
+ case DIEnumeratorKind:
+ case DIBasicTypeKind:
+ case DIDerivedTypeKind:
+ case DICompositeTypeKind:
+ case DISubroutineTypeKind:
+ case DIFileKind:
+ case DICompileUnitKind:
+ case DISubprogramKind:
+ case DILexicalBlockKind:
+ case DILexicalBlockFileKind:
+ case DINamespaceKind:
+ case DITemplateTypeParameterKind:
+ case DITemplateValueParameterKind:
+ case DIGlobalVariableKind:
+ case DILocalVariableKind:
+ case DIObjCPropertyKind:
+ case DIImportedEntityKind:
+ return true;
+ }
+ }
+};
+
+template <class T> struct simplify_type<const TypedDINodeRef<T>> {
+ typedef Metadata *SimpleType;
+ static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
+ return MD;
+ }
+};
+
+template <class T>
+struct simplify_type<TypedDINodeRef<T>>
+ : simplify_type<const TypedDINodeRef<T>> {};
+
+/// \brief Generic tagged DWARF-like metadata node.
+///
+/// An un-specialized DWARF-like metadata node. The first operand is a
+/// (possibly empty) null-separated \a MDString header that contains arbitrary
+/// fields. The remaining operands are \a dwarf_operands(), and are pointers
+/// to other metadata.
+class GenericDINode : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ GenericDINode(LLVMContext &C, StorageType Storage, unsigned Hash,
+ unsigned Tag, ArrayRef<Metadata *> Ops1,
+ ArrayRef<Metadata *> Ops2)
+ : DINode(C, GenericDINodeKind, Storage, Tag, Ops1, Ops2) {
+ setHash(Hash);
+ }
+ ~GenericDINode() { dropAllReferences(); }
+
+ void setHash(unsigned Hash) { SubclassData32 = Hash; }
+ void recalculateHash();
+
+ static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Header, ArrayRef<Metadata *> DwarfOps,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Header),
+ DwarfOps, Storage, ShouldCreate);
+ }
+
+ static GenericDINode *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Header, ArrayRef<Metadata *> DwarfOps,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempGenericDINode cloneImpl() const {
+ return getTemporary(
+ getContext(), getTag(), getHeader(),
+ SmallVector<Metadata *, 4>(dwarf_op_begin(), dwarf_op_end()));
+ }
+
+public:
+ unsigned getHash() const { return SubclassData32; }
+
+ DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header,
+ ArrayRef<Metadata *> DwarfOps),
+ (Tag, Header, DwarfOps))
+ DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header,
+ ArrayRef<Metadata *> DwarfOps),
+ (Tag, Header, DwarfOps))
+
+ /// \brief Return a (temporary) clone of this.
+ TempGenericDINode clone() const { return cloneImpl(); }
+
+ unsigned getTag() const { return SubclassData16; }
+ StringRef getHeader() const { return getStringOperand(0); }
+
+ op_iterator dwarf_op_begin() const { return op_begin() + 1; }
+ op_iterator dwarf_op_end() const { return op_end(); }
+ op_range dwarf_operands() const {
+ return op_range(dwarf_op_begin(), dwarf_op_end());
+ }
+
+ unsigned getNumDwarfOperands() const { return getNumOperands() - 1; }
+ const MDOperand &getDwarfOperand(unsigned I) const {
+ return getOperand(I + 1);
+ }
+ void replaceDwarfOperandWith(unsigned I, Metadata *New) {
+ replaceOperandWith(I + 1, New);
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == GenericDINodeKind;
+ }
+};
+
+/// \brief Array subrange.
+///
+/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
+/// type.
+class DISubrange : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ int64_t Count;
+ int64_t LowerBound;
+
+ DISubrange(LLVMContext &C, StorageType Storage, int64_t Count,
+ int64_t LowerBound)
+ : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, None),
+ Count(Count), LowerBound(LowerBound) {}
+ ~DISubrange() = default;
+
+ static DISubrange *getImpl(LLVMContext &Context, int64_t Count,
+ int64_t LowerBound, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDISubrange cloneImpl() const {
+ return getTemporary(getContext(), getCount(), getLowerBound());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0),
+ (Count, LowerBound))
+
+ TempDISubrange clone() const { return cloneImpl(); }
+
+ int64_t getLowerBound() const { return LowerBound; }
+ int64_t getCount() const { return Count; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DISubrangeKind;
+ }
+};
+
+/// \brief Enumeration value.
+///
+/// TODO: Add a pointer to the context (DW_TAG_enumeration_type) once that no
+/// longer creates a type cycle.
+class DIEnumerator : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ int64_t Value;
+
+ DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
+ Value(Value) {}
+ ~DIEnumerator() = default;
+
+ static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ StringRef Name, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
+ ShouldCreate);
+ }
+ static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ MDString *Name, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIEnumerator cloneImpl() const {
+ return getTemporary(getContext(), getValue(), getName());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, StringRef Name),
+ (Value, Name))
+ DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, MDString *Name),
+ (Value, Name))
+
+ TempDIEnumerator clone() const { return cloneImpl(); }
+
+ int64_t getValue() const { return Value; }
+ StringRef getName() const { return getStringOperand(0); }
+
+ MDString *getRawName() const { return getOperandAs<MDString>(0); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIEnumeratorKind;
+ }
+};
+
+/// \brief Base class for scope-like contexts.
+///
+/// Base class for lexical scopes and types (which are also declaration
+/// contexts).
+///
+/// TODO: Separate the concepts of declaration contexts and lexical scopes.
+class DIScope : public DINode {
+protected:
+ DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops)
+ : DINode(C, ID, Storage, Tag, Ops) {}
+ ~DIScope() = default;
+
+public:
+ DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
+
+ inline StringRef getFilename() const;
+ inline StringRef getDirectory() const;
+
+ StringRef getName() const;
+ DIScopeRef getScope() const;
+
+ /// \brief Return the raw underlying file.
+ ///
+ /// An \a DIFile is an \a DIScope, but it doesn't point at a separate file
+ /// (it\em is the file). If \c this is an \a DIFile, we need to return \c
+ /// this. Otherwise, return the first operand, which is where all other
+ /// subclasses store their file pointer.
+ Metadata *getRawFile() const {
+ return isa<DIFile>(this) ? const_cast<DIScope *>(this)
+ : static_cast<Metadata *>(getOperand(0));
+ }
+
+ DIScopeRef getRef() const { return DIScopeRef::get(this); }
+
+ static bool classof(const Metadata *MD) {
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case DIBasicTypeKind:
+ case DIDerivedTypeKind:
+ case DICompositeTypeKind:
+ case DISubroutineTypeKind:
+ case DIFileKind:
+ case DICompileUnitKind:
+ case DISubprogramKind:
+ case DILexicalBlockKind:
+ case DILexicalBlockFileKind:
+ case DINamespaceKind:
+ return true;
+ }
+ }
+};
+
+/// \brief File.
+///
+/// TODO: Merge with directory/file node (including users).
+/// TODO: Canonicalize paths on creation.
+class DIFile : public DIScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DIFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+ : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
+ ~DIFile() = default;
+
+ static DIFile *getImpl(LLVMContext &Context, StringRef Filename,
+ StringRef Directory, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Filename),
+ getCanonicalMDString(Context, Directory), Storage,
+ ShouldCreate);
+ }
+ static DIFile *getImpl(LLVMContext &Context, MDString *Filename,
+ MDString *Directory, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIFile cloneImpl() const {
+ return getTemporary(getContext(), getFilename(), getDirectory());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory),
+ (Filename, Directory))
+ DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory),
+ (Filename, Directory))
+
+ TempDIFile clone() const { return cloneImpl(); }
+
+ StringRef getFilename() const { return getStringOperand(0); }
+ StringRef getDirectory() const { return getStringOperand(1); }
+
+ MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
+ MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIFileKind;
+ }
+};
+
+StringRef DIScope::getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+}
+
+StringRef DIScope::getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+}
+
+/// \brief Base class for types.
+///
+/// TODO: Remove the hardcoded name and context, since many types don't use
+/// them.
+/// TODO: Split up flags.
+class DIType : public DIScope {
+ unsigned Line;
+ unsigned Flags;
+ uint64_t SizeInBits;
+ uint64_t AlignInBits;
+ uint64_t OffsetInBits;
+
+protected:
+ DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+ : DIScope(C, ID, Storage, Tag, Ops), Line(Line), Flags(Flags),
+ SizeInBits(SizeInBits), AlignInBits(AlignInBits),
+ OffsetInBits(OffsetInBits) {}
+ ~DIType() = default;
+
+public:
+ TempDIType clone() const {
+ return TempDIType(cast<DIType>(MDNode::clone().release()));
+ }
+
+ unsigned getLine() const { return Line; }
+ uint64_t getSizeInBits() const { return SizeInBits; }
+ uint64_t getAlignInBits() const { return AlignInBits; }
+ uint64_t getOffsetInBits() const { return OffsetInBits; }
+ unsigned getFlags() const { return Flags; }
+
+ DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
+ StringRef getName() const { return getStringOperand(2); }
+
+
+ Metadata *getRawScope() const { return getOperand(1); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
+ void setFlags(unsigned NewFlags) {
+ assert(!isUniqued() && "Cannot set flags on uniqued nodes");
+ Flags = NewFlags;
+ }
+
+ bool isPrivate() const {
+ return (getFlags() & FlagAccessibility) == FlagPrivate;
+ }
+ bool isProtected() const {
+ return (getFlags() & FlagAccessibility) == FlagProtected;
+ }
+ bool isPublic() const {
+ return (getFlags() & FlagAccessibility) == FlagPublic;
+ }
+ bool isForwardDecl() const { return getFlags() & FlagFwdDecl; }
+ bool isAppleBlockExtension() const { return getFlags() & FlagAppleBlock; }
+ bool isBlockByrefStruct() const { return getFlags() & FlagBlockByrefStruct; }
+ bool isVirtual() const { return getFlags() & FlagVirtual; }
+ bool isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
+ bool isObjcClassComplete() const {
+ return getFlags() & FlagObjcClassComplete;
+ }
+ bool isVector() const { return getFlags() & FlagVector; }
+ bool isStaticMember() const { return getFlags() & FlagStaticMember; }
+ bool isLValueReference() const { return getFlags() & FlagLValueReference; }
+ bool isRValueReference() const { return getFlags() & FlagRValueReference; }
+
+ DITypeRef getRef() const { return DITypeRef::get(this); }
+
+ static bool classof(const Metadata *MD) {
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+ case DIBasicTypeKind:
+ case DIDerivedTypeKind:
+ case DICompositeTypeKind:
+ case DISubroutineTypeKind:
+ return true;
+ }
+ }
+};
+
+/// \brief Basic type, like 'int' or 'float'.
+///
+/// TODO: Split out DW_TAG_unspecified_type.
+/// TODO: Drop unused accessors.
+class DIBasicType : public DIType {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Encoding;
+
+ DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
+ 0, Ops),
+ Encoding(Encoding) {}
+ ~DIBasicType() = default;
+
+ static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
+ SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
+ }
+ static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDIBasicType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
+ getAlignInBits(), getEncoding());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
+ (Tag, Name, 0, 0, 0))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding))
+ DEFINE_MDNODE_GET(DIBasicType,
+ (unsigned Tag, MDString *Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding),
+ (Tag, Name, SizeInBits, AlignInBits, Encoding))
+
+ TempDIBasicType clone() const { return cloneImpl(); }
+
+ unsigned getEncoding() const { return Encoding; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIBasicTypeKind;
+ }
+};
+
+/// \brief Base class for DIDerivedType and DICompositeType.
+///
+/// TODO: Delete; they're not really related.
+class DIDerivedTypeBase : public DIType {
+protected:
+ DIDerivedTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ unsigned Tag, unsigned Line, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : DIType(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Ops) {}
+ ~DIDerivedTypeBase() = default;
+
+public:
+ DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
+ Metadata *getRawBaseType() const { return getOperand(3); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIDerivedTypeKind ||
+ MD->getMetadataID() == DICompositeTypeKind ||
+ MD->getMetadataID() == DISubroutineTypeKind;
+ }
+};
+
+/// \brief Derived types.
+///
+/// This includes qualified types, pointers, references, friends, typedefs, and
+/// class members.
+///
+/// TODO: Split out members (inheritance, fields, methods, etc.).
+class DIDerivedType : public DIDerivedTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, ArrayRef<Metadata *> Ops)
+ : DIDerivedTypeBase(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Ops) {}
+ ~DIDerivedType() = default;
+
+ static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, DIFile *File, unsigned Line,
+ DIScopeRef Scope, DITypeRef BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ Metadata *ExtraData, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, ExtraData, Storage, ShouldCreate);
+ }
+ static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ Metadata *ExtraData, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIDerivedType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
+ getScope(), getBaseType(), getSizeInBits(),
+ getAlignInBits(), getOffsetInBits(), getFlags(),
+ getExtraData());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIDerivedType,
+ (unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ Metadata *ExtraData = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, ExtraData))
+ DEFINE_MDNODE_GET(DIDerivedType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, Metadata *ExtraData = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, ExtraData))
+
+ TempDIDerivedType clone() const { return cloneImpl(); }
+
+ /// \brief Get extra data associated with this derived type.
+ ///
+ /// Class type for pointer-to-members, objective-c property node for ivars,
+ /// or global constant wrapper for static members.
+ ///
+ /// TODO: Separate out types that need this extra operand: pointer-to-member
+ /// types and member fields (static members and ivars).
+ Metadata *getExtraData() const { return getRawExtraData(); }
+ Metadata *getRawExtraData() const { return getOperand(4); }
+
+ /// \brief Get casted version of extra data.
+ /// @{
+ DITypeRef getClassType() const {
+ assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
+ return DITypeRef(getExtraData());
+ }
+ DIObjCProperty *getObjCProperty() const {
+ return dyn_cast_or_null<DIObjCProperty>(getExtraData());
+ }
+ Constant *getConstant() const {
+ assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
+ return C->getValue();
+ return nullptr;
+ }
+ /// @}
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIDerivedTypeKind;
+ }
+};
+
+/// \brief Base class for DICompositeType and DISubroutineType.
+///
+/// TODO: Delete; they're not really related.
+class DICompositeTypeBase : public DIDerivedTypeBase {
+ unsigned RuntimeLang;
+
+protected:
+ DICompositeTypeBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ unsigned Tag, unsigned Line, unsigned RuntimeLang,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : DIDerivedTypeBase(C, ID, Storage, Tag, Line, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Ops),
+ RuntimeLang(RuntimeLang) {}
+ ~DICompositeTypeBase() = default;
+
+public:
+ /// \brief Get the elements of the composite type.
+ ///
+ /// \note Calling this is only valid for \a DICompositeType. This assertion
+ /// can be removed once \a DISubroutineType has been separated from
+ /// "composite types".
+ DINodeArray getElements() const {
+ assert(!isa<DISubroutineType>(this) && "no elements for DISubroutineType");
+ return cast_or_null<MDTuple>(getRawElements());
+ }
+ DITypeRef getVTableHolder() const { return DITypeRef(getRawVTableHolder()); }
+ DITemplateParameterArray getTemplateParams() const {
+ return cast_or_null<MDTuple>(getRawTemplateParams());
+ }
+ StringRef getIdentifier() const { return getStringOperand(7); }
+ unsigned getRuntimeLang() const { return RuntimeLang; }
+
+ Metadata *getRawElements() const { return getOperand(4); }
+ Metadata *getRawVTableHolder() const { return getOperand(5); }
+ Metadata *getRawTemplateParams() const { return getOperand(6); }
+ MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
+
+ /// \brief Replace operands.
+ ///
+ /// If this \a isUniqued() and not \a isResolved(), on a uniquing collision
+ /// this will be RAUW'ed and deleted. Use a \a TrackingMDRef to keep track
+ /// of its movement if necessary.
+ /// @{
+ void replaceElements(DINodeArray Elements) {
+#ifndef NDEBUG
+ for (DINode *Op : getElements())
+ assert(std::find(Elements->op_begin(), Elements->op_end(), Op) &&
+ "Lost a member during member list replacement");
+#endif
+ replaceOperandWith(4, Elements.get());
+ }
+ void replaceVTableHolder(DITypeRef VTableHolder) {
+ replaceOperandWith(5, VTableHolder);
+ }
+ void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
+ replaceOperandWith(6, TemplateParams.get());
+ }
+ /// @}
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DICompositeTypeKind ||
+ MD->getMetadataID() == DISubroutineTypeKind;
+ }
+};
+
+/// \brief Composite types.
+///
+/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).
+/// TODO: Create a custom, unrelated node for DW_TAG_array_type.
+class DICompositeType : public DICompositeTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : DICompositeTypeBase(C, DICompositeTypeKind, Storage, Tag, Line,
+ RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Ops) {}
+ ~DICompositeType() = default;
+
+ static DICompositeType *
+ getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
+ unsigned Line, DIScopeRef Scope, DITypeRef BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
+ uint64_t Flags, DINodeArray Elements, unsigned RuntimeLang,
+ DITypeRef VTableHolder, DITemplateParameterArray TemplateParams,
+ StringRef Identifier, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(
+ Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
+ RuntimeLang, VTableHolder, TemplateParams.get(),
+ getCanonicalMDString(Context, Identifier), Storage, ShouldCreate);
+ }
+ static DICompositeType *
+ getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, Metadata *Elements, unsigned RuntimeLang,
+ Metadata *VTableHolder, Metadata *TemplateParams,
+ MDString *Identifier, StorageType Storage, bool ShouldCreate = true);
+
+ TempDICompositeType cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
+ getScope(), getBaseType(), getSizeInBits(),
+ getAlignInBits(), getOffsetInBits(), getFlags(),
+ getElements(), getRuntimeLang(), getVTableHolder(),
+ getTemplateParams(), getIdentifier());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DICompositeType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DINodeArray Elements, unsigned RuntimeLang,
+ DITypeRef VTableHolder,
+ DITemplateParameterArray TemplateParams = nullptr,
+ StringRef Identifier = ""),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier))
+ DEFINE_MDNODE_GET(DICompositeType,
+ (unsigned Tag, MDString *Name, Metadata *File,
+ unsigned Line, Metadata *Scope, Metadata *BaseType,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, Metadata *Elements,
+ unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams = nullptr,
+ MDString *Identifier = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier))
+
+ TempDICompositeType clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DICompositeTypeKind;
+ }
+};
+
+template <class T> TypedDINodeRef<T> TypedDINodeRef<T>::get(const T *N) {
+ if (N)
+ if (auto *Composite = dyn_cast<DICompositeType>(N))
+ if (auto *S = Composite->getRawIdentifier())
+ return TypedDINodeRef<T>(S);
+ return TypedDINodeRef<T>(N);
+}
+
+/// \brief Type array for a subprogram.
+///
+/// TODO: Detach from CompositeType, and fold the array of types in directly
+/// as operands.
+class DISubroutineType : public DICompositeTypeBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DISubroutineType(LLVMContext &C, StorageType Storage, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : DICompositeTypeBase(C, DISubroutineTypeKind, Storage,
+ dwarf::DW_TAG_subroutine_type, 0, 0, 0, 0, 0, Flags,
+ Ops) {}
+ ~DISubroutineType() = default;
+
+ static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+ DITypeRefArray TypeArray,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Flags, TypeArray.get(), Storage, ShouldCreate);
+ }
+ static DISubroutineType *getImpl(LLVMContext &Context, unsigned Flags,
+ Metadata *TypeArray, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDISubroutineType cloneImpl() const {
+ return getTemporary(getContext(), getFlags(), getTypeArray());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DISubroutineType,
+ (unsigned Flags, DITypeRefArray TypeArray),
+ (Flags, TypeArray))
+ DEFINE_MDNODE_GET(DISubroutineType, (unsigned Flags, Metadata *TypeArray),
+ (Flags, TypeArray))
+
+ TempDISubroutineType clone() const { return cloneImpl(); }
+
+ DITypeRefArray getTypeArray() const {
+ return cast_or_null<MDTuple>(getRawTypeArray());
+ }
+ Metadata *getRawTypeArray() const { return getRawElements(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DISubroutineTypeKind;
+ }
+};
+
+/// \brief Compile unit.
+class DICompileUnit : public DIScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned SourceLanguage;
+ bool IsOptimized;
+ unsigned RuntimeVersion;
+ unsigned EmissionKind;
+ uint64_t DWOId;
+
+ DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
+ bool IsOptimized, unsigned RuntimeVersion,
+ unsigned EmissionKind, uint64_t DWOId, ArrayRef<Metadata *> Ops)
+ : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
+ SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
+ RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind),
+ DWOId(DWOId) {}
+ ~DICompileUnit() = default;
+
+ static DICompileUnit *
+ getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File,
+ StringRef Producer, bool IsOptimized, StringRef Flags,
+ unsigned RuntimeVersion, StringRef SplitDebugFilename,
+ unsigned EmissionKind, DICompositeTypeArray EnumTypes,
+ DITypeArray RetainedTypes, DISubprogramArray Subprograms,
+ DIGlobalVariableArray GlobalVariables,
+ DIImportedEntityArray ImportedEntities, uint64_t DWOId,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, SourceLanguage, File,
+ getCanonicalMDString(Context, Producer), IsOptimized,
+ getCanonicalMDString(Context, Flags), RuntimeVersion,
+ getCanonicalMDString(Context, SplitDebugFilename),
+ EmissionKind, EnumTypes.get(), RetainedTypes.get(),
+ Subprograms.get(), GlobalVariables.get(),
+ ImportedEntities.get(), DWOId, Storage, ShouldCreate);
+ }
+ static DICompileUnit *
+ getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
+ MDString *Producer, bool IsOptimized, MDString *Flags,
+ unsigned RuntimeVersion, MDString *SplitDebugFilename,
+ unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
+ Metadata *Subprograms, Metadata *GlobalVariables,
+ Metadata *ImportedEntities, uint64_t DWOId, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDICompileUnit cloneImpl() const {
+ return getTemporary(
+ getContext(), getSourceLanguage(), getFile(), getProducer(),
+ isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(),
+ getEmissionKind(), getEnumTypes(), getRetainedTypes(), getSubprograms(),
+ getGlobalVariables(), getImportedEntities(), DWOId);
+ }
+
+public:
+ DEFINE_MDNODE_GET(DICompileUnit,
+ (unsigned SourceLanguage, DIFile *File, StringRef Producer,
+ bool IsOptimized, StringRef Flags, unsigned RuntimeVersion,
+ StringRef SplitDebugFilename, unsigned EmissionKind,
+ DICompositeTypeArray EnumTypes, DITypeArray RetainedTypes,
+ DISubprogramArray Subprograms,
+ DIGlobalVariableArray GlobalVariables,
+ DIImportedEntityArray ImportedEntities, uint64_t DWOId),
+ (SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind,
+ EnumTypes, RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId))
+ DEFINE_MDNODE_GET(
+ DICompileUnit,
+ (unsigned SourceLanguage, Metadata *File, MDString *Producer,
+ bool IsOptimized, MDString *Flags, unsigned RuntimeVersion,
+ MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes,
+ Metadata *RetainedTypes, Metadata *Subprograms,
+ Metadata *GlobalVariables, Metadata *ImportedEntities, uint64_t DWOId),
+ (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities, DWOId))
+
+ TempDICompileUnit clone() const { return cloneImpl(); }
+
+ unsigned getSourceLanguage() const { return SourceLanguage; }
+ bool isOptimized() const { return IsOptimized; }
+ unsigned getRuntimeVersion() const { return RuntimeVersion; }
+ unsigned getEmissionKind() const { return EmissionKind; }
+ StringRef getProducer() const { return getStringOperand(1); }
+ StringRef getFlags() const { return getStringOperand(2); }
+ StringRef getSplitDebugFilename() const { return getStringOperand(3); }
+ DICompositeTypeArray getEnumTypes() const {
+ return cast_or_null<MDTuple>(getRawEnumTypes());
+ }
+ DITypeArray getRetainedTypes() const {
+ return cast_or_null<MDTuple>(getRawRetainedTypes());
+ }
+ DISubprogramArray getSubprograms() const {
+ return cast_or_null<MDTuple>(getRawSubprograms());
+ }
+ DIGlobalVariableArray getGlobalVariables() const {
+ return cast_or_null<MDTuple>(getRawGlobalVariables());
+ }
+ DIImportedEntityArray getImportedEntities() const {
+ return cast_or_null<MDTuple>(getRawImportedEntities());
+ }
+ unsigned getDWOId() const { return DWOId; }
+
+ MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
+ MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
+ MDString *getRawSplitDebugFilename() const {
+ return getOperandAs<MDString>(3);
+ }
+ Metadata *getRawEnumTypes() const { return getOperand(4); }
+ Metadata *getRawRetainedTypes() const { return getOperand(5); }
+ Metadata *getRawSubprograms() const { return getOperand(6); }
+ Metadata *getRawGlobalVariables() const { return getOperand(7); }
+ Metadata *getRawImportedEntities() const { return getOperand(8); }
+
+ /// \brief Replace arrays.
+ ///
+ /// If this \a isUniqued() and not \a isResolved(), it will be RAUW'ed and
+ /// deleted on a uniquing collision. In practice, uniquing collisions on \a
+ /// DICompileUnit should be fairly rare.
+ /// @{
+ void replaceSubprograms(DISubprogramArray N) {
+ replaceOperandWith(6, N.get());
+ }
+ void replaceGlobalVariables(DIGlobalVariableArray N) {
+ replaceOperandWith(7, N.get());
+ }
+ /// @}
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DICompileUnitKind;
+ }
+};
+
+/// \brief A scope for locals.
+///
+/// A legal scope for lexical blocks, local variables, and debug info
+/// locations. Subclasses are \a DISubprogram, \a DILexicalBlock, and \a
+/// DILexicalBlockFile.
+class DILocalScope : public DIScope {
+protected:
+ DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops)
+ : DIScope(C, ID, Storage, Tag, Ops) {}
+ ~DILocalScope() = default;
+
+public:
+ /// \brief Get the subprogram for this scope.
+ ///
+ /// Return this if it's an \a DISubprogram; otherwise, look up the scope
+ /// chain.
+ DISubprogram *getSubprogram() const;
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DISubprogramKind ||
+ MD->getMetadataID() == DILexicalBlockKind ||
+ MD->getMetadataID() == DILexicalBlockFileKind;
+ }
+};
+
+/// \brief Debug location.
+///
+/// A debug location in source code, used for debug info and otherwise.
+class DILocation : public MDNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> MDs);
+ ~DILocation() { dropAllReferences(); }
+
+ static DILocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true);
+ static DILocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, DILocalScope *Scope,
+ DILocation *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
+ }
+
+ TempDILocation cloneImpl() const {
+ return getTemporary(getContext(), getLine(), getColumn(), getScope(),
+ getInlinedAt());
+ }
+
+ // Disallow replacing operands.
+ void replaceOperandWith(unsigned I, Metadata *New) = delete;
+
+public:
+ DEFINE_MDNODE_GET(DILocation,
+ (unsigned Line, unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+ DEFINE_MDNODE_GET(DILocation,
+ (unsigned Line, unsigned Column, DILocalScope *Scope,
+ DILocation *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+
+ /// \brief Return a (temporary) clone of this.
+ TempDILocation clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return SubclassData32; }
+ unsigned getColumn() const { return SubclassData16; }
+ DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
+ DILocation *getInlinedAt() const {
+ return cast_or_null<DILocation>(getRawInlinedAt());
+ }
+
+ DIFile *getFile() const { return getScope()->getFile(); }
+ StringRef getFilename() const { return getScope()->getFilename(); }
+ StringRef getDirectory() const { return getScope()->getDirectory(); }
+
+ /// \brief Get the scope where this is inlined.
+ ///
+ /// Walk through \a getInlinedAt() and return \a getScope() from the deepest
+ /// location.
+ DILocalScope *getInlinedAtScope() const {
+ if (auto *IA = getInlinedAt())
+ return IA->getInlinedAtScope();
+ return getScope();
+ }
+
+ /// \brief Check whether this can be discriminated from another location.
+ ///
+ /// Check \c this can be discriminated from \c RHS in a linetable entry.
+ /// Scope and inlined-at chains are not recorded in the linetable, so they
+ /// cannot be used to distinguish basic blocks.
+ ///
+ /// The current implementation is weaker than it should be, since it just
+ /// checks filename and line.
+ ///
+ /// FIXME: Add a check for getDiscriminator().
+ /// FIXME: Add a check for getColumn().
+ /// FIXME: Change the getFilename() check to getFile() (or add one for
+ /// getDirectory()).
+ bool canDiscriminate(const DILocation &RHS) const {
+ return getFilename() != RHS.getFilename() || getLine() != RHS.getLine();
+ }
+
+ /// \brief Get the DWARF discriminator.
+ ///
+ /// DWARF discriminators distinguish identical file locations between
+ /// instructions that are on different basic blocks.
+ inline unsigned getDiscriminator() const;
+
+ /// \brief Compute new discriminator in the given context.
+ ///
+ /// This modifies the \a LLVMContext that \c this is in to increment the next
+ /// discriminator for \c this's line/filename combination.
+ ///
+ /// FIXME: Delete this. See comments in implementation and at the only call
+ /// site in \a AddDiscriminators::runOnFunction().
+ unsigned computeNewDiscriminator() const;
+
+ Metadata *getRawScope() const { return getOperand(0); }
+ Metadata *getRawInlinedAt() const {
+ if (getNumOperands() == 2)
+ return getOperand(1);
+ return nullptr;
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILocationKind;
+ }
+};
+
+/// \brief Subprogram description.
+///
+/// TODO: Remove DisplayName. It's always equal to Name.
+/// TODO: Split up flags.
+class DISubprogram : public DILocalScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned ScopeLine;
+ unsigned Virtuality;
+ unsigned VirtualIndex;
+ unsigned Flags;
+ bool IsLocalToUnit;
+ bool IsDefinition;
+ bool IsOptimized;
+
+ DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
+ bool IsOptimized, ArrayRef<Metadata *> Ops)
+ : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram,
+ Ops),
+ Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
+ VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
+ IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
+ ~DISubprogram() = default;
+
+ static DISubprogram *
+ getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name,
+ StringRef LinkageName, DIFile *File, unsigned Line,
+ DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition,
+ unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Constant *Function, DITemplateParameterArray TemplateParams,
+ DISubprogram *Declaration, DILocalVariableArray Variables,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ getCanonicalMDString(Context, LinkageName), File, Line, Type,
+ IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
+ Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function ? ConstantAsMetadata::get(Function) : nullptr,
+ TemplateParams.get(), Declaration, Variables.get(), Storage,
+ ShouldCreate);
+ }
+ static DISubprogram *
+ getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
+ unsigned Flags, bool IsOptimized, Metadata *Function,
+ Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDISubprogram cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
+ getFile(), getLine(), getType(), isLocalToUnit(),
+ isDefinition(), getScopeLine(), getContainingType(),
+ getVirtuality(), getVirtualIndex(), getFlags(),
+ isOptimized(), getFunctionConstant(),
+ getTemplateParams(), getDeclaration(), getVariables());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DISubprogram,
+ (DIScopeRef Scope, StringRef Name, StringRef LinkageName,
+ DIFile *File, unsigned Line, DISubroutineType *Type,
+ bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
+ DITypeRef ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Constant *Function = nullptr,
+ DITemplateParameterArray TemplateParams = nullptr,
+ DISubprogram *Declaration = nullptr,
+ DILocalVariableArray Variables = nullptr),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables))
+ DEFINE_MDNODE_GET(
+ DISubprogram,
+ (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
+ unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
+ unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
+ unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
+ Metadata *Function = nullptr, Metadata *TemplateParams = nullptr,
+ Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function, TemplateParams, Declaration, Variables))
+
+ TempDISubprogram clone() const { return cloneImpl(); }
+
+public:
+ unsigned getLine() const { return Line; }
+ unsigned getVirtuality() const { return Virtuality; }
+ unsigned getVirtualIndex() const { return VirtualIndex; }
+ unsigned getScopeLine() const { return ScopeLine; }
+ unsigned getFlags() const { return Flags; }
+ bool isLocalToUnit() const { return IsLocalToUnit; }
+ bool isDefinition() const { return IsDefinition; }
+ bool isOptimized() const { return IsOptimized; }
+
+ unsigned isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isPrivate() const {
+ return (getFlags() & FlagAccessibility) == FlagPrivate;
+ }
+ bool isProtected() const {
+ return (getFlags() & FlagAccessibility) == FlagProtected;
+ }
+ bool isPublic() const {
+ return (getFlags() & FlagAccessibility) == FlagPublic;
+ }
+ bool isExplicit() const { return getFlags() & FlagExplicit; }
+ bool isPrototyped() const { return getFlags() & FlagPrototyped; }
+
+ /// \brief Check if this is reference-qualified.
+ ///
+ /// Return true if this subprogram is a C++11 reference-qualified non-static
+ /// member function (void foo() &).
+ unsigned isLValueReference() const {
+ return getFlags() & FlagLValueReference;
+ }
+
+ /// \brief Check if this is rvalue-reference-qualified.
+ ///
+ /// Return true if this subprogram is a C++11 rvalue-reference-qualified
+ /// non-static member function (void foo() &&).
+ unsigned isRValueReference() const {
+ return getFlags() & FlagRValueReference;
+ }
+
+ DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
+
+ StringRef getName() const { return getStringOperand(2); }
+ StringRef getDisplayName() const { return getStringOperand(3); }
+ StringRef getLinkageName() const { return getStringOperand(4); }
+
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
+
+ DISubroutineType *getType() const {
+ return cast_or_null<DISubroutineType>(getRawType());
+ }
+ DITypeRef getContainingType() const {
+ return DITypeRef(getRawContainingType());
+ }
+
+ Constant *getFunctionConstant() const {
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getRawFunction()))
+ return C->getValue();
+ return nullptr;
+ }
+ DITemplateParameterArray getTemplateParams() const {
+ return cast_or_null<MDTuple>(getRawTemplateParams());
+ }
+ DISubprogram *getDeclaration() const {
+ return cast_or_null<DISubprogram>(getRawDeclaration());
+ }
+ DILocalVariableArray getVariables() const {
+ return cast_or_null<MDTuple>(getRawVariables());
+ }
+
+ Metadata *getRawScope() const { return getOperand(1); }
+ Metadata *getRawType() const { return getOperand(5); }
+ Metadata *getRawContainingType() const { return getOperand(6); }
+ Metadata *getRawFunction() const { return getOperand(7); }
+ Metadata *getRawTemplateParams() const { return getOperand(8); }
+ Metadata *getRawDeclaration() const { return getOperand(9); }
+ Metadata *getRawVariables() const { return getOperand(10); }
+
+ /// \brief Get a pointer to the function this subprogram describes.
+ ///
+ /// This dyn_casts \a getFunctionConstant() to \a Function.
+ ///
+ /// FIXME: Should this be looking through bitcasts?
+ Function *getFunction() const;
+
+ /// \brief Replace the function.
+ ///
+ /// If \a isUniqued() and not \a isResolved(), this could node will be
+ /// RAUW'ed and deleted out from under the caller. Use a \a TrackingMDRef if
+ /// that's a problem.
+ /// @{
+ void replaceFunction(Function *F);
+ void replaceFunction(ConstantAsMetadata *MD) { replaceOperandWith(7, MD); }
+ void replaceFunction(std::nullptr_t) { replaceOperandWith(7, nullptr); }
+ /// @}
+
+ /// \brief Check if this subprogram decribes the given function.
+ ///
+ /// FIXME: Should this be looking through bitcasts?
+ bool describes(const Function *F) const;
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DISubprogramKind;
+ }
+};
+
+class DILexicalBlockBase : public DILocalScope {
+protected:
+ DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
+ ~DILexicalBlockBase() = default;
+
+public:
+ DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
+
+ Metadata *getRawScope() const { return getOperand(1); }
+
+ /// \brief Forwarding accessors to LexicalBlock.
+ ///
+ /// TODO: Remove these and update code to use \a DILexicalBlock directly.
+ /// @{
+ inline unsigned getLine() const;
+ inline unsigned getColumn() const;
+ /// @}
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILexicalBlockKind ||
+ MD->getMetadataID() == DILexicalBlockFileKind;
+ }
+};
+
+class DILexicalBlock : public DILexicalBlockBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned Column;
+
+ DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> Ops)
+ : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
+ Column(Column) {}
+ ~DILexicalBlock() = default;
+
+ static DILexicalBlock *getImpl(LLVMContext &Context, DILocalScope *Scope,
+ DIFile *File, unsigned Line, unsigned Column,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(File), Line, Column, Storage,
+ ShouldCreate);
+ }
+
+ static DILexicalBlock *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, unsigned Line, unsigned Column,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDILexicalBlock cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(), getLine(),
+ getColumn());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File,
+ unsigned Line, unsigned Column),
+ (Scope, File, Line, Column))
+ DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File,
+ unsigned Line, unsigned Column),
+ (Scope, File, Line, Column))
+
+ TempDILexicalBlock clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILexicalBlockKind;
+ }
+};
+
+unsigned DILexicalBlockBase::getLine() const {
+ if (auto *N = dyn_cast<DILexicalBlock>(this))
+ return N->getLine();
+ return 0;
+}
+
+unsigned DILexicalBlockBase::getColumn() const {
+ if (auto *N = dyn_cast<DILexicalBlock>(this))
+ return N->getColumn();
+ return 0;
+}
+
+class DILexicalBlockFile : public DILexicalBlockBase {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Discriminator;
+
+ DILexicalBlockFile(LLVMContext &C, StorageType Storage,
+ unsigned Discriminator, ArrayRef<Metadata *> Ops)
+ : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
+ Discriminator(Discriminator) {}
+ ~DILexicalBlockFile() = default;
+
+ static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
+ DIFile *File, unsigned Discriminator,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(File), Discriminator, Storage,
+ ShouldCreate);
+ }
+
+ static DILexicalBlockFile *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, unsigned Discriminator,
+ StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDILexicalBlockFile cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(),
+ getDiscriminator());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File,
+ unsigned Discriminator),
+ (Scope, File, Discriminator))
+ DEFINE_MDNODE_GET(DILexicalBlockFile,
+ (Metadata * Scope, Metadata *File, unsigned Discriminator),
+ (Scope, File, Discriminator))
+
+ TempDILexicalBlockFile clone() const { return cloneImpl(); }
+
+ // TODO: Remove these once they're gone from DILexicalBlockBase.
+ unsigned getLine() const = delete;
+ unsigned getColumn() const = delete;
+
+ unsigned getDiscriminator() const { return Discriminator; }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILexicalBlockFileKind;
+ }
+};
+
+unsigned DILocation::getDiscriminator() const {
+ if (auto *F = dyn_cast<DILexicalBlockFile>(getScope()))
+ return F->getDiscriminator();
+ return 0;
+}
+
+class DINamespace : public DIScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+
+ DINamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
+ ArrayRef<Metadata *> Ops)
+ : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
+ Ops),
+ Line(Line) {}
+ ~DINamespace() = default;
+
+ static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
+ DIFile *File, StringRef Name, unsigned Line,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
+ Line, Storage, ShouldCreate);
+ }
+ static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
+ Metadata *File, MDString *Name, unsigned Line,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDINamespace cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getFile(), getName(),
+ getLine());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DINamespace, (DIScope * Scope, DIFile *File, StringRef Name,
+ unsigned Line),
+ (Scope, File, Name, Line))
+ DEFINE_MDNODE_GET(DINamespace, (Metadata * Scope, Metadata *File,
+ MDString *Name, unsigned Line),
+ (Scope, File, Name, Line))
+
+ TempDINamespace clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
+ StringRef getName() const { return getStringOperand(2); }
+
+ Metadata *getRawScope() const { return getOperand(1); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DINamespaceKind;
+ }
+};
+
+/// \brief Base class for template parameters.
+class DITemplateParameter : public DINode {
+protected:
+ DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
+ unsigned Tag, ArrayRef<Metadata *> Ops)
+ : DINode(Context, ID, Storage, Tag, Ops) {}
+ ~DITemplateParameter() = default;
+
+public:
+ StringRef getName() const { return getStringOperand(0); }
+ DITypeRef getType() const { return DITypeRef(getRawType()); }
+
+ MDString *getRawName() const { return getOperandAs<MDString>(0); }
+ Metadata *getRawType() const { return getOperand(1); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DITemplateTypeParameterKind ||
+ MD->getMetadataID() == DITemplateValueParameterKind;
+ }
+};
+
+class DITemplateTypeParameter : public DITemplateParameter {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
+ ArrayRef<Metadata *> Ops)
+ : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
+ dwarf::DW_TAG_template_type_parameter, Ops) {}
+ ~DITemplateTypeParameter() = default;
+
+ static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
+ DITypeRef Type, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
+ ShouldCreate);
+ }
+ static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
+ Metadata *Type, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDITemplateTypeParameter cloneImpl() const {
+ return getTemporary(getContext(), getName(), getType());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DITypeRef Type),
+ (Name, Type))
+ DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
+ (Name, Type))
+
+ TempDITemplateTypeParameter clone() const { return cloneImpl(); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DITemplateTypeParameterKind;
+ }
+};
+
+class DITemplateValueParameter : public DITemplateParameter {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
+ unsigned Tag, ArrayRef<Metadata *> Ops)
+ : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
+ Ops) {}
+ ~DITemplateValueParameter() = default;
+
+ static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
+ StringRef Name, DITypeRef Type,
+ Metadata *Value, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
+ Value, Storage, ShouldCreate);
+ }
+ static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
+ MDString *Name, Metadata *Type,
+ Metadata *Value, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDITemplateValueParameter cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getName(), getType(),
+ getValue());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, StringRef Name,
+ DITypeRef Type, Metadata *Value),
+ (Tag, Name, Type, Value))
+ DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
+ Metadata *Type, Metadata *Value),
+ (Tag, Name, Type, Value))
+
+ TempDITemplateValueParameter clone() const { return cloneImpl(); }
+
+ Metadata *getValue() const { return getOperand(2); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DITemplateValueParameterKind;
+ }
+};
+
+/// \brief Base class for variables.
+///
+/// TODO: Hardcode to DW_TAG_variable.
+class DIVariable : public DINode {
+ unsigned Line;
+
+protected:
+ DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ unsigned Line, ArrayRef<Metadata *> Ops)
+ : DINode(C, ID, Storage, Tag, Ops), Line(Line) {}
+ ~DIVariable() = default;
+
+public:
+ unsigned getLine() const { return Line; }
+ DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
+ StringRef getName() const { return getStringOperand(1); }
+ DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
+ DITypeRef getType() const { return DITypeRef(getRawType()); }
+
+ StringRef getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+ }
+ StringRef getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+ }
+
+ Metadata *getRawScope() const { return getOperand(0); }
+ MDString *getRawName() const { return getOperandAs<MDString>(1); }
+ Metadata *getRawFile() const { return getOperand(2); }
+ Metadata *getRawType() const { return getOperand(3); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILocalVariableKind ||
+ MD->getMetadataID() == DIGlobalVariableKind;
+ }
+};
+
+/// \brief Global variables.
+///
+/// TODO: Remove DisplayName. It's always equal to Name.
+class DIGlobalVariable : public DIVariable {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ bool IsLocalToUnit;
+ bool IsDefinition;
+
+ DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
+ bool IsLocalToUnit, bool IsDefinition,
+ ArrayRef<Metadata *> Ops)
+ : DIVariable(C, DIGlobalVariableKind, Storage, dwarf::DW_TAG_variable,
+ Line, Ops),
+ IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
+ ~DIGlobalVariable() = default;
+
+ static DIGlobalVariable *
+ getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
+ StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
+ bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
+ DIDerivedType *StaticDataMemberDeclaration, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ getCanonicalMDString(Context, LinkageName), File, Line, Type,
+ IsLocalToUnit, IsDefinition,
+ Variable ? ConstantAsMetadata::get(Variable) : nullptr,
+ StaticDataMemberDeclaration, Storage, ShouldCreate);
+ }
+ static DIGlobalVariable *
+ getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
+ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIGlobalVariable cloneImpl() const {
+ return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
+ getFile(), getLine(), getType(), isLocalToUnit(),
+ isDefinition(), getVariable(),
+ getStaticDataMemberDeclaration());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIGlobalVariable,
+ (DIScope * Scope, StringRef Name, StringRef LinkageName,
+ DIFile *File, unsigned Line, DITypeRef Type,
+ bool IsLocalToUnit, bool IsDefinition, Constant *Variable,
+ DIDerivedType *StaticDataMemberDeclaration),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, Variable, StaticDataMemberDeclaration))
+ DEFINE_MDNODE_GET(DIGlobalVariable,
+ (Metadata * Scope, MDString *Name, MDString *LinkageName,
+ Metadata *File, unsigned Line, Metadata *Type,
+ bool IsLocalToUnit, bool IsDefinition, Metadata *Variable,
+ Metadata *StaticDataMemberDeclaration),
+ (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, Variable, StaticDataMemberDeclaration))
+
+ TempDIGlobalVariable clone() const { return cloneImpl(); }
+
+ bool isLocalToUnit() const { return IsLocalToUnit; }
+ bool isDefinition() const { return IsDefinition; }
+ StringRef getDisplayName() const { return getStringOperand(4); }
+ StringRef getLinkageName() const { return getStringOperand(5); }
+ Constant *getVariable() const {
+ if (auto *C = cast_or_null<ConstantAsMetadata>(getRawVariable()))
+ return dyn_cast<Constant>(C->getValue());
+ return nullptr;
+ }
+ DIDerivedType *getStaticDataMemberDeclaration() const {
+ return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
+ }
+
+ MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
+ Metadata *getRawVariable() const { return getOperand(6); }
+ Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(7); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIGlobalVariableKind;
+ }
+};
+
+/// \brief Local variable.
+///
+/// TODO: Split between arguments and otherwise.
+/// TODO: Use \c DW_TAG_variable instead of fake tags.
+/// TODO: Split up flags.
+class DILocalVariable : public DIVariable {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Arg;
+ unsigned Flags;
+
+ DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, unsigned Arg, unsigned Flags,
+ ArrayRef<Metadata *> Ops)
+ : DIVariable(C, DILocalVariableKind, Storage, Tag, Line, Ops), Arg(Arg),
+ Flags(Flags) {}
+ ~DILocalVariable() = default;
+
+ static DILocalVariable *getImpl(LLVMContext &Context, unsigned Tag,
+ DIScope *Scope, StringRef Name, DIFile *File,
+ unsigned Line, DITypeRef Type, unsigned Arg,
+ unsigned Flags, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, Scope, getCanonicalMDString(Context, Name),
+ File, Line, Type, Arg, Flags, Storage, ShouldCreate);
+ }
+ static DILocalVariable *
+ getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type, unsigned Arg,
+ unsigned Flags, StorageType Storage, bool ShouldCreate = true);
+
+ TempDILocalVariable cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getScope(), getName(),
+ getFile(), getLine(), getType(), getArg(), getFlags());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DILocalVariable,
+ (unsigned Tag, DILocalScope *Scope, StringRef Name,
+ DIFile *File, unsigned Line, DITypeRef Type, unsigned Arg,
+ unsigned Flags),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags))
+ DEFINE_MDNODE_GET(DILocalVariable,
+ (unsigned Tag, Metadata *Scope, MDString *Name,
+ Metadata *File, unsigned Line, Metadata *Type,
+ unsigned Arg, unsigned Flags),
+ (Tag, Scope, Name, File, Line, Type, Arg, Flags))
+
+ TempDILocalVariable clone() const { return cloneImpl(); }
+
+ /// \brief Get the local scope for this variable.
+ ///
+ /// Variables must be defined in a local scope.
+ DILocalScope *getScope() const {
+ return cast<DILocalScope>(DIVariable::getScope());
+ }
+
+ unsigned getArg() const { return Arg; }
+ unsigned getFlags() const { return Flags; }
+
+ bool isArtificial() const { return getFlags() & FlagArtificial; }
+ bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
+
+ /// \brief Check that a location is valid for this variable.
+ ///
+ /// Check that \c DL exists, is in the same subprogram, and has the same
+ /// inlined-at location as \c this. (Otherwise, it's not a valid attachemnt
+ /// to a \a DbgInfoIntrinsic.)
+ bool isValidLocationForIntrinsic(const DILocation *DL) const {
+ return DL && getScope()->getSubprogram() == DL->getScope()->getSubprogram();
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DILocalVariableKind;
+ }
+};
+
+/// \brief DWARF expression.
+///
+/// This is (almost) a DWARF expression that modifies the location of a
+/// variable or (or the location of a single piece of a variable).
+///
+/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
+/// and have DW_OP_plus consume the topmost elements on the stack.
+///
+/// TODO: Co-allocate the expression elements.
+/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
+/// storage types.
+class DIExpression : public MDNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ std::vector<uint64_t> Elements;
+
+ DIExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
+ : MDNode(C, DIExpressionKind, Storage, None),
+ Elements(Elements.begin(), Elements.end()) {}
+ ~DIExpression() = default;
+
+ static DIExpression *getImpl(LLVMContext &Context,
+ ArrayRef<uint64_t> Elements, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIExpression cloneImpl() const {
+ return getTemporary(getContext(), getElements());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIExpression, (ArrayRef<uint64_t> Elements), (Elements))
+
+ TempDIExpression clone() const { return cloneImpl(); }
+
+ ArrayRef<uint64_t> getElements() const { return Elements; }
+
+ unsigned getNumElements() const { return Elements.size(); }
+ uint64_t getElement(unsigned I) const {
+ assert(I < Elements.size() && "Index out of range");
+ return Elements[I];
+ }
+
+ /// \brief Return whether this is a piece of an aggregate variable.
+ bool isBitPiece() const;
+
+ /// \brief Return the offset of this piece in bits.
+ uint64_t getBitPieceOffset() const;
+
+ /// \brief Return the size of this piece in bits.
+ uint64_t getBitPieceSize() const;
+
+ typedef ArrayRef<uint64_t>::iterator element_iterator;
+ element_iterator elements_begin() const { return getElements().begin(); }
+ element_iterator elements_end() const { return getElements().end(); }
+
+ /// \brief A lightweight wrapper around an expression operand.
+ ///
+ /// TODO: Store arguments directly and change \a DIExpression to store a
+ /// range of these.
+ class ExprOperand {
+ const uint64_t *Op;
+
+ public:
+ explicit ExprOperand(const uint64_t *Op) : Op(Op) {}
+
+ const uint64_t *get() const { return Op; }
+
+ /// \brief Get the operand code.
+ uint64_t getOp() const { return *Op; }
+
+ /// \brief Get an argument to the operand.
+ ///
+ /// Never returns the operand itself.
+ uint64_t getArg(unsigned I) const { return Op[I + 1]; }
+
+ unsigned getNumArgs() const { return getSize() - 1; }
+
+ /// \brief Return the size of the operand.
+ ///
+ /// Return the number of elements in the operand (1 + args).
+ unsigned getSize() const;
+ };
+
+ /// \brief An iterator for expression operands.
+ class expr_op_iterator
+ : public std::iterator<std::input_iterator_tag, ExprOperand> {
+ ExprOperand Op;
+
+ public:
+ explicit expr_op_iterator(element_iterator I) : Op(I) {}
+
+ element_iterator getBase() const { return Op.get(); }
+ const ExprOperand &operator*() const { return Op; }
+ const ExprOperand *operator->() const { return &Op; }
+
+ expr_op_iterator &operator++() {
+ increment();
+ return *this;
+ }
+ expr_op_iterator operator++(int) {
+ expr_op_iterator T(*this);
+ increment();
+ return T;
+ }
+
+ /// \brief Get the next iterator.
+ ///
+ /// \a std::next() doesn't work because this is technically an
+ /// input_iterator, but it's a perfectly valid operation. This is an
+ /// accessor to provide the same functionality.
+ expr_op_iterator getNext() const { return ++expr_op_iterator(*this); }
+
+ bool operator==(const expr_op_iterator &X) const {
+ return getBase() == X.getBase();
+ }
+ bool operator!=(const expr_op_iterator &X) const {
+ return getBase() != X.getBase();
+ }
+
+ private:
+ void increment() { Op = ExprOperand(getBase() + Op.getSize()); }
+ };
+
+ /// \brief Visit the elements via ExprOperand wrappers.
+ ///
+ /// These range iterators visit elements through \a ExprOperand wrappers.
+ /// This is not guaranteed to be a valid range unless \a isValid() gives \c
+ /// true.
+ ///
+ /// \pre \a isValid() gives \c true.
+ /// @{
+ expr_op_iterator expr_op_begin() const {
+ return expr_op_iterator(elements_begin());
+ }
+ expr_op_iterator expr_op_end() const {
+ return expr_op_iterator(elements_end());
+ }
+ /// @}
+
+ bool isValid() const;
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIExpressionKind;
+ }
+};
+
+class DIObjCProperty : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+ unsigned Attributes;
+
+ DIObjCProperty(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Attributes, ArrayRef<Metadata *> Ops)
+ : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property,
+ Ops),
+ Line(Line), Attributes(Attributes) {}
+ ~DIObjCProperty() = default;
+
+ static DIObjCProperty *
+ getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
+ StringRef GetterName, StringRef SetterName, unsigned Attributes,
+ DIType *Type, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
+ getCanonicalMDString(Context, GetterName),
+ getCanonicalMDString(Context, SetterName), Attributes, Type,
+ Storage, ShouldCreate);
+ }
+ static DIObjCProperty *getImpl(LLVMContext &Context, MDString *Name,
+ Metadata *File, unsigned Line,
+ MDString *GetterName, MDString *SetterName,
+ unsigned Attributes, Metadata *Type,
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempDIObjCProperty cloneImpl() const {
+ return getTemporary(getContext(), getName(), getFile(), getLine(),
+ getGetterName(), getSetterName(), getAttributes(),
+ getType());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIObjCProperty,
+ (StringRef Name, DIFile *File, unsigned Line,
+ StringRef GetterName, StringRef SetterName,
+ unsigned Attributes, DIType *Type),
+ (Name, File, Line, GetterName, SetterName, Attributes,
+ Type))
+ DEFINE_MDNODE_GET(DIObjCProperty,
+ (MDString * Name, Metadata *File, unsigned Line,
+ MDString *GetterName, MDString *SetterName,
+ unsigned Attributes, Metadata *Type),
+ (Name, File, Line, GetterName, SetterName, Attributes,
+ Type))
+
+ TempDIObjCProperty clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ unsigned getAttributes() const { return Attributes; }
+ StringRef getName() const { return getStringOperand(0); }
+ DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
+ StringRef getGetterName() const { return getStringOperand(2); }
+ StringRef getSetterName() const { return getStringOperand(3); }
+
+ /// \brief Get the type.
+ ///
+ /// \note Objective-C doesn't have an ODR, so there is no benefit in storing
+ /// a type ref here.
+ DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
+
+ StringRef getFilename() const {
+ if (auto *F = getFile())
+ return F->getFilename();
+ return "";
+ }
+ StringRef getDirectory() const {
+ if (auto *F = getFile())
+ return F->getDirectory();
+ return "";
+ }
+
+ MDString *getRawName() const { return getOperandAs<MDString>(0); }
+ Metadata *getRawFile() const { return getOperand(1); }
+ MDString *getRawGetterName() const { return getOperandAs<MDString>(2); }
+ MDString *getRawSetterName() const { return getOperandAs<MDString>(3); }
+ Metadata *getRawType() const { return getOperand(4); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIObjCPropertyKind;
+ }
+};
+
+/// \brief An imported module (C++ using directive or similar).
+class DIImportedEntity : public DINode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ unsigned Line;
+
+ DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
+ unsigned Line, ArrayRef<Metadata *> Ops)
+ : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
+ ~DIImportedEntity() = default;
+
+ static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+ DIScope *Scope, DINodeRef Entity,
+ unsigned Line, StringRef Name,
+ StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Tag, Scope, Entity, Line,
+ getCanonicalMDString(Context, Name), Storage, ShouldCreate);
+ }
+ static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
+ Metadata *Scope, Metadata *Entity,
+ unsigned Line, MDString *Name,
+ StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempDIImportedEntity cloneImpl() const {
+ return getTemporary(getContext(), getTag(), getScope(), getEntity(),
+ getLine(), getName());
+ }
+
+public:
+ DEFINE_MDNODE_GET(DIImportedEntity,
+ (unsigned Tag, DIScope *Scope, DINodeRef Entity,
+ unsigned Line, StringRef Name = ""),
+ (Tag, Scope, Entity, Line, Name))
+ DEFINE_MDNODE_GET(DIImportedEntity,
+ (unsigned Tag, Metadata *Scope, Metadata *Entity,
+ unsigned Line, MDString *Name),
+ (Tag, Scope, Entity, Line, Name))
+
+ TempDIImportedEntity clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return Line; }
+ DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
+ DINodeRef getEntity() const { return DINodeRef(getRawEntity()); }
+ StringRef getName() const { return getStringOperand(2); }
+
+ Metadata *getRawScope() const { return getOperand(0); }
+ Metadata *getRawEntity() const { return getOperand(1); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == DIImportedEntityKind;
+ }
+};
+
+} // end namespace llvm
+
+#undef DEFINE_MDNODE_GET_UNPACK_IMPL
+#undef DEFINE_MDNODE_GET_UNPACK
+#undef DEFINE_MDNODE_GET
+
+#endif
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index 86e64417099d..8ea5875e1f85 100644
--- a/include/llvm/IR/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -22,11 +22,15 @@ namespace llvm {
class LLVMContext;
class raw_ostream;
- class MDNode;
-
- /// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
- /// and MachineInstr to compactly encode file/line/scope information for an
- /// operation.
+ class DILocation;
+
+ /// \brief A debug info location.
+ ///
+ /// This class is a wrapper around a tracking reference to an \a DILocation
+ /// pointer.
+ ///
+ /// To avoid extra includes, \a DebugLoc doubles the \a DILocation API with a
+ /// one based on relatively opaque \a MDNode pointers.
class DebugLoc {
TrackingMDNodeRef Loc;
@@ -43,67 +47,78 @@ namespace llvm {
return *this;
}
+ /// \brief Construct from an \a DILocation.
+ DebugLoc(const DILocation *L);
+
+ /// \brief Construct from an \a MDNode.
+ ///
+ /// Note: if \c N is not an \a DILocation, a verifier check will fail, and
+ /// accessors will crash. However, construction from other nodes is
+ /// supported in order to handle forward references when reading textual
+ /// IR.
+ explicit DebugLoc(const MDNode *N);
+
+ /// \brief Get the underlying \a DILocation.
+ ///
+ /// \pre !*this or \c isa<DILocation>(getAsMDNode()).
+ /// @{
+ DILocation *get() const;
+ operator DILocation *() const { return get(); }
+ DILocation *operator->() const { return get(); }
+ DILocation &operator*() const { return *get(); }
+ /// @}
+
+ /// \brief Check for null.
+ ///
+ /// Check for null in a way that is safe with broken debug info. Unlike
+ /// the conversion to \c DILocation, this doesn't require that \c Loc is of
+ /// the right type. Important for cases like \a llvm::StripDebugInfo() and
+ /// \a Instruction::hasMetadata().
+ explicit operator bool() const { return Loc; }
+
/// \brief Check whether this has a trivial destructor.
bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }
- /// get - Get a new DebugLoc that corresponds to the specified line/col
- /// scope/inline location.
- static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope,
- MDNode *InlinedAt = nullptr);
-
- /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
- static DebugLoc getFromDILocation(MDNode *N);
-
- /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
- static DebugLoc getFromDILexicalBlock(MDNode *N);
-
- /// isUnknown - Return true if this is an unknown location.
- bool isUnknown() const { return !Loc; }
+ /// \brief Create a new DebugLoc.
+ ///
+ /// Create a new DebugLoc at the specified line/col and scope/inline. This
+ /// forwards to \a DILocation::get().
+ ///
+ /// If \c !Scope, returns a default-constructed \a DebugLoc.
+ ///
+ /// FIXME: Remove this. Users should use DILocation::get().
+ static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
+ const MDNode *InlinedAt = nullptr);
unsigned getLine() const;
unsigned getCol() const;
-
- /// getScope - This returns the scope pointer for this DebugLoc, or null if
- /// invalid.
MDNode *getScope() const;
- MDNode *getScope(const LLVMContext &) const { return getScope(); }
-
- /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
- /// null if invalid or not present.
- MDNode *getInlinedAt() const;
- MDNode *getInlinedAt(const LLVMContext &) const { return getInlinedAt(); }
-
- /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
- void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const;
- void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
- const LLVMContext &) const {
- return getScopeAndInlinedAt(Scope, IA);
- }
-
- /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
- MDNode *getScopeNode() const;
- MDNode *getScopeNode(const LLVMContext &) const { return getScopeNode(); }
-
- // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
- // number info for the function.
+ DILocation *getInlinedAt() const;
+
+ /// \brief Get the fully inlined-at scope for a DebugLoc.
+ ///
+ /// Gets the inlined-at scope for a DebugLoc.
+ MDNode *getInlinedAtScope() const;
+
+ /// \brief Find the debug info location for the start of the function.
+ ///
+ /// Walk up the scope chain of given debug loc and find line number info
+ /// for the function.
+ ///
+ /// FIXME: Remove this. Users should use DILocation/DILocalScope API to
+ /// find the subprogram, and then DILocation::get().
DebugLoc getFnDebugLoc() const;
- DebugLoc getFnDebugLoc(const LLVMContext &) const {
- return getFnDebugLoc();
- }
- /// getAsMDNode - This method converts the compressed DebugLoc node into a
- /// DILocation compatible MDNode.
- MDNode *getAsMDNode() const;
- MDNode *getAsMDNode(LLVMContext &) const { return getAsMDNode(); }
+ /// \brief Return \c this as a bar \a MDNode.
+ MDNode *getAsMDNode() const { return Loc; }
bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }
- bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
+ bool operator!=(const DebugLoc &DL) const { return Loc != DL.Loc; }
void dump() const;
- void dump(const LLVMContext &) const { dump(); }
+
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]
void print(raw_ostream &OS) const;
- void print(const LLVMContext &, raw_ostream &OS) const { print(OS); }
};
} // end namespace llvm
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index 182015c98aa2..38f1af0d70da 100644
--- a/include/llvm/IR/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -94,8 +94,8 @@ public:
/// FunctionType - Class to represent function types
///
class FunctionType : public Type {
- FunctionType(const FunctionType &) LLVM_DELETED_FUNCTION;
- const FunctionType &operator=(const FunctionType &) LLVM_DELETED_FUNCTION;
+ FunctionType(const FunctionType &) = delete;
+ const FunctionType &operator=(const FunctionType &) = delete;
FunctionType(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
public:
@@ -188,8 +188,8 @@ public:
/// generator for a target expects).
///
class StructType : public CompositeType {
- StructType(const StructType &) LLVM_DELETED_FUNCTION;
- const StructType &operator=(const StructType &) LLVM_DELETED_FUNCTION;
+ StructType(const StructType &) = delete;
+ const StructType &operator=(const StructType &) = delete;
StructType(LLVMContext &C)
: CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {}
enum {
@@ -308,8 +308,8 @@ public:
///
class SequentialType : public CompositeType {
Type *ContainedType; ///< Storage for the single contained type.
- SequentialType(const SequentialType &) LLVM_DELETED_FUNCTION;
- const SequentialType &operator=(const SequentialType &) LLVM_DELETED_FUNCTION;
+ SequentialType(const SequentialType &) = delete;
+ const SequentialType &operator=(const SequentialType &) = delete;
protected:
SequentialType(TypeID TID, Type *ElType)
@@ -335,8 +335,8 @@ public:
class ArrayType : public SequentialType {
uint64_t NumElements;
- ArrayType(const ArrayType &) LLVM_DELETED_FUNCTION;
- const ArrayType &operator=(const ArrayType &) LLVM_DELETED_FUNCTION;
+ ArrayType(const ArrayType &) = delete;
+ const ArrayType &operator=(const ArrayType &) = delete;
ArrayType(Type *ElType, uint64_t NumEl);
public:
/// ArrayType::get - This static method is the primary way to construct an
@@ -361,8 +361,8 @@ public:
class VectorType : public SequentialType {
unsigned NumElements;
- VectorType(const VectorType &) LLVM_DELETED_FUNCTION;
- const VectorType &operator=(const VectorType &) LLVM_DELETED_FUNCTION;
+ VectorType(const VectorType &) = delete;
+ const VectorType &operator=(const VectorType &) = delete;
VectorType(Type *ElType, unsigned NumEl);
public:
/// VectorType::get - This static method is the primary way to construct an
@@ -446,8 +446,8 @@ public:
/// PointerType - Class to represent pointers.
///
class PointerType : public SequentialType {
- PointerType(const PointerType &) LLVM_DELETED_FUNCTION;
- const PointerType &operator=(const PointerType &) LLVM_DELETED_FUNCTION;
+ PointerType(const PointerType &) = delete;
+ const PointerType &operator=(const PointerType &) = delete;
explicit PointerType(Type *ElType, unsigned AddrSpace);
public:
/// PointerType::get - This constructs a pointer to an object of the specified
@@ -464,6 +464,9 @@ public:
/// element type.
static bool isValidElementType(Type *ElemTy);
+ /// Return true if we can load or store from a pointer to this type.
+ static bool isLoadableOrStorableType(Type *ElemTy);
+
/// @brief Return the address space of the Pointer type.
inline unsigned getAddressSpace() const { return getSubclassData(); }
diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
index c6a8854e0774..6db5a40c5772 100644
--- a/include/llvm/IR/DiagnosticInfo.h
+++ b/include/llvm/IR/DiagnosticInfo.h
@@ -20,6 +20,7 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
+#include <functional>
namespace llvm {
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 51403281e964..6c228eae633a 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -19,6 +19,7 @@
#define LLVM_IR_FUNCTION_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -31,26 +32,6 @@ namespace llvm {
class FunctionType;
class LLVMContext;
-// Traits for intrusive list of basic blocks...
-template<> struct ilist_traits<BasicBlock>
- : public SymbolTableListTraits<BasicBlock, Function> {
-
- // createSentinel is used to get hold of the node that marks the end of the
- // list... (same trick used here as in ilist_traits<Instruction>)
- BasicBlock *createSentinel() const {
- return static_cast<BasicBlock*>(&Sentinel);
- }
- static void destroySentinel(BasicBlock*) {}
-
- BasicBlock *provideInitialHead() const { return createSentinel(); }
- BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
- static void noteHead(BasicBlock*, BasicBlock*) {}
-
- static ValueSymbolTable *getSymTab(Function *ItemParent);
-private:
- mutable ilist_half_node<BasicBlock> Sentinel;
-};
-
template<> struct ilist_traits<Argument>
: public SymbolTableListTraits<Argument, Function> {
@@ -86,6 +67,7 @@ private:
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
AttributeSet AttributeSets; ///< Parameter attributes
+ FunctionType *Ty;
/*
* Value::SubclassData
@@ -96,6 +78,17 @@ private:
* bit 3-6: CallingConvention
*/
+ /// Bits from GlobalObject::GlobalObjectSubclassData.
+ enum {
+ /// Whether this function is materializable.
+ IsMaterializableBit = 1 << 0,
+ HasMetadataHashEntryBit = 1 << 1
+ };
+ void setGlobalObjectBit(unsigned Mask, bool Value) {
+ setGlobalObjectSubClassData((~Mask & getGlobalObjectSubClassData()) |
+ (Value ? Mask : 0u));
+ }
+
friend class SymbolTableListTraits<Function, Module>;
void setParent(Module *parent);
@@ -113,12 +106,8 @@ private:
}
void BuildLazyArguments() const;
- Function(const Function&) LLVM_DELETED_FUNCTION;
- void operator=(const Function&) LLVM_DELETED_FUNCTION;
-
- /// Do the actual lookup of an intrinsic ID when the query could not be
- /// answered from the cache.
- unsigned lookupIntrinsicID() const LLVM_READONLY;
+ Function(const Function&) = delete;
+ void operator=(const Function&) = delete;
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
@@ -133,13 +122,13 @@ public:
return new(0) Function(Ty, Linkage, N, M);
}
- ~Function();
+ ~Function() override;
Type *getReturnType() const; // Return the type of the ret val
FunctionType *getFunctionType() const; // Return the FunctionType for me
- /// getContext - Return a pointer to the LLVMContext associated with this
- /// function, or NULL if this function is not bound to a context yet.
+ /// getContext - Return a reference to the LLVMContext associated with this
+ /// function.
LLVMContext &getContext() const;
/// isVarArg - Return true if this function takes a variable number of
@@ -154,13 +143,17 @@ public:
/// intrinsic, or if the pointer is null. This value is always defined to be
/// zero to allow easy checking for whether a function is intrinsic or not.
/// The particular intrinsic functions which correspond to this value are
- /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context,
- /// subsequent requests for the same ID return results much faster from the
- /// cache.
- ///
- unsigned getIntrinsicID() const LLVM_READONLY;
+ /// defined in llvm/Intrinsics.h.
+ Intrinsic::ID getIntrinsicID() const LLVM_READONLY { return IntID; }
bool isIntrinsic() const { return getName().startswith("llvm."); }
+ /// \brief Recalculate the ID for this function if it is an Intrinsic defined
+ /// in llvm/Intrinsics.h. Sets the intrinsic ID to Intrinsic::not_intrinsic
+ /// if the name of this function does not match an intrinsic in that header.
+ /// Note, this method does not need to be called directly, as it is called
+ /// from Value::setName() whenever the name of this function changes.
+ void recalculateIntrinsicID();
+
/// getCallingConv()/setCallingConv(CC) - These method get and set the
/// calling convention of this function. The enum values for the known
/// calling conventions are defined in CallingConv.h.
@@ -202,6 +195,12 @@ public:
AttributeSet::FunctionIndex, Kind, Value));
}
+ /// Set the entry count for this function.
+ void setEntryCount(uint64_t Count);
+
+ /// Get the entry count for this function.
+ Optional<uint64_t> getEntryCount() const;
+
/// @brief Return true if the function has the attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
@@ -218,6 +217,11 @@ public:
return AttributeSets.getAttribute(AttributeSet::FunctionIndex, Kind);
}
+ /// \brief Return the stack alignment for the function.
+ unsigned getFnStackAlignment() const {
+ return AttributeSets.getStackAlignment(AttributeSet::FunctionIndex);
+ }
+
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
/// to use during code generation.
bool hasGC() const;
@@ -234,6 +238,13 @@ public:
/// @brief removes the attributes from the list of attributes.
void removeAttributes(unsigned i, AttributeSet attr);
+ /// @brief adds the dereferenceable attribute to the list of attributes.
+ void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+
+ /// @brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
return AttributeSets.getParamAlignment(i);
@@ -244,7 +255,13 @@ public:
uint64_t getDereferenceableBytes(unsigned i) const {
return AttributeSets.getDereferenceableBytes(i);
}
-
+
+ /// @brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned i) const {
+ return AttributeSets.getDereferenceableOrNullBytes(i);
+ }
+
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
@@ -291,6 +308,16 @@ public:
addFnAttr(Attribute::NoDuplicate);
}
+ /// @brief Determine if the call is convergent.
+ bool isConvergent() const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::Convergent);
+ }
+ void setConvergent() {
+ addFnAttr(Attribute::Convergent);
+ }
+
+
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
@@ -464,6 +491,10 @@ public:
Constant *getPrologueData() const;
void setPrologueData(Constant *PrologueData);
+ /// Print the function to an output stream with an optional
+ /// AssemblyAnnotationWriter.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr) const;
+
/// viewCFG - This function is meant for use from the debugger. You can just
/// say 'call F->viewCFG()' and a ghostview window should pop up from the
/// program, displaying the CFG of the current function with the code for each
@@ -514,12 +545,50 @@ public:
/// setjmp or other function that gcc recognizes as "returning twice".
bool callsFunctionThatReturnsTwice() const;
+ /// \brief Check if this has any metadata.
+ bool hasMetadata() const { return hasMetadataHashEntry(); }
+
+ /// \brief Get the current metadata attachment, if any.
+ ///
+ /// Returns \c nullptr if such an attachment is missing.
+ /// @{
+ MDNode *getMetadata(unsigned KindID) const;
+ MDNode *getMetadata(StringRef Kind) const;
+ /// @}
+
+ /// \brief Set a particular kind of metadata attachment.
+ ///
+ /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or
+ /// replacing it if it already exists.
+ /// @{
+ void setMetadata(unsigned KindID, MDNode *MD);
+ void setMetadata(StringRef Kind, MDNode *MD);
+ /// @}
+
+ /// \brief Get all current metadata attachments.
+ void
+ getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const;
+
+ /// \brief Drop metadata not in the given list.
+ ///
+ /// Drop all metadata from \c this not included in \c KnownIDs.
+ void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
+
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) {
Value::setValueSubclassData(D);
}
+
+ bool hasMetadataHashEntry() const {
+ return getGlobalObjectSubClassData() & HasMetadataHashEntryBit;
+ }
+ void setHasMetadataHashEntry(bool HasEntry) {
+ setGlobalObjectBit(HasMetadataHashEntryBit, HasEntry);
+ }
+
+ void clearMetadata();
};
inline ValueSymbolTable *
diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index 6f57dc2a98a6..1d6c9157f0b8 100644
--- a/include/llvm/IR/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -47,11 +47,14 @@ public:
/// lazily. If the Materializer doesn't support this capability, this method
/// is a noop.
///
- virtual void Dematerialize(GlobalValue *) {}
+ virtual void dematerialize(GlobalValue *) {}
/// Make sure the entire Module has been completely read.
///
- virtual std::error_code MaterializeModule(Module *M) = 0;
+ virtual std::error_code materializeModule(Module *M) = 0;
+
+ virtual std::error_code materializeMetadata() = 0;
+ virtual void setStripDebugInfo() = 0;
virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0;
};
diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h
index dcf8e64dbb27..6bba0ae29e98 100644
--- a/include/llvm/IR/GetElementPtrTypeIterator.h
+++ b/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -16,7 +16,9 @@
#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/User.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace llvm {
template<typename ItTy = User::const_op_iterator>
@@ -26,19 +28,28 @@ namespace llvm {
Type *, ptrdiff_t> super;
ItTy OpIt;
- Type *CurTy;
+ PointerIntPair<Type *, 1> CurTy;
+ unsigned AddrSpace;
generic_gep_type_iterator() {}
public:
static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
generic_gep_type_iterator I;
- I.CurTy = Ty;
+ I.CurTy.setPointer(Ty);
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator begin(Type *Ty, unsigned AddrSpace,
+ ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy.setPointer(Ty);
+ I.CurTy.setInt(true);
+ I.AddrSpace = AddrSpace;
I.OpIt = It;
return I;
}
static generic_gep_type_iterator end(ItTy It) {
generic_gep_type_iterator I;
- I.CurTy = nullptr;
I.OpIt = It;
return I;
}
@@ -51,11 +62,15 @@ namespace llvm {
}
Type *operator*() const {
- return CurTy;
+ if (CurTy.getInt())
+ return CurTy.getPointer()->getPointerTo(AddrSpace);
+ return CurTy.getPointer();
}
Type *getIndexedType() const {
- CompositeType *CT = cast<CompositeType>(CurTy);
+ if (CurTy.getInt())
+ return CurTy.getPointer();
+ CompositeType *CT = cast<CompositeType>(CurTy.getPointer());
return CT->getTypeAtIndex(getOperand());
}
@@ -66,10 +81,13 @@ namespace llvm {
Value *getOperand() const { return *OpIt; }
generic_gep_type_iterator& operator++() { // Preincrement
- if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
- CurTy = CT->getTypeAtIndex(getOperand());
+ if (CurTy.getInt()) {
+ CurTy.setInt(false);
+ } else if (CompositeType *CT =
+ dyn_cast<CompositeType>(CurTy.getPointer())) {
+ CurTy.setPointer(CT->getTypeAtIndex(getOperand()));
} else {
- CurTy = nullptr;
+ CurTy.setPointer(nullptr);
}
++OpIt;
return *this;
@@ -83,15 +101,23 @@ namespace llvm {
typedef generic_gep_type_iterator<> gep_type_iterator;
inline gep_type_iterator gep_type_begin(const User *GEP) {
- return gep_type_iterator::begin
- (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
+ auto *GEPOp = cast<GEPOperator>(GEP);
+ return gep_type_iterator::begin(
+ GEPOp->getSourceElementType(),
+ cast<PointerType>(GEPOp->getPointerOperandType()->getScalarType())
+ ->getAddressSpace(),
+ GEP->op_begin() + 1);
}
inline gep_type_iterator gep_type_end(const User *GEP) {
return gep_type_iterator::end(GEP->op_end());
}
inline gep_type_iterator gep_type_begin(const User &GEP) {
- return gep_type_iterator::begin
- (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
+ auto &GEPOp = cast<GEPOperator>(GEP);
+ return gep_type_iterator::begin(
+ GEPOp.getSourceElementType(),
+ cast<PointerType>(GEPOp.getPointerOperandType()->getScalarType())
+ ->getAddressSpace(),
+ GEP.op_begin() + 1);
}
inline gep_type_iterator gep_type_end(const User &GEP) {
return gep_type_iterator::end(GEP.op_end());
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index 075b5703bccf..ce73b7af8ca1 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -28,13 +28,13 @@ template<typename ValueSubClass, typename ItemParentClass>
class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
friend class SymbolTableListTraits<GlobalAlias, Module>;
- void operator=(const GlobalAlias &) LLVM_DELETED_FUNCTION;
- GlobalAlias(const GlobalAlias &) LLVM_DELETED_FUNCTION;
+ void operator=(const GlobalAlias &) = delete;
+ GlobalAlias(const GlobalAlias &) = delete;
void setParent(Module *parent);
- GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
- const Twine &Name, Constant *Aliasee, Module *Parent);
+ GlobalAlias(PointerType *Ty, LinkageTypes Linkage, const Twine &Name,
+ Constant *Aliasee, Module *Parent);
public:
// allocate space for exactly one operand
@@ -44,19 +44,17 @@ public:
/// If a parent module is specified, the alias is automatically inserted into
/// the end of the specified module's alias list.
- static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
- LinkageTypes Linkage, const Twine &Name,
- Constant *Aliasee, Module *Parent);
+ static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage,
+ const Twine &Name, Constant *Aliasee,
+ Module *Parent);
// Without the Aliasee.
- static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
- LinkageTypes Linkage, const Twine &Name,
- Module *Parent);
+ static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage,
+ const Twine &Name, Module *Parent);
// The module is taken from the Aliasee.
- static GlobalAlias *create(Type *Ty, unsigned AddressSpace,
- LinkageTypes Linkage, const Twine &Name,
- GlobalValue *Aliasee);
+ static GlobalAlias *create(PointerType *Ty, LinkageTypes Linkage,
+ const Twine &Name, GlobalValue *Aliasee);
// Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(LinkageTypes Linkage, const Twine &Name,
diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h
index 546fea2dfa9b..f0552410b61d 100644
--- a/include/llvm/IR/GlobalObject.h
+++ b/include/llvm/IR/GlobalObject.h
@@ -24,10 +24,10 @@ class Comdat;
class Module;
class GlobalObject : public GlobalValue {
- GlobalObject(const GlobalObject &) LLVM_DELETED_FUNCTION;
+ GlobalObject(const GlobalObject &) = delete;
protected:
- GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+ GlobalObject(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
: GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name), ObjComdat(nullptr) {
setGlobalValueSubClassData(0);
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index d0f7e9a11790..1dfe0c28b02c 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -28,8 +28,12 @@ class Comdat;
class PointerType;
class Module;
+namespace Intrinsic {
+ enum ID : unsigned;
+}
+
class GlobalValue : public Constant {
- GlobalValue(const GlobalValue &) LLVM_DELETED_FUNCTION;
+ GlobalValue(const GlobalValue &) = delete;
public:
/// @brief An enumeration for the kinds of linkage for global values.
enum LinkageTypes {
@@ -61,12 +65,12 @@ public:
};
protected:
- GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
+ GlobalValue(PointerType *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
LinkageTypes Linkage, const Twine &Name)
: Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage),
Visibility(DefaultVisibility), UnnamedAddr(0),
DllStorageClass(DefaultStorageClass),
- ThreadLocal(NotThreadLocal), Parent(nullptr) {
+ ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) {
setName(Name);
}
@@ -84,7 +88,16 @@ private:
// Give subclasses access to what otherwise would be wasted padding.
// (19 + 3 + 2 + 1 + 2 + 5) == 32.
unsigned SubClassData : 19;
+
protected:
+ /// \brief The intrinsic ID for this subclass (which must be a Function).
+ ///
+ /// This member is defined by this class, but not used for anything.
+ /// Subclasses can use it to store their intrinsic ID, if they have one.
+ ///
+ /// This is stored here to save space in Function on 64-bit hosts.
+ Intrinsic::ID IntID;
+
static const unsigned GlobalValueSubClassDataBits = 19;
unsigned getGlobalValueSubClassData() const {
return SubClassData;
@@ -104,7 +117,7 @@ public:
LocalExecTLSModel
};
- ~GlobalValue() {
+ ~GlobalValue() override {
removeDeadConstantUsers(); // remove any dead constants using this.
}
@@ -165,9 +178,9 @@ public:
const char *getSection() const;
/// Global values are always pointers.
- inline PointerType *getType() const {
- return cast<PointerType>(User::getType());
- }
+ PointerType *getType() const { return cast<PointerType>(User::getType()); }
+
+ Type *getValueType() const { return getType()->getElementType(); }
static LinkageTypes getLinkOnceLinkage(bool ODR) {
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
@@ -317,7 +330,7 @@ public:
/// If this GlobalValue is read in, and if the GVMaterializer supports it,
/// release the memory for the function, and set it up to be materialized
/// lazily. If !isDematerializable(), this method is a noop.
- void Dematerialize();
+ void dematerialize();
/// @}
@@ -343,13 +356,11 @@ public:
virtual void eraseFromParent() = 0;
/// Get the module that this global value is contained inside of...
- inline Module *getParent() { return Parent; }
- inline const Module *getParent() const { return Parent; }
-
- const DataLayout *getDataLayout() const;
+ Module *getParent() { return Parent; }
+ const Module *getParent() const { return Parent; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Value *V) {
+ static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
V->getValueID() == Value::GlobalVariableVal ||
V->getValueID() == Value::GlobalAliasVal;
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 4189ccb90a54..9f57705dae72 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -34,9 +34,9 @@ template<typename ValueSubClass, typename ItemParentClass>
class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
friend class SymbolTableListTraits<GlobalVariable, Module>;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- void operator=(const GlobalVariable &) LLVM_DELETED_FUNCTION;
- GlobalVariable(const GlobalVariable &) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ void operator=(const GlobalVariable &) = delete;
+ GlobalVariable(const GlobalVariable &) = delete;
void setParent(Module *parent);
@@ -66,7 +66,7 @@ public:
ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
bool isExternallyInitialized = false);
- ~GlobalVariable() {
+ ~GlobalVariable() override {
NumOperands = 1; // FIXME: needed by operator delete
}
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index e5f62fb9625e..adf692469ad3 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -21,6 +21,8 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/ConstantFolder.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
@@ -115,17 +117,15 @@ public:
}
/// \brief Set location information used by debugging information.
- void SetCurrentDebugLocation(const DebugLoc &L) {
- CurDbgLocation = L;
- }
+ void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); }
/// \brief Get location information used by debugging information.
- DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
+ const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; }
/// \brief If this builder has a current debug location, set it on the
/// specified instruction.
void SetInstDebugLocation(Instruction *I) const {
- if (!CurDbgLocation.isUnknown())
+ if (CurDbgLocation)
I->setDebugLoc(CurDbgLocation);
}
@@ -200,8 +200,8 @@ public:
BasicBlock::iterator Point;
DebugLoc DbgLoc;
- InsertPointGuard(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
- InsertPointGuard &operator=(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
+ InsertPointGuard(const InsertPointGuard &) = delete;
+ InsertPointGuard &operator=(const InsertPointGuard &) = delete;
public:
InsertPointGuard(IRBuilderBase &B)
@@ -221,9 +221,9 @@ public:
FastMathFlags FMF;
MDNode *FPMathTag;
- FastMathFlagGuard(const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+ FastMathFlagGuard(const FastMathFlagGuard &) = delete;
FastMathFlagGuard &operator=(
- const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
+ const FastMathFlagGuard &) = delete;
public:
FastMathFlagGuard(IRBuilderBase &B)
@@ -245,7 +245,7 @@ public:
/// filled in with the null terminated string value specified. The new global
/// variable will be marked mergable with any others of the same contents. If
/// Name is specified, it is the name of the global variable created.
- Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
+ GlobalVariable *CreateGlobalString(StringRef Str, const Twine &Name = "");
/// \brief Get a constant value representing either true or false.
ConstantInt *getInt1(bool V) {
@@ -322,6 +322,11 @@ public:
return Type::getInt64Ty(Context);
}
+ /// \brief Fetch the type representing a 128-bit integer.
+ IntegerType *getInt128Ty() {
+ return Type::getInt128Ty(Context);
+ }
+
/// \brief Fetch the type representing an N-bit integer.
IntegerType *getIntNTy(unsigned N) {
return Type::getIntNTy(Context, N);
@@ -353,8 +358,8 @@ public:
}
/// \brief Fetch the type representing a pointer to an integer value.
- IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) {
- return DL->getIntPtrType(Context, AddrSpace);
+ IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) {
+ return DL.getIntPtrType(Context, AddrSpace);
}
//===--------------------------------------------------------------------===//
@@ -443,11 +448,40 @@ public:
/// \brief Create a call to the experimental.gc.statepoint intrinsic to
/// start a new statepoint sequence.
- CallInst *CreateGCStatepoint(Value *ActualCallee,
- ArrayRef<Value*> CallArgs,
- ArrayRef<Value*> DeoptArgs,
- ArrayRef<Value*> GCArgs,
- const Twine &Name = "");
+ CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualCallee,
+ ArrayRef<Value *> CallArgs,
+ ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> GCArgs,
+ const Twine &Name = "");
+
+ // \brief Conveninence function for the common case when CallArgs are filled
+ // in using makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be
+ // .get()'ed to get the Value pointer.
+ CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualCallee, ArrayRef<Use> CallArgs,
+ ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> GCArgs,
+ const Twine &Name = "");
+
+ /// brief Create an invoke to the experimental.gc.statepoint intrinsic to
+ /// start a new statepoint sequence.
+ InvokeInst *
+ CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualInvokee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs,
+ ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> GCArgs, const Twine &Name = "");
+
+ // Conveninence function for the common case when CallArgs are filled in using
+ // makeArrayRef(CS.arg_begin(), CS.arg_end()); Use needs to be .get()'ed to
+ // get the Value *.
+ InvokeInst *
+ CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
+ Value *ActualInvokee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
+ ArrayRef<Value *> DeoptArgs,
+ ArrayRef<Value *> GCArgs, const Twine &Name = "");
/// \brief Create a call to the experimental.gc.result intrinsic to extract
/// the result from a call wrapped in a statepoint.
@@ -466,7 +500,7 @@ public:
private:
/// \brief Create a call to a masked intrinsic with given Id.
/// Masked intrinsic has only one overloaded type - data type.
- CallInst *CreateMaskedIntrinsic(unsigned Id, ArrayRef<Value *> Ops,
+ CallInst *CreateMaskedIntrinsic(Intrinsic::ID Id, ArrayRef<Value *> Ops,
Type *DataTy, const Twine &Name = "");
Value *getCastedInt8PtrValue(Value *Ptr);
@@ -959,6 +993,9 @@ public:
LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
return Insert(new LoadInst(Ptr), Name);
}
+ LoadInst *CreateLoad(Type *Ty, Value *Ptr, const Twine &Name = "") {
+ return Insert(new LoadInst(Ty, Ptr), Name);
+ }
LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
return Insert(new LoadInst(Ptr, nullptr, isVolatile), Name);
}
@@ -1011,6 +1048,10 @@ public:
}
Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
+ return CreateGEP(nullptr, Ptr, IdxList, Name);
+ }
+ Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
size_t i, e;
@@ -1018,12 +1059,16 @@ public:
if (!isa<Constant>(IdxList[i]))
break;
if (i == e)
- return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name);
}
- return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name);
}
Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
+ return CreateInBoundsGEP(nullptr, Ptr, IdxList, Name);
+ }
+ Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
size_t i, e;
@@ -1031,79 +1076,88 @@ public:
if (!isa<Constant>(IdxList[i]))
break;
if (i == e)
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList),
+ Name);
}
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name);
}
Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ return CreateGEP(nullptr, Ptr, Idx, Name);
+ }
+ Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
- Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
+ return CreateConstGEP1_32(nullptr, Ptr, Idx0, Name);
+ }
+ Value *CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
+ const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
- Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+ Value *CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0,
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
- Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
+ Value *CreateConstGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const Twine &Name = "") {
Value *Idxs[] = {
ConstantInt::get(Type::getInt32Ty(Context), Idx0),
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
}
- Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
+ Value *CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0,
+ unsigned Idx1, const Twine &Name = "") {
Value *Idxs[] = {
ConstantInt::get(Type::getInt32Ty(Context), Idx0),
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
}
Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
const Twine &Name = "") {
@@ -1113,9 +1167,9 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateGetElementPtr(nullptr, PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
const Twine &Name = "") {
@@ -1125,21 +1179,23 @@ public:
};
if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+ return Insert(Folder.CreateInBoundsGetElementPtr(nullptr, PC, Idxs),
+ Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
}
- Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
- return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
+ Value *CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx,
+ const Twine &Name = "") {
+ return CreateConstInBoundsGEP2_32(Ty, Ptr, 0, Idx, Name);
}
/// \brief Same as CreateGlobalString, but return a pointer with "i8*" type
/// instead of a pointer to array of i8.
Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
- Value *gv = CreateGlobalString(Str, Name);
+ GlobalVariable *gv = CreateGlobalString(Str, Name);
Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
Value *Args[] = { zero, zero };
- return CreateInBoundsGEP(gv, Args, Name);
+ return CreateInBoundsGEP(gv->getValueType(), gv, Args, Name);
}
//===--------------------------------------------------------------------===//
@@ -1297,7 +1353,7 @@ private:
// \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
// compile time error, instead of converting the string to bool for the
// isSigned parameter.
- Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION;
+ Value *CreateIntCast(Value *, Type *, const char *) = delete;
public:
Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
if (V->getType() == DestTy)
@@ -1409,36 +1465,19 @@ public:
return Insert(PHINode::Create(Ty, NumReservedValues), Name);
}
- CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
- return Insert(CallInst::Create(Callee), Name);
- }
- CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
- return Insert(CallInst::Create(Callee, Arg), Name);
- }
- CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
- const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
- CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
- CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- Value *Arg4, const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
+ CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
+ const Twine &Name = "") {
return Insert(CallInst::Create(Callee, Args), Name);
}
- CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- Value *Arg4, Value *Arg5, const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
- return Insert(CallInst::Create(Callee, Args), Name);
+
+ CallInst *CreateCall(llvm::FunctionType *FTy, Value *Callee,
+ ArrayRef<Value *> Args, const Twine &Name = "") {
+ return Insert(CallInst::Create(FTy, Callee, Args), Name);
}
- CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
+ CallInst *CreateCall(Function *Callee, ArrayRef<Value *> Args,
const Twine &Name = "") {
- return Insert(CallInst::Create(Callee, Args), Name);
+ return CreateCall(Callee->getFunctionType(), Callee, Args, Name);
}
Value *CreateSelect(Value *C, Value *True, Value *False,
@@ -1462,6 +1501,11 @@ public:
return Insert(ExtractElementInst::Create(Vec, Idx), Name);
}
+ Value *CreateExtractElement(Value *Vec, uint64_t Idx,
+ const Twine &Name = "") {
+ return CreateExtractElement(Vec, getInt64(Idx), Name);
+ }
+
Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
const Twine &Name = "") {
if (Constant *VC = dyn_cast<Constant>(Vec))
@@ -1471,6 +1515,11 @@ public:
return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
}
+ Value *CreateInsertElement(Value *Vec, Value *NewElt, uint64_t Idx,
+ const Twine &Name = "") {
+ return CreateInsertElement(Vec, NewElt, getInt64(Idx), Name);
+ }
+
Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
const Twine &Name = "") {
if (Constant *V1C = dyn_cast<Constant>(V1))
@@ -1480,6 +1529,16 @@ public:
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
}
+ Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<int> IntMask,
+ const Twine &Name = "") {
+ size_t MaskSize = IntMask.size();
+ SmallVector<Constant*, 8> MaskVec(MaskSize);
+ for (size_t i = 0; i != MaskSize; ++i)
+ MaskVec[i] = getInt32(IntMask[i]);
+ Value *Mask = ConstantVector::get(MaskVec);
+ return CreateShuffleVector(V1, V2, Mask, Name);
+ }
+
Value *CreateExtractValue(Value *Agg,
ArrayRef<unsigned> Idxs,
const Twine &Name = "") {
@@ -1589,7 +1648,7 @@ public:
"trying to create an alignment assumption on a non-pointer?");
PointerType *PtrTy = cast<PointerType>(PtrValue->getType());
- Type *IntPtrTy = getIntPtrTy(&DL, PtrTy->getAddressSpace());
+ Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
Value *Mask = ConstantInt::get(IntPtrTy,
diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h
index 7f2027b6e297..5f1d56f7e831 100644
--- a/include/llvm/IR/IRPrintingPasses.h
+++ b/include/llvm/IR/IRPrintingPasses.h
@@ -34,7 +34,8 @@ class raw_ostream;
/// \brief Create and return a pass that writes the module to the specified
/// \c raw_ostream.
ModulePass *createPrintModulePass(raw_ostream &OS,
- const std::string &Banner = "");
+ const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false);
/// \brief Create and return a pass that prints functions to the specified
/// \c raw_ostream as they are processed.
@@ -53,10 +54,12 @@ BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS,
class PrintModulePass {
raw_ostream &OS;
std::string Banner;
+ bool ShouldPreserveUseListOrder;
public:
PrintModulePass();
- PrintModulePass(raw_ostream &OS, const std::string &Banner = "");
+ PrintModulePass(raw_ostream &OS, const std::string &Banner = "",
+ bool ShouldPreserveUseListOrder = false);
PreservedAnalyses run(Module &M);
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index b2d79d0f0bfc..15942f16e67e 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -40,8 +40,8 @@ private:
friend struct InlineAsmKeyType;
friend class ConstantUniqueMap<InlineAsm>;
- InlineAsm(const InlineAsm &) LLVM_DELETED_FUNCTION;
- void operator=(const InlineAsm&) LLVM_DELETED_FUNCTION;
+ InlineAsm(const InlineAsm &) = delete;
+ void operator=(const InlineAsm&) = delete;
std::string AsmString, Constraints;
bool HasSideEffects;
@@ -51,7 +51,7 @@ private:
InlineAsm(PointerType *Ty, const std::string &AsmString,
const std::string &Constraints, bool hasSideEffects,
bool isAlignStack, AsmDialect asmDialect);
- virtual ~InlineAsm();
+ ~InlineAsm() override;
/// When the ConstantUniqueMap merges two types and makes two InlineAsms
/// identical, it destroys one of them with this method.
@@ -189,6 +189,20 @@ public:
// These are helper methods for dealing with flags in the INLINEASM SDNode
// in the backend.
+ //
+ // The encoding of the flag word is currently:
+ // Bits 2-0 - A Kind_* value indicating the kind of the operand.
+ // Bits 15-3 - The number of SDNode operands associated with this inline
+ // assembly operand.
+ // If bit 31 is set:
+ // Bit 30-16 - The operand number that this operand must match.
+ // When bits 2-0 are Kind_Mem, the Constraint_* value must be
+ // obtained from the flags for this operand number.
+ // Else if bits 2-0 are Kind_Mem:
+ // Bit 30-16 - A Constraint_* value indicating the original constraint
+ // code.
+ // Else:
+ // Bit 30-16 - The register class ID to use for the operand.
enum : uint32_t {
// Fixed operands on an INLINEASM SDNode.
@@ -220,6 +234,27 @@ public:
Kind_Imm = 5, // Immediate.
Kind_Mem = 6, // Memory operand, "m".
+ // Memory constraint codes.
+ // These could be tablegenerated but there's little need to do that since
+ // there's plenty of space in the encoding to support the union of all
+ // constraint codes for all targets.
+ Constraint_Unknown = 0,
+ Constraint_es,
+ Constraint_i,
+ Constraint_m,
+ Constraint_o,
+ Constraint_v,
+ Constraint_Q,
+ Constraint_R,
+ Constraint_S,
+ Constraint_T,
+ Constraint_X,
+ Constraint_Z,
+ Constraint_ZC,
+ Constraint_Zy,
+ Constraints_Max = Constraint_Zy,
+ Constraints_ShiftAmount = 16,
+
Flag_MatchingOperand = 0x80000000
};
@@ -252,6 +287,20 @@ public:
return InputFlag | (RC << 16);
}
+ /// Augment an existing flag word returned by getFlagWord with the constraint
+ /// code for a memory constraint.
+ static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
+ assert(Constraint <= 0x7fff && "Too large a memory constraint ID");
+ assert(Constraint <= Constraints_Max && "Unknown constraint ID");
+ assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+ return InputFlag | (Constraint << Constraints_ShiftAmount);
+ }
+
+ static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
+ assert(isMemKind(InputFlag));
+ return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
+ }
+
static unsigned getKind(unsigned Flags) {
return Flags & 7;
}
@@ -266,6 +315,11 @@ public:
return getKind(Flag) == Kind_Clobber;
}
+ static unsigned getMemoryConstraintID(unsigned Flag) {
+ assert(isMemKind(Flag));
+ return (Flag >> Constraints_ShiftAmount) & 0x7fff;
+ }
+
/// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) {
diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h
index 75e93bd2ff8c..f3ce6490fb66 100644
--- a/include/llvm/IR/InstIterator.h
+++ b/include/llvm/IR/InstIterator.h
@@ -27,15 +27,14 @@ namespace llvm {
// This class implements inst_begin() & inst_end() for
// inst_iterator and const_inst_iterator's.
//
-template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
-class InstIterator {
- typedef _BB_t BBty;
- typedef _BB_i_t BBIty;
- typedef _BI_t BIty;
- typedef _II_t IIty;
- _BB_t *BBs; // BasicBlocksType
- _BB_i_t BB; // BasicBlocksType::iterator
- _BI_t BI; // BasicBlock::iterator
+template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
+ typedef BB_t BBty;
+ typedef BB_i_t BBIty;
+ typedef BI_t BIty;
+ typedef II_t IIty;
+ BB_t *BBs; // BasicBlocksType
+ BB_i_t BB; // BasicBlocksType::iterator
+ BI_t BI; // BasicBlock::iterator
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef IIty value_type;
@@ -127,20 +126,32 @@ typedef InstIterator<const iplist<BasicBlock>,
inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
+inline iterator_range<inst_iterator> inst_range(Function *F) {
+ return iterator_range<inst_iterator>(inst_begin(F), inst_end(F));
+}
inline const_inst_iterator inst_begin(const Function *F) {
return const_inst_iterator(*F);
}
inline const_inst_iterator inst_end(const Function *F) {
return const_inst_iterator(*F, true);
}
+inline iterator_range<const_inst_iterator> inst_range(const Function *F) {
+ return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F));
+}
inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
+inline iterator_range<inst_iterator> inst_range(Function &F) {
+ return iterator_range<inst_iterator>(inst_begin(F), inst_end(F));
+}
inline const_inst_iterator inst_begin(const Function &F) {
return const_inst_iterator(F);
}
inline const_inst_iterator inst_end(const Function &F) {
return const_inst_iterator(F, true);
}
+inline iterator_range<const_inst_iterator> inst_range(const Function &F) {
+ return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F));
+}
} // End llvm namespace
diff --git a/include/llvm/IR/InstVisitor.h b/include/llvm/IR/InstVisitor.h
index 1cdcd55448c9..581e860b8382 100644
--- a/include/llvm/IR/InstVisitor.h
+++ b/include/llvm/IR/InstVisitor.h
@@ -259,7 +259,7 @@ private:
// Special helper function to delegate to CallInst subclass visitors.
RetTy delegateCallInst(CallInst &I) {
if (const Function *F = I.getCalledFunction()) {
- switch ((Intrinsic::ID)F->getIntrinsicID()) {
+ switch (F->getIntrinsicID()) {
default: DELEGATE(IntrinsicInst);
case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index 030f5d690a0c..108b9eb36b7e 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -44,7 +44,7 @@ protected:
: Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
// Out of line virtual method, so the vtable, etc has a home.
- ~TerminatorInst();
+ ~TerminatorInst() override;
/// Virtual methods - Terminators should overload these and provide inline
/// overrides of non-V methods.
@@ -83,7 +83,7 @@ public:
//===----------------------------------------------------------------------===//
class UnaryInstruction : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
protected:
UnaryInstruction(Type *Ty, unsigned iType, Value *V,
@@ -102,7 +102,7 @@ public:
}
// Out of line virtual method, so the vtable, etc has a home.
- ~UnaryInstruction();
+ ~UnaryInstruction() override;
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -132,7 +132,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
//===----------------------------------------------------------------------===//
class BinaryOperator : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
@@ -570,10 +570,9 @@ public:
/// This ensures that any pointer<->integer cast has enough bits in the
/// integer and any other cast is a bitcast.
static bool isBitOrNoopPointerCastable(
- Type *SrcTy, ///< The Type from which the value should be cast.
- Type *DestTy, ///< The Type to which the value should be cast.
- const DataLayout *Layout = 0 ///< Optional DataLayout.
- );
+ Type *SrcTy, ///< The Type from which the value should be cast.
+ Type *DestTy, ///< The Type to which the value should be cast.
+ const DataLayout &DL);
/// Returns the opcode necessary to cast Val into Ty using usual casting
/// rules.
@@ -621,9 +620,9 @@ public:
) const;
/// @brief Determine if this cast is a no-op cast.
- bool isNoopCast(
- const DataLayout *DL ///< DataLayout to get the Int Ptr type from.
- ) const;
+ ///
+ /// \param DL is the DataLayout to get the Int Ptr type from.
+ bool isNoopCast(const DataLayout &DL) const;
/// Determine how a pair of casts can be eliminated, if they can be at all.
/// This is a helper function for both CastInst and ConstantExpr.
@@ -674,8 +673,8 @@ public:
/// This class is the base class for the comparison instructions.
/// @brief Abstract base class of comparison instructions.
class CmpInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- CmpInst() LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ CmpInst() = delete;
protected:
CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
Value *LHS, Value *RHS, const Twine &Name = "",
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index ba7791c99b6a..752c3f09bded 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/User.h"
namespace llvm {
@@ -25,14 +26,31 @@ namespace llvm {
class FastMathFlags;
class LLVMContext;
class MDNode;
+class BasicBlock;
struct AAMDNodes;
-template<typename ValueSubClass, typename ItemParentClass>
- class SymbolTableListTraits;
+template <>
+struct ilist_traits<Instruction>
+ : public SymbolTableListTraits<Instruction, BasicBlock> {
+
+ /// \brief Return a node that marks the end of a list.
+ ///
+ /// The sentinel is relative to this instance, so we use a non-static
+ /// method.
+ Instruction *createSentinel() const;
+ static void destroySentinel(Instruction *) {}
+
+ Instruction *provideInitialHead() const { return createSentinel(); }
+ Instruction *ensureHead(Instruction *) const { return createSentinel(); }
+ static void noteHead(Instruction *, Instruction *) {}
+
+private:
+ mutable ilist_half_node<Instruction> Sentinel;
+};
class Instruction : public User, public ilist_node<Instruction> {
- void operator=(const Instruction &) LLVM_DELETED_FUNCTION;
- Instruction(const Instruction &) LLVM_DELETED_FUNCTION;
+ void operator=(const Instruction &) = delete;
+ Instruction(const Instruction &) = delete;
BasicBlock *Parent;
DebugLoc DbgLoc; // 'dbg' Metadata cache.
@@ -44,7 +62,7 @@ class Instruction : public User, public ilist_node<Instruction> {
};
public:
// Out of line virtual method, so the vtable, etc has a home.
- ~Instruction();
+ ~Instruction() override;
/// user_back - Specialize the methods defined in Value, as we know that an
/// instruction can only be used by other instructions.
@@ -54,7 +72,13 @@ public:
inline const BasicBlock *getParent() const { return Parent; }
inline BasicBlock *getParent() { return Parent; }
- const DataLayout *getDataLayout() const;
+ /// \brief Return the module owning the function this instruction belongs to
+ /// or nullptr it the function does not have a module.
+ ///
+ /// Note: this is undefined behavior if the instruction does not have a
+ /// parent, or the parent basic block does not have a parent function.
+ const Module *getModule() const;
+ Module *getModule();
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, but does not delete it.
@@ -64,14 +88,15 @@ public:
/// eraseFromParent - This method unlinks 'this' from the containing basic
/// block and deletes it.
///
- void eraseFromParent();
+ /// \returns an iterator pointing to the element after the erased one
+ iplist<Instruction>::iterator eraseFromParent();
- /// insertBefore - Insert an unlinked instructions into a basic block
- /// immediately before the specified instruction.
+ /// Insert an unlinked instruction into a basic block immediately before
+ /// the specified instruction.
void insertBefore(Instruction *InsertPos);
- /// insertAfter - Insert an unlinked instructions into a basic block
- /// immediately after the specified instruction.
+ /// Insert an unlinked instruction into a basic block immediately after the
+ /// specified instruction.
void insertAfter(Instruction *InsertPos);
/// moveBefore - Unlink this instruction from its current basic block and
@@ -129,9 +154,7 @@ public:
/// hasMetadata() - Return true if this instruction has any metadata attached
/// to it.
- bool hasMetadata() const {
- return !DbgLoc.isUnknown() || hasMetadataHashEntry();
- }
+ bool hasMetadata() const { return DbgLoc || hasMetadataHashEntry(); }
/// hasMetadataOtherThanDebugLoc - Return true if this instruction has
/// metadata attached to it other than a debug location.
@@ -201,7 +224,7 @@ public:
void setAAMetadata(const AAMDNodes &N);
/// setDebugLoc - Set the debug location information for this instruction.
- void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
+ void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
/// getDebugLoc - Return the debug location for this node as a DebugLoc.
const DebugLoc &getDebugLoc() const { return DbgLoc; }
@@ -490,6 +513,17 @@ protected:
};
+inline Instruction *ilist_traits<Instruction>::createSentinel() const {
+ // Since i(p)lists always publicly derive from their corresponding traits,
+ // placing a data member in this class will augment the i(p)list. But since
+ // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+ // there is a legal viable downcast from it to NodeTy. We use this trick to
+ // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+ // sentinel. Dereferencing the sentinel is forbidden (save the
+ // ilist_node<NodeTy>), so no one will ever notice the superposition.
+ return static_cast<Instruction *>(&Sentinel);
+}
+
// Instruction* is only 4-byte aligned.
template<>
class PointerLikeTypeTraits<Instruction*> {
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 045e51eb1baa..9f5e244f0021 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -73,6 +73,8 @@ return (Ord == Release ||
/// AllocaInst - an instruction to allocate memory on the stack
///
class AllocaInst : public UnaryInstruction {
+ Type *AllocatedType;
+
protected:
AllocaInst *clone_impl() const override;
public:
@@ -91,7 +93,7 @@ public:
const Twine &Name, BasicBlock *InsertAtEnd);
// Out of line virtual method, so the vtable, etc. has a home.
- virtual ~AllocaInst();
+ ~AllocaInst() override;
/// isArrayAllocation - Return true if there is an allocation size parameter
/// to the allocation instruction that is not 1.
@@ -113,7 +115,10 @@ public:
/// getAllocatedType - Return the type that is being allocated by the
/// instruction.
///
- Type *getAllocatedType() const;
+ Type *getAllocatedType() const { return AllocatedType; }
+ /// \brief for use only in special circumstances that need to generically
+ /// transform a whole instruction (eg: IR linking and vectorization).
+ void setAllocatedType(Type *Ty) { AllocatedType = Ty; }
/// getAlignment - Return the alignment of the memory that is being allocated
/// by the instruction.
@@ -172,15 +177,28 @@ protected:
public:
LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore);
LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false,
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile = false,
Instruction *InsertBefore = nullptr);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false,
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, InsertBefore) {}
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align,
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, Align, InsertBefore) {}
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, Instruction *InsertBefore = nullptr);
LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, BasicBlock *InsertAtEnd);
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align,
+ AtomicOrdering Order, SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, Align, Order, SynchScope, InsertBefore) {}
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
unsigned Align, AtomicOrdering Order,
SynchronizationScope SynchScope = CrossThread,
Instruction *InsertBefore = nullptr);
@@ -191,9 +209,13 @@ public:
LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore);
LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd);
+ LoadInst(Type *Ty, Value *Ptr, const char *NameStr = nullptr,
+ bool isVolatile = false, Instruction *InsertBefore = nullptr);
explicit LoadInst(Value *Ptr, const char *NameStr = nullptr,
bool isVolatile = false,
- Instruction *InsertBefore = nullptr);
+ Instruction *InsertBefore = nullptr)
+ : LoadInst(cast<PointerType>(Ptr->getType())->getElementType(), Ptr,
+ NameStr, isVolatile, InsertBefore) {}
LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
BasicBlock *InsertAtEnd);
@@ -285,7 +307,7 @@ private:
/// StoreInst - an instruction for storing to memory
///
class StoreInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
void AssertOK();
protected:
StoreInst *clone_impl() const override;
@@ -411,7 +433,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
/// FenceInst - an instruction for ordering other memory operations
///
class FenceInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
protected:
FenceInst *clone_impl() const override;
@@ -478,7 +500,7 @@ private:
/// there. Returns the value that was loaded.
///
class AtomicCmpXchgInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
void Init(Value *Ptr, Value *Cmp, Value *NewVal,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
@@ -634,7 +656,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
/// the old value.
///
class AtomicRMWInst : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
protected:
AtomicRMWInst *clone_impl() const override;
public:
@@ -787,6 +809,8 @@ inline Type *checkGEPType(Type *Ty) {
/// access elements of arrays and structs
///
class GetElementPtrInst : public Instruction {
+ Type *SourceElementType;
+
GetElementPtrInst(const GetElementPtrInst &GEPI);
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
@@ -794,28 +818,45 @@ class GetElementPtrInst : public Instruction {
/// list of indices. The first ctor can optionally insert before an existing
/// instruction, the second appends the new instruction to the specified
/// BasicBlock.
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- Instruction *InsertBefore);
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- BasicBlock *InsertAtEnd);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
protected:
GetElementPtrInst *clone_impl() const override;
public:
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore);
- }
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ if (!PointeeType)
+ PointeeType =
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType();
+ else
+ assert(
+ PointeeType ==
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType());
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd);
+ if (!PointeeType)
+ PointeeType =
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType();
+ else
+ assert(
+ PointeeType ==
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType());
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertAtEnd);
}
/// Create an "inbounds" getelementptr. See the documentation for the
@@ -824,7 +865,14 @@ public:
ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr){
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *
+ CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
GEP->setIsInBounds(true);
return GEP;
}
@@ -832,7 +880,14 @@ public:
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd);
+ }
+ static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
GEP->setIsInBounds(true);
return GEP;
}
@@ -845,6 +900,14 @@ public:
return cast<SequentialType>(Instruction::getType());
}
+ Type *getSourceElementType() const { return SourceElementType; }
+
+ void setSourceElementType(Type *Ty) { SourceElementType = Ty; }
+
+ Type *getResultElementType() const {
+ return cast<PointerType>(getType()->getScalarType())->getElementType();
+ }
+
/// \brief Returns the address space of this instruction's pointer type.
unsigned getAddressSpace() const {
// Note that this is always the same as the pointer operand's address space
@@ -858,9 +921,9 @@ public:
/// Null is returned if the indices are invalid for the specified
/// pointer type.
///
- static Type *getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<Constant *> IdxList);
- static Type *getIndexedType(Type *Ptr, ArrayRef<uint64_t> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
+ static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
@@ -891,8 +954,13 @@ public:
/// GetGEPReturnType - Returns the pointer type returned by the GEP
/// instruction, which may be a vector of pointers.
static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
- Type *PtrTy = PointerType::get(checkGEPType(
- getIndexedType(Ptr->getType(), IdxList)),
+ return getGEPReturnType(
+ cast<PointerType>(Ptr->getType()->getScalarType())->getElementType(),
+ Ptr, IdxList);
+ }
+ static Type *getGEPReturnType(Type *ElTy, Value *Ptr,
+ ArrayRef<Value *> IdxList) {
+ Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)),
Ptr->getType()->getPointerAddressSpace());
// Vector GEP
if (Ptr->getType()->isVectorTy()) {
@@ -953,26 +1021,24 @@ struct OperandTraits<GetElementPtrInst> :
public VariadicOperandTraits<GetElementPtrInst, 1> {
};
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
Instruction *InsertBefore)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertBefore) {
+ : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertBefore),
+ SourceElementType(PointeeType) {
init(Ptr, IdxList, NameStr);
}
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertAtEnd) {
+ : Instruction(getGEPReturnType(PointeeType, Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertAtEnd),
+ SourceElementType(PointeeType) {
init(Ptr, IdxList, NameStr);
}
@@ -1194,11 +1260,15 @@ public:
/// @returns true if the predicate of this instruction is EQ or NE.
/// \brief Determine if this is an equality predicate.
- bool isEquality() const {
- return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
- getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
+ static bool isEquality(Predicate Pred) {
+ return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ ||
+ Pred == FCMP_UNE;
}
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// \brief Determine if this is an equality predicate.
+ bool isEquality() const { return isEquality(getPredicate()); }
+
/// @returns true if the predicate of this instruction is commutative.
/// \brief Determine if this is a commutative predicate.
bool isCommutative() const {
@@ -1240,14 +1310,26 @@ public:
///
class CallInst : public Instruction {
AttributeSet AttributeList; ///< parameter attributes for call
+ FunctionType *FTy;
CallInst(const CallInst &CI);
- void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr);
+ void init(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr);
+ }
+ void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr);
void init(Value *Func, const Twine &NameStr);
/// Construct a CallInst given a range of arguments.
/// \brief Construct a CallInst from a range of arguments
- inline CallInst(Value *Func, ArrayRef<Value *> Args,
+ inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore);
+ inline CallInst(Value *Func, ArrayRef<Value *> Args, const Twine &NameStr,
+ Instruction *InsertBefore)
+ : CallInst(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr, InsertBefore) {}
/// Construct a CallInst given a range of arguments.
/// \brief Construct a CallInst from a range of arguments
@@ -1264,8 +1346,15 @@ public:
ArrayRef<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
- return new(unsigned(Args.size() + 1))
- CallInst(Func, Args, NameStr, InsertBefore);
+ return Create(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, Args, NameStr, InsertBefore);
+ }
+ static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ return new (unsigned(Args.size() + 1))
+ CallInst(Ty, Func, Args, NameStr, InsertBefore);
}
static CallInst *Create(Value *Func,
ArrayRef<Value *> Args,
@@ -1301,7 +1390,14 @@ public:
static Instruction* CreateFree(Value* Source, Instruction *InsertBefore);
static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
- ~CallInst();
+ ~CallInst() override;
+
+ FunctionType *getFunctionType() const { return FTy; }
+
+ void mutateFunctionType(FunctionType *FTy) {
+ mutateType(FTy->getReturnType());
+ this->FTy = FTy;
+ }
// Note that 'musttail' implies 'tail'.
enum TailCallKind { TCK_None = 0, TCK_Tail = 1, TCK_MustTail = 2 };
@@ -1375,6 +1471,13 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute attr);
+ /// \brief adds the dereferenceable attribute to the list of attributes.
+ void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
@@ -1396,6 +1499,12 @@ public:
return AttributeList.getDereferenceableBytes(i);
}
+ /// \brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned i) const {
+ return AttributeList.getDereferenceableOrNullBytes(i);
+ }
+
/// \brief Return true if the call should not be treated as a call to a
/// builtin.
bool isNoBuiltin() const {
@@ -1477,6 +1586,14 @@ public:
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
+ setCalledFunction(
+ cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
+ Fn);
+ }
+ void setCalledFunction(FunctionType *FTy, Value *Fn) {
+ this->FTy = FTy;
+ assert(FTy == cast<FunctionType>(
+ cast<PointerType>(Fn->getType())->getElementType()));
Op<-1>() = Fn;
}
@@ -1517,14 +1634,12 @@ CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
init(Func, Args, NameStr);
}
-CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore)
- : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
- ->getElementType())->getReturnType(),
- Instruction::Call,
- OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
- unsigned(Args.size() + 1), InsertBefore) {
- init(Func, Args, NameStr);
+ : Instruction(Ty->getReturnType(), Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+ unsigned(Args.size() + 1), InsertBefore) {
+ init(Ty, Func, Args, NameStr);
}
@@ -1898,6 +2013,9 @@ public:
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
@@ -1958,7 +2076,7 @@ ExtractValueInst::ExtractValueInst(Value *Agg,
class InsertValueInst : public Instruction {
SmallVector<unsigned, 4> Indices;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
InsertValueInst(const InsertValueInst &IVI);
void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
const Twine &NameStr);
@@ -2009,6 +2127,9 @@ public:
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
@@ -2088,7 +2209,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
// scientist's overactive imagination.
//
class PHINode : public Instruction {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
/// ReservedSpace - The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -2132,7 +2253,7 @@ public:
const Twine &NameStr, BasicBlock *InsertAtEnd) {
return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
}
- ~PHINode();
+ ~PHINode() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2163,6 +2284,10 @@ public:
return block_begin() + getNumOperands();
}
+ op_range incoming_values() { return operands(); }
+
+ const_op_range incoming_values() const { return operands(); }
+
/// getNumIncomingValues - Return the number of incoming edges
///
unsigned getNumIncomingValues() const { return getNumOperands(); }
@@ -2295,7 +2420,7 @@ class LandingPadInst : public Instruction {
public:
enum ClauseType { Catch, Filter };
private:
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
// Allocate space for exactly zero operands.
void *operator new(size_t s) {
return User::operator new(s, 0);
@@ -2321,7 +2446,7 @@ public:
static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
unsigned NumReservedClauses,
const Twine &NameStr, BasicBlock *InsertAtEnd);
- ~LandingPadInst();
+ ~LandingPadInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2423,7 +2548,7 @@ public:
static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
return new(0) ReturnInst(C, InsertAtEnd);
}
- virtual ~ReturnInst();
+ ~ReturnInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2562,7 +2687,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
/// SwitchInst - Multiway switch
///
class SwitchInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
@@ -2720,7 +2845,7 @@ public:
return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
}
- ~SwitchInst();
+ ~SwitchInst() override;
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2871,7 +2996,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
/// IndirectBrInst - Indirect Branch Instruction.
///
class IndirectBrInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
unsigned ReservedSpace;
// Operand[0] = Value to switch on
// Operand[1] = Default basic block destination
@@ -2906,7 +3031,7 @@ public:
BasicBlock *InsertAtEnd) {
return new IndirectBrInst(Address, NumDests, InsertAtEnd);
}
- ~IndirectBrInst();
+ ~IndirectBrInst() override;
/// Provide fast operand accessors.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -2970,17 +3095,33 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
///
class InvokeInst : public TerminatorInst {
AttributeSet AttributeList;
+ FunctionType *FTy;
InvokeInst(const InvokeInst &BI);
void init(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
- ArrayRef<Value *> Args, const Twine &NameStr);
+ ArrayRef<Value *> Args, const Twine &NameStr) {
+ init(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, NameStr);
+ }
+ void init(FunctionType *FTy, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ const Twine &NameStr);
/// Construct an InvokeInst given a range of arguments.
///
/// \brief Construct an InvokeInst from a range of arguments
inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, unsigned Values,
- const Twine &NameStr, Instruction *InsertBefore);
-
+ const Twine &NameStr, Instruction *InsertBefore)
+ : InvokeInst(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, Values, NameStr,
+ InsertBefore) {}
+
+ inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore);
/// Construct an InvokeInst given a range of arguments.
///
/// \brief Construct an InvokeInst from a range of arguments
@@ -2994,9 +3135,17 @@ public:
BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
+ return Create(cast<FunctionType>(
+ cast<PointerType>(Func->getType())->getElementType()),
+ Func, IfNormal, IfException, Args, NameStr, InsertBefore);
+ }
+ static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
unsigned Values = unsigned(Args.size()) + 3;
- return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
- Values, NameStr, InsertBefore);
+ return new (Values) InvokeInst(Ty, Func, IfNormal, IfException, Args,
+ Values, NameStr, InsertBefore);
}
static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
@@ -3010,6 +3159,13 @@ public:
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+ FunctionType *getFunctionType() const { return FTy; }
+
+ void mutateFunctionType(FunctionType *FTy) {
+ mutateType(FTy->getReturnType());
+ this->FTy = FTy;
+ }
+
/// getNumArgOperands - Return the number of invoke arguments.
///
unsigned getNumArgOperands() const { return getNumOperands() - 3; }
@@ -3056,6 +3212,13 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attribute attr);
+ /// \brief adds the dereferenceable attribute to the list of attributes.
+ void addDereferenceableAttr(unsigned i, uint64_t Bytes);
+
+ /// \brief adds the dereferenceable_or_null attribute to the list of
+ /// attributes.
+ void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
+
/// \brief Determine whether this call has the given attribute.
bool hasFnAttr(Attribute::AttrKind A) const {
assert(A != Attribute::NoBuiltin &&
@@ -3076,6 +3239,12 @@ public:
uint64_t getDereferenceableBytes(unsigned i) const {
return AttributeList.getDereferenceableBytes(i);
}
+
+ /// \brief Extract the number of dereferenceable_or_null bytes for a call or
+ /// parameter (0=unknown).
+ uint64_t getDereferenceableOrNullBytes(unsigned i) const {
+ return AttributeList.getDereferenceableOrNullBytes(i);
+ }
/// \brief Return true if the call should not be treated as a call to a
/// builtin.
@@ -3152,6 +3321,14 @@ public:
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
+ setCalledFunction(
+ cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType()),
+ Fn);
+ }
+ void setCalledFunction(FunctionType *FTy, Value *Fn) {
+ this->FTy = FTy;
+ assert(FTy == cast<FunctionType>(
+ cast<PointerType>(Fn->getType())->getElementType()));
Op<-3>() = Fn;
}
@@ -3211,16 +3388,14 @@ template <>
struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
};
-InvokeInst::InvokeInst(Value *Func,
- BasicBlock *IfNormal, BasicBlock *IfException,
- ArrayRef<Value *> Args, unsigned Values,
- const Twine &NameStr, Instruction *InsertBefore)
- : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
- ->getElementType())->getReturnType(),
- Instruction::Invoke,
- OperandTraits<InvokeInst>::op_end(this) - Values,
- Values, InsertBefore) {
- init(Func, IfNormal, IfException, Args, NameStr);
+InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
+ BasicBlock *IfException, ArrayRef<Value *> Args,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore)
+ : TerminatorInst(Ty->getReturnType(), Instruction::Invoke,
+ OperandTraits<InvokeInst>::op_end(this) - Values, Values,
+ InsertBefore) {
+ init(Ty, Func, IfNormal, IfException, Args, NameStr);
}
InvokeInst::InvokeInst(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
@@ -3296,7 +3471,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
/// end of the block cannot be reached.
///
class UnreachableInst : public TerminatorInst {
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
protected:
UnreachableInst *clone_impl() const override;
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index c227ea080167..2c8b6eb6f39a 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -35,14 +35,14 @@ namespace llvm {
/// functions. This allows the standard isa/dyncast/cast functionality to
/// work with calls to intrinsic functions.
class IntrinsicInst : public CallInst {
- IntrinsicInst() LLVM_DELETED_FUNCTION;
- IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
- void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION;
+ IntrinsicInst() = delete;
+ IntrinsicInst(const IntrinsicInst&) = delete;
+ void operator=(const IntrinsicInst&) = delete;
public:
/// getIntrinsicID - Return the intrinsic ID of this intrinsic.
///
Intrinsic::ID getIntrinsicID() const {
- return (Intrinsic::ID)getCalledFunction()->getIntrinsicID();
+ return getCalledFunction()->getIntrinsicID();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -82,13 +82,18 @@ namespace llvm {
class DbgDeclareInst : public DbgInfoIntrinsic {
public:
Value *getAddress() const;
- MDNode *getVariable() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(1))->getMetadata());
+ DILocalVariable *getVariable() const {
+ return cast<DILocalVariable>(getRawVariable());
}
- MDNode *getExpression() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(2))->getMetadata());
+ DIExpression *getExpression() const {
+ return cast<DIExpression>(getRawExpression());
+ }
+
+ Metadata *getRawVariable() const {
+ return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
+ }
+ Metadata *getRawExpression() const {
+ return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -110,13 +115,18 @@ namespace llvm {
return cast<ConstantInt>(
const_cast<Value*>(getArgOperand(1)))->getZExtValue();
}
- MDNode *getVariable() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(2))->getMetadata());
+ DILocalVariable *getVariable() const {
+ return cast<DILocalVariable>(getRawVariable());
+ }
+ DIExpression *getExpression() const {
+ return cast<DIExpression>(getRawExpression());
+ }
+
+ Metadata *getRawVariable() const {
+ return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
}
- MDNode *getExpression() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(3))->getMetadata());
+ Metadata *getRawExpression() const {
+ return cast<MetadataAsValue>(getArgOperand(3))->getMetadata();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index 56d1e4af26aa..e12ccace25ca 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -32,7 +32,7 @@ class AttributeSet;
/// function known by LLVM. The enum values are returned by
/// Function::getIntrinsicID().
namespace Intrinsic {
- enum ID {
+ enum ID : unsigned {
not_intrinsic = 0, // Must be zero
// Get the intrinsic enums generated from Intrinsics.td
@@ -41,7 +41,7 @@ namespace Intrinsic {
#undef GET_INTRINSIC_ENUM_VALUES
, num_intrinsics
};
-
+
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
std::string getName(ID id, ArrayRef<Type*> Tys = None);
@@ -69,7 +69,7 @@ namespace Intrinsic {
/// Map a MS builtin name to an intrinsic ID.
ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
-
+
/// This is a type descriptor which explains the type requirements of an
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
struct IITDescriptor {
@@ -77,9 +77,9 @@ namespace Intrinsic {
Void, VarArg, MMX, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
- SameVecWidthArgument, PtrToArgument
+ SameVecWidthArgument, PtrToArgument, VecOfPtrsToElt
} Kind;
-
+
union {
unsigned Integer_Width;
unsigned Float_Width;
@@ -88,8 +88,9 @@ namespace Intrinsic {
unsigned Struct_NumElements;
unsigned Argument_Info;
};
-
+
enum ArgKind {
+ AK_Any,
AK_AnyInteger,
AK_AnyFloat,
AK_AnyVector,
@@ -98,26 +99,28 @@ namespace Intrinsic {
unsigned getArgumentNumber() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
- Kind == SameVecWidthArgument || Kind == PtrToArgument);
- return Argument_Info >> 2;
+ Kind == SameVecWidthArgument || Kind == PtrToArgument ||
+ Kind == VecOfPtrsToElt);
+ return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
- Kind == SameVecWidthArgument || Kind == PtrToArgument);
- return (ArgKind)(Argument_Info & 3);
+ Kind == SameVecWidthArgument || Kind == PtrToArgument ||
+ Kind == VecOfPtrsToElt);
+ return (ArgKind)(Argument_Info & 7);
}
-
+
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
}
};
-
+
/// Return the IIT table descriptor for the specified intrinsic into an array
/// of IITDescriptors.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
-
+
} // End Intrinsic namespace
} // End llvm namespace
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index a1188bccdc25..8f6cdebb0491 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -73,6 +73,11 @@ def IntrNoReturn : IntrinsicProperty;
// Parallels the noduplicate attribute on LLVM IR functions.
def IntrNoDuplicate : IntrinsicProperty;
+// IntrConvergent - Calls to this intrinsic are convergent and may only be
+// moved to control equivalent blocks.
+// Parallels the convergent attribute on LLVM IR functions.
+def IntrConvergent : IntrinsicProperty;
+
//===----------------------------------------------------------------------===//
// Types used by intrinsics.
//===----------------------------------------------------------------------===//
@@ -117,12 +122,14 @@ class LLVMVectorSameWidth<int num, LLVMType elty>
ValueType ElTy = elty.VT;
}
class LLVMPointerTo<int num> : LLVMMatchType<num>;
+class LLVMVectorOfPointersToElt<int num> : LLVMMatchType<num>;
// Match the type of another intrinsic parameter that is expected to be a
// vector type, but change the element count to be half as many
class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
def llvm_void_ty : LLVMType<isVoid>;
+def llvm_any_ty : LLVMType<Any>;
def llvm_anyint_ty : LLVMType<iAny>;
def llvm_anyfloat_ty : LLVMType<fAny>;
def llvm_anyvector_ty : LLVMType<vAny>;
@@ -179,6 +186,8 @@ def llvm_v4i64_ty : LLVMType<v4i64>; // 4 x i64
def llvm_v8i64_ty : LLVMType<v8i64>; // 8 x i64
def llvm_v16i64_ty : LLVMType<v16i64>; // 16 x i64
+def llvm_v1i128_ty : LLVMType<v1i128>; // 1 x i128
+
def llvm_v2f16_ty : LLVMType<v2f16>; // 2 x half (__fp16)
def llvm_v4f16_ty : LLVMType<v4f16>; // 4 x half (__fp16)
def llvm_v8f16_ty : LLVMType<v8f16>; // 8 x half (__fp16)
@@ -259,12 +268,12 @@ def int_gcwrite : Intrinsic<[],
//
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
-def int_frameallocate : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
+def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>;
def int_framerecover : Intrinsic<[llvm_ptr_ty],
- [llvm_ptr_ty, llvm_ptr_ty],
- [IntrNoMem]>;
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
- [IntrNoMem], "llvm.read_register">;
+ [IntrReadMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
[], "llvm.write_register">;
@@ -409,6 +418,19 @@ def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
+// eh.begincatch takes a pointer returned by a landingpad instruction and
+// copies the exception object into the memory pointed to by the second
+// parameter. If the second parameter is null, no copy occurs.
+def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+ [NoCapture<0>, NoCapture<1>]>;
+def int_eh_endcatch : Intrinsic<[], []>;
+
+// Represents the list of actions to take when an exception is thrown.
+def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
+
+def int_eh_exceptioncode : Intrinsic<[llvm_i32_ty], []>;
+def int_eh_exceptioninfo : Intrinsic<[llvm_ptr_ty], []>;
+
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
// callee-saved registers to be saved and restored (regardless of whether they
// are used) in the calling function. It is used by libgcc_eh.
@@ -513,17 +535,20 @@ def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
// These are documented in docs/Statepoint.rst
def int_experimental_gc_statepoint : Intrinsic<[llvm_i32_ty],
- [llvm_anyptr_ty, llvm_i32_ty,
+ [llvm_i64_ty, llvm_i32_ty,
+ llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty, llvm_vararg_ty]>;
+def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
+def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
+
+// Deprecated: will be removed in a couple of weeks
def int_experimental_gc_result_int : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty]>;
-def int_experimental_gc_result_float : Intrinsic<[llvm_anyfloat_ty],
+def int_experimental_gc_result_float : Intrinsic<[llvm_anyfloat_ty],
[llvm_i32_ty]>;
def int_experimental_gc_result_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty]>;
-def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
-
//===-------------------------- Other Intrinsics --------------------------===//
//
def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
@@ -581,6 +606,23 @@ def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[LLVMPointerTo<0>, llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
[IntrReadArgMem]>;
+
+def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
+ [LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ LLVMVectorSameWidth<0, llvm_i1_ty>,
+ LLVMMatchType<0>],
+ [IntrReadArgMem]>;
+
+def int_masked_scatter: Intrinsic<[],
+ [llvm_anyvector_ty,
+ LLVMVectorOfPointersToElt<0>, llvm_i32_ty,
+ LLVMVectorSameWidth<0, llvm_i1_ty>],
+ [IntrReadWriteArgMem]>;
+
+// Intrinsics to support bit sets.
+def int_bitset_test : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty],
+ [IntrNoMem]>;
+
//===----------------------------------------------------------------------===//
// Target-specific intrinsics
//===----------------------------------------------------------------------===//
@@ -594,3 +636,5 @@ include "llvm/IR/IntrinsicsHexagon.td"
include "llvm/IR/IntrinsicsNVVM.td"
include "llvm/IR/IntrinsicsMips.td"
include "llvm/IR/IntrinsicsR600.td"
+include "llvm/IR/IntrinsicsBPF.td"
+include "llvm/IR/IntrinsicsSystemZ.td"
diff --git a/include/llvm/IR/IntrinsicsBPF.td b/include/llvm/IR/IntrinsicsBPF.td
new file mode 100644
index 000000000000..94eca8e40332
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsBPF.td
@@ -0,0 +1,24 @@
+//===- IntrinsicsBPF.td - Defines BPF intrinsics -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the BPF-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+// Specialized loads from packet
+let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
+ def int_bpf_load_byte : GCCBuiltin<"__builtin_bpf_load_byte">,
+ Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>;
+ def int_bpf_load_half : GCCBuiltin<"__builtin_bpf_load_half">,
+ Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>;
+ def int_bpf_load_word : GCCBuiltin<"__builtin_bpf_load_word">,
+ Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>;
+ def int_bpf_pseudo : GCCBuiltin<"__builtin_bpf_pseudo">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty]>;
+}
diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td
index 8a8872931f36..78ee651d20f9 100644
--- a/include/llvm/IR/IntrinsicsHexagon.td
+++ b/include/llvm/IR/IntrinsicsHexagon.td
@@ -254,7 +254,7 @@ class Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
//
class Hexagon_qi_qiqiqi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [llvm_i1_ty], [llvm_i1_ty, llvm_i1_ty, llvm_i1_ty],
[IntrNoMem]>;
//
// DEF_FUNCTION_TYPE_2(SI_ftype_QIQI,BT_INT,BT_BOOL,BT_BOOL) ->
@@ -422,19 +422,49 @@ class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
+class Hexagon_mem_memmemsi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memsisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memdisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
llvm_i32_ty, llvm_i32_ty],
[IntrReadWriteArgMem]>;
+class Hexagon_mem_memsisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
//
// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
//
class Hexagon_sf_si_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_float_ty], [llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
//
@@ -490,21 +520,21 @@ class Hexagon_si_df_Intrinsic<string GCCIntSuffix>
class Hexagon_sf_sfsf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
-// Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+// Hexagon_si_sfsf_Intrinsic<string GCCIntSuffix>
//
-class Hexagon_qi_sfsf_Intrinsic<string GCCIntSuffix>
+class Hexagon_si_sfsf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i1_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem]>;
+ [llvm_i32_ty], [llvm_float_ty, llvm_float_ty],
+ [IntrNoMem, Throws]>;
//
-// Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+// Hexagon_si_sfsi_Intrinsic<string GCCIntSuffix>
//
-class Hexagon_qi_sfsi_Intrinsic<string GCCIntSuffix>
+class Hexagon_si_sfsi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i1_ty], [llvm_float_ty, llvm_i32_ty],
- [IntrNoMem]>;
+ [llvm_i32_ty], [llvm_float_ty, llvm_i32_ty],
+ [IntrNoMem, Throws]>;
//
// Hexagon_qi_sfqi_Intrinsic<string GCCIntSuffix>
//
@@ -519,7 +549,7 @@ class Hexagon_sf_sfsfsf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_float_ty], [llvm_float_ty, llvm_float_ty,
llvm_float_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
// Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
//
@@ -528,7 +558,7 @@ class Hexagon_sf_sfsfsfqi_Intrinsic<string GCCIntSuffix>
[llvm_float_ty], [llvm_float_ty, llvm_float_ty,
llvm_float_ty,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
// Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
//
@@ -543,7 +573,7 @@ class Hexagon_di_dididisi_Intrinsic<string GCCIntSuffix>
class Hexagon_df_si_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_double_ty], [llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
// Hexagon_df_di_Intrinsic<string GCCIntSuffix>
//
@@ -571,21 +601,21 @@ class Hexagon_df_df_Intrinsic<string GCCIntSuffix>
class Hexagon_df_dfdf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
-// Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+// Hexagon_si_dfdf_Intrinsic<string GCCIntSuffix>
//
-class Hexagon_qi_dfdf_Intrinsic<string GCCIntSuffix>
+class Hexagon_si_dfdf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i1_ty], [llvm_double_ty, llvm_double_ty],
- [IntrNoMem]>;
+ [llvm_i32_ty], [llvm_double_ty, llvm_double_ty],
+ [IntrNoMem, Throws]>;
//
-// Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+// Hexagon_si_dfsi_Intrinsic<string GCCIntSuffix>
//
-class Hexagon_qi_dfsi_Intrinsic<string GCCIntSuffix>
+class Hexagon_si_dfsi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i1_ty], [llvm_double_ty, llvm_i32_ty],
- [IntrNoMem]>;
+ [llvm_i32_ty], [llvm_double_ty, llvm_i32_ty],
+ [IntrNoMem, Throws]>;
//
//
// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
@@ -594,7 +624,7 @@ class Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_double_ty], [llvm_double_ty, llvm_double_ty,
llvm_double_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
//
// Hexagon_df_dfdfdf_Intrinsic<string GCCIntSuffix>
//
@@ -603,53 +633,159 @@ class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix>
[llvm_double_ty], [llvm_double_ty, llvm_double_ty,
llvm_double_ty,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, Throws]>;
-// This one below will not be generated from iset.py.
-// So make sure, you don't overwrite this one.
+// This one below will not be auto-generated,
+// so make sure, you don't overwrite this one.
//
// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
//
def int_hexagon_SI_to_SXTHI_asrh :
Hexagon_si_si_Intrinsic<"SI_to_SXTHI_asrh">;
//
+// BUILTIN_INFO_NONCONST(brev_ldd,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldd :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldd">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldw,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldw :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldw">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldh,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldh :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldh">;
+//
+// BUILTIN_INFO_NONCONST(brev_lduh,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_lduh :
+Hexagon_mem_memmemsi_Intrinsic<"brev_lduh">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldb,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldb :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldb">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldub,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldub :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldub">;
+//
// BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4)
//
def int_hexagon_circ_ldd :
Hexagon_mem_memmemsisi_Intrinsic<"circ_ldd">;
-// This one above will not be generated from iset.py.
-// So make sure, you don't overwrite this one.
+//
+// BUILTIN_INFO_NONCONST(circ_ldw,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldw :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldw">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldh,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldh :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldh">;
+//
+// BUILTIN_INFO_NONCONST(circ_lduh,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_lduh :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_lduh">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldb,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldb :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldb">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldub,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldub :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldub">;
+
+//
+// BUILTIN_INFO_NONCONST(brev_stb,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_stb :
+Hexagon_mem_memsisi_Intrinsic<"brev_stb">;
+//
+// BUILTIN_INFO_NONCONST(brev_sthhi,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_sthhi :
+Hexagon_mem_memsisi_Intrinsic<"brev_sthhi">;
+//
+// BUILTIN_INFO_NONCONST(brev_sth,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_sth :
+Hexagon_mem_memsisi_Intrinsic<"brev_sth">;
+//
+// BUILTIN_INFO_NONCONST(brev_stw,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_stw :
+Hexagon_mem_memsisi_Intrinsic<"brev_stw">;
+//
+// BUILTIN_INFO_NONCONST(brev_std,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_std :
+Hexagon_mem_memdisi_Intrinsic<"brev_std">;
+//
+// BUILTIN_INFO_NONCONST(circ_std,PTR_ftype_PTRDISISI,4)
+//
+def int_hexagon_circ_std :
+Hexagon_mem_memdisisi_Intrinsic<"circ_std">;
+//
+// BUILTIN_INFO_NONCONST(circ_stw,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_stw :
+Hexagon_mem_memsisisi_Intrinsic<"circ_stw">;
+//
+// BUILTIN_INFO_NONCONST(circ_sth,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_sth :
+Hexagon_mem_memsisisi_Intrinsic<"circ_sth">;
+//
+// BUILTIN_INFO_NONCONST(circ_sthhi,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_sthhi :
+Hexagon_mem_memsisisi_Intrinsic<"circ_sthhi">;
+//
+// BUILTIN_INFO_NONCONST(circ_stb,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_stb :
+Hexagon_mem_memsisisi_Intrinsic<"circ_stb">;
+
+
//
// BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpeq :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeq">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpeq">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgt,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgt :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgt">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgt">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtu,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgtu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgtu">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpeqp,QI_ftype_DIDI,2)
//
def int_hexagon_C2_cmpeqp :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpeqp">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_C2_cmpeqp">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtp,QI_ftype_DIDI,2)
//
def int_hexagon_C2_cmpgtp :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtp">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_C2_cmpgtp">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtup,QI_ftype_DIDI,2)
//
def int_hexagon_C2_cmpgtup :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_C2_cmpgtup">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_C2_cmpgtup">;
//
// BUILTIN_INFO(HEXAGON.A4_rcmpeqi,SI_ftype_SISI,2)
//
@@ -674,182 +810,182 @@ Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_rcmpneq">;
// BUILTIN_INFO(HEXAGON.C2_bitsset,QI_ftype_SISI,2)
//
def int_hexagon_C2_bitsset :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsset">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_bitsset">;
//
// BUILTIN_INFO(HEXAGON.C2_bitsclr,QI_ftype_SISI,2)
//
def int_hexagon_C2_bitsclr :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclr">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_bitsclr">;
//
// BUILTIN_INFO(HEXAGON.C4_nbitsset,QI_ftype_SISI,2)
//
def int_hexagon_C4_nbitsset :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsset">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_nbitsset">;
//
// BUILTIN_INFO(HEXAGON.C4_nbitsclr,QI_ftype_SISI,2)
//
def int_hexagon_C4_nbitsclr :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclr">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_nbitsclr">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpeqi,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpeqi :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpeqi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpeqi">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgti,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgti :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgti">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgti">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgtui,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgtui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgtui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgtui">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgei,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgei :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgei">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgei">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpgeui,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpgeui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpgeui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpgeui">;
//
// BUILTIN_INFO(HEXAGON.C2_cmplt,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmplt :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmplt">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmplt">;
//
// BUILTIN_INFO(HEXAGON.C2_cmpltu,QI_ftype_SISI,2)
//
def int_hexagon_C2_cmpltu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_cmpltu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_cmpltu">;
//
// BUILTIN_INFO(HEXAGON.C2_bitsclri,QI_ftype_SISI,2)
//
def int_hexagon_C2_bitsclri :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C2_bitsclri">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_bitsclri">;
//
// BUILTIN_INFO(HEXAGON.C4_nbitsclri,QI_ftype_SISI,2)
//
def int_hexagon_C4_nbitsclri :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_nbitsclri">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_nbitsclri">;
//
// BUILTIN_INFO(HEXAGON.C4_cmpneqi,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmpneqi :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneqi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmpneqi">;
//
// BUILTIN_INFO(HEXAGON.C4_cmpltei,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmpltei :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpltei">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmpltei">;
//
// BUILTIN_INFO(HEXAGON.C4_cmplteui,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmplteui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmplteui">;
//
// BUILTIN_INFO(HEXAGON.C4_cmpneq,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmpneq :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmpneq">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmpneq">;
//
// BUILTIN_INFO(HEXAGON.C4_cmplte,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmplte :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplte">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmplte">;
//
// BUILTIN_INFO(HEXAGON.C4_cmplteu,QI_ftype_SISI,2)
//
def int_hexagon_C4_cmplteu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_C4_cmplteu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C4_cmplteu">;
//
// BUILTIN_INFO(HEXAGON.C2_and,QI_ftype_QIQI,2)
//
def int_hexagon_C2_and :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_and">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_and">;
//
// BUILTIN_INFO(HEXAGON.C2_or,QI_ftype_QIQI,2)
//
def int_hexagon_C2_or :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_or">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_or">;
//
// BUILTIN_INFO(HEXAGON.C2_xor,QI_ftype_QIQI,2)
//
def int_hexagon_C2_xor :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_xor">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_xor">;
//
// BUILTIN_INFO(HEXAGON.C2_andn,QI_ftype_QIQI,2)
//
def int_hexagon_C2_andn :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_andn">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_andn">;
//
// BUILTIN_INFO(HEXAGON.C2_not,QI_ftype_QI,1)
//
def int_hexagon_C2_not :
-Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_not">;
+Hexagon_si_si_Intrinsic<"HEXAGON_C2_not">;
//
// BUILTIN_INFO(HEXAGON.C2_orn,QI_ftype_QIQI,2)
//
def int_hexagon_C2_orn :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C2_orn">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_C2_orn">;
//
// BUILTIN_INFO(HEXAGON.C4_and_and,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_and_and :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_and_and">;
//
// BUILTIN_INFO(HEXAGON.C4_and_or,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_and_or :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_and_or">;
//
// BUILTIN_INFO(HEXAGON.C4_or_and,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_or_and :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_and">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_or_and">;
//
// BUILTIN_INFO(HEXAGON.C4_or_or,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_or_or :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_or">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_or_or">;
//
// BUILTIN_INFO(HEXAGON.C4_and_andn,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_and_andn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_andn">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_and_andn">;
//
// BUILTIN_INFO(HEXAGON.C4_and_orn,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_and_orn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_and_orn">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_and_orn">;
//
// BUILTIN_INFO(HEXAGON.C4_or_andn,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_or_andn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_andn">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_or_andn">;
//
// BUILTIN_INFO(HEXAGON.C4_or_orn,QI_ftype_QIQIQI,3)
//
def int_hexagon_C4_or_orn :
-Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON_C4_or_orn">;
+Hexagon_si_sisisi_Intrinsic<"HEXAGON_C4_or_orn">;
//
// BUILTIN_INFO(HEXAGON.C2_pxfer_map,QI_ftype_QI,1)
//
def int_hexagon_C2_pxfer_map :
-Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_pxfer_map">;
+Hexagon_si_qi_Intrinsic<"HEXAGON_C2_pxfer_map">;
//
// BUILTIN_INFO(HEXAGON.C2_any8,QI_ftype_QI,1)
//
def int_hexagon_C2_any8 :
-Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_any8">;
+Hexagon_si_qi_Intrinsic<"HEXAGON_C2_any8">;
//
// BUILTIN_INFO(HEXAGON.C2_all8,QI_ftype_QI,1)
//
def int_hexagon_C2_all8 :
-Hexagon_qi_qi_Intrinsic<"HEXAGON_C2_all8">;
+Hexagon_si_qi_Intrinsic<"HEXAGON_C2_all8">;
//
// BUILTIN_INFO(HEXAGON.C2_vitpack,SI_ftype_QIQI,2)
//
@@ -889,167 +1025,167 @@ Hexagon_di_qi_Intrinsic<"HEXAGON_C2_mask">;
// BUILTIN_INFO(HEXAGON.A2_vcmpbeq,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpbeq :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbeq">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpbeq">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpbeqi,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpbeqi :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbeqi">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpbeqi">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpbeq_any,QI_ftype_DIDI,2)
//
def int_hexagon_A4_vcmpbeq_any :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpbgtu,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpbgtu :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpbgtui,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpbgtui :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgtui">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpbgtui">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpbgt,QI_ftype_DIDI,2)
//
def int_hexagon_A4_vcmpbgt :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A4_vcmpbgt">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A4_vcmpbgt">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpbgti,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpbgti :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpbgti">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpbgti">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbeq,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbeq :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeq">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbeq">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbeqi,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbeqi :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbeqi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbeqi">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbgtu,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbgtu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbgtu">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbgtui,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbgtui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgtui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbgtui">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbgt,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbgt :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgt">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbgt">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpbgti,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpbgti :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpbgti">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpbgti">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpheq,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpheq :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpheq">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpheq">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmphgt,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmphgt :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgt">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmphgt">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmphgtu,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmphgtu :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmphgtu">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmphgtu">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpheqi,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpheqi :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpheqi">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpheqi">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmphgti,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmphgti :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgti">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmphgti">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmphgtui,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmphgtui :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmphgtui">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmphgtui">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpheq,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpheq :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheq">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpheq">;
//
// BUILTIN_INFO(HEXAGON.A4_cmphgt,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmphgt :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgt">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmphgt">;
//
// BUILTIN_INFO(HEXAGON.A4_cmphgtu,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmphgtu :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtu">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmphgtu">;
//
// BUILTIN_INFO(HEXAGON.A4_cmpheqi,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmpheqi :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmpheqi">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmpheqi">;
//
// BUILTIN_INFO(HEXAGON.A4_cmphgti,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmphgti :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgti">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmphgti">;
//
// BUILTIN_INFO(HEXAGON.A4_cmphgtui,QI_ftype_SISI,2)
//
def int_hexagon_A4_cmphgtui :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_A4_cmphgtui">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_A4_cmphgtui">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpweq,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpweq :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpweq">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpweq">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpwgt,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpwgt :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgt">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpwgt">;
//
// BUILTIN_INFO(HEXAGON.A2_vcmpwgtu,QI_ftype_DIDI,2)
//
def int_hexagon_A2_vcmpwgtu :
-Hexagon_qi_didi_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
+Hexagon_si_didi_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpweqi,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpweqi :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpweqi">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpweqi">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpwgti,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpwgti :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgti">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpwgti">;
//
// BUILTIN_INFO(HEXAGON.A4_vcmpwgtui,QI_ftype_DISI,2)
//
def int_hexagon_A4_vcmpwgtui :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_vcmpwgtui">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_vcmpwgtui">;
//
// BUILTIN_INFO(HEXAGON.A4_boundscheck,QI_ftype_SIDI,2)
//
def int_hexagon_A4_boundscheck :
-Hexagon_qi_sidi_Intrinsic<"HEXAGON_A4_boundscheck">;
+Hexagon_si_sidi_Intrinsic<"HEXAGON_A4_boundscheck">;
//
// BUILTIN_INFO(HEXAGON.A4_tlbmatch,QI_ftype_DISI,2)
//
def int_hexagon_A4_tlbmatch :
-Hexagon_qi_disi_Intrinsic<"HEXAGON_A4_tlbmatch">;
+Hexagon_si_disi_Intrinsic<"HEXAGON_A4_tlbmatch">;
//
// BUILTIN_INFO(HEXAGON.C2_tfrpr,SI_ftype_QI,1)
//
@@ -1059,17 +1195,17 @@ Hexagon_si_qi_Intrinsic<"HEXAGON_C2_tfrpr">;
// BUILTIN_INFO(HEXAGON.C2_tfrrp,QI_ftype_SI,1)
//
def int_hexagon_C2_tfrrp :
-Hexagon_qi_si_Intrinsic<"HEXAGON_C2_tfrrp">;
+Hexagon_si_si_Intrinsic<"HEXAGON_C2_tfrrp">;
//
// BUILTIN_INFO(HEXAGON.C4_fastcorner9,QI_ftype_QIQI,2)
//
def int_hexagon_C4_fastcorner9 :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9">;
+Hexagon_si_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9">;
//
// BUILTIN_INFO(HEXAGON.C4_fastcorner9_not,QI_ftype_QIQI,2)
//
def int_hexagon_C4_fastcorner9_not :
-Hexagon_qi_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
+Hexagon_si_qiqi_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
//
// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s0,SI_ftype_SISISI,3)
//
@@ -2849,7 +2985,7 @@ Hexagon_di_di_Intrinsic<"HEXAGON_A2_tfrp">;
// BUILTIN_INFO(HEXAGON.A2_tfrpi,DI_ftype_SI,1)
//
def int_hexagon_A2_tfrpi :
-Hexagon_di_si_Intrinsic<"HEXAGON_A2_tfrpi">;
+Hexagon_di_di_Intrinsic<"HEXAGON_A2_tfrpi">;
//
// BUILTIN_INFO(HEXAGON.A2_zxtb,SI_ftype_SI,1)
//
@@ -3609,22 +3745,22 @@ Hexagon_sf_sfsfsf_Intrinsic<"HEXAGON_F2_sffms_lib">;
// BUILTIN_INFO(HEXAGON.F2_sfcmpeq,QI_ftype_SFSF,2)
//
def int_hexagon_F2_sfcmpeq :
-Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpeq">;
+Hexagon_si_sfsf_Intrinsic<"HEXAGON_F2_sfcmpeq">;
//
// BUILTIN_INFO(HEXAGON.F2_sfcmpgt,QI_ftype_SFSF,2)
//
def int_hexagon_F2_sfcmpgt :
-Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpgt">;
+Hexagon_si_sfsf_Intrinsic<"HEXAGON_F2_sfcmpgt">;
//
// BUILTIN_INFO(HEXAGON.F2_sfcmpge,QI_ftype_SFSF,2)
//
def int_hexagon_F2_sfcmpge :
-Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpge">;
+Hexagon_si_sfsf_Intrinsic<"HEXAGON_F2_sfcmpge">;
//
// BUILTIN_INFO(HEXAGON.F2_sfcmpuo,QI_ftype_SFSF,2)
//
def int_hexagon_F2_sfcmpuo :
-Hexagon_qi_sfsf_Intrinsic<"HEXAGON_F2_sfcmpuo">;
+Hexagon_si_sfsf_Intrinsic<"HEXAGON_F2_sfcmpuo">;
//
// BUILTIN_INFO(HEXAGON.F2_sfmax,SF_ftype_SFSF,2)
//
@@ -3639,7 +3775,7 @@ Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sfmin">;
// BUILTIN_INFO(HEXAGON.F2_sfclass,QI_ftype_SFSI,2)
//
def int_hexagon_F2_sfclass :
-Hexagon_qi_sfsi_Intrinsic<"HEXAGON_F2_sfclass">;
+Hexagon_si_sfsi_Intrinsic<"HEXAGON_F2_sfclass">;
//
// BUILTIN_INFO(HEXAGON.F2_sfimm_p,SF_ftype_SI,1)
//
@@ -3666,80 +3802,30 @@ Hexagon_sf_sfsf_Intrinsic<"HEXAGON_F2_sffixupd">;
def int_hexagon_F2_sffixupr :
Hexagon_sf_sf_Intrinsic<"HEXAGON_F2_sffixupr">;
//
-// BUILTIN_INFO(HEXAGON.F2_dfadd,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dfadd :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfadd">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dfsub,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dfsub :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfsub">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dfmpy,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dfmpy :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmpy">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffma,DF_ftype_DFDFDF,3)
-//
-def int_hexagon_F2_dffma :
-Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffms,DF_ftype_DFDFDF,3)
-//
-def int_hexagon_F2_dffms :
-Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffma_lib,DF_ftype_DFDFDF,3)
-//
-def int_hexagon_F2_dffma_lib :
-Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffma_lib">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffms_lib,DF_ftype_DFDFDF,3)
-//
-def int_hexagon_F2_dffms_lib :
-Hexagon_df_dfdfdf_Intrinsic<"HEXAGON_F2_dffms_lib">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffma_sc,DF_ftype_DFDFDFQI,4)
-//
-def int_hexagon_F2_dffma_sc :
-Hexagon_df_dfdfdfqi_Intrinsic<"HEXAGON_F2_dffma_sc">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dfmax,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dfmax :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmax">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dfmin,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dfmin :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dfmin">;
-//
// BUILTIN_INFO(HEXAGON.F2_dfcmpeq,QI_ftype_DFDF,2)
//
def int_hexagon_F2_dfcmpeq :
-Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpeq">;
+Hexagon_si_dfdf_Intrinsic<"HEXAGON_F2_dfcmpeq">;
//
// BUILTIN_INFO(HEXAGON.F2_dfcmpgt,QI_ftype_DFDF,2)
//
def int_hexagon_F2_dfcmpgt :
-Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpgt">;
+Hexagon_si_dfdf_Intrinsic<"HEXAGON_F2_dfcmpgt">;
//
// BUILTIN_INFO(HEXAGON.F2_dfcmpge,QI_ftype_DFDF,2)
//
def int_hexagon_F2_dfcmpge :
-Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpge">;
+Hexagon_si_dfdf_Intrinsic<"HEXAGON_F2_dfcmpge">;
//
// BUILTIN_INFO(HEXAGON.F2_dfcmpuo,QI_ftype_DFDF,2)
//
def int_hexagon_F2_dfcmpuo :
-Hexagon_qi_dfdf_Intrinsic<"HEXAGON_F2_dfcmpuo">;
+Hexagon_si_dfdf_Intrinsic<"HEXAGON_F2_dfcmpuo">;
//
// BUILTIN_INFO(HEXAGON.F2_dfclass,QI_ftype_DFSI,2)
//
def int_hexagon_F2_dfclass :
-Hexagon_qi_dfsi_Intrinsic<"HEXAGON_F2_dfclass">;
+Hexagon_si_dfsi_Intrinsic<"HEXAGON_F2_dfclass">;
//
// BUILTIN_INFO(HEXAGON.F2_dfimm_p,DF_ftype_SI,1)
//
@@ -3751,21 +3837,6 @@ Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_p">;
def int_hexagon_F2_dfimm_n :
Hexagon_df_si_Intrinsic<"HEXAGON_F2_dfimm_n">;
//
-// BUILTIN_INFO(HEXAGON.F2_dffixupn,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dffixupn :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupn">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffixupd,DF_ftype_DFDF,2)
-//
-def int_hexagon_F2_dffixupd :
-Hexagon_df_dfdf_Intrinsic<"HEXAGON_F2_dffixupd">;
-//
-// BUILTIN_INFO(HEXAGON.F2_dffixupr,DF_ftype_DF,1)
-//
-def int_hexagon_F2_dffixupr :
-Hexagon_df_df_Intrinsic<"HEXAGON_F2_dffixupr">;
-//
// BUILTIN_INFO(HEXAGON.F2_conv_sf2df,DF_ftype_SF,1)
//
def int_hexagon_F2_conv_sf2df :
@@ -4494,12 +4565,12 @@ Hexagon_di_didi_Intrinsic<"HEXAGON_S2_extractup_rp">;
// BUILTIN_INFO(HEXAGON.S2_tstbit_i,QI_ftype_SISI,2)
//
def int_hexagon_S2_tstbit_i :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_i">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_tstbit_i">;
//
// BUILTIN_INFO(HEXAGON.S4_ntstbit_i,QI_ftype_SISI,2)
//
def int_hexagon_S4_ntstbit_i :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_i">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_ntstbit_i">;
//
// BUILTIN_INFO(HEXAGON.S2_setbit_i,SI_ftype_SISI,2)
//
@@ -4519,12 +4590,12 @@ Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_clrbit_i">;
// BUILTIN_INFO(HEXAGON.S2_tstbit_r,QI_ftype_SISI,2)
//
def int_hexagon_S2_tstbit_r :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_S2_tstbit_r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S2_tstbit_r">;
//
// BUILTIN_INFO(HEXAGON.S4_ntstbit_r,QI_ftype_SISI,2)
//
def int_hexagon_S4_ntstbit_r :
-Hexagon_qi_sisi_Intrinsic<"HEXAGON_S4_ntstbit_r">;
+Hexagon_si_sisi_Intrinsic<"HEXAGON_S4_ntstbit_r">;
//
// BUILTIN_INFO(HEXAGON.S2_setbit_r,SI_ftype_SISI,2)
//
@@ -4875,3 +4946,21 @@ Hexagon_di_di_Intrinsic<"HEXAGON_S2_interleave">;
//
def int_hexagon_S2_deinterleave :
Hexagon_di_di_Intrinsic<"HEXAGON_S2_deinterleave">;
+
+def llvm_ptr32_ty : LLVMPointerType<llvm_i32_ty>;
+def llvm_ptr64_ty : LLVMPointerType<llvm_i64_ty>;
+
+// Mark locked loads as read/write to prevent any accidental reordering.
+def int_hexagon_L2_loadw_locked :
+Hexagon_Intrinsic<"HEXAGON_L2_loadw_locked", [llvm_i32_ty], [llvm_ptr32_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+def int_hexagon_L4_loadd_locked :
+Hexagon_Intrinsic<"HEXAGON_L4_loadd_locked", [llvm_i64_ty], [llvm_ptr64_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+
+def int_hexagon_S2_storew_locked :
+Hexagon_Intrinsic<"HEXAGON_S2_storew_locked", [llvm_i32_ty],
+ [llvm_ptr32_ty, llvm_i32_ty], [IntrReadWriteArgMem, NoCapture<0>]>;
+def int_hexagon_S4_stored_locked :
+Hexagon_Intrinsic<"HEXAGON_S4_stored_locked", [llvm_i32_ty],
+ [llvm_ptr64_ty, llvm_i64_ty], [IntrReadWriteArgMem, NoCapture<0>]>;
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index 5cdabdeadaea..79654695837d 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -24,7 +24,8 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty],
[IntrReadWriteArgMem, NoCapture<0>]>;
- def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
@@ -37,6 +38,25 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// generated by the PowerPC backend!
def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>;
+
+ // Intrinsics for [double]word extended forms of divide instructions
+ def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_divweu : GCCBuiltin<"__builtin_divweu">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_divde : GCCBuiltin<"__builtin_divde">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_divdeu : GCCBuiltin<"__builtin_divdeu">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+
+ // Bit permute doubleword
+ def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
}
@@ -73,7 +93,7 @@ class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
-/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
+/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16i8
/// vectors and returns one. These intrinsics have no side effects.
class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix>
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
@@ -94,6 +114,19 @@ class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
+/// PowerPC_Vec_DDD_Intrinsic - A PowerPC intrinsic that takes two v2i64
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_DDD_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_QQQ_Intrinsic - A PowerPC intrinsic that takes two v1i128
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_QQQ_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v1i128_ty], [llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Class Definitions.
@@ -120,7 +153,6 @@ class PowerPC_VSX_Sca_DDD_Intrinsic<string GCCIntSuffix>
[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
[IntrNoMem]>;
-
//===----------------------------------------------------------------------===//
// PowerPC Altivec Intrinsic Definitions.
@@ -198,7 +230,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
-
+
+ def int_ppc_altivec_vcmpequd : GCCBuiltin<"__builtin_altivec_vcmpequd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsd : GCCBuiltin<"__builtin_altivec_vcmpgtsd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtud : GCCBuiltin<"__builtin_altivec_vcmpgtud">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
@@ -242,7 +284,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">,
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
[IntrNoMem]>;
-
+
+ def int_ppc_altivec_vcmpequd_p : GCCBuiltin<"__builtin_altivec_vcmpequd_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsd_p : GCCBuiltin<"__builtin_altivec_vcmpgtsd_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtud_p : GCCBuiltin<"__builtin_altivec_vcmpgtud_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+
def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
[IntrNoMem]>;
@@ -287,18 +339,22 @@ def int_ppc_altivec_vmaxfp : PowerPC_Vec_FFF_Intrinsic<"vmaxfp">;
def int_ppc_altivec_vmaxsb : PowerPC_Vec_BBB_Intrinsic<"vmaxsb">;
def int_ppc_altivec_vmaxsh : PowerPC_Vec_HHH_Intrinsic<"vmaxsh">;
def int_ppc_altivec_vmaxsw : PowerPC_Vec_WWW_Intrinsic<"vmaxsw">;
+def int_ppc_altivec_vmaxsd : PowerPC_Vec_DDD_Intrinsic<"vmaxsd">;
def int_ppc_altivec_vmaxub : PowerPC_Vec_BBB_Intrinsic<"vmaxub">;
def int_ppc_altivec_vmaxuh : PowerPC_Vec_HHH_Intrinsic<"vmaxuh">;
def int_ppc_altivec_vmaxuw : PowerPC_Vec_WWW_Intrinsic<"vmaxuw">;
+def int_ppc_altivec_vmaxud : PowerPC_Vec_DDD_Intrinsic<"vmaxud">;
// Vector minimum.
def int_ppc_altivec_vminfp : PowerPC_Vec_FFF_Intrinsic<"vminfp">;
def int_ppc_altivec_vminsb : PowerPC_Vec_BBB_Intrinsic<"vminsb">;
def int_ppc_altivec_vminsh : PowerPC_Vec_HHH_Intrinsic<"vminsh">;
def int_ppc_altivec_vminsw : PowerPC_Vec_WWW_Intrinsic<"vminsw">;
+def int_ppc_altivec_vminsd : PowerPC_Vec_DDD_Intrinsic<"vminsd">;
def int_ppc_altivec_vminub : PowerPC_Vec_BBB_Intrinsic<"vminub">;
def int_ppc_altivec_vminuh : PowerPC_Vec_HHH_Intrinsic<"vminuh">;
def int_ppc_altivec_vminuw : PowerPC_Vec_WWW_Intrinsic<"vminuw">;
+def int_ppc_altivec_vminud : PowerPC_Vec_DDD_Intrinsic<"vminud">;
// Saturating adds.
def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">;
@@ -308,6 +364,7 @@ def int_ppc_altivec_vaddshs : PowerPC_Vec_HHH_Intrinsic<"vaddshs">;
def int_ppc_altivec_vadduws : PowerPC_Vec_WWW_Intrinsic<"vadduws">;
def int_ppc_altivec_vaddsws : PowerPC_Vec_WWW_Intrinsic<"vaddsws">;
def int_ppc_altivec_vaddcuw : PowerPC_Vec_WWW_Intrinsic<"vaddcuw">;
+def int_ppc_altivec_vaddcuq : PowerPC_Vec_QQQ_Intrinsic<"vaddcuq">;
// Saturating subs.
def int_ppc_altivec_vsububs : PowerPC_Vec_BBB_Intrinsic<"vsububs">;
@@ -317,6 +374,7 @@ def int_ppc_altivec_vsubshs : PowerPC_Vec_HHH_Intrinsic<"vsubshs">;
def int_ppc_altivec_vsubuws : PowerPC_Vec_WWW_Intrinsic<"vsubuws">;
def int_ppc_altivec_vsubsws : PowerPC_Vec_WWW_Intrinsic<"vsubsws">;
def int_ppc_altivec_vsubcuw : PowerPC_Vec_WWW_Intrinsic<"vsubcuw">;
+def int_ppc_altivec_vsubcuq : PowerPC_Vec_QQQ_Intrinsic<"vsubcuq">;
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
// Saturating multiply-adds.
@@ -361,12 +419,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulesw : GCCBuiltin<"__builtin_altivec_vmulesw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmuleuw : GCCBuiltin<"__builtin_altivec_vmuleuw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
@@ -374,12 +438,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulosw : GCCBuiltin<"__builtin_altivec_vmulosw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulouw : GCCBuiltin<"__builtin_altivec_vmulouw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
// Vector Sum Intructions.
def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
@@ -419,6 +489,12 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vpksdss : GCCBuiltin<"__builtin_altivec_vpksdss">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpksdus : GCCBuiltin<"__builtin_altivec_vpksdus">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
// vpkuhum is lowered to a shuffle.
def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
@@ -427,6 +503,10 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
+ // vpkudum is lowered to a shuffle.
+ def int_ppc_altivec_vpkudus : GCCBuiltin<"__builtin_altivec_vpkudus">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
// Unpacks.
def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
@@ -435,12 +515,16 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vupkhsh : GCCBuiltin<"__builtin_altivec_vupkhsh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupkhsw : GCCBuiltin<"__builtin_altivec_vupkhsw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
def int_ppc_altivec_vupklpx : GCCBuiltin<"__builtin_altivec_vupklpx">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
def int_ppc_altivec_vupklsb : GCCBuiltin<"__builtin_altivec_vupklsb">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_altivec_vupklsh : GCCBuiltin<"__builtin_altivec_vupklsh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklsw : GCCBuiltin<"__builtin_altivec_vupklsw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
// FP <-> integer conversion.
@@ -465,6 +549,26 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
def int_ppc_altivec_vrfiz : GCCBuiltin<"__builtin_altivec_vrfiz">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+ // Add Extended Quadword
+ def int_ppc_altivec_vaddeuqm : GCCBuiltin<"__builtin_altivec_vaddeuqm">,
+ Intrinsic<[llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vaddecuq : GCCBuiltin<"__builtin_altivec_vaddecuq">,
+ Intrinsic<[llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+
+ // Sub Extended Quadword
+ def int_ppc_altivec_vsubeuqm : GCCBuiltin<"__builtin_altivec_vsubeuqm">,
+ Intrinsic<[llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsubecuq : GCCBuiltin<"__builtin_altivec_vsubecuq">,
+ Intrinsic<[llvm_v1i128_ty],
+ [llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
+ [IntrNoMem]>;
}
def int_ppc_altivec_vsl : PowerPC_Vec_WWW_Intrinsic<"vsl">;
@@ -489,6 +593,7 @@ def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">;
def int_ppc_altivec_vrlb : PowerPC_Vec_BBB_Intrinsic<"vrlb">;
def int_ppc_altivec_vrlh : PowerPC_Vec_HHH_Intrinsic<"vrlh">;
def int_ppc_altivec_vrlw : PowerPC_Vec_WWW_Intrinsic<"vrlw">;
+def int_ppc_altivec_vrld : PowerPC_Vec_DDD_Intrinsic<"vrld">;
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
// Miscellaneous.
@@ -510,6 +615,42 @@ def int_ppc_altivec_vlogefp : PowerPC_Vec_FF_Intrinsic<"vlogefp">;
def int_ppc_altivec_vrefp : PowerPC_Vec_FF_Intrinsic<"vrefp">;
def int_ppc_altivec_vrsqrtefp : PowerPC_Vec_FF_Intrinsic<"vrsqrtefp">;
+// Power8 Intrinsics
+// Crypto
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ def int_ppc_altivec_crypto_vsbox :
+ GCCBuiltin<"__builtin_altivec_crypto_vsbox">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_crypto_vpermxor :
+ GCCBuiltin<"__builtin_altivec_crypto_vpermxor">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+def int_ppc_altivec_crypto_vshasigmad :
+ GCCBuiltin<"__builtin_altivec_crypto_vshasigmad">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_altivec_crypto_vshasigmaw :
+ GCCBuiltin<"__builtin_altivec_crypto_vshasigmaw">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+def int_ppc_altivec_crypto_vcipher :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vcipher">;
+def int_ppc_altivec_crypto_vcipherlast :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vcipherlast">;
+def int_ppc_altivec_crypto_vncipher :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vncipher">;
+def int_ppc_altivec_crypto_vncipherlast :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vncipherlast">;
+def int_ppc_altivec_crypto_vpmsumb :
+ PowerPC_Vec_BBB_Intrinsic<"crypto_vpmsumb">;
+def int_ppc_altivec_crypto_vpmsumh :
+ PowerPC_Vec_HHH_Intrinsic<"crypto_vpmsumh">;
+def int_ppc_altivec_crypto_vpmsumw :
+ PowerPC_Vec_WWW_Intrinsic<"crypto_vpmsumw">;
+def int_ppc_altivec_crypto_vpmsumd :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vpmsumd">;
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Definitions.
@@ -542,3 +683,239 @@ def int_ppc_vsx_xsmindp : PowerPC_VSX_Sca_DDD_Intrinsic<"xsmindp">;
def int_ppc_vsx_xvdivdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvdivdp">;
def int_ppc_vsx_xvdivsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvdivsp">;
}
+
+//===----------------------------------------------------------------------===//
+// PowerPC QPX Intrinsics.
+//
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ /// PowerPC_QPX_Intrinsic - Base class for all QPX intrinsics.
+ class PowerPC_QPX_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
+ list<LLVMType> param_types,
+ list<IntrinsicProperty> properties>
+ : GCCBuiltin<!strconcat("__builtin_qpx_", GCCIntSuffix)>,
+ Intrinsic<ret_types, param_types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+// PowerPC QPX Intrinsic Class Definitions.
+//
+
+/// PowerPC_QPX_FF_Intrinsic - A PowerPC intrinsic that takes one v4f64
+/// vector and returns one. These intrinsics have no side effects.
+class PowerPC_QPX_FF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+
+/// PowerPC_QPX_FFF_Intrinsic - A PowerPC intrinsic that takes two v4f64
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_QPX_FFF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_QPX_FFFF_Intrinsic - A PowerPC intrinsic that takes three v4f64
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_QPX_FFFF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_QPX_Load_Intrinsic - A PowerPC intrinsic that takes a pointer
+/// and returns a v4f64.
+class PowerPC_QPX_Load_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
+
+/// PowerPC_QPX_LoadPerm_Intrinsic - A PowerPC intrinsic that takes a pointer
+/// and returns a v4f64 permutation.
+class PowerPC_QPX_LoadPerm_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [llvm_v4f64_ty], [llvm_ptr_ty], [IntrNoMem]>;
+
+/// PowerPC_QPX_Store_Intrinsic - A PowerPC intrinsic that takes a pointer
+/// and stores a v4f64.
+class PowerPC_QPX_Store_Intrinsic<string GCCIntSuffix>
+ : PowerPC_QPX_Intrinsic<GCCIntSuffix,
+ [], [llvm_v4f64_ty, llvm_ptr_ty],
+ [IntrReadWriteArgMem]>;
+
+//===----------------------------------------------------------------------===//
+// PowerPC QPX Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+ // Add Instructions
+ def int_ppc_qpx_qvfadd : PowerPC_QPX_FFF_Intrinsic<"qvfadd">;
+ def int_ppc_qpx_qvfadds : PowerPC_QPX_FFF_Intrinsic<"qvfadds">;
+ def int_ppc_qpx_qvfsub : PowerPC_QPX_FFF_Intrinsic<"qvfsub">;
+ def int_ppc_qpx_qvfsubs : PowerPC_QPX_FFF_Intrinsic<"qvfsubs">;
+
+ // Estimate Instructions
+ def int_ppc_qpx_qvfre : PowerPC_QPX_FF_Intrinsic<"qvfre">;
+ def int_ppc_qpx_qvfres : PowerPC_QPX_FF_Intrinsic<"qvfres">;
+ def int_ppc_qpx_qvfrsqrte : PowerPC_QPX_FF_Intrinsic<"qvfrsqrte">;
+ def int_ppc_qpx_qvfrsqrtes : PowerPC_QPX_FF_Intrinsic<"qvfrsqrtes">;
+
+ // Multiply Instructions
+ def int_ppc_qpx_qvfmul : PowerPC_QPX_FFF_Intrinsic<"qvfmul">;
+ def int_ppc_qpx_qvfmuls : PowerPC_QPX_FFF_Intrinsic<"qvfmuls">;
+ def int_ppc_qpx_qvfxmul : PowerPC_QPX_FFF_Intrinsic<"qvfxmul">;
+ def int_ppc_qpx_qvfxmuls : PowerPC_QPX_FFF_Intrinsic<"qvfxmuls">;
+
+ // Multiply-add instructions
+ def int_ppc_qpx_qvfmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfmadd">;
+ def int_ppc_qpx_qvfmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfmadds">;
+ def int_ppc_qpx_qvfnmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfnmadd">;
+ def int_ppc_qpx_qvfnmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfnmadds">;
+ def int_ppc_qpx_qvfmsub : PowerPC_QPX_FFFF_Intrinsic<"qvfmsub">;
+ def int_ppc_qpx_qvfmsubs : PowerPC_QPX_FFFF_Intrinsic<"qvfmsubs">;
+ def int_ppc_qpx_qvfnmsub : PowerPC_QPX_FFFF_Intrinsic<"qvfnmsub">;
+ def int_ppc_qpx_qvfnmsubs : PowerPC_QPX_FFFF_Intrinsic<"qvfnmsubs">;
+ def int_ppc_qpx_qvfxmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfxmadd">;
+ def int_ppc_qpx_qvfxmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfxmadds">;
+ def int_ppc_qpx_qvfxxnpmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfxxnpmadd">;
+ def int_ppc_qpx_qvfxxnpmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfxxnpmadds">;
+ def int_ppc_qpx_qvfxxcpnmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfxxcpnmadd">;
+ def int_ppc_qpx_qvfxxcpnmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfxxcpnmadds">;
+ def int_ppc_qpx_qvfxxmadd : PowerPC_QPX_FFFF_Intrinsic<"qvfxxmadd">;
+ def int_ppc_qpx_qvfxxmadds : PowerPC_QPX_FFFF_Intrinsic<"qvfxxmadds">;
+
+ // Select Instruction
+ def int_ppc_qpx_qvfsel : PowerPC_QPX_FFFF_Intrinsic<"qvfsel">;
+
+ // Permute Instruction
+ def int_ppc_qpx_qvfperm : PowerPC_QPX_FFFF_Intrinsic<"qvfperm">;
+
+ // Convert and Round Instructions
+ def int_ppc_qpx_qvfctid : PowerPC_QPX_FF_Intrinsic<"qvfctid">;
+ def int_ppc_qpx_qvfctidu : PowerPC_QPX_FF_Intrinsic<"qvfctidu">;
+ def int_ppc_qpx_qvfctidz : PowerPC_QPX_FF_Intrinsic<"qvfctidz">;
+ def int_ppc_qpx_qvfctiduz : PowerPC_QPX_FF_Intrinsic<"qvfctiduz">;
+ def int_ppc_qpx_qvfctiw : PowerPC_QPX_FF_Intrinsic<"qvfctiw">;
+ def int_ppc_qpx_qvfctiwu : PowerPC_QPX_FF_Intrinsic<"qvfctiwu">;
+ def int_ppc_qpx_qvfctiwz : PowerPC_QPX_FF_Intrinsic<"qvfctiwz">;
+ def int_ppc_qpx_qvfctiwuz : PowerPC_QPX_FF_Intrinsic<"qvfctiwuz">;
+ def int_ppc_qpx_qvfcfid : PowerPC_QPX_FF_Intrinsic<"qvfcfid">;
+ def int_ppc_qpx_qvfcfidu : PowerPC_QPX_FF_Intrinsic<"qvfcfidu">;
+ def int_ppc_qpx_qvfcfids : PowerPC_QPX_FF_Intrinsic<"qvfcfids">;
+ def int_ppc_qpx_qvfcfidus : PowerPC_QPX_FF_Intrinsic<"qvfcfidus">;
+ def int_ppc_qpx_qvfrsp : PowerPC_QPX_FF_Intrinsic<"qvfrsp">;
+ def int_ppc_qpx_qvfriz : PowerPC_QPX_FF_Intrinsic<"qvfriz">;
+ def int_ppc_qpx_qvfrin : PowerPC_QPX_FF_Intrinsic<"qvfrin">;
+ def int_ppc_qpx_qvfrip : PowerPC_QPX_FF_Intrinsic<"qvfrip">;
+ def int_ppc_qpx_qvfrim : PowerPC_QPX_FF_Intrinsic<"qvfrim">;
+
+ // Move Instructions
+ def int_ppc_qpx_qvfneg : PowerPC_QPX_FF_Intrinsic<"qvfneg">;
+ def int_ppc_qpx_qvfabs : PowerPC_QPX_FF_Intrinsic<"qvfabs">;
+ def int_ppc_qpx_qvfnabs : PowerPC_QPX_FF_Intrinsic<"qvfnabs">;
+ def int_ppc_qpx_qvfcpsgn : PowerPC_QPX_FFF_Intrinsic<"qvfcpsgn">;
+
+ // Compare Instructions
+ def int_ppc_qpx_qvftstnan : PowerPC_QPX_FFF_Intrinsic<"qvftstnan">;
+ def int_ppc_qpx_qvfcmplt : PowerPC_QPX_FFF_Intrinsic<"qvfcmplt">;
+ def int_ppc_qpx_qvfcmpgt : PowerPC_QPX_FFF_Intrinsic<"qvfcmpgt">;
+ def int_ppc_qpx_qvfcmpeq : PowerPC_QPX_FFF_Intrinsic<"qvfcmpeq">;
+
+ // Load instructions
+ def int_ppc_qpx_qvlfd : PowerPC_QPX_Load_Intrinsic<"qvlfd">;
+ def int_ppc_qpx_qvlfda : PowerPC_QPX_Load_Intrinsic<"qvlfda">;
+ def int_ppc_qpx_qvlfs : PowerPC_QPX_Load_Intrinsic<"qvlfs">;
+ def int_ppc_qpx_qvlfsa : PowerPC_QPX_Load_Intrinsic<"qvlfsa">;
+
+ def int_ppc_qpx_qvlfcda : PowerPC_QPX_Load_Intrinsic<"qvlfcda">;
+ def int_ppc_qpx_qvlfcd : PowerPC_QPX_Load_Intrinsic<"qvlfcd">;
+ def int_ppc_qpx_qvlfcsa : PowerPC_QPX_Load_Intrinsic<"qvlfcsa">;
+ def int_ppc_qpx_qvlfcs : PowerPC_QPX_Load_Intrinsic<"qvlfcs">;
+ def int_ppc_qpx_qvlfiwaa : PowerPC_QPX_Load_Intrinsic<"qvlfiwaa">;
+ def int_ppc_qpx_qvlfiwa : PowerPC_QPX_Load_Intrinsic<"qvlfiwa">;
+ def int_ppc_qpx_qvlfiwza : PowerPC_QPX_Load_Intrinsic<"qvlfiwza">;
+ def int_ppc_qpx_qvlfiwz : PowerPC_QPX_Load_Intrinsic<"qvlfiwz">;
+
+ def int_ppc_qpx_qvlpcld : PowerPC_QPX_LoadPerm_Intrinsic<"qvlpcld">;
+ def int_ppc_qpx_qvlpcls : PowerPC_QPX_LoadPerm_Intrinsic<"qvlpcls">;
+ def int_ppc_qpx_qvlpcrd : PowerPC_QPX_LoadPerm_Intrinsic<"qvlpcrd">;
+ def int_ppc_qpx_qvlpcrs : PowerPC_QPX_LoadPerm_Intrinsic<"qvlpcrs">;
+
+ // Store instructions
+ def int_ppc_qpx_qvstfd : PowerPC_QPX_Store_Intrinsic<"qvstfd">;
+ def int_ppc_qpx_qvstfda : PowerPC_QPX_Store_Intrinsic<"qvstfda">;
+ def int_ppc_qpx_qvstfs : PowerPC_QPX_Store_Intrinsic<"qvstfs">;
+ def int_ppc_qpx_qvstfsa : PowerPC_QPX_Store_Intrinsic<"qvstfsa">;
+
+ def int_ppc_qpx_qvstfcda : PowerPC_QPX_Store_Intrinsic<"qvstfcda">;
+ def int_ppc_qpx_qvstfcd : PowerPC_QPX_Store_Intrinsic<"qvstfcd">;
+ def int_ppc_qpx_qvstfcsa : PowerPC_QPX_Store_Intrinsic<"qvstfcsa">;
+ def int_ppc_qpx_qvstfcs : PowerPC_QPX_Store_Intrinsic<"qvstfcs">;
+ def int_ppc_qpx_qvstfiwa : PowerPC_QPX_Store_Intrinsic<"qvstfiwa">;
+ def int_ppc_qpx_qvstfiw : PowerPC_QPX_Store_Intrinsic<"qvstfiw">;
+
+ // Logical and permutation formation
+ def int_ppc_qpx_qvflogical : PowerPC_QPX_Intrinsic<"qvflogical",
+ [llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_qpx_qvgpci : PowerPC_QPX_Intrinsic<"qvgpci",
+ [llvm_v4f64_ty], [llvm_i32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// PowerPC HTM Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+
+def int_ppc_tbegin : GCCBuiltin<"__builtin_tbegin">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tend : GCCBuiltin<"__builtin_tend">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tabortwc : GCCBuiltin<"__builtin_tabortwc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortwci : GCCBuiltin<"__builtin_tabortwci">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdc : GCCBuiltin<"__builtin_tabortdc">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdci : GCCBuiltin<"__builtin_tabortdci">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsr : GCCBuiltin<"__builtin_tsr">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_texasru : GCCBuiltin<"__builtin_get_texasru">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfhar : GCCBuiltin<"__builtin_get_tfhar">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfiar : GCCBuiltin<"__builtin_get_tfiar">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+
+def int_ppc_set_texasr : GCCBuiltin<"__builtin_set_texasr">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_texasru : GCCBuiltin<"__builtin_set_texasru">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfhar : GCCBuiltin<"__builtin_set_tfhar">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfiar : GCCBuiltin<"__builtin_set_tfiar">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+
+// Extended mnemonics
+def int_ppc_tendall : GCCBuiltin<"__builtin_tendall">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tresume : GCCBuiltin<"__builtin_tresume">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+
+def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+}
diff --git a/include/llvm/IR/IntrinsicsSystemZ.td b/include/llvm/IR/IntrinsicsSystemZ.td
new file mode 100644
index 000000000000..96e7ca525696
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsSystemZ.td
@@ -0,0 +1,376 @@
+//===- IntrinsicsSystemZ.td - Defines SystemZ intrinsics ---*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the SystemZ-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+class SystemZUnaryConv<string name, LLVMType result, LLVMType arg>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[result], [arg], [IntrNoMem]>;
+
+class SystemZUnary<string name, LLVMType type>
+ : SystemZUnaryConv<name, type, type>;
+
+class SystemZUnaryConvCC<LLVMType result, LLVMType arg>
+ : Intrinsic<[result, llvm_i32_ty], [arg], [IntrNoMem]>;
+
+class SystemZUnaryCC<LLVMType type>
+ : SystemZUnaryConvCC<type, type>;
+
+class SystemZBinaryConv<string name, LLVMType result, LLVMType arg>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[result], [arg, arg], [IntrNoMem]>;
+
+class SystemZBinary<string name, LLVMType type>
+ : SystemZBinaryConv<name, type, type>;
+
+class SystemZBinaryInt<string name, LLVMType type>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[type], [type, llvm_i32_ty], [IntrNoMem]>;
+
+class SystemZBinaryConvCC<LLVMType result, LLVMType arg>
+ : Intrinsic<[result, llvm_i32_ty], [arg, arg], [IntrNoMem]>;
+
+class SystemZBinaryConvIntCC<LLVMType result, LLVMType arg>
+ : Intrinsic<[result, llvm_i32_ty], [arg, llvm_i32_ty], [IntrNoMem]>;
+
+class SystemZBinaryCC<LLVMType type>
+ : SystemZBinaryConvCC<type, type>;
+
+class SystemZTernaryConv<string name, LLVMType result, LLVMType arg>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[result], [arg, arg, result], [IntrNoMem]>;
+
+class SystemZTernary<string name, LLVMType type>
+ : SystemZTernaryConv<name, type, type>;
+
+class SystemZTernaryInt<string name, LLVMType type>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem]>;
+
+class SystemZTernaryIntCC<LLVMType type>
+ : Intrinsic<[type, llvm_i32_ty], [type, type, llvm_i32_ty], [IntrNoMem]>;
+
+class SystemZQuaternaryInt<string name, LLVMType type>
+ : GCCBuiltin<"__builtin_s390_" ## name>,
+ Intrinsic<[type], [type, type, type, llvm_i32_ty], [IntrNoMem]>;
+
+class SystemZQuaternaryIntCC<LLVMType type>
+ : Intrinsic<[type, llvm_i32_ty], [type, type, type, llvm_i32_ty],
+ [IntrNoMem]>;
+
+multiclass SystemZUnaryExtBHF<string name> {
+ def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZUnaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+}
+
+multiclass SystemZUnaryExtBHWF<string name> {
+ def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def hw : SystemZUnaryConv<name##"hw", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+}
+
+multiclass SystemZUnaryBHF<string name> {
+ def b : SystemZUnary<name##"b", llvm_v16i8_ty>;
+ def h : SystemZUnary<name##"h", llvm_v8i16_ty>;
+ def f : SystemZUnary<name##"f", llvm_v4i32_ty>;
+}
+
+multiclass SystemZUnaryBHFG<string name> : SystemZUnaryBHF<name> {
+ def g : SystemZUnary<name##"g", llvm_v2i64_ty>;
+}
+
+multiclass SystemZUnaryCCBHF {
+ def bs : SystemZUnaryCC<llvm_v16i8_ty>;
+ def hs : SystemZUnaryCC<llvm_v8i16_ty>;
+ def fs : SystemZUnaryCC<llvm_v4i32_ty>;
+}
+
+multiclass SystemZBinaryTruncHFG<string name> {
+ def h : SystemZBinaryConv<name##"h", llvm_v16i8_ty, llvm_v8i16_ty>;
+ def f : SystemZBinaryConv<name##"f", llvm_v8i16_ty, llvm_v4i32_ty>;
+ def g : SystemZBinaryConv<name##"g", llvm_v4i32_ty, llvm_v2i64_ty>;
+}
+
+multiclass SystemZBinaryTruncCCHFG {
+ def hs : SystemZBinaryConvCC<llvm_v16i8_ty, llvm_v8i16_ty>;
+ def fs : SystemZBinaryConvCC<llvm_v8i16_ty, llvm_v4i32_ty>;
+ def gs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v2i64_ty>;
+}
+
+multiclass SystemZBinaryExtBHF<string name> {
+ def b : SystemZBinaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZBinaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZBinaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+}
+
+multiclass SystemZBinaryExtBHFG<string name> : SystemZBinaryExtBHF<name> {
+ def g : SystemZBinaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
+}
+
+multiclass SystemZBinaryBHF<string name> {
+ def b : SystemZBinary<name##"b", llvm_v16i8_ty>;
+ def h : SystemZBinary<name##"h", llvm_v8i16_ty>;
+ def f : SystemZBinary<name##"f", llvm_v4i32_ty>;
+}
+
+multiclass SystemZBinaryBHFG<string name> : SystemZBinaryBHF<name> {
+ def g : SystemZBinary<name##"g", llvm_v2i64_ty>;
+}
+
+multiclass SystemZBinaryIntBHFG<string name> {
+ def b : SystemZBinaryInt<name##"b", llvm_v16i8_ty>;
+ def h : SystemZBinaryInt<name##"h", llvm_v8i16_ty>;
+ def f : SystemZBinaryInt<name##"f", llvm_v4i32_ty>;
+ def g : SystemZBinaryInt<name##"g", llvm_v2i64_ty>;
+}
+
+multiclass SystemZBinaryCCBHF {
+ def bs : SystemZBinaryCC<llvm_v16i8_ty>;
+ def hs : SystemZBinaryCC<llvm_v8i16_ty>;
+ def fs : SystemZBinaryCC<llvm_v4i32_ty>;
+}
+
+multiclass SystemZCompareBHFG<string name> {
+ def bs : SystemZBinaryCC<llvm_v16i8_ty>;
+ def hs : SystemZBinaryCC<llvm_v8i16_ty>;
+ def fs : SystemZBinaryCC<llvm_v4i32_ty>;
+ def gs : SystemZBinaryCC<llvm_v2i64_ty>;
+}
+
+multiclass SystemZTernaryExtBHF<string name> {
+ def b : SystemZTernaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZTernaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZTernaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+}
+
+multiclass SystemZTernaryExtBHFG<string name> : SystemZTernaryExtBHF<name> {
+ def g : SystemZTernaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
+}
+
+multiclass SystemZTernaryBHF<string name> {
+ def b : SystemZTernary<name##"b", llvm_v16i8_ty>;
+ def h : SystemZTernary<name##"h", llvm_v8i16_ty>;
+ def f : SystemZTernary<name##"f", llvm_v4i32_ty>;
+}
+
+multiclass SystemZTernaryIntBHF<string name> {
+ def b : SystemZTernaryInt<name##"b", llvm_v16i8_ty>;
+ def h : SystemZTernaryInt<name##"h", llvm_v8i16_ty>;
+ def f : SystemZTernaryInt<name##"f", llvm_v4i32_ty>;
+}
+
+multiclass SystemZTernaryIntCCBHF {
+ def bs : SystemZTernaryIntCC<llvm_v16i8_ty>;
+ def hs : SystemZTernaryIntCC<llvm_v8i16_ty>;
+ def fs : SystemZTernaryIntCC<llvm_v4i32_ty>;
+}
+
+multiclass SystemZQuaternaryIntBHF<string name> {
+ def b : SystemZQuaternaryInt<name##"b", llvm_v16i8_ty>;
+ def h : SystemZQuaternaryInt<name##"h", llvm_v8i16_ty>;
+ def f : SystemZQuaternaryInt<name##"f", llvm_v4i32_ty>;
+}
+
+multiclass SystemZQuaternaryIntBHFG<string name> : SystemZQuaternaryIntBHF<name> {
+ def g : SystemZQuaternaryInt<name##"g", llvm_v2i64_ty>;
+}
+
+multiclass SystemZQuaternaryIntCCBHF {
+ def bs : SystemZQuaternaryIntCC<llvm_v16i8_ty>;
+ def hs : SystemZQuaternaryIntCC<llvm_v8i16_ty>;
+ def fs : SystemZQuaternaryIntCC<llvm_v4i32_ty>;
+}
+
+//===----------------------------------------------------------------------===//
+//
+// Transactional-execution intrinsics
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "s390" in {
+ def int_s390_tbegin : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tbegin_nofloat : Intrinsic<[llvm_i32_ty],
+ [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tbeginc : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoDuplicate]>;
+
+ def int_s390_tabort : Intrinsic<[], [llvm_i64_ty],
+ [IntrNoReturn, Throws]>;
+
+ def int_s390_tend : GCCBuiltin<"__builtin_tend">,
+ Intrinsic<[llvm_i32_ty], []>;
+
+ def int_s390_etnd : GCCBuiltin<"__builtin_tx_nesting_depth">,
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+
+ def int_s390_ntstg : Intrinsic<[], [llvm_i64_ty, llvm_ptr64_ty],
+ [IntrReadWriteArgMem]>;
+
+ def int_s390_ppa_txassist : GCCBuiltin<"__builtin_tx_assist">,
+ Intrinsic<[], [llvm_i32_ty]>;
+}
+
+//===----------------------------------------------------------------------===//
+//
+// Vector intrinsics
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "s390" in {
+ def int_s390_lcbb : GCCBuiltin<"__builtin_s390_lcbb">,
+ Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_s390_vlbb : GCCBuiltin<"__builtin_s390_vlbb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadArgMem]>;
+
+ def int_s390_vll : GCCBuiltin<"__builtin_s390_vll">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty],
+ [IntrReadArgMem]>;
+
+ def int_s390_vpdi : GCCBuiltin<"__builtin_s390_vpdi">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_s390_vperm : GCCBuiltin<"__builtin_s390_vperm">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+ defm int_s390_vpks : SystemZBinaryTruncHFG<"vpks">;
+ defm int_s390_vpks : SystemZBinaryTruncCCHFG;
+
+ defm int_s390_vpkls : SystemZBinaryTruncHFG<"vpkls">;
+ defm int_s390_vpkls : SystemZBinaryTruncCCHFG;
+
+ def int_s390_vstl : GCCBuiltin<"__builtin_s390_vstl">,
+ Intrinsic<[], [llvm_v16i8_ty, llvm_i32_ty, llvm_ptr_ty],
+ // In fact write-only but there's no property
+ // for that.
+ [IntrReadWriteArgMem]>;
+
+ defm int_s390_vupl : SystemZUnaryExtBHWF<"vupl">;
+ defm int_s390_vupll : SystemZUnaryExtBHF<"vupll">;
+
+ defm int_s390_vuph : SystemZUnaryExtBHF<"vuph">;
+ defm int_s390_vuplh : SystemZUnaryExtBHF<"vuplh">;
+
+ defm int_s390_vacc : SystemZBinaryBHFG<"vacc">;
+
+ def int_s390_vaq : SystemZBinary<"vaq", llvm_v16i8_ty>;
+ def int_s390_vacq : SystemZTernary<"vacq", llvm_v16i8_ty>;
+ def int_s390_vaccq : SystemZBinary<"vaccq", llvm_v16i8_ty>;
+ def int_s390_vacccq : SystemZTernary<"vacccq", llvm_v16i8_ty>;
+
+ defm int_s390_vavg : SystemZBinaryBHFG<"vavg">;
+ defm int_s390_vavgl : SystemZBinaryBHFG<"vavgl">;
+
+ def int_s390_vcksm : SystemZBinary<"vcksm", llvm_v4i32_ty>;
+
+ defm int_s390_vgfm : SystemZBinaryExtBHFG<"vgfm">;
+ defm int_s390_vgfma : SystemZTernaryExtBHFG<"vgfma">;
+
+ defm int_s390_vmah : SystemZTernaryBHF<"vmah">;
+ defm int_s390_vmalh : SystemZTernaryBHF<"vmalh">;
+ defm int_s390_vmae : SystemZTernaryExtBHF<"vmae">;
+ defm int_s390_vmale : SystemZTernaryExtBHF<"vmale">;
+ defm int_s390_vmao : SystemZTernaryExtBHF<"vmao">;
+ defm int_s390_vmalo : SystemZTernaryExtBHF<"vmalo">;
+
+ defm int_s390_vmh : SystemZBinaryBHF<"vmh">;
+ defm int_s390_vmlh : SystemZBinaryBHF<"vmlh">;
+ defm int_s390_vme : SystemZBinaryExtBHF<"vme">;
+ defm int_s390_vmle : SystemZBinaryExtBHF<"vmle">;
+ defm int_s390_vmo : SystemZBinaryExtBHF<"vmo">;
+ defm int_s390_vmlo : SystemZBinaryExtBHF<"vmlo">;
+
+ defm int_s390_verllv : SystemZBinaryBHFG<"verllv">;
+ defm int_s390_verll : SystemZBinaryIntBHFG<"verll">;
+ defm int_s390_verim : SystemZQuaternaryIntBHFG<"verim">;
+
+ def int_s390_vsl : SystemZBinary<"vsl", llvm_v16i8_ty>;
+ def int_s390_vslb : SystemZBinary<"vslb", llvm_v16i8_ty>;
+ def int_s390_vsra : SystemZBinary<"vsra", llvm_v16i8_ty>;
+ def int_s390_vsrab : SystemZBinary<"vsrab", llvm_v16i8_ty>;
+ def int_s390_vsrl : SystemZBinary<"vsrl", llvm_v16i8_ty>;
+ def int_s390_vsrlb : SystemZBinary<"vsrlb", llvm_v16i8_ty>;
+
+ def int_s390_vsldb : GCCBuiltin<"__builtin_s390_vsldb">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ defm int_s390_vscbi : SystemZBinaryBHFG<"vscbi">;
+
+ def int_s390_vsq : SystemZBinary<"vsq", llvm_v16i8_ty>;
+ def int_s390_vsbiq : SystemZTernary<"vsbiq", llvm_v16i8_ty>;
+ def int_s390_vscbiq : SystemZBinary<"vscbiq", llvm_v16i8_ty>;
+ def int_s390_vsbcbiq : SystemZTernary<"vsbcbiq", llvm_v16i8_ty>;
+
+ def int_s390_vsumb : SystemZBinaryConv<"vsumb", llvm_v4i32_ty, llvm_v16i8_ty>;
+ def int_s390_vsumh : SystemZBinaryConv<"vsumh", llvm_v4i32_ty, llvm_v8i16_ty>;
+
+ def int_s390_vsumgh : SystemZBinaryConv<"vsumgh", llvm_v2i64_ty,
+ llvm_v8i16_ty>;
+ def int_s390_vsumgf : SystemZBinaryConv<"vsumgf", llvm_v2i64_ty,
+ llvm_v4i32_ty>;
+
+ def int_s390_vsumqf : SystemZBinaryConv<"vsumqf", llvm_v16i8_ty,
+ llvm_v4i32_ty>;
+ def int_s390_vsumqg : SystemZBinaryConv<"vsumqg", llvm_v16i8_ty,
+ llvm_v2i64_ty>;
+
+ def int_s390_vtm : SystemZBinaryConv<"vtm", llvm_i32_ty, llvm_v16i8_ty>;
+
+ defm int_s390_vceq : SystemZCompareBHFG<"vceq">;
+ defm int_s390_vch : SystemZCompareBHFG<"vch">;
+ defm int_s390_vchl : SystemZCompareBHFG<"vchl">;
+
+ defm int_s390_vfae : SystemZTernaryIntBHF<"vfae">;
+ defm int_s390_vfae : SystemZTernaryIntCCBHF;
+ defm int_s390_vfaez : SystemZTernaryIntBHF<"vfaez">;
+ defm int_s390_vfaez : SystemZTernaryIntCCBHF;
+
+ defm int_s390_vfee : SystemZBinaryBHF<"vfee">;
+ defm int_s390_vfee : SystemZBinaryCCBHF;
+ defm int_s390_vfeez : SystemZBinaryBHF<"vfeez">;
+ defm int_s390_vfeez : SystemZBinaryCCBHF;
+
+ defm int_s390_vfene : SystemZBinaryBHF<"vfene">;
+ defm int_s390_vfene : SystemZBinaryCCBHF;
+ defm int_s390_vfenez : SystemZBinaryBHF<"vfenez">;
+ defm int_s390_vfenez : SystemZBinaryCCBHF;
+
+ defm int_s390_vistr : SystemZUnaryBHF<"vistr">;
+ defm int_s390_vistr : SystemZUnaryCCBHF;
+
+ defm int_s390_vstrc : SystemZQuaternaryIntBHF<"vstrc">;
+ defm int_s390_vstrc : SystemZQuaternaryIntCCBHF;
+ defm int_s390_vstrcz : SystemZQuaternaryIntBHF<"vstrcz">;
+ defm int_s390_vstrcz : SystemZQuaternaryIntCCBHF;
+
+ def int_s390_vfcedbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
+ def int_s390_vfchdbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
+ def int_s390_vfchedbs : SystemZBinaryConvCC<llvm_v2i64_ty, llvm_v2f64_ty>;
+
+ def int_s390_vftcidb : SystemZBinaryConvIntCC<llvm_v2i64_ty, llvm_v2f64_ty>;
+
+ def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 81c729065505..3a8a4a643a43 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -18,6 +18,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
}
//===----------------------------------------------------------------------===//
+// SEH LSDA for Windows
+let TargetPrefix = "x86" in {
+ def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
// Read Time Stamp Counter.
let TargetPrefix = "x86" in {
def int_x86_rdtsc : GCCBuiltin<"__builtin_ia32_rdtsc">,
@@ -453,19 +459,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse2_psrai_d : GCCBuiltin<"__builtin_ia32_psradi128">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
llvm_i32_ty], [IntrNoMem]>;
-
- def int_x86_sse2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi128">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_sse2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi128">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_sse2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi128_byteshift">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_sse2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi128_byteshift">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
}
// Conversion ops
@@ -895,15 +888,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb128">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_v16i8_ty],
[IntrNoMem]>;
- def int_x86_sse41_pblendw : GCCBuiltin<"__builtin_ia32_pblendw128">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_sse41_blendpd : GCCBuiltin<"__builtin_ia32_blendpd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_sse41_blendps : GCCBuiltin<"__builtin_ia32_blendps">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem]>;
def int_x86_sse41_blendvpd : GCCBuiltin<"__builtin_ia32_blendvpd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_v2f64_ty],
[IntrNoMem]>;
@@ -1169,12 +1153,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector blend
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_blend_pd_256 : GCCBuiltin<"__builtin_ia32_blendpd256">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_blend_ps_256 : GCCBuiltin<"__builtin_ia32_blendps256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>;
@@ -1200,32 +1178,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
}
-// Vector extract and insert
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_vextractf128_pd_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_pd256">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vextractf128_ps_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_ps256">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vextractf128_si_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_si256">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx_vinsertf128_pd_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_pd256">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vinsertf128_ps_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_ps256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vinsertf128_si_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_si256">,
- Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
- llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
-}
-
// Vector convert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_cvtdq2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtdq2pd256">,
@@ -1363,6 +1315,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_loadu_pd_512 : GCCBuiltin<"__builtin_ia32_loadupd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
[IntrReadArgMem]>;
+ def int_x86_avx512_mask_load_ps_512 : GCCBuiltin<"__builtin_ia32_loadaps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+ [IntrReadArgMem]>;
+ def int_x86_avx512_mask_load_pd_512 : GCCBuiltin<"__builtin_ia32_loadapd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+ [IntrReadArgMem]>;
}
// Conditional store ops
@@ -1389,6 +1347,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_storeupd512_mask">,
Intrinsic<[], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
[IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_store_ps_512 :
+ GCCBuiltin<"__builtin_ia32_storeaps512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+ [IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_store_pd_512 :
+ GCCBuiltin<"__builtin_ia32_storeapd512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+ [IntrReadWriteArgMem]>;
def int_x86_avx512_mask_store_ss :
GCCBuiltin<"__builtin_ia32_storess_mask">,
Intrinsic<[], [llvm_ptr_ty, llvm_v4f32_ty, llvm_i8_ty],
@@ -1448,12 +1414,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">,
Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty,
llvm_v32i8_ty], [IntrNoMem, Commutative]>;
- def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
// Vector min, max
@@ -1572,19 +1532,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi256_byteshift">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi256_byteshift">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
-
def int_x86_avx512_mask_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
llvm_i32_ty, llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
@@ -1746,15 +1693,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb256">,
Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
llvm_v32i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendw : GCCBuiltin<"__builtin_ia32_pblendw256">,
- Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendd_128 : GCCBuiltin<"__builtin_ia32_pblendd128">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendd_256 : GCCBuiltin<"__builtin_ia32_pblendd256">,
- Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
}
// Vector load with broadcast
@@ -1768,8 +1706,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_vbroadcast_ss_ps_256 :
GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
- def int_x86_avx2_vbroadcasti128 :
- Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
def int_x86_avx2_pbroadcastb_128 :
GCCBuiltin<"__builtin_ia32_pbroadcastb128">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
@@ -1823,13 +1759,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector extract and insert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx2_vextracti128 : GCCBuiltin<"__builtin_ia32_extract128i256">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_vinserti128 : GCCBuiltin<"__builtin_ia32_insert128i256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
-
def int_x86_avx512_mask_vextractf32x4_512 :
GCCBuiltin<"__builtin_ia32_extractf32x4_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i8_ty,
@@ -3068,6 +2997,46 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_i64_ty], [IntrNoMem]>;
}
+// Pack ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx512_mask_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packsswb_256 : GCCBuiltin<"__builtin_ia32_packsswb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,llvm_v16i16_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packsswb_512 : GCCBuiltin<"__builtin_ia32_packsswb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packssdw_128 : GCCBuiltin<"__builtin_ia32_packssdw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packssdw_256 : GCCBuiltin<"__builtin_ia32_packssdw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packssdw_512 : GCCBuiltin<"__builtin_ia32_packssdw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packuswb_128 : GCCBuiltin<"__builtin_ia32_packuswb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packuswb_256 : GCCBuiltin<"__builtin_ia32_packuswb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,llvm_v16i16_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packuswb_512 : GCCBuiltin<"__builtin_ia32_packuswb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v32i16_ty,llvm_v32i16_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packusdw_128 : GCCBuiltin<"__builtin_ia32_packusdw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packusdw_256 : GCCBuiltin<"__builtin_ia32_packusdw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_packusdw_512 : GCCBuiltin<"__builtin_ia32_packusdw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
// Vector convert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_cvttps2dq_512: GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">,
@@ -3164,28 +3133,238 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v8i64_ty], [llvm_v8i32_ty],
[IntrNoMem]>;
}
-
+//Bitwise Ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx512_mask_pand_d_128 : GCCBuiltin<"__builtin_ia32_pandd128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_d_256 : GCCBuiltin<"__builtin_ia32_pandd256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_q_128 : GCCBuiltin<"__builtin_ia32_pandq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_q_256 : GCCBuiltin<"__builtin_ia32_pandq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_d_128 : GCCBuiltin<"__builtin_ia32_pandnd128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_d_256 : GCCBuiltin<"__builtin_ia32_pandnd256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_d_512 : GCCBuiltin<"__builtin_ia32_pandnd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_q_128 : GCCBuiltin<"__builtin_ia32_pandnq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_q_256 : GCCBuiltin<"__builtin_ia32_pandnq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pandn_q_512 : GCCBuiltin<"__builtin_ia32_pandnq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_d_128 : GCCBuiltin<"__builtin_ia32_pord128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_d_256 : GCCBuiltin<"__builtin_ia32_pord256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_d_512 : GCCBuiltin<"__builtin_ia32_pord512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_q_128 : GCCBuiltin<"__builtin_ia32_porq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_q_256 : GCCBuiltin<"__builtin_ia32_porq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_por_q_512 : GCCBuiltin<"__builtin_ia32_porq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_d_128 : GCCBuiltin<"__builtin_ia32_pxord128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_d_256 : GCCBuiltin<"__builtin_ia32_pxord256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_d_512 : GCCBuiltin<"__builtin_ia32_pxord512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_q_128 : GCCBuiltin<"__builtin_ia32_pxorq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_q_256 : GCCBuiltin<"__builtin_ia32_pxorq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pxor_q_512 : GCCBuiltin<"__builtin_ia32_pxorq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
// Arithmetic ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+
+ def int_x86_avx512_mask_add_ps_128 : GCCBuiltin<"__builtin_ia32_addps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_ps_256 : GCCBuiltin<"__builtin_ia32_addps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_ps_512 : GCCBuiltin<"__builtin_ia32_addps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_pd_128 : GCCBuiltin<"__builtin_ia32_addpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_pd_256 : GCCBuiltin<"__builtin_ia32_addpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_pd_512 : GCCBuiltin<"__builtin_ia32_addpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_ps_128 : GCCBuiltin<"__builtin_ia32_subps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_ps_256 : GCCBuiltin<"__builtin_ia32_subps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_ps_512 : GCCBuiltin<"__builtin_ia32_subps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_pd_128 : GCCBuiltin<"__builtin_ia32_subpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_pd_256 : GCCBuiltin<"__builtin_ia32_subpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_pd_512 : GCCBuiltin<"__builtin_ia32_subpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_ps_128 : GCCBuiltin<"__builtin_ia32_mulps_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_ps_256 : GCCBuiltin<"__builtin_ia32_mulps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_ps_512 : GCCBuiltin<"__builtin_ia32_mulps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_pd_128 : GCCBuiltin<"__builtin_ia32_mulpd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_pd_256 : GCCBuiltin<"__builtin_ia32_mulpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_pd_512 : GCCBuiltin<"__builtin_ia32_mulpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_ps_128 : GCCBuiltin<"__builtin_ia32_divps_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_ps_256 : GCCBuiltin<"__builtin_ia32_divps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_ps_512 : GCCBuiltin<"__builtin_ia32_divps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_pd_128 : GCCBuiltin<"__builtin_ia32_divpd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_pd_256 : GCCBuiltin<"__builtin_ia32_divpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_pd_512 : GCCBuiltin<"__builtin_ia32_divpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_ps_128 : GCCBuiltin<"__builtin_ia32_maxps_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_ps_256 : GCCBuiltin<"__builtin_ia32_maxps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_pd_128 : GCCBuiltin<"__builtin_ia32_maxpd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_pd_256 : GCCBuiltin<"__builtin_ia32_maxpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_ps_128 : GCCBuiltin<"__builtin_ia32_minps_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_ps_256 : GCCBuiltin<"__builtin_ia32_minps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_pd_128 : GCCBuiltin<"__builtin_ia32_minpd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_pd_256 : GCCBuiltin<"__builtin_ia32_minpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx512_mask_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_ss_round : GCCBuiltin<"__builtin_ia32_addss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_ss_round : GCCBuiltin<"__builtin_ia32_divss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_ss_round : GCCBuiltin<"__builtin_ia32_mulss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_ss_round : GCCBuiltin<"__builtin_ia32_subss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_ss_round : GCCBuiltin<"__builtin_ia32_maxss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_ss_round : GCCBuiltin<"__builtin_ia32_minss_round">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_add_sd_round : GCCBuiltin<"__builtin_ia32_addsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_div_sd_round : GCCBuiltin<"__builtin_ia32_divsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_mul_sd_round : GCCBuiltin<"__builtin_ia32_mulsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_sub_sd_round : GCCBuiltin<"__builtin_ia32_subsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_sd_round : GCCBuiltin<"__builtin_ia32_maxsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_sd_round : GCCBuiltin<"__builtin_ia32_minsd_round">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_mask_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_mask_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_x86_avx512_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtrndss">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
@@ -3265,21 +3444,273 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
}
-
-// Integer shift ops.
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi512_byteshift">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi512_byteshift">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_i32_ty], [IntrNoMem]>;
+// FP logical ops
+let TargetPrefix = "x86" in {
+ def int_x86_avx512_mask_and_pd_128 : GCCBuiltin<"__builtin_ia32_andpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_and_pd_256 : GCCBuiltin<"__builtin_ia32_andpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_and_pd_512 : GCCBuiltin<"__builtin_ia32_andpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_and_ps_128 : GCCBuiltin<"__builtin_ia32_andps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_and_ps_256 : GCCBuiltin<"__builtin_ia32_andps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_and_ps_512 : GCCBuiltin<"__builtin_ia32_andps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_pd_128 : GCCBuiltin<"__builtin_ia32_andnpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_pd_256 : GCCBuiltin<"__builtin_ia32_andnpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_pd_512 : GCCBuiltin<"__builtin_ia32_andnpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_ps_128 : GCCBuiltin<"__builtin_ia32_andnps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_ps_256 : GCCBuiltin<"__builtin_ia32_andnps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_andn_ps_512 : GCCBuiltin<"__builtin_ia32_andnps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_pd_128 : GCCBuiltin<"__builtin_ia32_orpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_pd_256 : GCCBuiltin<"__builtin_ia32_orpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_pd_512 : GCCBuiltin<"__builtin_ia32_orpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_ps_128 : GCCBuiltin<"__builtin_ia32_orps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_ps_256 : GCCBuiltin<"__builtin_ia32_orps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_or_ps_512 : GCCBuiltin<"__builtin_ia32_orps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_mask_xor_pd_128 : GCCBuiltin<"__builtin_ia32_xorpd128_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_xor_pd_256 : GCCBuiltin<"__builtin_ia32_xorpd256_mask">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_xor_pd_512 : GCCBuiltin<"__builtin_ia32_xorpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_xor_ps_128 : GCCBuiltin<"__builtin_ia32_xorps128_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_xor_ps_256 : GCCBuiltin<"__builtin_ia32_xorps256_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_xor_ps_512 : GCCBuiltin<"__builtin_ia32_xorps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty], [IntrNoMem]>;
+}
+// Integer arithmetic ops
+let TargetPrefix = "x86" in {
+ def int_x86_avx512_mask_padd_b_128 : GCCBuiltin<"__builtin_ia32_paddb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_b_256 : GCCBuiltin<"__builtin_ia32_paddb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_b_512 : GCCBuiltin<"__builtin_ia32_paddb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_w_128 : GCCBuiltin<"__builtin_ia32_paddw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_w_256 : GCCBuiltin<"__builtin_ia32_paddw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_w_512 : GCCBuiltin<"__builtin_ia32_paddw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_b_128 : GCCBuiltin<"__builtin_ia32_paddsb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_b_256 : GCCBuiltin<"__builtin_ia32_paddsb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_b_512 : GCCBuiltin<"__builtin_ia32_paddsb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_w_128 : GCCBuiltin<"__builtin_ia32_paddsw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_w_256 : GCCBuiltin<"__builtin_ia32_paddsw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padds_w_512 : GCCBuiltin<"__builtin_ia32_paddsw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_b_128 : GCCBuiltin<"__builtin_ia32_paddusb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_b_256 : GCCBuiltin<"__builtin_ia32_paddusb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_b_512 : GCCBuiltin<"__builtin_ia32_paddusb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_w_128 : GCCBuiltin<"__builtin_ia32_paddusw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_w_256 : GCCBuiltin<"__builtin_ia32_paddusw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_paddus_w_512 : GCCBuiltin<"__builtin_ia32_paddusw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_d_128 : GCCBuiltin<"__builtin_ia32_paddd128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_d_256 : GCCBuiltin<"__builtin_ia32_paddd256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_d_512 : GCCBuiltin<"__builtin_ia32_paddd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_q_128 : GCCBuiltin<"__builtin_ia32_paddq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_q_256 : GCCBuiltin<"__builtin_ia32_paddq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_padd_q_512 : GCCBuiltin<"__builtin_ia32_paddq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_b_128 : GCCBuiltin<"__builtin_ia32_psubb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_b_256 : GCCBuiltin<"__builtin_ia32_psubb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_b_512 : GCCBuiltin<"__builtin_ia32_psubb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_w_128 : GCCBuiltin<"__builtin_ia32_psubw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_w_256 : GCCBuiltin<"__builtin_ia32_psubw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_w_512 : GCCBuiltin<"__builtin_ia32_psubw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_b_128 : GCCBuiltin<"__builtin_ia32_psubsb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_b_256 : GCCBuiltin<"__builtin_ia32_psubsb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_b_512 : GCCBuiltin<"__builtin_ia32_psubsb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_w_128 : GCCBuiltin<"__builtin_ia32_psubsw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_w_256 : GCCBuiltin<"__builtin_ia32_psubsw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubs_w_512 : GCCBuiltin<"__builtin_ia32_psubsw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_b_128 : GCCBuiltin<"__builtin_ia32_psubusb128_mask">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_b_256 : GCCBuiltin<"__builtin_ia32_psubusb256_mask">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_b_512 : GCCBuiltin<"__builtin_ia32_psubusb512_mask">,
+ Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
+ llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_w_128 : GCCBuiltin<"__builtin_ia32_psubusw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_w_256 : GCCBuiltin<"__builtin_ia32_psubusw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psubus_w_512 : GCCBuiltin<"__builtin_ia32_psubusw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_d_128 : GCCBuiltin<"__builtin_ia32_psubd128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_d_256 : GCCBuiltin<"__builtin_ia32_psubd256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_d_512 : GCCBuiltin<"__builtin_ia32_psubd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_q_128 : GCCBuiltin<"__builtin_ia32_psubq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_q_256 : GCCBuiltin<"__builtin_ia32_psubq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_psub_q_512 : GCCBuiltin<"__builtin_ia32_psubq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulu_dq_128 : GCCBuiltin<"__builtin_ia32_pmuludq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_dq_128 : GCCBuiltin<"__builtin_ia32_pmuldq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulu_dq_256 : GCCBuiltin<"__builtin_ia32_pmuludq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_dq_256 : GCCBuiltin<"__builtin_ia32_pmuldq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_w_128 : GCCBuiltin<"__builtin_ia32_pmullw128_mask">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_w_256 : GCCBuiltin<"__builtin_ia32_pmullw256_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_w_512 : GCCBuiltin<"__builtin_ia32_pmullw512_mask">,
+ Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
+ llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_d_128 : GCCBuiltin<"__builtin_ia32_pmulld128_mask">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_d_256 : GCCBuiltin<"__builtin_ia32_pmulld256_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_d_512 : GCCBuiltin<"__builtin_ia32_pmulld512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_q_128 : GCCBuiltin<"__builtin_ia32_pmullq128_mask">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_q_256 : GCCBuiltin<"__builtin_ia32_pmullq256_mask">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmull_q_512 : GCCBuiltin<"__builtin_ia32_pmullq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
// Gather and Scatter ops
@@ -3390,22 +3821,22 @@ let TargetPrefix = "x86" in {
GCCBuiltin<"__builtin_ia32_vpconflictsi_512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
llvm_v16i32_ty, llvm_i16_ty],
- []>;
+ [IntrNoMem]>;
def int_x86_avx512_mask_conflict_q_512 :
GCCBuiltin<"__builtin_ia32_vpconflictdi_512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
llvm_v8i64_ty, llvm_i8_ty],
- []>;
+ [IntrNoMem]>;
def int_x86_avx512_mask_lzcnt_d_512 :
GCCBuiltin<"__builtin_ia32_vplzcntd_512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
llvm_v16i32_ty, llvm_i16_ty],
- []>;
+ [IntrNoMem]>;
def int_x86_avx512_mask_lzcnt_q_512 :
GCCBuiltin<"__builtin_ia32_vplzcntq_512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
llvm_v8i64_ty, llvm_i8_ty],
- []>;
+ [IntrNoMem]>;
}
// Vector blend
@@ -3867,21 +4298,33 @@ let TargetPrefix = "x86" in {
}
// Misc.
let TargetPrefix = "x86" in {
- def int_x86_avx512_mask_cmp_ps_512 : GCCBuiltin<"__builtin_ia32_cmpps512_mask">,
- Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty,
- llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_cmp_pd_512 : GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
- Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty,
- llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_v16i32_ty, llvm_i16_ty],
- [IntrNoMem]>;
- def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
- llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_avx512_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa512">,
+ def int_x86_avx512_mask_cmp_ps_512 :
+ GCCBuiltin<"__builtin_ia32_cmpps512_mask">,
+ Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_pd_512 :
+ GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_ps_256 :
+ GCCBuiltin<"__builtin_ia32_cmpps256_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_pd_256 :
+ GCCBuiltin<"__builtin_ia32_cmppd256_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_ps_128 :
+ GCCBuiltin<"__builtin_ia32_cmpps128_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_pd_128 :
+ GCCBuiltin<"__builtin_ia32_cmppd128_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i32_ty, llvm_i8_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_movntdqa :
+ GCCBuiltin<"__builtin_ia32_movntdqa512">,
Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
}
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index 2f18782a0730..e6c22090ab6d 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -58,7 +58,9 @@ public:
MD_noalias = 8, // "noalias",
MD_nontemporal = 9, // "nontemporal"
MD_mem_parallel_loop_access = 10, // "llvm.mem.parallel_loop_access"
- MD_nonnull = 11 // "nonnull"
+ MD_nonnull = 11, // "nonnull"
+ MD_dereferenceable = 12, // "dereferenceable"
+ MD_dereferenceable_or_null = 13 // "dereferenceable_or_null"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
@@ -176,8 +178,8 @@ public:
}
private:
- LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
- void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
+ LLVMContext(LLVMContext&) = delete;
+ void operator=(LLVMContext&) = delete;
/// addModule - Register a module as being instantiated in this context. If
/// the context is deleted, the module will be deleted as well.
diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h
index 6c04e9dc3d3f..5257a0eed488 100644
--- a/include/llvm/IR/LegacyPassManager.h
+++ b/include/llvm/IR/LegacyPassManager.h
@@ -50,7 +50,7 @@ class PassManager : public PassManagerBase {
public:
PassManager();
- ~PassManager();
+ ~PassManager() override;
void add(Pass *P) override;
@@ -70,7 +70,7 @@ public:
/// FunctionPassManager ctor - This initializes the pass manager. It needs,
/// but does not take ownership of, the specified Module.
explicit FunctionPassManager(Module *M);
- ~FunctionPassManager();
+ ~FunctionPassManager() override;
void add(Pass *P) override;
diff --git a/include/llvm/IR/LegacyPassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h
index e2e4912ef64e..39ae80d797c7 100644
--- a/include/llvm/IR/LegacyPassNameParser.h
+++ b/include/llvm/IR/LegacyPassNameParser.h
@@ -41,14 +41,12 @@ namespace llvm {
//
class PassNameParser : public PassRegistrationListener,
public cl::parser<const PassInfo*> {
- cl::Option *Opt;
public:
- PassNameParser();
- virtual ~PassNameParser();
+ PassNameParser(cl::Option &O);
+ ~PassNameParser() override;
- void initialize(cl::Option &O) {
- Opt = &O;
- cl::parser<const PassInfo*>::initialize(O);
+ void initialize() {
+ cl::parser<const PassInfo*>::initialize();
// Add all of the passes to the map that got initialized before 'this' did.
enumeratePasses();
@@ -69,7 +67,7 @@ public:
// Implement the PassRegistrationListener callbacks used to populate our map
//
void passRegistered(const PassInfo *P) override {
- if (ignorablePass(P) || !Opt) return;
+ if (ignorablePass(P)) return;
if (findOption(P->getPassArgument()) != getNumOptions()) {
errs() << "Two passes with the same argument (-"
<< P->getPassArgument() << ") attempted to be registered!\n";
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index 91a6685f6125..ba14457f7185 100644
--- a/include/llvm/IR/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -60,6 +60,9 @@ public:
/// \brief Return metadata containing a number of branch weights.
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights);
+ /// Return metadata containing the entry count for a function.
+ MDNode *createFunctionEntryCount(uint64_t Count);
+
//===------------------------------------------------------------------===//
// Range metadata.
//===------------------------------------------------------------------===//
@@ -67,6 +70,9 @@ public:
/// \brief Return metadata describing the range [Lo, Hi).
MDNode *createRange(const APInt &Lo, const APInt &Hi);
+ /// \brief Return metadata describing the range [Lo, Hi).
+ MDNode *createRange(Constant *Lo, Constant *Hi);
+
//===------------------------------------------------------------------===//
// AA metadata.
//===------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def
index 2098bb57eb56..f2abff4752f7 100644
--- a/include/llvm/IR/Metadata.def
+++ b/include/llvm/IR/Metadata.def
@@ -1,4 +1,4 @@
-//===- llvm/Metadata.def - Metadata definitions -----------------*- C++ -*-===//
+//===- llvm/IR/Metadata.def - Metadata definitions --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,10 @@
//===----------------------------------------------------------------------===//
#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \
- defined HANDLE_METADATA_BRANCH || defined HANDLE_UNIQUABLE_LEAF || \
- defined HANDLE_UNIQUABLE_BRANCH)
+ defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \
+ defined HANDLE_MDNODE_BRANCH || \
+ defined HANDLE_SPECIALIZED_MDNODE_LEAF || \
+ defined HANDLE_SPECIALIZED_MDNODE_BRANCH)
#error "Missing macro definition of HANDLE_METADATA*"
#endif
@@ -32,28 +34,67 @@
#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)
#endif
-// Handler for leaf nodes under UniquableMDNode.
-#ifndef HANDLE_UNIQUABLE_LEAF
-#define HANDLE_UNIQUABLE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
+// Handler for leaf nodes under MDNode.
+#ifndef HANDLE_MDNODE_LEAF
+#define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
#endif
-// Handler for non-leaf nodes under UniquableMDNode.
-#ifndef HANDLE_UNIQUABLE_BRANCH
-#define HANDLE_UNIQUABLE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS)
+// Handler for non-leaf nodes under MDNode.
+#ifndef HANDLE_MDNODE_BRANCH
+#define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS)
+#endif
+
+// Handler for specialized leaf nodes under MDNode.
+#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF
+#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) HANDLE_MDNODE_LEAF(CLASS)
+#endif
+
+// Handler for specialized non-leaf nodes under MDNode.
+#ifndef HANDLE_SPECIALIZED_MDNODE_BRANCH
+#define HANDLE_SPECIALIZED_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_BRANCH(CLASS)
#endif
HANDLE_METADATA_LEAF(MDString)
HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata)
-HANDLE_METADATA_BRANCH(MDNode)
-HANDLE_METADATA_LEAF(MDNodeFwdDecl)
-HANDLE_UNIQUABLE_BRANCH(UniquableMDNode)
-HANDLE_UNIQUABLE_LEAF(MDTuple)
-HANDLE_UNIQUABLE_LEAF(MDLocation)
+HANDLE_MDNODE_BRANCH(MDNode)
+HANDLE_MDNODE_LEAF(MDTuple)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DILocation)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIExpression)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode)
+HANDLE_SPECIALIZED_MDNODE_LEAF(GenericDINode)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DISubrange)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIEnumerator)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DIScope)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DIType)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIBasicType)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DIDerivedTypeBase)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIDerivedType)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DICompositeTypeBase)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DICompositeType)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DISubroutineType)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIFile)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DICompileUnit)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DILocalScope)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DISubprogram)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlock)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlockFile)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DINamespace)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateTypeParameter)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateValueParameter)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(DIVariable)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIGlobalVariable)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DILocalVariable)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIObjCProperty)
+HANDLE_SPECIALIZED_MDNODE_LEAF(DIImportedEntity)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
#undef HANDLE_METADATA_BRANCH
-#undef HANDLE_UNIQUABLE_LEAF
-#undef HANDLE_UNIQUABLE_BRANCH
+#undef HANDLE_MDNODE_LEAF
+#undef HANDLE_MDNODE_BRANCH
+#undef HANDLE_SPECIALIZED_MDNODE_LEAF
+#undef HANDLE_SPECIALIZED_MDNODE_BRANCH
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index 27a5d6f80041..60718f531bd7 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -1,4 +1,4 @@
-//===-- llvm/Metadata.h - Metadata definitions ------------------*- C++ -*-===//
+//===- llvm/IR/Metadata.h - Metadata definitions ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,9 +32,8 @@ class Module;
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-
enum LLVMConstants : uint32_t {
- DEBUG_METADATA_VERSION = 2 // Current debug info version number.
+ DEBUG_METADATA_VERSION = 3 // Current debug info version number.
};
/// \brief Root of the metadata hierarchy.
@@ -47,8 +46,11 @@ class Metadata {
const unsigned char SubclassID;
protected:
+ /// \brief Active type of storage.
+ enum StorageType { Uniqued, Distinct, Temporary };
+
/// \brief Storage flag for non-uniqued, otherwise unowned, metadata.
- bool IsDistinctInContext : 1;
+ unsigned Storage : 2;
// TODO: expose remaining bits to subclasses.
unsigned short SubclassData16;
@@ -57,21 +59,37 @@ protected:
public:
enum MetadataKind {
MDTupleKind,
- MDLocationKind,
- MDNodeFwdDeclKind,
+ DILocationKind,
+ GenericDINodeKind,
+ DISubrangeKind,
+ DIEnumeratorKind,
+ DIBasicTypeKind,
+ DIDerivedTypeKind,
+ DICompositeTypeKind,
+ DISubroutineTypeKind,
+ DIFileKind,
+ DICompileUnitKind,
+ DISubprogramKind,
+ DILexicalBlockKind,
+ DILexicalBlockFileKind,
+ DINamespaceKind,
+ DITemplateTypeParameterKind,
+ DITemplateValueParameterKind,
+ DIGlobalVariableKind,
+ DILocalVariableKind,
+ DIExpressionKind,
+ DIObjCPropertyKind,
+ DIImportedEntityKind,
ConstantAsMetadataKind,
LocalAsMetadataKind,
MDStringKind
};
protected:
- Metadata(unsigned ID)
- : SubclassID(ID), IsDistinctInContext(false), SubclassData16(0),
- SubclassData32(0) {}
- ~Metadata() {}
-
- /// \brief Store this in a big non-uniqued untyped bucket.
- bool isStoredDistinctInContext() const { return IsDistinctInContext; }
+ Metadata(unsigned ID, StorageType Storage)
+ : SubclassID(ID), Storage(Storage), SubclassData16(0), SubclassData32(0) {
+ }
+ ~Metadata() = default;
/// \brief Default handling of a changed operand, which asserts.
///
@@ -85,15 +103,48 @@ public:
unsigned getMetadataID() const { return SubclassID; }
/// \brief User-friendly dump.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ ///
+ /// Note: this uses an explicit overload instead of default arguments so that
+ /// the nullptr version is easy to call from a debugger.
+ ///
+ /// @{
void dump() const;
- void print(raw_ostream &OS) const;
- void printAsOperand(raw_ostream &OS, bool PrintType = true,
- const Module *M = nullptr) const;
+ void dump(const Module *M) const;
+ /// @}
+
+ /// \brief Print.
+ ///
+ /// Prints definition of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ void print(raw_ostream &OS, const Module *M = nullptr) const;
+
+ /// \brief Print as operand.
+ ///
+ /// Prints reference of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ void printAsOperand(raw_ostream &OS, const Module *M = nullptr) const;
};
#define HANDLE_METADATA(CLASS) class CLASS;
#include "llvm/IR/Metadata.def"
+// Provide specializations of isa so that we don't need definitions of
+// subclasses to see if the metadata is a subclass.
+#define HANDLE_METADATA_LEAF(CLASS) \
+ template <> struct isa_impl<CLASS, Metadata> { \
+ static inline bool doit(const Metadata &MD) { \
+ return MD.getMetadataID() == Metadata::CLASS##Kind; \
+ } \
+ };
+#include "llvm/IR/Metadata.def"
+
inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) {
MD.print(OS);
return OS;
@@ -113,7 +164,7 @@ class MetadataAsValue : public Value {
Metadata *MD;
MetadataAsValue(Type *Ty, Metadata *MD);
- ~MetadataAsValue();
+ ~MetadataAsValue() override;
/// \brief Drop use of metadata (during teardown).
void dropUse() { MD = nullptr; }
@@ -145,15 +196,19 @@ public:
typedef MetadataTracking::OwnerTy OwnerTy;
private:
+ LLVMContext &Context;
uint64_t NextIndex;
SmallDenseMap<void *, std::pair<OwnerTy, uint64_t>, 4> UseMap;
public:
- ReplaceableMetadataImpl() : NextIndex(0) {}
+ ReplaceableMetadataImpl(LLVMContext &Context)
+ : Context(Context), NextIndex(0) {}
~ReplaceableMetadataImpl() {
assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");
}
+ LLVMContext &getContext() const { return Context; }
+
/// \brief Replace all uses of this with MD.
///
/// Replace all uses of this with \c MD, which is allowed to be null.
@@ -162,8 +217,8 @@ public:
/// \brief Resolve all uses of this.
///
/// Resolve all uses of this, turning off RAUW permanently. If \c
- /// ResolveUsers, call \a UniquableMDNode::resolve() on any users whose last
- /// operand is resolved.
+ /// ResolveUsers, call \a MDNode::resolve() on any users whose last operand
+ /// is resolved.
void resolveAllUses(bool ResolveUsers = true);
private:
@@ -195,10 +250,10 @@ class ValueAsMetadata : public Metadata, ReplaceableMetadataImpl {
protected:
ValueAsMetadata(unsigned ID, Value *V)
- : Metadata(ID), V(V) {
+ : Metadata(ID, Uniqued), ReplaceableMetadataImpl(V->getContext()), V(V) {
assert(V && "Expected valid value");
}
- ~ValueAsMetadata() {}
+ ~ValueAsMetadata() = default;
public:
static ValueAsMetadata *get(Value *V);
@@ -441,13 +496,13 @@ dyn_extract_or_null(Y &&MD) {
class MDString : public Metadata {
friend class StringMapEntry<MDString>;
- MDString(const MDString &) LLVM_DELETED_FUNCTION;
- MDString &operator=(MDString &&) LLVM_DELETED_FUNCTION;
- MDString &operator=(const MDString &) LLVM_DELETED_FUNCTION;
+ MDString(const MDString &) = delete;
+ MDString &operator=(MDString &&) = delete;
+ MDString &operator=(const MDString &) = delete;
StringMapEntry<MDString> *Entry;
- MDString() : Metadata(MDStringKind), Entry(nullptr) {}
- MDString(MDString &&) : Metadata(MDStringKind) {}
+ MDString() : Metadata(MDStringKind, Uniqued), Entry(nullptr) {}
+ MDString(MDString &&) : Metadata(MDStringKind, Uniqued) {}
public:
static MDString *get(LLVMContext &Context, StringRef Str);
@@ -489,7 +544,7 @@ struct AAMDNodes {
bool operator!=(const AAMDNodes &A) const { return !(*this == A); }
- LLVM_EXPLICIT operator bool() const { return TBAA || Scope || NoAlias; }
+ explicit operator bool() const { return TBAA || Scope || NoAlias; }
/// \brief The tag for type-based alias analysis.
MDNode *TBAA;
@@ -528,10 +583,10 @@ struct DenseMapInfo<AAMDNodes> {
///
/// In particular, this is used by \a MDNode.
class MDOperand {
- MDOperand(MDOperand &&) LLVM_DELETED_FUNCTION;
- MDOperand(const MDOperand &) LLVM_DELETED_FUNCTION;
- MDOperand &operator=(MDOperand &&) LLVM_DELETED_FUNCTION;
- MDOperand &operator=(const MDOperand &) LLVM_DELETED_FUNCTION;
+ MDOperand(MDOperand &&) = delete;
+ MDOperand(const MDOperand &) = delete;
+ MDOperand &operator=(MDOperand &&) = delete;
+ MDOperand &operator=(const MDOperand &) = delete;
Metadata *MD;
@@ -580,18 +635,109 @@ template <> struct simplify_type<const MDOperand> {
static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); }
};
-//===----------------------------------------------------------------------===//
-/// \brief Tuple of metadata.
+/// \brief Pointer to the context, with optional RAUW support.
+///
+/// Either a raw (non-null) pointer to the \a LLVMContext, or an owned pointer
+/// to \a ReplaceableMetadataImpl (which has a reference to \a LLVMContext).
+class ContextAndReplaceableUses {
+ PointerUnion<LLVMContext *, ReplaceableMetadataImpl *> Ptr;
+
+ ContextAndReplaceableUses() = delete;
+ ContextAndReplaceableUses(ContextAndReplaceableUses &&) = delete;
+ ContextAndReplaceableUses(const ContextAndReplaceableUses &) = delete;
+ ContextAndReplaceableUses &operator=(ContextAndReplaceableUses &&) = delete;
+ ContextAndReplaceableUses &
+ operator=(const ContextAndReplaceableUses &) = delete;
+
+public:
+ ContextAndReplaceableUses(LLVMContext &Context) : Ptr(&Context) {}
+ ContextAndReplaceableUses(
+ std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses)
+ : Ptr(ReplaceableUses.release()) {
+ assert(getReplaceableUses() && "Expected non-null replaceable uses");
+ }
+ ~ContextAndReplaceableUses() { delete getReplaceableUses(); }
+
+ operator LLVMContext &() { return getContext(); }
+
+ /// \brief Whether this contains RAUW support.
+ bool hasReplaceableUses() const {
+ return Ptr.is<ReplaceableMetadataImpl *>();
+ }
+ LLVMContext &getContext() const {
+ if (hasReplaceableUses())
+ return getReplaceableUses()->getContext();
+ return *Ptr.get<LLVMContext *>();
+ }
+ ReplaceableMetadataImpl *getReplaceableUses() const {
+ if (hasReplaceableUses())
+ return Ptr.get<ReplaceableMetadataImpl *>();
+ return nullptr;
+ }
+
+ /// \brief Assign RAUW support to this.
+ ///
+ /// Make this replaceable, taking ownership of \c ReplaceableUses (which must
+ /// not be null).
+ void
+ makeReplaceable(std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses) {
+ assert(ReplaceableUses && "Expected non-null replaceable uses");
+ assert(&ReplaceableUses->getContext() == &getContext() &&
+ "Expected same context");
+ delete getReplaceableUses();
+ Ptr = ReplaceableUses.release();
+ }
+
+ /// \brief Drop RAUW support.
+ ///
+ /// Cede ownership of RAUW support, returning it.
+ std::unique_ptr<ReplaceableMetadataImpl> takeReplaceableUses() {
+ assert(hasReplaceableUses() && "Expected to own replaceable uses");
+ std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses(
+ getReplaceableUses());
+ Ptr = &ReplaceableUses->getContext();
+ return ReplaceableUses;
+ }
+};
+
+struct TempMDNodeDeleter {
+ inline void operator()(MDNode *Node) const;
+};
+
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ typedef std::unique_ptr<CLASS, TempMDNodeDeleter> Temp##CLASS;
+#define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_LEAF(CLASS)
+#include "llvm/IR/Metadata.def"
+
+/// \brief Metadata node.
+///
+/// Metadata nodes can be uniqued, like constants, or distinct. Temporary
+/// metadata nodes (with full support for RAUW) can be used to delay uniquing
+/// until forward references are known. The basic metadata node is an \a
+/// MDTuple.
+///
+/// There is limited support for RAUW at construction time. At construction
+/// time, if any operand is a temporary node (or an unresolved uniqued node,
+/// which indicates a transitive temporary operand), the node itself will be
+/// unresolved. As soon as all operands become resolved, it will drop RAUW
+/// support permanently.
+///
+/// If an unresolved node is part of a cycle, \a resolveCycles() needs
+/// to be called on some member of the cycle once all temporary nodes have been
+/// replaced.
class MDNode : public Metadata {
- MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
- void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
- void *operator new(size_t) LLVM_DELETED_FUNCTION;
+ friend class ReplaceableMetadataImpl;
+ friend class LLVMContextImpl;
+
+ MDNode(const MDNode &) = delete;
+ void operator=(const MDNode &) = delete;
+ void *operator new(size_t) = delete;
- LLVMContext &Context;
unsigned NumOperands;
+ unsigned NumUnresolved;
protected:
- unsigned MDNodeSubclassData;
+ ContextAndReplaceableUses Context;
void *operator new(size_t Size, unsigned NumOps);
void operator delete(void *Mem);
@@ -606,56 +752,163 @@ protected:
llvm_unreachable("Constructor throws?");
}
- MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs);
- ~MDNode() {}
+ MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None);
+ ~MDNode() = default;
void dropAllReferences();
MDOperand *mutable_begin() { return mutable_end() - NumOperands; }
MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }
-public:
- static inline MDNode *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
- static inline MDNode *getIfExists(LLVMContext &Context,
- ArrayRef<Metadata *> MDs);
- static inline MDNode *getDistinct(LLVMContext &Context,
- ArrayRef<Metadata *> MDs);
+ typedef iterator_range<MDOperand *> mutable_op_range;
+ mutable_op_range mutable_operands() {
+ return mutable_op_range(mutable_begin(), mutable_end());
+ }
- /// \brief Return a temporary MDNode
- ///
- /// For use in constructing cyclic MDNode structures. A temporary MDNode is
- /// not uniqued, may be RAUW'd, and must be manually deleted with
- /// deleteTemporary.
- static MDNodeFwdDecl *getTemporary(LLVMContext &Context,
+public:
+ static inline MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
+ static inline MDTuple *getIfExists(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs);
+ static inline MDTuple *getDistinct(LLVMContext &Context,
ArrayRef<Metadata *> MDs);
+ static inline TempMDTuple getTemporary(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs);
+
+ /// \brief Create a (temporary) clone of this.
+ TempMDNode clone() const;
/// \brief Deallocate a node created by getTemporary.
///
- /// The node must not have any users.
+ /// Calls \c replaceAllUsesWith(nullptr) before deleting, so any remaining
+ /// references will be reset.
static void deleteTemporary(MDNode *N);
- LLVMContext &getContext() const { return Context; }
+ LLVMContext &getContext() const { return Context.getContext(); }
/// \brief Replace a specific operand.
void replaceOperandWith(unsigned I, Metadata *New);
/// \brief Check if node is fully resolved.
- bool isResolved() const;
+ ///
+ /// If \a isTemporary(), this always returns \c false; if \a isDistinct(),
+ /// this always returns \c true.
+ ///
+ /// If \a isUniqued(), returns \c true if this has already dropped RAUW
+ /// support (because all operands are resolved).
+ ///
+ /// As forward declarations are resolved, their containers should get
+ /// resolved automatically. However, if this (or one of its operands) is
+ /// involved in a cycle, \a resolveCycles() needs to be called explicitly.
+ bool isResolved() const { return !Context.hasReplaceableUses(); }
+
+ bool isUniqued() const { return Storage == Uniqued; }
+ bool isDistinct() const { return Storage == Distinct; }
+ bool isTemporary() const { return Storage == Temporary; }
- /// \brief Check if node is distinct.
+ /// \brief RAUW a temporary.
///
- /// Distinct nodes are not uniqued, and will not be returned by \a
- /// MDNode::get().
- bool isDistinct() const {
- return isStoredDistinctInContext() || isa<MDNodeFwdDecl>(this);
+ /// \pre \a isTemporary() must be \c true.
+ void replaceAllUsesWith(Metadata *MD) {
+ assert(isTemporary() && "Expected temporary node");
+ assert(!isResolved() && "Expected RAUW support");
+ Context.getReplaceableUses()->replaceAllUsesWith(MD);
}
+ /// \brief Resolve cycles.
+ ///
+ /// Once all forward declarations have been resolved, force cycles to be
+ /// resolved.
+ ///
+ /// \pre No operands (or operands' operands, etc.) have \a isTemporary().
+ void resolveCycles();
+
+ /// \brief Replace a temporary node with a permanent one.
+ ///
+ /// Try to create a uniqued version of \c N -- in place, if possible -- and
+ /// return it. If \c N cannot be uniqued, return a distinct node instead.
+ template <class T>
+ static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ replaceWithPermanent(std::unique_ptr<T, TempMDNodeDeleter> N) {
+ return cast<T>(N.release()->replaceWithPermanentImpl());
+ }
+
+ /// \brief Replace a temporary node with a uniqued one.
+ ///
+ /// Create a uniqued version of \c N -- in place, if possible -- and return
+ /// it. Takes ownership of the temporary node.
+ ///
+ /// \pre N does not self-reference.
+ template <class T>
+ static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ replaceWithUniqued(std::unique_ptr<T, TempMDNodeDeleter> N) {
+ return cast<T>(N.release()->replaceWithUniquedImpl());
+ }
+
+ /// \brief Replace a temporary node with a distinct one.
+ ///
+ /// Create a distinct version of \c N -- in place, if possible -- and return
+ /// it. Takes ownership of the temporary node.
+ template <class T>
+ static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ replaceWithDistinct(std::unique_ptr<T, TempMDNodeDeleter> N) {
+ return cast<T>(N.release()->replaceWithDistinctImpl());
+ }
+
+private:
+ MDNode *replaceWithPermanentImpl();
+ MDNode *replaceWithUniquedImpl();
+ MDNode *replaceWithDistinctImpl();
+
protected:
/// \brief Set an operand.
///
/// Sets the operand directly, without worrying about uniquing.
void setOperand(unsigned I, Metadata *New);
+ void storeDistinctInContext();
+ template <class T, class StoreT>
+ static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
+
+private:
+ void handleChangedOperand(void *Ref, Metadata *New);
+
+ void resolve();
+ void resolveAfterOperandChange(Metadata *Old, Metadata *New);
+ void decrementUnresolvedOperandCount();
+ unsigned countUnresolvedOperands();
+
+ /// \brief Mutate this to be "uniqued".
+ ///
+ /// Mutate this so that \a isUniqued().
+ /// \pre \a isTemporary().
+ /// \pre already added to uniquing set.
+ void makeUniqued();
+
+ /// \brief Mutate this to be "distinct".
+ ///
+ /// Mutate this so that \a isDistinct().
+ /// \pre \a isTemporary().
+ void makeDistinct();
+
+ void deleteAsSubclass();
+ MDNode *uniquify();
+ void eraseFromStore();
+
+ template <class NodeTy> struct HasCachedHash;
+ template <class NodeTy>
+ static void dispatchRecalculateHash(NodeTy *N, std::true_type) {
+ N->recalculateHash();
+ }
+ template <class NodeTy>
+ static void dispatchRecalculateHash(NodeTy *N, std::false_type) {}
+ template <class NodeTy>
+ static void dispatchResetHash(NodeTy *N, std::true_type) {
+ N->setHash(0);
+ }
+ template <class NodeTy>
+ static void dispatchResetHash(NodeTy *N, std::false_type) {}
+
public:
typedef const MDOperand *op_iterator;
typedef iterator_range<op_iterator> op_range;
@@ -678,9 +931,14 @@ public:
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDTupleKind ||
- MD->getMetadataID() == MDLocationKind ||
- MD->getMetadataID() == MDNodeFwdDeclKind;
+ switch (MD->getMetadataID()) {
+ default:
+ return false;
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ return true;
+#include "llvm/IR/Metadata.def"
+ }
}
/// \brief Check whether MDNode is a vtable access.
@@ -690,225 +948,163 @@ public:
static MDNode *concatenate(MDNode *A, MDNode *B);
static MDNode *intersect(MDNode *A, MDNode *B);
static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
- static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
};
-/// \brief Uniquable metadata node.
-///
-/// A uniquable metadata node. This contains the basic functionality
-/// for implementing sub-types of \a MDNode that can be uniqued like
-/// constants.
-///
-/// There is limited support for RAUW at construction time. At
-/// construction time, if any operands are an instance of \a
-/// MDNodeFwdDecl (or another unresolved \a UniquableMDNode, which
-/// indicates an \a MDNodeFwdDecl in its path), the node itself will be
-/// unresolved. As soon as all operands become resolved, it will drop
-/// RAUW support permanently.
-///
-/// If an unresolved node is part of a cycle, \a resolveCycles() needs
-/// to be called on some member of the cycle when each \a MDNodeFwdDecl
-/// has been removed.
-class UniquableMDNode : public MDNode {
- friend class ReplaceableMetadataImpl;
- friend class MDNode;
- friend class LLVMContextImpl;
-
- /// \brief Support RAUW as long as one of its arguments is replaceable.
- ///
- /// FIXME: Save memory by storing this in a pointer union with the
- /// LLVMContext, and adding an LLVMContext reference to RMI.
- std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses;
-
-protected:
- /// \brief Create a new node.
- ///
- /// If \c AllowRAUW, then if any operands are unresolved support RAUW. RAUW
- /// will be dropped once all operands have been resolved (or if \a
- /// resolveCycles() is called).
- UniquableMDNode(LLVMContext &C, unsigned ID, ArrayRef<Metadata *> Vals,
- bool AllowRAUW);
- ~UniquableMDNode() {}
-
- void storeDistinctInContext();
-
-public:
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDTupleKind ||
- MD->getMetadataID() == MDLocationKind;
- }
-
- /// \brief Check whether any operands are forward declarations.
- ///
- /// Returns \c true as long as any operands (or their operands, etc.) are \a
- /// MDNodeFwdDecl.
- ///
- /// As forward declarations are resolved, their containers should get
- /// resolved automatically. However, if this (or one of its operands) is
- /// involved in a cycle, \a resolveCycles() needs to be called explicitly.
- bool isResolved() const { return !ReplaceableUses; }
-
- /// \brief Resolve cycles.
- ///
- /// Once all forward declarations have been resolved, force cycles to be
- /// resolved.
- ///
- /// \pre No operands (or operands' operands, etc.) are \a MDNodeFwdDecl.
- void resolveCycles();
-
-private:
- void handleChangedOperand(void *Ref, Metadata *New);
-
- void resolve();
- void resolveAfterOperandChange(Metadata *Old, Metadata *New);
- void decrementUnresolvedOperandCount();
-
- void deleteAsSubclass();
- UniquableMDNode *uniquify();
- void eraseFromStore();
-};
-
/// \brief Tuple of metadata.
///
/// This is the simple \a MDNode arbitrary tuple. Nodes are uniqued by
/// default based on their operands.
-class MDTuple : public UniquableMDNode {
+class MDTuple : public MDNode {
friend class LLVMContextImpl;
- friend class UniquableMDNode;
+ friend class MDNode;
- MDTuple(LLVMContext &C, ArrayRef<Metadata *> Vals, bool AllowRAUW)
- : UniquableMDNode(C, MDTupleKind, Vals, AllowRAUW) {}
+ MDTuple(LLVMContext &C, StorageType Storage, unsigned Hash,
+ ArrayRef<Metadata *> Vals)
+ : MDNode(C, MDTupleKind, Storage, Vals) {
+ setHash(Hash);
+ }
~MDTuple() { dropAllReferences(); }
- void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }
+ void setHash(unsigned Hash) { SubclassData32 = Hash; }
void recalculateHash();
static MDTuple *getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
- bool ShouldCreate);
+ StorageType Storage, bool ShouldCreate = true);
+
+ TempMDTuple cloneImpl() const {
+ return getTemporary(getContext(),
+ SmallVector<Metadata *, 4>(op_begin(), op_end()));
+ }
public:
/// \brief Get the hash, if any.
- unsigned getHash() const { return MDNodeSubclassData; }
+ unsigned getHash() const { return SubclassData32; }
static MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return getImpl(Context, MDs, /* ShouldCreate */ true);
+ return getImpl(Context, MDs, Uniqued);
}
static MDTuple *getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return getImpl(Context, MDs, /* ShouldCreate */ false);
+ return getImpl(Context, MDs, Uniqued, /* ShouldCreate */ false);
}
/// \brief Return a distinct node.
///
/// Return a distinct node -- i.e., a node that is not uniqued.
- static MDTuple *getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs);
+ static MDTuple *getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+ return getImpl(Context, MDs, Distinct);
+ }
+
+ /// \brief Return a temporary node.
+ ///
+ /// For use in constructing cyclic MDNode structures. A temporary MDNode is
+ /// not uniqued, may be RAUW'd, and must be manually deleted with
+ /// deleteTemporary.
+ static TempMDTuple getTemporary(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs) {
+ return TempMDTuple(getImpl(Context, MDs, Temporary));
+ }
+
+ /// \brief Return a (temporary) clone of this.
+ TempMDTuple clone() const { return cloneImpl(); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind;
}
-
-private:
- MDTuple *uniquifyImpl();
- void eraseFromStoreImpl();
};
-MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::get(Context, MDs);
}
-MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::getIfExists(Context, MDs);
}
-MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::getDistinct(Context, MDs);
}
+TempMDTuple MDNode::getTemporary(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs) {
+ return MDTuple::getTemporary(Context, MDs);
+}
-/// \brief Debug location.
-///
-/// A debug location in source code, used for debug info and otherwise.
-class MDLocation : public UniquableMDNode {
- friend class LLVMContextImpl;
- friend class UniquableMDNode;
-
- MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
- ArrayRef<Metadata *> MDs, bool AllowRAUW);
- ~MDLocation() { dropAllReferences(); }
-
- static MDLocation *constructHelper(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, bool AllowRAUW);
-
- static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, bool ShouldCreate);
+void TempMDNodeDeleter::operator()(MDNode *Node) const {
+ MDNode::deleteTemporary(Node);
+}
- // Disallow replacing operands.
- void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
+/// \brief Typed iterator through MDNode operands.
+///
+/// An iterator that transforms an \a MDNode::iterator into an iterator over a
+/// particular Metadata subclass.
+template <class T>
+class TypedMDOperandIterator
+ : std::iterator<std::input_iterator_tag, T *, std::ptrdiff_t, void, T *> {
+ MDNode::op_iterator I = nullptr;
public:
- static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
- Metadata *Scope, Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt,
- /* ShouldCreate */ true);
- }
- static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt,
- /* ShouldCreate */ false);
- }
- static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr);
-
- unsigned getLine() const { return MDNodeSubclassData; }
- unsigned getColumn() const { return SubclassData16; }
- Metadata *getScope() const { return getOperand(0); }
- Metadata *getInlinedAt() const {
- if (getNumOperands() == 2)
- return getOperand(1);
- return nullptr;
+ TypedMDOperandIterator() = default;
+ explicit TypedMDOperandIterator(MDNode::op_iterator I) : I(I) {}
+ T *operator*() const { return cast_or_null<T>(*I); }
+ TypedMDOperandIterator &operator++() {
+ ++I;
+ return *this;
}
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDLocationKind;
+ TypedMDOperandIterator operator++(int) {
+ TypedMDOperandIterator Temp(*this);
+ ++I;
+ return Temp;
}
-
-private:
- MDLocation *uniquifyImpl();
- void eraseFromStoreImpl();
+ bool operator==(const TypedMDOperandIterator &X) const { return I == X.I; }
+ bool operator!=(const TypedMDOperandIterator &X) const { return I != X.I; }
};
-/// \brief Forward declaration of metadata.
+/// \brief Typed, array-like tuple of metadata.
///
-/// Forward declaration of metadata, in the form of a basic tuple. Unlike \a
-/// MDTuple, this class has full support for RAUW, is not owned, is not
-/// uniqued, and is suitable for forward references.
-class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl {
- friend class Metadata;
- friend class ReplaceableMetadataImpl;
-
- MDNodeFwdDecl(LLVMContext &C, ArrayRef<Metadata *> Vals)
- : MDNode(C, MDNodeFwdDeclKind, Vals) {}
+/// This is a wrapper for \a MDTuple that makes it act like an array holding a
+/// particular type of metadata.
+template <class T> class MDTupleTypedArrayWrapper {
+ const MDTuple *N = nullptr;
public:
- ~MDNodeFwdDecl() { dropAllReferences(); }
-
- // MSVC doesn't see the alternative: "using MDNode::operator delete".
- void operator delete(void *Mem) { MDNode::operator delete(Mem); }
-
- static MDNodeFwdDecl *get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return new (MDs.size()) MDNodeFwdDecl(Context, MDs);
- }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDNodeFwdDeclKind;
- }
-
- using ReplaceableMetadataImpl::replaceAllUsesWith;
+ MDTupleTypedArrayWrapper() = default;
+ MDTupleTypedArrayWrapper(const MDTuple *N) : N(N) {}
+
+ template <class U>
+ MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ template <class U>
+ explicit MDTupleTypedArrayWrapper(
+ const MDTupleTypedArrayWrapper<U> &Other,
+ typename std::enable_if<!std::is_convertible<U *, T *>::value>::type * =
+ nullptr)
+ : N(Other.get()) {}
+
+ explicit operator bool() const { return get(); }
+ explicit operator MDTuple *() const { return get(); }
+
+ MDTuple *get() const { return const_cast<MDTuple *>(N); }
+ MDTuple *operator->() const { return get(); }
+ MDTuple &operator*() const { return *get(); }
+
+ // FIXME: Fix callers and remove condition on N.
+ unsigned size() const { return N ? N->getNumOperands() : 0u; }
+ T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); }
+
+ // FIXME: Fix callers and remove condition on N.
+ typedef TypedMDOperandIterator<T> iterator;
+ iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); }
+ iterator end() const { return N ? iterator(N->op_end()) : iterator(); }
};
+#define HANDLE_METADATA(CLASS) \
+ typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array;
+#include "llvm/IR/Metadata.def"
+
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///
@@ -921,7 +1117,7 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
friend struct ilist_traits<NamedMDNode>;
friend class LLVMContextImpl;
friend class Module;
- NamedMDNode(const NamedMDNode &) LLVM_DELETED_FUNCTION;
+ NamedMDNode(const NamedMDNode &) = delete;
std::string Name;
Module *Parent;
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index b24023b05e4f..d8636dfb123e 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -219,14 +219,7 @@ private:
std::string TargetTriple; ///< Platform target triple Module compiled on
///< Format: (arch)(sub)-(vendor)-(sys0-(abi)
void *NamedMDSymTab; ///< NamedMDNode names.
-
- // We need to keep the string because the C API expects us to own the string
- // representation.
- // Since we have it, we also use an empty string to represent a module without
- // a DataLayout. If it has a DataLayout, these variables are in sync and the
- // string is just a cache of getDataLayout()->getStringRepresentation().
- std::string DataLayoutStr;
- DataLayout DL;
+ DataLayout DL; ///< DataLayout associated with the module
friend class Constant;
@@ -256,10 +249,12 @@ public:
/// Get the data layout string for the module's target platform. This is
/// equivalent to getDataLayout()->getStringRepresentation().
- const std::string &getDataLayoutStr() const { return DataLayoutStr; }
+ const std::string getDataLayoutStr() const {
+ return DL.getStringRepresentation();
+ }
/// Get the data layout for the module's target platform.
- const DataLayout *getDataLayout() const;
+ const DataLayout &getDataLayout() const;
/// Get the target triple which is a string describing the target host.
/// @returns a string containing the target triple.
@@ -293,12 +288,13 @@ public:
/// Set the data layout
void setDataLayout(StringRef Desc);
- void setDataLayout(const DataLayout *Other);
+ void setDataLayout(const DataLayout &Other);
/// Set the target triple.
void setTargetTriple(StringRef T) { TargetTriple = T; }
/// Set the module-scope inline assembly blocks.
+ /// A trailing newline is added if the input doesn't have one.
void setModuleInlineAsm(StringRef Asm) {
GlobalScopeAsm = Asm;
if (!GlobalScopeAsm.empty() &&
@@ -306,8 +302,8 @@ public:
GlobalScopeAsm += '\n';
}
- /// Append to the module-scope inline assembly blocks, automatically inserting
- /// a separating newline if necessary.
+ /// Append to the module-scope inline assembly blocks.
+ /// A trailing newline is added if the input doesn't have one.
void appendModuleInlineAsm(StringRef Asm) {
GlobalScopeAsm += Asm;
if (!GlobalScopeAsm.empty() &&
@@ -496,7 +492,7 @@ public:
/// If the GlobalValue is read in, and if the GVMaterializer supports it,
/// release the memory for the function, and set it up to be materialized
/// lazily. If !isDematerializable(), this method is a no-op.
- void Dematerialize(GlobalValue *GV);
+ void dematerialize(GlobalValue *GV);
/// Make sure all GlobalValues in this Module are fully read.
std::error_code materializeAll();
@@ -506,6 +502,8 @@ public:
/// Materializer.
std::error_code materializeAllPermanently();
+ std::error_code materializeMetadata();
+
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
/// @{
@@ -630,13 +628,25 @@ public:
named_metadata_end());
}
+ /// Destroy ConstantArrays in LLVMContext if they are not used.
+ /// ConstantArrays constructed during linking can cause quadratic memory
+ /// explosion. Releasing all unused constants can cause a 20% LTO compile-time
+ /// slowdown for a large application.
+ ///
+ /// NOTE: Constants are currently owned by LLVMContext. This can then only
+ /// be called where all uses of the LLVMContext are understood.
+ void dropTriviallyDeadConstantArrays();
+
/// @}
/// @name Utility functions for printing and dumping Module objects
/// @{
/// Print the module to an output stream with an optional
- /// AssemblyAnnotationWriter.
- void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const;
+ /// AssemblyAnnotationWriter. If \c ShouldPreserveUseListOrder, then include
+ /// uselistorder directives so that use-lists can be recreated when reading
+ /// the assembly.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW,
+ bool ShouldPreserveUseListOrder = false) const;
/// Dump the module to stderr (for debugging).
void dump() const;
diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h
index a9cdfc36fb4a..61f4817a9b62 100644
--- a/include/llvm/IR/NoFolder.h
+++ b/include/llvm/IR/NoFolder.h
@@ -177,34 +177,35 @@ public:
// Memory Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateGetElementPtr(Constant *C,
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getGetElementPtr(C, IdxList);
+ return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(C, Idx);
+ return ConstantExpr::getGetElementPtr(Ty, C, Idx);
}
- Instruction *CreateGetElementPtr(Constant *C,
+ Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::Create(C, IdxList);
+ return GetElementPtrInst::Create(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C,
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Constant *> IdxList) const {
- return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Instruction *CreateInBoundsGetElementPtr(Constant *C,
+ Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::CreateInBounds(C, IdxList);
+ return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 0933f2170236..1b9102ecc7e4 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -18,7 +18,6 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Type.h"
@@ -34,15 +33,15 @@ class Operator : public User {
private:
// The Operator class is intended to be used as a utility, and is never itself
// instantiated.
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- void *operator new(size_t s) LLVM_DELETED_FUNCTION;
- Operator() LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ void *operator new(size_t s) = delete;
+ Operator() = delete;
protected:
- // NOTE: Cannot use LLVM_DELETED_FUNCTION because it's not legal to delete
+ // NOTE: Cannot use = delete because it's not legal to delete
// an overridden method that's not deleted in the base class. Cannot leave
// this unimplemented because that leads to an ODR-violation.
- ~Operator();
+ ~Operator() override;
public:
/// Return the opcode for this Instruction or ConstantExpr.
@@ -181,17 +180,17 @@ public:
{ }
/// Whether any flag is set
- bool any() { return Flags != 0; }
+ bool any() const { return Flags != 0; }
/// Set all the flags to false
void clear() { Flags = 0; }
/// Flag queries
- bool noNaNs() { return 0 != (Flags & NoNaNs); }
- bool noInfs() { return 0 != (Flags & NoInfs); }
- bool noSignedZeros() { return 0 != (Flags & NoSignedZeros); }
- bool allowReciprocal() { return 0 != (Flags & AllowReciprocal); }
- bool unsafeAlgebra() { return 0 != (Flags & UnsafeAlgebra); }
+ bool noNaNs() const { return 0 != (Flags & NoNaNs); }
+ bool noInfs() const { return 0 != (Flags & NoInfs); }
+ bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
+ bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
+ bool unsafeAlgebra() const { return 0 != (Flags & UnsafeAlgebra); }
/// Flag setters
void setNoNaNs() { Flags |= NoNaNs; }
@@ -400,6 +399,8 @@ public:
return getPointerOperand()->getType();
}
+ Type *getSourceElementType() const;
+
/// Method to return the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
return getPointerOperandType()->getPointerAddressSpace();
@@ -445,36 +446,7 @@ public:
/// undefined (it is *not* preserved!). The APInt passed into this routine
/// must be at exactly as wide as the IntPtr type for the address space of the
/// base GEP pointer.
- bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
- assert(Offset.getBitWidth() ==
- DL.getPointerSizeInBits(getPointerAddressSpace()) &&
- "The offset must have exactly as many bits as our pointer.");
-
- for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
- GTI != GTE; ++GTI) {
- ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
- if (!OpC)
- return false;
- if (OpC->isZero())
- continue;
-
- // Handle a struct index, which adds its field offset to the pointer.
- if (StructType *STy = dyn_cast<StructType>(*GTI)) {
- unsigned ElementIdx = OpC->getZExtValue();
- const StructLayout *SL = DL.getStructLayout(STy);
- Offset += APInt(Offset.getBitWidth(),
- SL->getElementOffset(ElementIdx));
- continue;
- }
-
- // For array or vector indices, scale the index by the size of the type.
- APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
- Offset += Index * APInt(Offset.getBitWidth(),
- DL.getTypeAllocSize(GTI.getIndexedType()));
- }
- return true;
- }
-
+ bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
};
class PtrToIntOperator
@@ -504,6 +476,20 @@ public:
}
};
+class BitCastOperator
+ : public ConcreteOperator<Operator, Instruction::BitCast> {
+ friend class BitCastInst;
+ friend class ConstantExpr;
+
+public:
+ Type *getSrcTy() const {
+ return getOperand(0)->getType();
+ }
+
+ Type *getDestTy() const {
+ return getType();
+ }
+};
} // End llvm namespace
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
index 262576849264..4166babd63e5 100644
--- a/include/llvm/IR/PassManager.h
+++ b/include/llvm/IR/PassManager.h
@@ -46,6 +46,7 @@
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
#include <list>
#include <memory>
@@ -241,8 +242,8 @@ public:
private:
typedef detail::PassConcept<IRUnitT> PassConceptT;
- PassManager(const PassManager &) LLVM_DELETED_FUNCTION;
- PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
+ PassManager(const PassManager &) = delete;
+ PassManager &operator=(const PassManager &) = delete;
std::vector<std::unique_ptr<PassConceptT>> Passes;
@@ -281,9 +282,9 @@ template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
return static_cast<const DerivedT *>(this);
}
- AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+ AnalysisManagerBase(const AnalysisManagerBase &) = delete;
AnalysisManagerBase &
- operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+ operator=(const AnalysisManagerBase &) = delete;
protected:
typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
@@ -453,8 +454,8 @@ public:
}
private:
- AnalysisManager(const AnalysisManager &) LLVM_DELETED_FUNCTION;
- AnalysisManager &operator=(const AnalysisManager &) LLVM_DELETED_FUNCTION;
+ AnalysisManager(const AnalysisManager &) = delete;
+ AnalysisManager &operator=(const AnalysisManager &) = delete;
/// \brief Get an analysis result, running the pass if necessary.
ResultConceptT &getResultImpl(void *PassID, IRUnitT &IR) {
@@ -471,6 +472,12 @@ private:
dbgs() << "Running analysis: " << P.name() << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(PassID, P.run(IR, this));
+
+ // P.run may have inserted elements into AnalysisResults and invalidated
+ // RI.
+ RI = AnalysisResults.find(std::make_pair(PassID, &IR));
+ assert(RI != AnalysisResults.end() && "we just inserted it!");
+
RI->second = std::prev(ResultList.end());
}
@@ -502,7 +509,7 @@ private:
PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) {
// Short circuit for a common case of all analyses being preserved.
if (PA.areAllPreserved())
- return std::move(PA);
+ return PA;
if (DebugLogging)
dbgs() << "Invalidating all non-preserved analyses for: "
@@ -542,7 +549,7 @@ private:
if (ResultsList.empty())
AnalysisResultLists.erase(&IR);
- return std::move(PA);
+ return PA;
}
/// \brief List of function analysis pass IDs and associated concept pointers.
@@ -782,8 +789,11 @@ public:
FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
- PreservedAnalyses PassPA = Pass.run(*I, FAM);
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+
+ PreservedAnalyses PassPA = Pass.run(F, FAM);
// We know that the function pass couldn't have invalidated any other
// function's analyses (that's the contract of a function pass), so
@@ -791,7 +801,7 @@ public:
// update our preserved set to reflect that these have already been
// handled.
if (FAM)
- PassPA = FAM->invalidate(*I, std::move(PassPA));
+ PassPA = FAM->invalidate(F, std::move(PassPA));
// Then intersect the preserved set so that invalidation of module
// analyses will eventually occur when the module pass completes.
@@ -817,7 +827,7 @@ private:
template <typename FunctionPassT>
ModuleToFunctionPassAdaptor<FunctionPassT>
createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
- return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
+ return ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
}
/// \brief A template utility pass to force an analysis result to be available.
diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h
index 297f5f4e07f4..92de10bcd75b 100644
--- a/include/llvm/IR/PassManagerInternal.h
+++ b/include/llvm/IR/PassManagerInternal.h
@@ -19,6 +19,7 @@
#define LLVM_IR_PASSMANAGERINTERNAL_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
namespace llvm {
diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h
index f94e10576893..41154e6441a9 100644
--- a/include/llvm/IR/PatternMatch.h
+++ b/include/llvm/IR/PatternMatch.h
@@ -295,6 +295,9 @@ template <typename Class> struct bind_ty {
/// \brief Match a value, capturing it if we match.
inline bind_ty<Value> m_Value(Value *&V) { return V; }
+/// \brief Match an instruction, capturing it if we match.
+inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
+
/// \brief Match a binary operator, capturing it if we match.
inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
@@ -1103,6 +1106,52 @@ m_UnordFMax(const LHS &L, const RHS &R) {
return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
}
+//===----------------------------------------------------------------------===//
+// Matchers for overflow check patterns: e.g. (a + b) u< a
+//
+
+template <typename LHS_t, typename RHS_t, typename Sum_t>
+struct UAddWithOverflow_match {
+ LHS_t L;
+ RHS_t R;
+ Sum_t S;
+
+ UAddWithOverflow_match(const LHS_t &L, const RHS_t &R, const Sum_t &S)
+ : L(L), R(R), S(S) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ Value *ICmpLHS, *ICmpRHS;
+ ICmpInst::Predicate Pred;
+ if (!m_ICmp(Pred, m_Value(ICmpLHS), m_Value(ICmpRHS)).match(V))
+ return false;
+
+ Value *AddLHS, *AddRHS;
+ auto AddExpr = m_Add(m_Value(AddLHS), m_Value(AddRHS));
+
+ // (a + b) u< a, (a + b) u< b
+ if (Pred == ICmpInst::ICMP_ULT)
+ if (AddExpr.match(ICmpLHS) && (ICmpRHS == AddLHS || ICmpRHS == AddRHS))
+ return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpLHS);
+
+ // a >u (a + b), b >u (a + b)
+ if (Pred == ICmpInst::ICMP_UGT)
+ if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
+ return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
+
+ return false;
+ }
+};
+
+/// \brief Match an icmp instruction checking for unsigned overflow on addition.
+///
+/// S is matched to the addition whose result is being checked for overflow, and
+/// L and R are matched to the LHS and RHS of S.
+template <typename LHS_t, typename RHS_t, typename Sum_t>
+UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>
+m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
+ return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
+}
+
/// \brief Match an 'unordered' floating point minimum function.
/// Floating point has one special value 'NaN'. Therefore, there is no total
/// order. However, if we can ignore the 'NaN' value (for example, because of a
diff --git a/include/llvm/IR/PredIteratorCache.h b/include/llvm/IR/PredIteratorCache.h
index 5e1be37805ff..118310aed1d0 100644
--- a/include/llvm/IR/PredIteratorCache.h
+++ b/include/llvm/IR/PredIteratorCache.h
@@ -14,6 +14,7 @@
#ifndef LLVM_IR_PREDITERATORCACHE_H
#define LLVM_IR_PREDITERATORCACHE_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/CFG.h"
@@ -21,50 +22,58 @@
namespace llvm {
- /// PredIteratorCache - This class is an extremely trivial cache for
- /// predecessor iterator queries. This is useful for code that repeatedly
- /// wants the predecessor list for the same blocks.
- class PredIteratorCache {
- /// BlockToPredsMap - Pointer to null-terminated list.
- DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
- DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
+/// PredIteratorCache - This class is an extremely trivial cache for
+/// predecessor iterator queries. This is useful for code that repeatedly
+/// wants the predecessor list for the same blocks.
+class PredIteratorCache {
+ /// BlockToPredsMap - Pointer to null-terminated list.
+ DenseMap<BasicBlock *, BasicBlock **> BlockToPredsMap;
+ DenseMap<BasicBlock *, unsigned> BlockToPredCountMap;
- /// Memory - This is the space that holds cached preds.
- BumpPtrAllocator Memory;
- public:
+ /// Memory - This is the space that holds cached preds.
+ BumpPtrAllocator Memory;
- /// GetPreds - Get a cached list for the null-terminated predecessor list of
- /// the specified block. This can be used in a loop like this:
- /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
- /// use(*PI);
- /// instead of:
- /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
- BasicBlock **GetPreds(BasicBlock *BB) {
- BasicBlock **&Entry = BlockToPredsMap[BB];
- if (Entry) return Entry;
+private:
+ /// GetPreds - Get a cached list for the null-terminated predecessor list of
+ /// the specified block. This can be used in a loop like this:
+ /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
+ /// use(*PI);
+ /// instead of:
+ /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
+ BasicBlock **GetPreds(BasicBlock *BB) {
+ BasicBlock **&Entry = BlockToPredsMap[BB];
+ if (Entry)
+ return Entry;
- SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
- PredCache.push_back(nullptr); // null terminator.
-
- BlockToPredCountMap[BB] = PredCache.size()-1;
+ SmallVector<BasicBlock *, 32> PredCache(pred_begin(BB), pred_end(BB));
+ PredCache.push_back(nullptr); // null terminator.
- Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
- std::copy(PredCache.begin(), PredCache.end(), Entry);
- return Entry;
- }
-
- unsigned GetNumPreds(BasicBlock *BB) {
- GetPreds(BB);
- return BlockToPredCountMap[BB];
- }
+ BlockToPredCountMap[BB] = PredCache.size() - 1;
+
+ Entry = Memory.Allocate<BasicBlock *>(PredCache.size());
+ std::copy(PredCache.begin(), PredCache.end(), Entry);
+ return Entry;
+ }
+
+ unsigned GetNumPreds(BasicBlock *BB) {
+ GetPreds(BB);
+ return BlockToPredCountMap[BB];
+ }
+
+public:
+ size_t size(BasicBlock *BB) { return GetNumPreds(BB); }
+ ArrayRef<BasicBlock *> get(BasicBlock *BB) {
+ return makeArrayRef(GetPreds(BB), GetNumPreds(BB));
+ }
+
+ /// clear - Remove all information.
+ void clear() {
+ BlockToPredsMap.clear();
+ BlockToPredCountMap.clear();
+ Memory.Reset();
+ }
+};
- /// clear - Remove all information.
- void clear() {
- BlockToPredsMap.clear();
- BlockToPredCountMap.clear();
- Memory.Reset();
- }
- };
} // end namespace llvm
#endif
diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h
index e3c4243e9d81..cd09618e3eee 100644
--- a/include/llvm/IR/Statepoint.h
+++ b/include/llvm/IR/Statepoint.h
@@ -17,21 +17,35 @@
#define __LLVM_IR_STATEPOINT_H
#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
+/// The statepoint intrinsic accepts a set of flags as its third argument.
+/// Valid values come out of this set.
+enum class StatepointFlags {
+ None = 0,
+ GCTransition = 1, ///< Indicates that this statepoint is a transition from
+ ///< GC-aware code to code that is not GC-aware.
+
+ MaskAll = GCTransition ///< A bitmask that includes all valid flags.
+};
+
+class GCRelocateOperands;
+class ImmutableStatepoint;
bool isStatepoint(const ImmutableCallSite &CS);
-bool isStatepoint(const Instruction *inst);
-bool isStatepoint(const Instruction &inst);
+bool isStatepoint(const Value *inst);
+bool isStatepoint(const Value &inst);
-bool isGCRelocate(const Instruction *inst);
+bool isGCRelocate(const Value *inst);
bool isGCRelocate(const ImmutableCallSite &CS);
-bool isGCResult(const Instruction *inst);
+bool isGCResult(const Value *inst);
bool isGCResult(const ImmutableCallSite &CS);
/// Analogous to CallSiteBase, this provides most of the actual
@@ -45,10 +59,10 @@ bool isGCResult(const ImmutableCallSite &CS);
template <typename InstructionTy, typename ValueTy, typename CallSiteTy>
class StatepointBase {
CallSiteTy StatepointCS;
- void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
- void *operator new(size_t s) LLVM_DELETED_FUNCTION;
+ void *operator new(size_t, unsigned) = delete;
+ void *operator new(size_t s) = delete;
- protected:
+protected:
explicit StatepointBase(InstructionTy *I) : StatepointCS(I) {
assert(isStatepoint(I));
}
@@ -56,38 +70,68 @@ class StatepointBase {
assert(isStatepoint(CS));
}
- public:
+public:
typedef typename CallSiteTy::arg_iterator arg_iterator;
+ enum {
+ IDPos = 0,
+ NumPatchBytesPos = 1,
+ ActualCalleePos = 2,
+ NumCallArgsPos = 3,
+ FlagsPos = 4,
+ CallArgsBeginPos = 5,
+ };
+
/// Return the underlying CallSite.
- CallSiteTy getCallSite() {
- return StatepointCS;
+ CallSiteTy getCallSite() { return StatepointCS; }
+
+ uint64_t getFlags() const {
+ return cast<ConstantInt>(StatepointCS.getArgument(FlagsPos))
+ ->getZExtValue();
+ }
+
+ /// Return the ID associated with this statepoint.
+ uint64_t getID() {
+ const Value *IDVal = StatepointCS.getArgument(IDPos);
+ return cast<ConstantInt>(IDVal)->getZExtValue();
+ }
+
+ /// Return the number of patchable bytes associated with this statepoint.
+ uint32_t getNumPatchBytes() {
+ const Value *NumPatchBytesVal = StatepointCS.getArgument(NumPatchBytesPos);
+ uint64_t NumPatchBytes =
+ cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
+ assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
+ return NumPatchBytes;
}
/// Return the value actually being called or invoked.
- ValueTy *actualCallee() {
- return StatepointCS.getArgument(0);
+ ValueTy *getActualCallee() {
+ return StatepointCS.getArgument(ActualCalleePos);
}
- /// Number of arguments to be passed to the actual callee.
- int numCallArgs() {
- return cast<ConstantInt>(StatepointCS.getArgument(1))->getZExtValue();
+
+ /// Return the type of the value returned by the call underlying the
+ /// statepoint.
+ Type *getActualReturnType() {
+ auto *FTy = cast<FunctionType>(
+ cast<PointerType>(getActualCallee()->getType())->getElementType());
+ return FTy->getReturnType();
}
- /// Number of additional arguments excluding those intended
- /// for garbage collection.
- int numTotalVMSArgs() {
- return cast<ConstantInt>(StatepointCS.getArgument(3 + numCallArgs()))->getZExtValue();
+
+ /// Number of arguments to be passed to the actual callee.
+ int getNumCallArgs() {
+ const Value *NumCallArgsVal = StatepointCS.getArgument(NumCallArgsPos);
+ return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
}
typename CallSiteTy::arg_iterator call_args_begin() {
- // 3 = callTarget, #callArgs, flag
- int Offset = 3;
- assert(Offset <= (int)StatepointCS.arg_size());
- return StatepointCS.arg_begin() + Offset;
+ assert(CallArgsBeginPos <= (int)StatepointCS.arg_size());
+ return StatepointCS.arg_begin() + CallArgsBeginPos;
}
typename CallSiteTy::arg_iterator call_args_end() {
- int Offset = 3 + numCallArgs();
- assert(Offset <= (int)StatepointCS.arg_size());
- return StatepointCS.arg_begin() + Offset;
+ auto I = call_args_begin() + getNumCallArgs();
+ assert((StatepointCS.arg_end() - I) >= 0);
+ return I;
}
/// range adapter for call arguments
@@ -95,13 +139,44 @@ class StatepointBase {
return iterator_range<arg_iterator>(call_args_begin(), call_args_end());
}
+ /// Number of GC transition args.
+ int getNumTotalGCTransitionArgs() {
+ const Value *NumGCTransitionArgs = *call_args_end();
+ return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
+ }
+ typename CallSiteTy::arg_iterator gc_transition_args_begin() {
+ auto I = call_args_end() + 1;
+ assert((StatepointCS.arg_end() - I) >= 0);
+ return I;
+ }
+ typename CallSiteTy::arg_iterator gc_transition_args_end() {
+ auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
+ assert((StatepointCS.arg_end() - I) >= 0);
+ return I;
+ }
+
+ /// range adapter for GC transition arguments
+ iterator_range<arg_iterator> gc_transition_args() {
+ return iterator_range<arg_iterator>(gc_transition_args_begin(),
+ gc_transition_args_end());
+ }
+
+ /// Number of additional arguments excluding those intended
+ /// for garbage collection.
+ int getNumTotalVMSArgs() {
+ const Value *NumVMSArgs = *gc_transition_args_end();
+ return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
+ }
+
typename CallSiteTy::arg_iterator vm_state_begin() {
- return call_args_end();
+ auto I = gc_transition_args_end() + 1;
+ assert((StatepointCS.arg_end() - I) >= 0);
+ return I;
}
typename CallSiteTy::arg_iterator vm_state_end() {
- int Offset = 3 + numCallArgs() + 1 + numTotalVMSArgs();
- assert(Offset <= (int)StatepointCS.arg_size());
- return StatepointCS.arg_begin() + Offset;
+ auto I = vm_state_begin() + getNumTotalVMSArgs();
+ assert((StatepointCS.arg_end() - I) >= 0);
+ return I;
}
/// range adapter for vm state arguments
@@ -109,15 +184,7 @@ class StatepointBase {
return iterator_range<arg_iterator>(vm_state_begin(), vm_state_end());
}
- typename CallSiteTy::arg_iterator first_vm_state_stack_begin() {
- // 6 = numTotalVMSArgs, 1st_objectID, 1st_bci,
- // 1st_#stack, 1st_#local, 1st_#monitor
- return vm_state_begin() + 6;
- }
-
- typename CallSiteTy::arg_iterator gc_args_begin() {
- return vm_state_end();
- }
+ typename CallSiteTy::arg_iterator gc_args_begin() { return vm_state_end(); }
typename CallSiteTy::arg_iterator gc_args_end() {
return StatepointCS.arg_end();
}
@@ -127,18 +194,25 @@ class StatepointBase {
return iterator_range<arg_iterator>(gc_args_begin(), gc_args_end());
}
+ /// Get list of all gc reloactes linked to this statepoint
+ /// May contain several relocations for the same base/derived pair.
+ /// For example this could happen due to relocations on unwinding
+ /// path of invoke.
+ std::vector<GCRelocateOperands> getRelocates(ImmutableStatepoint &IS);
#ifndef NDEBUG
/// Asserts if this statepoint is malformed. Common cases for failure
/// include incorrect length prefixes for variable length sections or
/// illegal values for parameters.
void verify() {
- assert(numCallArgs() >= 0 &&
+ assert(getNumCallArgs() >= 0 &&
"number of arguments to actually callee can't be negative");
// The internal asserts in the iterator accessors do the rest.
(void)call_args_begin();
(void)call_args_end();
+ (void)gc_transition_args_begin();
+ (void)gc_transition_args_end();
(void)vm_state_begin();
(void)vm_state_end();
(void)gc_args_begin();
@@ -150,8 +224,7 @@ class StatepointBase {
/// A specialization of it's base class for read only access
/// to a gc.statepoint.
class ImmutableStatepoint
- : public StatepointBase<const Instruction, const Value,
- ImmutableCallSite> {
+ : public StatepointBase<const Instruction, const Value, ImmutableCallSite> {
typedef StatepointBase<const Instruction, const Value, ImmutableCallSite>
Base;
@@ -176,40 +249,106 @@ public:
class GCRelocateOperands {
ImmutableCallSite RelocateCS;
- public:
- GCRelocateOperands(const User* U) : RelocateCS(U) {
- assert(isGCRelocate(U));
- }
+public:
+ GCRelocateOperands(const User *U) : RelocateCS(U) { assert(isGCRelocate(U)); }
GCRelocateOperands(const Instruction *inst) : RelocateCS(inst) {
assert(isGCRelocate(inst));
}
- GCRelocateOperands(CallSite CS) : RelocateCS(CS) {
- assert(isGCRelocate(CS));
+ GCRelocateOperands(CallSite CS) : RelocateCS(CS) { assert(isGCRelocate(CS)); }
+
+ /// Return true if this relocate is tied to the invoke statepoint.
+ /// This includes relocates which are on the unwinding path.
+ bool isTiedToInvoke() const {
+ const Value *Token = RelocateCS.getArgument(0);
+
+ return isa<ExtractValueInst>(Token) || isa<InvokeInst>(Token);
}
+ /// Get enclosed relocate intrinsic
+ ImmutableCallSite getUnderlyingCallSite() { return RelocateCS; }
+
/// The statepoint with which this gc.relocate is associated.
- const Instruction *statepoint() {
- return cast<Instruction>(RelocateCS.getArgument(0));
+ const Instruction *getStatepoint() {
+ const Value *Token = RelocateCS.getArgument(0);
+
+ // This takes care both of relocates for call statepoints and relocates
+ // on normal path of invoke statepoint.
+ if (!isa<ExtractValueInst>(Token)) {
+ return cast<Instruction>(Token);
+ }
+
+ // This relocate is on exceptional path of an invoke statepoint
+ const BasicBlock *InvokeBB =
+ cast<Instruction>(Token)->getParent()->getUniquePredecessor();
+
+ assert(InvokeBB && "safepoints should have unique landingpads");
+ assert(InvokeBB->getTerminator() &&
+ "safepoint block should be well formed");
+ assert(isStatepoint(InvokeBB->getTerminator()));
+
+ return InvokeBB->getTerminator();
}
+
/// The index into the associate statepoint's argument list
/// which contains the base pointer of the pointer whose
/// relocation this gc.relocate describes.
- int basePtrIndex() {
+ unsigned getBasePtrIndex() {
return cast<ConstantInt>(RelocateCS.getArgument(1))->getZExtValue();
}
+
/// The index into the associate statepoint's argument list which
/// contains the pointer whose relocation this gc.relocate describes.
- int derivedPtrIndex() {
+ unsigned getDerivedPtrIndex() {
return cast<ConstantInt>(RelocateCS.getArgument(2))->getZExtValue();
}
- Value *basePtr() {
- ImmutableCallSite CS(statepoint());
- return *(CS.arg_begin() + basePtrIndex());
+
+ Value *getBasePtr() {
+ ImmutableCallSite CS(getStatepoint());
+ return *(CS.arg_begin() + getBasePtrIndex());
}
- Value *derivedPtr() {
- ImmutableCallSite CS(statepoint());
- return *(CS.arg_begin() + derivedPtrIndex());
+
+ Value *getDerivedPtr() {
+ ImmutableCallSite CS(getStatepoint());
+ return *(CS.arg_begin() + getDerivedPtrIndex());
}
};
+
+template <typename InstructionTy, typename ValueTy, typename CallSiteTy>
+std::vector<GCRelocateOperands>
+StatepointBase<InstructionTy, ValueTy, CallSiteTy>::getRelocates(
+ ImmutableStatepoint &IS) {
+
+ std::vector<GCRelocateOperands> Result;
+
+ ImmutableCallSite StatepointCS = IS.getCallSite();
+
+ // Search for relocated pointers. Note that working backwards from the
+ // gc_relocates ensures that we only get pairs which are actually relocated
+ // and used after the statepoint.
+ for (const User *U : StatepointCS.getInstruction()->users())
+ if (isGCRelocate(U))
+ Result.push_back(GCRelocateOperands(U));
+
+ if (!StatepointCS.isInvoke())
+ return Result;
+
+ // We need to scan thorough exceptional relocations if it is invoke statepoint
+ LandingPadInst *LandingPad =
+ cast<InvokeInst>(StatepointCS.getInstruction())->getLandingPadInst();
+
+ // Search for extract value from landingpad instruction to which
+ // gc relocates will be attached
+ for (const User *LandingPadUser : LandingPad->users()) {
+ if (!isa<ExtractValueInst>(LandingPadUser))
+ continue;
+
+ // gc relocates should be attached to this extract value
+ for (const User *U : LandingPadUser->users())
+ if (isGCRelocate(U))
+ Result.push_back(GCRelocateOperands(U));
+ }
+ return Result;
+}
}
+
#endif
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index c2073c7750b2..6ab0bd0631a0 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -91,8 +91,8 @@ protected:
NumContainedTys(0), ContainedTys(nullptr) {
setTypeID(tid);
}
- ~Type() {}
-
+ ~Type() = default;
+
void setTypeID(TypeID ID) {
IDAndSubclassData = (ID & 0xFF) | (IDAndSubclassData & 0xFFFFFF00);
assert(getTypeID() == ID && "TypeID data too large for field");
@@ -395,7 +395,8 @@ public:
static IntegerType *getInt16Ty(LLVMContext &C);
static IntegerType *getInt32Ty(LLVMContext &C);
static IntegerType *getInt64Ty(LLVMContext &C);
-
+ static IntegerType *getInt128Ty(LLVMContext &C);
+
//===--------------------------------------------------------------------===//
// Convenience methods for getting pointer types with one of the above builtin
// types as pointee.
diff --git a/include/llvm/IR/TypeBuilder.h b/include/llvm/IR/TypeBuilder.h
index 5a29e1e10855..d2c6f00079da 100644
--- a/include/llvm/IR/TypeBuilder.h
+++ b/include/llvm/IR/TypeBuilder.h
@@ -34,6 +34,8 @@ namespace llvm {
/// you'll need to specialize it. For example, say you want to call a
/// function defined externally as:
///
+/// \code{.cpp}
+///
/// struct MyType {
/// int32 a;
/// int32 *b;
@@ -41,12 +43,16 @@ namespace llvm {
/// };
/// int8 AFunction(struct MyType *value);
///
+/// \endcode
+///
/// You'll want to use
/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
/// to declare the function, but when you first try this, your compiler will
/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
/// write:
///
+/// \code{.cpp}
+///
/// namespace llvm {
/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
/// public:
@@ -57,7 +63,7 @@ namespace llvm {
/// TypeBuilder<types::i<32>, xcompile>::get(Context),
/// TypeBuilder<types::i<32>*, xcompile>::get(Context),
/// TypeBuilder<types::i<8>*[], xcompile>::get(Context),
-/// NULL);
+/// nullptr);
/// }
///
/// // You may find this a convenient place to put some constants
@@ -71,6 +77,8 @@ namespace llvm {
/// }
/// } // namespace llvm
///
+/// \endcode
+///
/// TypeBuilder cannot handle recursive types or types you only know at runtime.
/// If you try to give it a recursive type, it will deadlock, infinitely
/// recurse, or do something similarly undesirable.
diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h
index 033cd3e2f5da..160d71b03e7f 100644
--- a/include/llvm/IR/Use.h
+++ b/include/llvm/IR/Use.h
@@ -77,7 +77,7 @@ public:
typedef PointerIntPair<User *, 1, unsigned> UserRef;
private:
- Use(const Use &U) LLVM_DELETED_FUNCTION;
+ Use(const Use &U) = delete;
/// Destructor - Only for zap()
~Use() {
diff --git a/include/llvm/IR/UseListOrder.h b/include/llvm/IR/UseListOrder.h
index 5df459b1bd30..b7c2418d348d 100644
--- a/include/llvm/IR/UseListOrder.h
+++ b/include/llvm/IR/UseListOrder.h
@@ -45,18 +45,12 @@ struct UseListOrder {
}
private:
- UseListOrder(const UseListOrder &X) LLVM_DELETED_FUNCTION;
- UseListOrder &operator=(const UseListOrder &X) LLVM_DELETED_FUNCTION;
+ UseListOrder(const UseListOrder &X) = delete;
+ UseListOrder &operator=(const UseListOrder &X) = delete;
};
typedef std::vector<UseListOrder> UseListOrderStack;
-/// \brief Whether to preserve use-list ordering.
-bool shouldPreserveBitcodeUseListOrder();
-bool shouldPreserveAssemblyUseListOrder();
-void setPreserveBitcodeUseListOrder(bool ShouldPreserve);
-void setPreserveAssemblyUseListOrder(bool ShouldPreserve);
-
} // end namespace llvm
#endif
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index f578227d6cae..455900566afd 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -33,8 +33,8 @@ template <class>
struct OperandTraits;
class User : public Value {
- User(const User &) LLVM_DELETED_FUNCTION;
- void *operator new(size_t) LLVM_DELETED_FUNCTION;
+ User(const User &) = delete;
+ void *operator new(size_t) = delete;
template <unsigned>
friend struct HungoffOperandTraits;
virtual void anchor();
@@ -60,9 +60,7 @@ protected:
NumOperands = 0;
}
public:
- ~User() {
- Use::zap(OperandList, OperandList + NumOperands);
- }
+ ~User() override { Use::zap(OperandList, OperandList + NumOperands); }
/// \brief Free memory allocated for User and Use objects.
void operator delete(void *Usr);
/// \brief Placement delete - required by std, but never called.
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 705fc0f52d58..3bf2943a8980 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -106,17 +106,12 @@ protected:
private:
template <typename UseT> // UseT == 'Use' or 'const Use'
class use_iterator_impl
- : public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> super;
-
+ : public std::iterator<std::forward_iterator_tag, UseT *> {
UseT *U;
explicit use_iterator_impl(UseT *u) : U(u) {}
friend class Value;
public:
- typedef typename super::reference reference;
- typedef typename super::pointer pointer;
-
use_iterator_impl() : U() {}
bool operator==(const use_iterator_impl &x) const { return U == x.U; }
@@ -147,17 +142,12 @@ private:
template <typename UserTy> // UserTy == 'User' or 'const User'
class user_iterator_impl
- : public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> {
- typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super;
-
+ : public std::iterator<std::forward_iterator_tag, UserTy *> {
use_iterator_impl<Use> UI;
explicit user_iterator_impl(Use *U) : UI(U) {}
friend class Value;
public:
- typedef typename super::reference reference;
- typedef typename super::pointer pointer;
-
user_iterator_impl() {}
bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
@@ -188,15 +178,10 @@ private:
}
Use &getUse() const { return *UI; }
-
- /// \brief Return the operand # of this use in its User.
- ///
- /// FIXME: Replace all callers with a direct call to Use::getOperandNo.
- unsigned getOperandNo() const { return UI->getOperandNo(); }
};
- void operator=(const Value &) LLVM_DELETED_FUNCTION;
- Value(const Value &) LLVM_DELETED_FUNCTION;
+ void operator=(const Value &) = delete;
+ Value(const Value &) = delete;
protected:
Value(Type *Ty, unsigned scid);
@@ -231,6 +216,7 @@ public:
private:
void destroyValueName();
+ void setNameImpl(const Twine &Name);
public:
/// \brief Return a constant reference to the value's name.
@@ -461,12 +447,6 @@ public:
return const_cast<Value*>(this)->stripInBoundsOffsets();
}
- /// \brief Check if this is always a dereferenceable pointer.
- ///
- /// Test if this value is always a pointer to allocated and suitably aligned
- /// memory for a simple load or store.
- bool isDereferenceablePointer(const DataLayout *DL = nullptr) const;
-
/// \brief Translate PHI node to its predecessor from the given basic block.
///
/// If this value is a PHI node with CurBB as its parent, return the value in
@@ -484,7 +464,8 @@ public:
///
/// This is the greatest alignment value supported by load, store, and alloca
/// instructions, and global values.
- static const unsigned MaximumAlignment = 1u << 29;
+ static const unsigned MaxAlignmentExponent = 29;
+ static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent;
/// \brief Mutate the type of this Value to be of the specified type.
///
diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h
index 8fc7fdb03950..355748e05977 100644
--- a/include/llvm/IR/ValueHandle.h
+++ b/include/llvm/IR/ValueHandle.h
@@ -58,7 +58,7 @@ private:
Value* V;
- ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION;
+ ValueHandleBase(const ValueHandleBase&) = delete;
public:
explicit ValueHandleBase(HandleBaseKind Kind)
: PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {}
diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h
index f2ea405f1428..4d00b637609c 100644
--- a/include/llvm/IR/ValueMap.h
+++ b/include/llvm/IR/ValueMap.h
@@ -86,8 +86,8 @@ class ValueMap {
MapT Map;
std::unique_ptr<MDMapT> MDMap;
ExtraData Data;
- ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
- ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
+ ValueMap(const ValueMap&) = delete;
+ ValueMap& operator=(const ValueMap&) = delete;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;
@@ -99,8 +99,6 @@ public:
explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data(Data) {}
- ~ValueMap() {}
-
bool hasMD() const { return MDMap; }
MDMapT &MD() {
if (!MDMap)
@@ -149,9 +147,14 @@ public:
// If the key is already in the map, it returns false and doesn't update the
// value.
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<typename MapT::iterator, bool> map_result=
- Map.insert(std::make_pair(Wrap(KV.first), KV.second));
- return std::make_pair(iterator(map_result.first), map_result.second);
+ auto MapResult = Map.insert(std::make_pair(Wrap(KV.first), KV.second));
+ return std::make_pair(iterator(MapResult.first), MapResult.second);
+ }
+
+ std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
+ auto MapResult =
+ Map.insert(std::make_pair(Wrap(KV.first), std::move(KV.second)));
+ return std::make_pair(iterator(MapResult.first), MapResult.second);
}
/// insert - Range insertion of pairs.
@@ -258,9 +261,9 @@ public:
// I could == Copy.Map->Map.end() if the onRAUW callback already
// removed the old mapping.
if (I != Copy.Map->Map.end()) {
- ValueT Target(I->second);
+ ValueT Target(std::move(I->second));
Copy.Map->Map.erase(I); // Definitely destroys *this.
- Copy.Map->insert(std::make_pair(typed_new_key, Target));
+ Copy.Map->insert(std::make_pair(typed_new_key, std::move(Target)));
}
}
}
diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h
index 43bd123e7f44..89039d24195e 100644
--- a/include/llvm/IR/Verifier.h
+++ b/include/llvm/IR/Verifier.h
@@ -56,20 +56,9 @@ bool verifyModule(const Module &M, raw_ostream *OS = nullptr);
/// printed to stderr, and by default they are fatal. You can override that by
/// passing \c false to \p FatalErrors.
///
-/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
-FunctionPass *createVerifierPass(bool FatalErrors = true);
-
-/// \brief Create a debug-info verifier pass.
-///
-/// Check a module for validity of debug info. This is essentially a pass
-/// wrapped around the debug-info parts of \a verifyModule(). When the pass
-/// detects a verification error it is always printed to stderr, and by default
-/// they are fatal. You can override that by passing \c false to \p
-/// FatalErrors.
-///
/// Note that this creates a pass suitable for the legacy pass manager. It has
/// nothing to do with \c VerifierPass.
-ModulePass *createDebugInfoVerifierPass(bool FatalErrors = true);
+FunctionPass *createVerifierPass(bool FatalErrors = true);
class VerifierPass {
bool FatalErrors;