clang 23.0.0git
Address.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class provides a simple wrapper for a pair of a pointer and an
10// alignment.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CLANG_LIB_CIR_ADDRESS_H
15#define CLANG_LIB_CIR_ADDRESS_H
16
17#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
18#include "mlir/IR/Value.h"
19#include "clang/AST/CharUnits.h"
23#include "llvm/ADT/PointerIntPair.h"
24#include "llvm/Support/Casting.h"
25
26namespace clang::CIRGen {
27
28// Forward declaration to avoid a circular dependency
29class CIRGenBuilderTy;
30
31class Address {
32
33 // The boolean flag indicates whether the pointer is known to be non-null.
34 llvm::PointerIntPair<mlir::Value, 1, bool> pointerAndKnownNonNull;
35
36 /// The expected CIR type of the pointer. Carrying accurate element type
37 /// information in Address makes it more convenient to work with Address
38 /// values and allows frontend assertions to catch simple mistakes.
39 mlir::Type elementType;
40
41 clang::CharUnits alignment;
42
43protected:
44 Address(std::nullptr_t) : elementType(nullptr) {}
45
46public:
47 Address(mlir::Value pointer, mlir::Type elementType,
48 clang::CharUnits alignment)
49 : Address(pointer, elementType, alignment, false) {}
50
51 Address(mlir::Value pointer, mlir::Type elementType,
52 clang::CharUnits alignment, bool isKnownNonNull)
53 : pointerAndKnownNonNull(pointer, isKnownNonNull),
54 elementType(elementType), alignment(alignment) {
55 assert(pointer && "Pointer cannot be null");
56 assert(elementType && "Element type cannot be null");
57 assert(!alignment.isZero() && "Alignment cannot be zero");
58
59 assert(mlir::isa<cir::PointerType>(pointer.getType()) &&
60 "Expected cir.ptr type");
61
62 assert(mlir::cast<cir::PointerType>(pointer.getType()).getPointee() ==
63 elementType);
64 }
65
66 Address(mlir::Value pointer, clang::CharUnits alignment)
67 : Address(pointer,
68 mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
69 alignment) {
70 assert((!alignment.isZero() || pointer == nullptr) &&
71 "creating valid address with invalid alignment");
72 }
73
74 static Address invalid() { return Address(nullptr); }
75 bool isValid() const {
76 return pointerAndKnownNonNull.getPointer() != nullptr;
77 }
78
79 /// Return address with different pointer, but same element type and
80 /// alignment.
81 Address withPointer(mlir::Value newPtr) const {
82 return Address(newPtr, getElementType(), getAlignment());
83 }
84
85 /// Return address with different alignment, but same pointer and element
86 /// type.
88 return Address(getPointer(), getElementType(), newAlignment,
90 }
91
92 /// Return address with different element type, a bitcast pointer, and
93 /// the same alignment.
94 Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const;
95
96 mlir::Value getPointer() const {
97 assert(isValid());
98 return pointerAndKnownNonNull.getPointer();
99 }
100
101 mlir::Value getBasePointer() const {
102 // TODO(cir): Remove the version above when we catchup with OG codegen on
103 // ptr auth.
104 assert(isValid() && "pointer isn't valid");
105 return getPointer();
106 }
107
108 /// Return the pointer contained in this class after authenticating it and
109 /// adding offset to it if necessary.
110 mlir::Value emitRawPointer() const {
112 return getBasePointer();
113 }
114
115 mlir::Type getType() const {
116 assert(mlir::cast<cir::PointerType>(
117 pointerAndKnownNonNull.getPointer().getType())
118 .getPointee() == elementType);
119
120 return mlir::cast<cir::PointerType>(getPointer().getType());
121 }
122
123 mlir::Type getElementType() const {
124 assert(isValid());
125 assert(mlir::cast<cir::PointerType>(
126 pointerAndKnownNonNull.getPointer().getType())
127 .getPointee() == elementType);
128 return elementType;
129 }
130
131 mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const {
132 auto ptrTy = mlir::dyn_cast<cir::PointerType>(getType());
133 return ptrTy.getAddrSpace();
134 }
135
136 clang::CharUnits getAlignment() const { return alignment; }
137
138 /// Get the operation which defines this address.
139 mlir::Operation *getDefiningOp() const {
140 if (!isValid())
141 return nullptr;
142 return getPointer().getDefiningOp();
143 }
144
145 template <typename OpTy> OpTy getDefiningOp() const {
146 return mlir::dyn_cast_or_null<OpTy>(getDefiningOp());
147 }
148
149 /// Whether the pointer is known not to be null.
150 bool isKnownNonNull() const {
151 assert(isValid() && "Invalid address");
152 return static_cast<bool>(pointerAndKnownNonNull.getInt());
153 }
154
155 /// Set the non-null bit.
157 assert(isValid() && "Invalid address");
158 pointerAndKnownNonNull.setInt(true);
159 return *this;
160 }
161};
162
163} // namespace clang::CIRGen
164
165#endif // CLANG_LIB_CIR_ADDRESS_H
bool isKnownNonNull() const
Whether the pointer is known not to be null.
Definition Address.h:150
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
Definition Address.h:81
mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const
Definition Address.h:131
mlir::Value getPointer() const
Definition Address.h:96
Address(mlir::Value pointer, clang::CharUnits alignment)
Definition Address.h:66
mlir::Type getElementType() const
Definition Address.h:123
static Address invalid()
Definition Address.h:74
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
Address setKnownNonNull()
Set the non-null bit.
Definition Address.h:156
clang::CharUnits getAlignment() const
Definition Address.h:136
Address withAlignment(clang::CharUnits newAlignment) const
Return address with different alignment, but same pointer and element type.
Definition Address.h:87
mlir::Value getBasePointer() const
Definition Address.h:101
mlir::Type getType() const
Definition Address.h:115
Address(std::nullptr_t)
Definition Address.h:44
Address(mlir::Value pointer, mlir::Type elementType, clang::CharUnits alignment, bool isKnownNonNull)
Definition Address.h:51
bool isValid() const
Definition Address.h:75
Address(mlir::Value pointer, mlir::Type elementType, clang::CharUnits alignment)
Definition Address.h:47
OpTy getDefiningOp() const
Definition Address.h:145
mlir::Operation * getDefiningOp() const
Get the operation which defines this address.
Definition Address.h:139
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:110
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3336
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
Definition Address.h:327
#define false
Definition stdbool.h:26
static bool addressPointerAuthInfo()