aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/IR
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2015-04-08 08:55:49 -0700
committerPirama Arumuga Nainar <pirama@google.com>2015-04-09 15:04:38 -0700
commit4c5e43da7792f75567b693105cc53e3f1992ad98 (patch)
tree1b2c9792582e12f5af0b1512e3094425f0dc0df9 /include/llvm/IR
parentc75239e6119d0f9a74c57099d91cbc9bde56bf33 (diff)
downloadexternal_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.zip
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.gz
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.bz2
Update aosp/master llvm for rebase to r233350
Change-Id: I07d935f8793ee8ec6b7da003f6483046594bca49
Diffstat (limited to 'include/llvm/IR')
-rw-r--r--include/llvm/IR/BasicBlock.h6
-rw-r--r--include/llvm/IR/CFG.h10
-rw-r--r--include/llvm/IR/CallSite.h2
-rw-r--r--include/llvm/IR/ConstantRange.h33
-rw-r--r--include/llvm/IR/DataLayout.h47
-rw-r--r--include/llvm/IR/DebugInfo.h714
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h273
-rw-r--r--include/llvm/IR/DebugLoc.h1
-rw-r--r--include/llvm/IR/DiagnosticInfo.h1
-rw-r--r--include/llvm/IR/GVMaterializer.h2
-rw-r--r--include/llvm/IR/GlobalValue.h2
-rw-r--r--include/llvm/IR/IRBuilder.h44
-rw-r--r--include/llvm/IR/InlineAsm.h53
-rw-r--r--include/llvm/IR/InstIterator.h17
-rw-r--r--include/llvm/IR/InstrTypes.h13
-rw-r--r--include/llvm/IR/Instruction.h7
-rw-r--r--include/llvm/IR/Instructions.h95
-rw-r--r--include/llvm/IR/IntrinsicInst.h34
-rw-r--r--include/llvm/IR/Intrinsics.td19
-rw-r--r--include/llvm/IR/IntrinsicsHexagon.td144
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td144
-rw-r--r--include/llvm/IR/IntrinsicsX86.td59
-rw-r--r--include/llvm/IR/Metadata.def3
-rw-r--r--include/llvm/IR/Metadata.h42
-rw-r--r--include/llvm/IR/Module.h24
-rw-r--r--include/llvm/IR/NoFolder.h4
-rw-r--r--include/llvm/IR/Operator.h5
-rw-r--r--include/llvm/IR/PassManager.h7
-rw-r--r--include/llvm/IR/PassManagerInternal.h1
-rw-r--r--include/llvm/IR/Value.h2
-rw-r--r--include/llvm/IR/Verifier.h13
31 files changed, 1282 insertions, 539 deletions
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 185fc29..8f5cdeb 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -119,7 +119,11 @@ public:
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;
/// \brief Returns the terminator instruction if the block is well formed or
/// null if the block is not well formed.
diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h
index 8476431..f78220a 100644
--- a/include/llvm/IR/CFG.h
+++ b/include/llvm/IR/CFG.h
@@ -121,7 +121,7 @@ public:
typedef typename super::reference reference;
private:
- const Term_ Term;
+ Term_ Term;
unsigned idx;
typedef SuccIterator<Term_, BB_> Self;
@@ -136,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;
@@ -165,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; }
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index a4ea243..9c87936 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -151,7 +151,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(); }
diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h
index 5e8cd34..9ded3ca 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/DataLayout.h b/include/llvm/IR/DataLayout.h
index 9479ba4..3e1f974 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -108,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;
@@ -116,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;
@@ -185,6 +195,7 @@ public:
DataLayout &operator=(const DataLayout &DL) {
clear();
+ StringRepresentation = DL.StringRepresentation;
BigEndian = DL.isBigEndian();
StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode;
@@ -209,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.
@@ -236,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; }
@@ -244,7 +259,7 @@ public:
const char *getLinkerPrivateGlobalPrefix() const {
if (ManglingMode == MM_MachO)
return "l";
- return getPrivateGlobalPrefix();
+ return "";
}
char getGlobalPrefix() const {
@@ -252,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");
@@ -269,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");
@@ -451,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 d2e5975..0163c05 100644
--- a/include/llvm/IR/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -165,7 +165,6 @@ protected:
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) {}
@@ -175,6 +174,10 @@ public:
MDNode *get() const { return const_cast<MDNode *>(DbgNode); }
operator MDNode *() const { return get(); }
MDNode *operator->() const { return get(); }
+ MDNode &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
// An explicit operator bool so that we can do testing of DI values
// easily.
@@ -215,29 +218,49 @@ public:
return getHeaderIterator(Index).getNumber<T>();
}
- 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;
+ uint16_t getTag() const {
+ if (auto *N = dyn_cast_or_null<DebugNode>(get()))
+ return N->getTag();
+ return 0;
+ }
+
+ bool isDerivedType() const { return get() && isa<MDDerivedTypeBase>(get()); }
+ bool isCompositeType() const {
+ return get() && isa<MDCompositeTypeBase>(get());
+ }
+ bool isSubroutineType() const {
+ return get() && isa<MDSubroutineType>(get());
+ }
+ bool isBasicType() const { return get() && isa<MDBasicType>(get()); }
+ bool isVariable() const { return get() && isa<MDLocalVariable>(get()); }
+ bool isSubprogram() const { return get() && isa<MDSubprogram>(get()); }
+ bool isGlobalVariable() const {
+ return get() && isa<MDGlobalVariable>(get());
+ }
+ bool isScope() const { return get() && isa<MDScope>(get()); }
+ bool isFile() const { return get() && isa<MDFile>(get()); }
+ bool isCompileUnit() const { return get() && isa<MDCompileUnit>(get()); }
+ bool isNameSpace() const{ return get() && isa<MDNamespace>(get()); }
+ bool isLexicalBlockFile() const {
+ return get() && isa<MDLexicalBlockFile>(get());
+ }
+ bool isLexicalBlock() const {
+ return get() && isa<MDLexicalBlockBase>(get());
+ }
+ bool isSubrange() const { return get() && isa<MDSubrange>(get()); }
+ bool isEnumerator() const { return get() && isa<MDEnumerator>(get()); }
+ bool isType() const { return get() && isa<MDType>(get()); }
+ bool isTemplateTypeParameter() const {
+ return get() && isa<MDTemplateTypeParameter>(get());
+ }
+ bool isTemplateValueParameter() const {
+ return get() && isa<MDTemplateValueParameter>(get());
+ }
+ bool isObjCProperty() const { return get() && isa<MDObjCProperty>(get()); }
+ bool isImportedEntity() const {
+ return get() && isa<MDImportedEntity>(get());
+ }
+ bool isExpression() const { return get() && isa<MDExpression>(get()); }
void print(raw_ostream &OS) const;
void dump() const;
@@ -247,29 +270,43 @@ public:
void replaceAllUsesWith(MDNode *D);
};
-#define RETURN_FROM_RAW(VALID, DEFAULT) \
+#define RETURN_FROM_RAW(VALID, UNUSED) \
do { \
- if (auto *N = getRaw()) \
- return VALID; \
- return DEFAULT; \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return VALID; \
} while (false)
#define RETURN_DESCRIPTOR_FROM_RAW(DESC, VALID) \
do { \
- if (auto *N = getRaw()) \
- return DESC(dyn_cast_or_null<MDNode>(VALID)); \
- return DESC(static_cast<const MDNode *>(nullptr)); \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return DESC(dyn_cast_or_null<MDNode>(VALID)); \
+ } while (false)
+#define RETURN_REF_FROM_RAW(REF, VALID) \
+ do { \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return REF::get(VALID); \
} while (false)
/// \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) {}
+ DISubrange(const MDSubrange *N) : DIDescriptor(N) {}
+
+ MDSubrange *get() const {
+ return cast_or_null<MDSubrange>(DIDescriptor::get());
+ }
+ operator MDSubrange *() const { return get(); }
+ MDSubrange *operator->() const { return get(); }
+ MDSubrange &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- int64_t getLo() const { return getHeaderFieldAs<int64_t>(1); }
- int64_t getCount() const { return getHeaderFieldAs<int64_t>(2); }
+ int64_t getLo() const { RETURN_FROM_RAW(N->getLo(), 0); }
+ int64_t getCount() const { RETURN_FROM_RAW(N->getCount(), 0); }
bool Verify() const;
};
@@ -290,14 +327,22 @@ typedef DITypedArray<DIDescriptor> DIArray;
/// 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) {}
+ DIEnumerator(const MDEnumerator *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
- int64_t getEnumValue() const { return getHeaderFieldAs<int64_t>(2); }
+ MDEnumerator *get() const {
+ return cast_or_null<MDEnumerator>(DIDescriptor::get());
+ }
+ operator MDEnumerator *() const { return get(); }
+ MDEnumerator *operator->() const { return get(); }
+ MDEnumerator &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ int64_t getEnumValue() const { RETURN_FROM_RAW(N->getValue(), 0); }
bool Verify() const;
};
@@ -316,12 +361,17 @@ typedef DITypedArray<DITypeRef> DITypeArray;
/// 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) {}
+ DIScope(const MDScope *N) : DIDescriptor(N) {}
+
+ MDScope *get() const { return cast_or_null<MDScope>(DIDescriptor::get()); }
+ operator MDScope *() const { return get(); }
+ MDScope *operator->() const { return get(); }
+ MDScope &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
/// \brief Get the parent scope.
///
@@ -362,6 +412,8 @@ public:
T resolve(const DITypeIdentifierMap &Map) const;
StringRef getName() const;
operator Metadata *() const { return const_cast<Metadata *>(Val); }
+
+ static DIRef get(const Metadata *MD) { return DIRef(MD); }
};
template <typename T>
@@ -413,12 +465,18 @@ template <> DIRef<DIType>::DIRef(const Metadata *V);
/// 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) {}
+ DIType(const MDType *N) : DIScope(N) {}
+
+ MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); }
+ operator MDType *() const { return get(); }
+ MDType *operator->() const { return get(); }
+ MDType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
operator DITypeRef() const {
assert(isType() &&
"constructing DITypeRef from an MDNode that is not a type");
@@ -427,15 +485,17 @@ public:
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); }
+ DIScopeRef getContext() const {
+ RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
+ }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ uint64_t getSizeInBits() const { RETURN_FROM_RAW(N->getSizeInBits(), 0); }
+ uint64_t getAlignInBits() const { RETURN_FROM_RAW(N->getAlignInBits(), 0); }
// 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); }
+ uint64_t getOffsetInBits() const { RETURN_FROM_RAW(N->getOffsetInBits(), 0); }
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
bool isPrivate() const {
return (getFlags() & FlagAccessibility) == FlagPrivate;
}
@@ -473,8 +533,19 @@ public:
class DIBasicType : public DIType {
public:
explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {}
+ DIBasicType(const MDBasicType *N) : DIType(N) {}
- unsigned getEncoding() const { return getHeaderFieldAs<unsigned>(7); }
+ MDBasicType *get() const {
+ return cast_or_null<MDBasicType>(DIDescriptor::get());
+ }
+ operator MDBasicType *() const { return get(); }
+ MDBasicType *operator->() const { return get(); }
+ MDBasicType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ unsigned getEncoding() const { RETURN_FROM_RAW(N->getEncoding(), 0); }
bool Verify() const;
};
@@ -484,25 +555,45 @@ public:
/// 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) {}
+ DIDerivedType(const MDDerivedTypeBase *N) : DIType(N) {}
- DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(3); }
+ MDDerivedTypeBase *get() const {
+ return cast_or_null<MDDerivedTypeBase>(DIDescriptor::get());
+ }
+ operator MDDerivedTypeBase *() const { return get(); }
+ MDDerivedTypeBase *operator->() const { return get(); }
+ MDDerivedTypeBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DITypeRef getTypeDerivedFrom() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getBaseType());
+ }
/// \brief Return property node, if this ivar is associated with one.
- MDNode *getObjCProperty() const;
+ MDNode *getObjCProperty() const {
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ return dyn_cast_or_null<MDNode>(N->getExtraData());
+ return nullptr;
+ }
DITypeRef getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- return getFieldAs<DITypeRef>(4);
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ return DITypeRef::get(N->getExtraData());
+ return DITypeRef::get(nullptr);
}
Constant *getConstant() const {
assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
- return getConstantField(4);
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getExtraData()))
+ return C->getValue();
+
+ return nullptr;
}
bool Verify() const;
@@ -519,18 +610,27 @@ public:
// 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) {}
+ DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {}
+
+ MDCompositeTypeBase *get() const {
+ return cast_or_null<MDCompositeTypeBase>(DIDescriptor::get());
+ }
+ operator MDCompositeTypeBase *() const { return get(); }
+ MDCompositeTypeBase *operator->() const { return get(); }
+ MDCompositeTypeBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
DIArray getElements() const {
assert(!isSubroutineType() && "no elements for DISubroutineType");
- return getFieldAs<DIArray>(4);
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getElements());
}
private:
@@ -544,16 +644,22 @@ private:
}
public:
- unsigned getRunTimeLang() const { return getHeaderFieldAs<unsigned>(7); }
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(5); }
+ unsigned getRunTimeLang() const { RETURN_FROM_RAW(N->getRuntimeLang(), 0); }
+ DITypeRef getContainingType() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getVTableHolder());
+ }
private:
/// \brief Set the containing type.
void setContainingType(DICompositeType ContainingType);
public:
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); }
- MDString *getIdentifier() const;
+ DIArray getTemplateParams() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
+ }
+ MDString *getIdentifier() const {
+ RETURN_FROM_RAW(N->getRawIdentifier(), nullptr);
+ }
bool Verify() const;
};
@@ -561,100 +667,163 @@ public:
class DISubroutineType : public DICompositeType {
public:
explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {}
+ DISubroutineType(const MDSubroutineType *N) : DICompositeType(N) {}
+
+ MDSubroutineType *get() const {
+ return cast_or_null<MDSubroutineType>(DIDescriptor::get());
+ }
+ operator MDSubroutineType *() const { return get(); }
+ MDSubroutineType *operator->() const { return get(); }
+ MDSubroutineType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
DITypedArray<DITypeRef> getTypeArray() const {
- return getFieldAs<DITypedArray<DITypeRef>>(4);
+ RETURN_DESCRIPTOR_FROM_RAW(DITypedArray<DITypeRef>, N->getTypeArray());
}
};
/// \brief This is a wrapper for a file.
class DIFile : public DIScope {
- friend class DIDescriptor;
-
public:
explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {}
+ DIFile(const MDFile *N) : DIScope(N) {}
+
+ MDFile *get() const { return cast_or_null<MDFile>(DIDescriptor::get()); }
+ operator MDFile *() const { return get(); }
+ MDFile *operator->() const { return get(); }
+ MDFile &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
/// \brief Retrieve the MDNode for the directory/file pair.
- MDNode *getFileNode() const;
+ MDNode *getFileNode() const { return get(); }
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) {}
+ DICompileUnit(const MDCompileUnit *N) : DIScope(N) {}
- dwarf::SourceLanguage getLanguage() const {
- return static_cast<dwarf::SourceLanguage>(getHeaderFieldAs<unsigned>(1));
+ MDCompileUnit *get() const {
+ return cast_or_null<MDCompileUnit>(DIDescriptor::get());
+ }
+ operator MDCompileUnit *() const { return get(); }
+ MDCompileUnit *operator->() const { return get(); }
+ MDCompileUnit &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
}
- 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); }
+ dwarf::SourceLanguage getLanguage() const {
+ RETURN_FROM_RAW(static_cast<dwarf::SourceLanguage>(N->getSourceLanguage()),
+ static_cast<dwarf::SourceLanguage>(0));
+ }
+ StringRef getProducer() const { RETURN_FROM_RAW(N->getProducer(), ""); }
+ bool isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), false); }
+ StringRef getFlags() const { RETURN_FROM_RAW(N->getFlags(), ""); }
+ unsigned getRunTimeVersion() const {
+ RETURN_FROM_RAW(N->getRuntimeVersion(), 0);
+ }
- DIArray getEnumTypes() const;
- DIArray getRetainedTypes() const;
- DIArray getSubprograms() const;
- DIArray getGlobalVariables() const;
- DIArray getImportedEntities() const;
+ DIArray getEnumTypes() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getEnumTypes());
+ }
+ DIArray getRetainedTypes() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getRetainedTypes());
+ }
+ DIArray getSubprograms() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getSubprograms());
+ }
+ DIArray getGlobalVariables() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getGlobalVariables());
+ }
+ DIArray getImportedEntities() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getImportedEntities());
+ }
void replaceSubprograms(DIArray Subprograms);
void replaceGlobalVariables(DIArray GlobalVariables);
- StringRef getSplitDebugFilename() const { return getHeaderField(6); }
- unsigned getEmissionKind() const { return getHeaderFieldAs<unsigned>(7); }
+ StringRef getSplitDebugFilename() const {
+ RETURN_FROM_RAW(N->getSplitDebugFilename(), "");
+ }
+ unsigned getEmissionKind() const { RETURN_FROM_RAW(N->getEmissionKind(), 0); }
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) {}
+ DISubprogram(const MDSubprogram *N) : 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); }
+ MDSubprogram *get() const {
+ return cast_or_null<MDSubprogram>(DIDescriptor::get());
+ }
+ operator MDSubprogram *() const { return get(); }
+ MDSubprogram *operator->() const { return get(); }
+ MDSubprogram &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
+ StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
/// \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 isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
+ unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
- unsigned getVirtuality() const { return getHeaderFieldAs<unsigned>(7); }
- unsigned getVirtualIndex() const { return getHeaderFieldAs<unsigned>(8); }
+ unsigned getVirtuality() const { RETURN_FROM_RAW(N->getVirtuality(), 0); }
+ unsigned getVirtualIndex() const { RETURN_FROM_RAW(N->getVirtualIndex(), 0); }
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(9); }
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
- unsigned isOptimized() const { return getHeaderFieldAs<bool>(10); }
+ unsigned isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), 0); }
/// \brief Get the beginning of the scope of the function (not the name).
- unsigned getScopeLineNumber() const { return getHeaderFieldAs<unsigned>(11); }
+ unsigned getScopeLineNumber() const { RETURN_FROM_RAW(N->getScopeLine(), 0); }
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- DISubroutineType getType() const { return getFieldAs<DISubroutineType>(3); }
+ DIScopeRef getContext() const {
+ RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
+ }
+ DISubroutineType getType() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DISubroutineType, N->getType());
+ }
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(4); }
+ DITypeRef getContainingType() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getContainingType());
+ }
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); }
+ Function *getFunction() const;
+
+ void replaceFunction(Function *F) {
+ if (auto *N = get())
+ N->replaceFunction(F);
+ }
+ DIArray getTemplateParams() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
+ }
DISubprogram getFunctionDeclaration() const {
- return getFieldAs<DISubprogram>(7);
+ RETURN_DESCRIPTOR_FROM_RAW(DISubprogram, N->getDeclaration());
+ }
+ MDNode *getVariablesNodes() const { return getVariables(); }
+ DIArray getVariables() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getVariables());
}
- MDNode *getVariablesNodes() const;
- DIArray getVariables() const;
unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
/// \brief Check for the "private" access specifier.
@@ -695,9 +864,31 @@ public:
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); }
+ DILexicalBlock(const MDLexicalBlock *N) : DIScope(N) {}
+
+ MDLexicalBlockBase *get() const {
+ return cast_or_null<MDLexicalBlockBase>(DIDescriptor::get());
+ }
+ operator MDLexicalBlockBase *() const { return get(); }
+ MDLexicalBlockBase *operator->() const { return get(); }
+ MDLexicalBlockBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ unsigned getLineNumber() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(get()))
+ return N->getLine();
+ return 0;
+ }
+ unsigned getColumnNumber() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(get()))
+ return N->getColumn();
+ return 0;
+ }
bool Verify() const;
};
@@ -705,6 +896,18 @@ public:
class DILexicalBlockFile : public DIScope {
public:
explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {}
+ DILexicalBlockFile(const MDLexicalBlockFile *N) : DIScope(N) {}
+
+ MDLexicalBlockFile *get() const {
+ return cast_or_null<MDLexicalBlockFile>(DIDescriptor::get());
+ }
+ operator MDLexicalBlockFile *() const { return get(); }
+ MDLexicalBlockFile *operator->() const { return get(); }
+ MDLexicalBlockFile &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
DIScope getContext() const {
// FIXME: This logic is horrible. getScope() returns a DILexicalBlock, but
// then we check if it's a subprogram? WHAT?!?
@@ -714,21 +917,36 @@ public:
}
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); }
+ DILexicalBlock getScope() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DILexicalBlock, N->getScope());
+ }
+ unsigned getDiscriminator() const {
+ RETURN_FROM_RAW(N->getDiscriminator(), 0);
+ }
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); }
+ DINameSpace(const MDNamespace *N) : DIScope(N) {}
+
+ MDNamespace *get() const {
+ return cast_or_null<MDNamespace>(DIDescriptor::get());
+ }
+ operator MDNamespace *() const { return get(); }
+ MDNamespace *operator->() const { return get(); }
+ MDNamespace &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
bool Verify() const;
};
@@ -737,10 +955,21 @@ class DITemplateTypeParameter : public DIDescriptor {
public:
explicit DITemplateTypeParameter(const MDNode *N = nullptr)
: DIDescriptor(N) {}
+ DITemplateTypeParameter(const MDTemplateTypeParameter *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
+ MDTemplateTypeParameter *get() const {
+ return cast_or_null<MDTemplateTypeParameter>(DIDescriptor::get());
+ }
+ operator MDTemplateTypeParameter *() const { return get(); }
+ MDTemplateTypeParameter *operator->() const { return get(); }
+ MDTemplateTypeParameter &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
bool Verify() const;
};
@@ -749,40 +978,67 @@ class DITemplateValueParameter : public DIDescriptor {
public:
explicit DITemplateValueParameter(const MDNode *N = nullptr)
: DIDescriptor(N) {}
+ DITemplateValueParameter(const MDTemplateValueParameter *N)
+ : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
+ MDTemplateValueParameter *get() const {
+ return cast_or_null<MDTemplateValueParameter>(DIDescriptor::get());
+ }
+ operator MDTemplateValueParameter *() const { return get(); }
+ MDTemplateValueParameter *operator->() const { return get(); }
+ MDTemplateValueParameter &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
- Metadata *getValue() const;
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
+ Metadata *getValue() const { RETURN_FROM_RAW(N->getValue(), nullptr); }
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;
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
public:
explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIGlobalVariable(const MDGlobalVariable *N) : 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); }
+ MDGlobalVariable *get() const {
+ return cast_or_null<MDGlobalVariable>(DIDescriptor::get());
+ }
+ operator MDGlobalVariable *() const { return get(); }
+ MDGlobalVariable *operator->() const { return get(); }
+ MDGlobalVariable &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
+ StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
+ unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getFilename() const { return getFieldAs<DIFile>(2).getFilename(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(2).getDirectory();
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
}
- DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
+ StringRef getFilename() const { return getFile().getFilename(); }
+ StringRef getDirectory() const { return getFile().getDirectory(); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
- GlobalVariable *getGlobal() const { return getGlobalVariableField(4); }
- Constant *getConstant() const { return getConstantField(4); }
+ GlobalVariable *getGlobal() const;
+ Constant *getConstant() const {
+ if (auto *N = get())
+ if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getVariable()))
+ return C->getValue();
+ return nullptr;
+ }
DIDerivedType getStaticDataMemberDeclaration() const {
- return getFieldAs<DIDerivedType>(5);
+ RETURN_DESCRIPTOR_FROM_RAW(DIDerivedType,
+ N->getStaticDataMemberDeclaration());
}
bool Verify() const;
@@ -790,34 +1046,45 @@ public:
/// \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;
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
public:
explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIVariable(const MDLocalVariable *N) : 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;
+ MDLocalVariable *get() const {
+ return cast_or_null<MDLocalVariable>(DIDescriptor::get());
+ }
+ operator MDLocalVariable *() const { return get(); }
+ MDLocalVariable *operator->() const { return get(); }
+ MDLocalVariable &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
}
- 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); }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ unsigned getArgNumber() const { RETURN_FROM_RAW(N->getArg(), 0); }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
/// \brief Return true if this variable is marked as "artificial".
bool isArtificial() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagArtificial) != 0;
+ return (getFlags() & FlagArtificial) != 0;
}
bool isObjectPointer() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0;
+ return (getFlags() & FlagObjectPointer) != 0;
}
/// \brief If this variable is inlined then return inline location.
- MDNode *getInlinedAt() const;
+ MDNode *getInlinedAt() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIDescriptor, N->getInlinedAt());
+ }
bool Verify() const;
@@ -843,25 +1110,28 @@ public:
/// 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.
class DIExpression : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIExpression(const MDExpression *N) : DIDescriptor(N) {}
- bool Verify() const;
+ MDExpression *get() const {
+ return cast_or_null<MDExpression>(DIDescriptor::get());
+ }
+ operator MDExpression *() const { return get(); }
+ MDExpression *operator->() const { return get(); }
+ MDExpression &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ // Don't call this. Call isValid() directly.
+ bool Verify() const = delete;
/// \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;
- }
+ unsigned getNumElements() const { return get()->getNumElements(); }
/// \brief return the Idx'th complex address element.
- uint64_t getElement(unsigned Idx) const;
+ uint64_t getElement(unsigned I) const { return get()->getElement(I); }
/// \brief Return whether this is a piece of an aggregate variable.
bool isBitPiece() const;
@@ -874,34 +1144,33 @@ public:
/// \brief A lightweight wrapper around an element of a DIExpression.
class Operand {
friend class iterator;
- DIHeaderFieldIterator I;
+ MDExpression::element_iterator I;
Operand() {}
- Operand(DIHeaderFieldIterator I) : I(I) {}
+ Operand(MDExpression::element_iterator I) : I(I) {}
public:
/// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments.
/// Argument 0 is the operand itself.
uint64_t getArg(unsigned N) const {
- DIHeaderFieldIterator In = I;
+ MDExpression::element_iterator In = I;
std::advance(In, N);
- return In.getNumber<uint64_t>();
+ return *In;
}
- operator uint64_t () const { return I.getNumber<uint64_t>(); }
- /// \brief Returns underlying DIHeaderFieldIterator.
- const DIHeaderFieldIterator &getBase() const { return I; }
+ operator uint64_t () const { return *I; }
+ /// \brief Returns underlying MDExpression::element_iterator.
+ const MDExpression::element_iterator &getBase() const { return I; }
/// \brief Returns the next operand.
- Operand getNext() const;
+ iterator getNext() const;
};
/// \brief An iterator for DIExpression elements.
class iterator : public std::iterator<std::input_iterator_tag, StringRef,
unsigned, const Operand*, Operand> {
friend class Operand;
- DIHeaderFieldIterator I;
+ MDExpression::element_iterator I;
Operand Tmp;
- iterator(DIHeaderFieldIterator I) : I(I) {}
+
public:
- iterator() {}
- iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {}
+ iterator(MDExpression::element_iterator I) : I(I) {}
const Operand &operator*() { return Tmp = Operand(I); }
const Operand *operator->() { return &(Tmp = Operand(I)); }
iterator &operator++() {
@@ -928,19 +1197,27 @@ public:
}
};
- iterator begin() const;
- iterator end() const;
+ iterator begin() const { return get()->elements_begin(); }
+ iterator end() const { return get()->elements_end(); }
};
/// \brief This object holds location information.
///
/// This object is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
- MDLocation *getRaw() const { return dyn_cast_or_null<MDLocation>(get()); }
-
public:
explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
+ MDLocation *get() const {
+ return cast_or_null<MDLocation>(DIDescriptor::get());
+ }
+ operator MDLocation *() const { return get(); }
+ MDLocation *operator->() const { return get(); }
+ MDLocation &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
unsigned getColumnNumber() const { RETURN_FROM_RAW(N->getColumn(), 0); }
DIScope getScope() const {
@@ -983,19 +1260,31 @@ public:
};
class DIObjCProperty : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
+ DIObjCProperty(const MDObjCProperty *N) : DIDescriptor(N) {}
+
+ MDObjCProperty *get() const {
+ return cast_or_null<MDObjCProperty>(DIDescriptor::get());
+ }
+ operator MDObjCProperty *() const { return get(); }
+ MDObjCProperty *operator->() const { return get(); }
+ MDObjCProperty &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- StringRef getObjCPropertyName() const { return getHeaderField(1); }
- DIFile getFile() const { return getFieldAs<DIFile>(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
+ StringRef getObjCPropertyName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- StringRef getObjCPropertyGetterName() const { return getHeaderField(3); }
- StringRef getObjCPropertySetterName() const { return getHeaderField(4); }
- unsigned getAttributes() const { return getHeaderFieldAs<unsigned>(5); }
+ StringRef getObjCPropertyGetterName() const {
+ RETURN_FROM_RAW(N->getGetterName(), "");
+ }
+ StringRef getObjCPropertySetterName() const {
+ RETURN_FROM_RAW(N->getSetterName(), "");
+ }
+ unsigned getAttributes() const { RETURN_FROM_RAW(N->getAttributes(), 0); }
bool isReadOnlyObjCProperty() const {
return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
}
@@ -1019,28 +1308,42 @@ public:
///
/// \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); }
+ DIType getType() const { RETURN_DESCRIPTOR_FROM_RAW(DIType, N->getType()); }
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:
DIImportedEntity() = default;
explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIDescriptorRef getEntity() const { return getFieldAs<DIDescriptorRef>(2); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); }
- StringRef getName() const { return getHeaderField(2); }
+ DIImportedEntity(const MDImportedEntity *N) : DIDescriptor(N) {}
+
+ MDImportedEntity *get() const {
+ return cast_or_null<MDImportedEntity>(DIDescriptor::get());
+ }
+ operator MDImportedEntity *() const { return get(); }
+ MDImportedEntity *operator->() const { return get(); }
+ MDImportedEntity &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ DIDescriptorRef getEntity() const {
+ RETURN_REF_FROM_RAW(DIDescriptorRef, N->getEntity());
+ }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
bool Verify() const;
};
#undef RETURN_FROM_RAW
#undef RETURN_DESCRIPTOR_FROM_RAW
+#undef RETURN_REF_FROM_RAW
/// \brief Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope);
@@ -1098,9 +1401,6 @@ public:
/// \brief Process DILocation.
void processLocation(const Module &M, DILocation Loc);
- /// \brief Process DIExpression.
- void processExpression(DIExpression Expr);
-
/// \brief Clear all lists.
void reset();
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index 4534a14..d7563fc 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -41,53 +41,6 @@
namespace llvm {
-/// \brief Debug location.
-///
-/// A debug location in source code, used for debug info and otherwise.
-class MDLocation : public MDNode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
- unsigned Column, ArrayRef<Metadata *> MDs);
- ~MDLocation() { dropAllReferences(); }
-
- static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, StorageType Storage,
- bool ShouldCreate = true);
-
- TempMDLocation cloneImpl() const {
- return getTemporary(getContext(), getLine(), getColumn(), getScope(),
- getInlinedAt());
- }
-
- // Disallow replacing operands.
- void replaceOperandWith(unsigned I, Metadata *New) = delete;
-
-public:
- DEFINE_MDNODE_GET(MDLocation,
- (unsigned Line, unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr),
- (Line, Column, Scope, InlinedAt))
-
- /// \brief Return a (temporary) clone of this.
- TempMDLocation clone() const { return cloneImpl(); }
-
- unsigned getLine() const { return SubclassData32; }
- unsigned getColumn() const { return SubclassData16; }
- Metadata *getScope() const { return getOperand(0); }
- Metadata *getInlinedAt() const {
- if (getNumOperands() == 2)
- return getOperand(1);
- return nullptr;
- }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDLocationKind;
- }
-};
-
/// \brief Tagged DWARF-like metadata node.
///
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
@@ -146,7 +99,6 @@ public:
case MDTemplateValueParameterKind:
case MDGlobalVariableKind:
case MDLocalVariableKind:
- case MDExpressionKind:
case MDObjCPropertyKind:
case MDImportedEntityKind:
return true;
@@ -330,7 +282,16 @@ protected:
~MDScope() {}
public:
- Metadata *getFile() const { return getOperand(0); }
+ /// \brief Return the underlying file.
+ ///
+ /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
+ /// (it\em is the file). If \c this is an \a MDFile, we need to return \c
+ /// this. Otherwise, return the first operand, which is where all other
+ /// subclasses store their file pointer.
+ Metadata *getFile() const {
+ return isa<MDFile>(this) ? const_cast<MDScope *>(this)
+ : static_cast<Metadata *>(getOperand(0));
+ }
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
@@ -351,6 +312,52 @@ public:
}
};
+/// \brief File.
+///
+/// TODO: Merge with directory/file node (including users).
+/// TODO: Canonicalize paths on creation.
+class MDFile : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+ : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
+ ~MDFile() {}
+
+ static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
+ StringRef Directory, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Filename),
+ getCanonicalMDString(Context, Directory), Storage,
+ ShouldCreate);
+ }
+ static MDFile *getImpl(LLVMContext &Context, MDString *Filename,
+ MDString *Directory, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDFile cloneImpl() const {
+ return getTemporary(getContext(), getFilename(), getDirectory());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
+ (Filename, Directory))
+ DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
+ (Filename, Directory))
+
+ TempMDFile 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() == MDFileKind;
+ }
+};
+
/// \brief Base class for types.
///
/// TODO: Remove the hardcoded name and context, since many types don't use
@@ -373,6 +380,10 @@ protected:
~MDType() {}
public:
+ TempMDType clone() const {
+ return TempMDType(cast<MDType>(MDNode::clone().release()));
+ }
+
unsigned getLine() const { return Line; }
uint64_t getSizeInBits() const { return SizeInBits; }
uint64_t getAlignInBits() const { return AlignInBits; }
@@ -384,6 +395,11 @@ public:
MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ void setFlags(unsigned NewFlags) {
+ assert(!isUniqued() && "Cannot set flags on uniqued nodes");
+ Flags = NewFlags;
+ }
+
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@@ -433,6 +449,8 @@ class MDBasicType : public MDType {
}
public:
+ DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name),
+ (Tag, Name, 0, 0, 0))
DEFINE_MDNODE_GET(MDBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Encoding),
@@ -719,52 +737,6 @@ public:
}
};
-/// \brief File.
-///
-/// TODO: Merge with directory/file node (including users).
-/// TODO: Canonicalize paths on creation.
-class MDFile : public MDScope {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
- : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
- ~MDFile() {}
-
- static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
- StringRef Directory, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(Context, getCanonicalMDString(Context, Filename),
- getCanonicalMDString(Context, Directory), Storage,
- ShouldCreate);
- }
- static MDFile *getImpl(LLVMContext &Context, MDString *Filename,
- MDString *Directory, StorageType Storage,
- bool ShouldCreate = true);
-
- TempMDFile cloneImpl() const {
- return getTemporary(getContext(), getFilename(), getDirectory());
- }
-
-public:
- DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
- (Filename, Directory))
- DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
- (Filename, Directory))
-
- TempMDFile 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() == MDFileKind;
- }
-};
-
/// \brief Compile unit.
class MDCompileUnit : public MDScope {
friend class LLVMContextImpl;
@@ -875,11 +847,96 @@ public:
}
};
+/// \brief A scope for locals.
+///
+/// A legal scope for lexical blocks, local variables, and debug info
+/// locations. Subclasses are \a MDSubprogram, \a MDLexicalBlock, and \a
+/// MDLexicalBlockFile.
+class MDLocalScope : public MDScope {
+protected:
+ MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops)
+ : MDScope(C, ID, Storage, Tag, Ops) {}
+ ~MDLocalScope() {}
+
+public:
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDSubprogramKind ||
+ MD->getMetadataID() == MDLexicalBlockKind ||
+ MD->getMetadataID() == MDLexicalBlockFileKind;
+ }
+};
+
+/// \brief Debug location.
+///
+/// A debug location in source code, used for debug info and otherwise.
+class MDLocation : public MDNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> MDs);
+ ~MDLocation() { dropAllReferences(); }
+
+ static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true);
+ static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, MDLocalScope *Scope,
+ MDLocation *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
+ }
+
+ TempMDLocation cloneImpl() const {
+ return getTemporary(getContext(), getLine(), getColumn(), getScope(),
+ getInlinedAt());
+ }
+
+ // Disallow replacing operands.
+ void replaceOperandWith(unsigned I, Metadata *New) = delete;
+
+public:
+ DEFINE_MDNODE_GET(MDLocation,
+ (unsigned Line, unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+ DEFINE_MDNODE_GET(MDLocation,
+ (unsigned Line, unsigned Column, MDLocalScope *Scope,
+ MDLocation *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+
+ /// \brief Return a (temporary) clone of this.
+ TempMDLocation clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return SubclassData32; }
+ unsigned getColumn() const { return SubclassData16; }
+ MDLocalScope *getScope() const {
+ return cast_or_null<MDLocalScope>(getRawScope());
+ }
+ MDLocation *getInlinedAt() const {
+ return cast_or_null<MDLocation>(getRawInlinedAt());
+ }
+
+ 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() == MDLocationKind;
+ }
+};
+
/// \brief Subprogram description.
///
/// TODO: Remove DisplayName. It's always equal to Name.
/// TODO: Split up flags.
-class MDSubprogram : public MDScope {
+class MDSubprogram : public MDLocalScope {
friend class LLVMContextImpl;
friend class MDNode;
@@ -896,7 +953,8 @@ class MDSubprogram : public MDScope {
unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
bool IsOptimized, ArrayRef<Metadata *> Ops)
- : MDScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
+ : MDLocalScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram,
+ Ops),
Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
@@ -1004,11 +1062,11 @@ public:
}
};
-class MDLexicalBlockBase : public MDScope {
+class MDLexicalBlockBase : public MDLocalScope {
protected:
MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops)
- : MDScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
+ : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
~MDLexicalBlockBase() {}
public:
@@ -1407,6 +1465,18 @@ public:
unsigned getFlags() const { return Flags; }
Metadata *getInlinedAt() const { return getOperand(4); }
+ /// \brief Get an inlined version of this variable.
+ ///
+ /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt.
+ MDLocalVariable *withInline(MDLocation *InlinedAt) const {
+ if (InlinedAt == getInlinedAt())
+ return const_cast<MDLocalVariable *>(this);
+ auto Temp = clone();
+ Temp->replaceOperandWith(4, InlinedAt);
+ return replaceWithUniqued(std::move(Temp));
+ }
+ MDLocalVariable *withoutInline() const { return withInline(nullptr); }
+
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLocalVariableKind;
}
@@ -1415,17 +1485,16 @@ public:
/// \brief DWARF expression.
///
/// TODO: Co-allocate the expression elements.
-/// TODO: Drop fake DW_TAG_expression and separate from DebugNode.
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
/// storage types.
-class MDExpression : public DebugNode {
+class MDExpression : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
std::vector<uint64_t> Elements;
MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
- : DebugNode(C, MDExpressionKind, Storage, dwarf::DW_TAG_expression, None),
+ : MDNode(C, MDExpressionKind, Storage, None),
Elements(Elements.begin(), Elements.end()) {}
~MDExpression() {}
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index 86e6441..c29d5bf 100644
--- a/include/llvm/IR/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -103,7 +103,6 @@ namespace llvm {
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/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
index c6a8854..6db5a40 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/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index 6f57dc2..ae2f2e1 100644
--- a/include/llvm/IR/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -53,6 +53,8 @@ public:
///
virtual std::error_code MaterializeModule(Module *M) = 0;
+ virtual std::error_code materializeMetadata() = 0;
+
virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0;
};
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index aaecc1d..002e5e7 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -346,8 +346,6 @@ public:
inline Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; }
- const DataLayout *getDataLayout() const;
-
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 33649d7..617e2bc 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -351,8 +351,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);
}
//===--------------------------------------------------------------------===//
@@ -1017,6 +1017,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;
@@ -1026,7 +1030,7 @@ public:
if (i == e)
return Insert(Folder.CreateGetElementPtr(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 = "") {
@@ -1039,19 +1043,19 @@ public:
if (i == e)
return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
}
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, IdxList), Name);
}
Value *CreateGEP(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(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateInBoundsGEP(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(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
@@ -1059,7 +1063,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
const Twine &Name = "") {
@@ -1068,7 +1072,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
const Twine &Name = "") {
@@ -1080,7 +1084,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
const Twine &Name = "") {
@@ -1092,7 +1096,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
@@ -1100,7 +1104,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(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 = "") {
@@ -1109,7 +1113,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(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 = "") {
@@ -1121,7 +1125,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(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 = "") {
@@ -1133,7 +1137,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(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);
@@ -1486,6 +1490,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 = "") {
@@ -1595,7 +1609,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/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 84ae9df..6ae4122 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -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,26 @@ 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_Z,
+ Constraint_ZC,
+ Constraint_Zy,
+ Constraints_Max = Constraint_Zy,
+ Constraints_ShiftAmount = 16,
+
Flag_MatchingOperand = 0x80000000
};
@@ -252,6 +286,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 +314,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 0bb2854..f3ce649 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;
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index e086282..3a33f43 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -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.
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index dfece3e..dc96b57 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -54,7 +54,12 @@ 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;
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, but does not delete it.
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 83f9d04..52fa360 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -794,28 +794,31 @@ 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);
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertBefore);
}
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ 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);
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertAtEnd);
}
/// Create an "inbounds" getelementptr. See the documentation for the
@@ -824,7 +827,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 +842,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;
}
@@ -846,12 +863,12 @@ public:
}
Type *getSourceElementType() const {
- SequentialType *Ty = cast<SequentialType>(getPointerOperandType());
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- Ty = cast<SequentialType>(VTy->getElementType());
- return Ty->getElementType();
+ return cast<SequentialType>(getPointerOperandType()->getScalarType())
+ ->getElementType();
}
+ Type *getResultElementType() const { return getType()->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
@@ -960,27 +977,25 @@ 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(Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertBefore) {
init(Ptr, IdxList, NameStr);
+ assert(!PointeeType || PointeeType == getSourceElementType());
}
-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(Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
init(Ptr, IdxList, NameStr);
+ assert(!PointeeType || PointeeType == getSourceElementType());
}
@@ -1201,11 +1216,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 {
@@ -1908,6 +1927,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);
@@ -2019,6 +2041,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);
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index d434432..bf0adc3 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -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());
+ MDLocalVariable *getVariable() const {
+ return cast<MDLocalVariable>(getRawVariable());
}
- MDNode *getExpression() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(2))->getMetadata());
+ MDExpression *getExpression() const {
+ return cast<MDExpression>(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());
+ MDLocalVariable *getVariable() const {
+ return cast<MDLocalVariable>(getRawVariable());
+ }
+ MDExpression *getExpression() const {
+ return cast<MDExpression>(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.td b/include/llvm/IR/Intrinsics.td
index e89e65d..da9d8cb 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -261,10 +261,10 @@ 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">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
@@ -412,10 +412,19 @@ 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
-// returns the exception object pointer for the exception to be handled.
-def int_eh_begincatch : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>;
+// 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], []>;
+
+// Designates the provided static alloca as the unwind help object. Required
+// for WinEH.
+def int_eh_unwindhelp : 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.
diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td
index b566956..78ee651 100644
--- a/include/llvm/IR/IntrinsicsHexagon.td
+++ b/include/llvm/IR/IntrinsicsHexagon.td
@@ -422,12 +422,42 @@ 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>
//
@@ -606,20 +636,126 @@ class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix>
[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)
//
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index 110d55d..95fc3e5 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -73,7 +73,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 +94,12 @@ 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 VSX Intrinsic Class Definitions.
@@ -120,7 +126,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 +203,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 +257,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 +312,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">;
@@ -361,12 +390,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 +409,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">,
@@ -489,6 +530,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 +552,41 @@ 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]>;
+
+// These need diagnostics for invalid arguments so don't inherit from GCCBuiltin
+def int_ppc_altivec_crypto_vshasigmad :
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_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.
@@ -719,3 +796,62 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
[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 :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_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 :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortwci :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdc :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_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 :
+ 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/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 60deb32..39b8e3b 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -882,15 +882,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]>;
@@ -1156,12 +1147,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]>;
@@ -1187,32 +1172,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">,
@@ -1734,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
@@ -1756,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]>;
@@ -1811,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,
diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def
index 66589e0..0eb29bc 100644
--- a/include/llvm/IR/Metadata.def
+++ b/include/llvm/IR/Metadata.def
@@ -61,6 +61,7 @@ HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocation)
+HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DebugNode)
HANDLE_SPECIALIZED_MDNODE_LEAF(GenericDebugNode)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubrange)
@@ -75,6 +76,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompositeType)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubroutineType)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDFile)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompileUnit)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLocalScope)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubprogram)
HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLexicalBlockBase)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLexicalBlock)
@@ -86,7 +88,6 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDTemplateValueParameter)
HANDLE_SPECIALIZED_MDNODE_BRANCH(MDVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDGlobalVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocalVariable)
-HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDObjCProperty)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDImportedEntity)
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index ff8f837..a31bdbf 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -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.
@@ -104,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;
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 62f4194..ac60c8e 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() &&
@@ -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
/// @{
diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h
index a9cdfc3..ab7bed6 100644
--- a/include/llvm/IR/NoFolder.h
+++ b/include/llvm/IR/NoFolder.h
@@ -189,7 +189,7 @@ public:
}
Instruction *CreateGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::Create(C, IdxList);
+ return GetElementPtrInst::Create(nullptr, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Constant *C,
@@ -204,7 +204,7 @@ public:
}
Instruction *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::CreateInBounds(C, IdxList);
+ return GetElementPtrInst::CreateInBounds(nullptr, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 46935ce..c87f89c 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -400,6 +400,11 @@ public:
return getPointerOperand()->getType();
}
+ Type *getSourceElementType() const {
+ return cast<SequentialType>(getPointerOperandType()->getScalarType())
+ ->getElementType();
+ }
+
/// Method to return the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
return getPointerOperandType()->getPointerAddressSpace();
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
index c92e7c9..3c24e72 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>
@@ -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());
}
diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h
index 297f5f4..92de10b 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/Value.h b/include/llvm/IR/Value.h
index b7213a6..8217ef7 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -450,7 +450,7 @@ public:
///
/// 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;
+ bool isDereferenceablePointer(const DataLayout &DL) const;
/// \brief Translate PHI node to its predecessor from the given basic block.
///
diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h
index 43bd123..89039d2 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;