aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/Address.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/Address.h')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/Address.h92
1 files changed, 68 insertions, 24 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/Address.h b/contrib/llvm-project/clang/lib/CodeGen/Address.h
index 6a8e57f8db33..cf48df8f5e73 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/Address.h
+++ b/contrib/llvm-project/clang/lib/CodeGen/Address.h
@@ -14,29 +14,43 @@
#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
-#include "llvm/IR/Constants.h"
#include "clang/AST/CharUnits.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/Support/MathExtras.h"
namespace clang {
namespace CodeGen {
+// Indicates whether a pointer is known not to be null.
+enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
+
/// An aligned address.
class Address {
- llvm::Value *Pointer;
+ llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull;
+ llvm::Type *ElementType;
CharUnits Alignment;
+
+protected:
+ Address(std::nullptr_t) : ElementType(nullptr) {}
+
public:
- Address(llvm::Value *pointer, CharUnits alignment)
- : Pointer(pointer), Alignment(alignment) {
- assert((!alignment.isZero() || pointer == nullptr) &&
- "creating valid address with invalid alignment");
+ Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
+ KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
+ : PointerAndKnownNonNull(Pointer, IsKnownNonNull),
+ ElementType(ElementType), Alignment(Alignment) {
+ assert(Pointer != nullptr && "Pointer cannot be null");
+ assert(ElementType != nullptr && "Element type cannot be null");
}
- static Address invalid() { return Address(nullptr, CharUnits()); }
- bool isValid() const { return Pointer != nullptr; }
+ static Address invalid() { return Address(nullptr); }
+ bool isValid() const {
+ return PointerAndKnownNonNull.getPointer() != nullptr;
+ }
llvm::Value *getPointer() const {
assert(isValid());
- return Pointer;
+ return PointerAndKnownNonNull.getPointer();
}
/// Return the type of the pointer value.
@@ -45,11 +59,9 @@ public:
}
/// Return the type of the values stored in this address.
- ///
- /// When IR pointer types lose their element type, we should simply
- /// store it in Address instead for the convenience of writing code.
llvm::Type *getElementType() const {
- return getType()->getElementType();
+ assert(isValid());
+ return ElementType;
}
/// Return the address space that this address resides in.
@@ -67,30 +79,62 @@ public:
assert(isValid());
return Alignment;
}
+
+ /// Return address with different pointer, but same element type and
+ /// alignment.
+ Address withPointer(llvm::Value *NewPointer,
+ KnownNonNull_t IsKnownNonNull) const {
+ return Address(NewPointer, getElementType(), getAlignment(),
+ IsKnownNonNull);
+ }
+
+ /// Return address with different alignment, but same pointer and element
+ /// type.
+ Address withAlignment(CharUnits NewAlignment) const {
+ return Address(getPointer(), getElementType(), NewAlignment,
+ isKnownNonNull());
+ }
+
+ /// Return address with different element type, but same pointer and
+ /// alignment.
+ Address withElementType(llvm::Type *ElemTy) const {
+ return Address(getPointer(), ElemTy, getAlignment(), isKnownNonNull());
+ }
+
+ /// Whether the pointer is known not to be null.
+ KnownNonNull_t isKnownNonNull() const {
+ assert(isValid());
+ return (KnownNonNull_t)PointerAndKnownNonNull.getInt();
+ }
+
+ /// Set the non-null bit.
+ Address setKnownNonNull() {
+ assert(isValid());
+ PointerAndKnownNonNull.setInt(true);
+ return *this;
+ }
};
/// A specialization of Address that requires the address to be an
/// LLVM Constant.
class ConstantAddress : public Address {
+ ConstantAddress(std::nullptr_t) : Address(nullptr) {}
+
public:
- ConstantAddress(llvm::Constant *pointer, CharUnits alignment)
- : Address(pointer, alignment) {}
+ ConstantAddress(llvm::Constant *pointer, llvm::Type *elementType,
+ CharUnits alignment)
+ : Address(pointer, elementType, alignment) {}
static ConstantAddress invalid() {
- return ConstantAddress(nullptr, CharUnits());
+ return ConstantAddress(nullptr);
}
llvm::Constant *getPointer() const {
return llvm::cast<llvm::Constant>(Address::getPointer());
}
- ConstantAddress getBitCast(llvm::Type *ty) const {
- return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty),
- getAlignment());
- }
-
- ConstantAddress getElementBitCast(llvm::Type *ty) const {
- return getBitCast(ty->getPointerTo(getAddressSpace()));
+ ConstantAddress withElementType(llvm::Type *ElemTy) const {
+ return ConstantAddress(getPointer(), ElemTy, getAlignment());
}
static bool isaImpl(Address addr) {
@@ -98,7 +142,7 @@ public:
}
static ConstantAddress castImpl(Address addr) {
return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
- addr.getAlignment());
+ addr.getElementType(), addr.getAlignment());
}
};