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"
25#include "llvm/ADT/PointerIntPair.h"
26#include "llvm/Support/Casting.h"
27
28namespace clang::CIRGen {
29
30// Forward declaration to avoid a circular dependency
31class CIRGenBuilderTy;
32
33class Address {
34
35 // The boolean flag indicates whether the pointer is known to be non-null.
36 llvm::PointerIntPair<mlir::Value, 1, bool> pointerAndKnownNonNull;
37
38 /// The expected CIR type of the pointer. Carrying accurate element type
39 /// information in Address makes it more convenient to work with Address
40 /// values and allows frontend assertions to catch simple mistakes.
41 mlir::Type elementType;
42
43 clang::CharUnits alignment;
44
45protected:
46 Address(std::nullptr_t) : elementType(nullptr) {}
47
48public:
49 Address(mlir::Value pointer, mlir::Type elementType,
50 clang::CharUnits alignment)
51 : Address(pointer, elementType, alignment, false) {}
52
53 Address(mlir::Value pointer, mlir::Type elementType,
54 clang::CharUnits alignment, bool isKnownNonNull)
55 : pointerAndKnownNonNull(pointer, isKnownNonNull),
56 elementType(elementType), alignment(alignment) {
57 assert(pointer && "Pointer cannot be null");
58 assert(elementType && "Element type cannot be null");
59 assert(!alignment.isZero() && "Alignment cannot be zero");
60
61 assert(mlir::isa<cir::PointerType>(pointer.getType()) &&
62 "Expected cir.ptr type");
63
64 assert(mlir::cast<cir::PointerType>(pointer.getType()).getPointee() ==
65 elementType);
66 }
67
68 Address(mlir::Value pointer, clang::CharUnits alignment)
69 : Address(pointer,
70 mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),
71 alignment) {
72 assert((!alignment.isZero() || pointer == nullptr) &&
73 "creating valid address with invalid alignment");
74 }
75
76 static Address invalid() { return Address(nullptr); }
77 bool isValid() const {
78 return pointerAndKnownNonNull.getPointer() != nullptr;
79 }
80
81 /// Return address with different pointer, but same element type and
82 /// alignment.
83 Address withPointer(mlir::Value newPtr) const {
84 return Address(newPtr, getElementType(), getAlignment());
85 }
86
87 /// Return address with different alignment, but same pointer and element
88 /// type.
90 return Address(getPointer(), getElementType(), newAlignment,
92 }
93
94 /// Return address with different element type, a bitcast pointer, and
95 /// the same alignment.
96 Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const;
97
98 mlir::Value getPointer() const {
99 assert(isValid());
100 return pointerAndKnownNonNull.getPointer();
101 }
102
103 mlir::Value getBasePointer() const {
104 // TODO(cir): Remove the version above when we catchup with OG codegen on
105 // ptr auth.
106 assert(isValid() && "pointer isn't valid");
107 return getPointer();
108 }
109
110 /// Return the pointer contained in this class after authenticating it and
111 /// adding offset to it if necessary.
112 mlir::Value emitRawPointer() const {
114 return getBasePointer();
115 }
116
117 mlir::Type getType() const {
118 assert(mlir::cast<cir::PointerType>(
119 pointerAndKnownNonNull.getPointer().getType())
120 .getPointee() == elementType);
121
122 return mlir::cast<cir::PointerType>(getPointer().getType());
123 }
124
125 mlir::Type getElementType() const {
126 assert(isValid());
127 assert(mlir::cast<cir::PointerType>(
128 pointerAndKnownNonNull.getPointer().getType())
129 .getPointee() == elementType);
130 return elementType;
131 }
132
133 mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const {
134 auto ptrTy = mlir::dyn_cast<cir::PointerType>(getType());
135 return ptrTy.getAddrSpace();
136 }
137
138 clang::CharUnits getAlignment() const { return alignment; }
139
140 /// Get the operation which defines this address.
141 mlir::Operation *getDefiningOp() const {
142 if (!isValid())
143 return nullptr;
144 return getPointer().getDefiningOp();
145 }
146
147 template <typename OpTy> OpTy getDefiningOp() const {
148 return mlir::dyn_cast_or_null<OpTy>(getDefiningOp());
149 }
150
151 /// Return the underlying alloca for this address, if any.
152 ///
153 /// Addresses may refer to an alloca through an address space cast, for
154 /// example when a target stack address space is cast to the language-visible
155 /// address space. Peel those casts so callers that need to annotate the
156 /// original alloca can still find it.
157 cir::AllocaOp getUnderlyingAllocaOp() const {
158 mlir::Value ptr = getPointer();
159 while (cir::CastOp castOp = ptr.getDefiningOp<cir::CastOp>()) {
160 if (!castOp.isAllocaPreservingCast())
161 break;
162 ptr = castOp.getSrc();
163 }
164 return ptr.getDefiningOp<cir::AllocaOp>();
165 }
166
167 /// Whether the pointer is known not to be null.
168 bool isKnownNonNull() const {
169 assert(isValid() && "Invalid address");
170 return static_cast<bool>(pointerAndKnownNonNull.getInt());
171 }
172
173 /// Set the non-null bit.
175 assert(isValid() && "Invalid address");
176 pointerAndKnownNonNull.setInt(true);
177 return *this;
178 }
179};
180
181} // namespace clang::CIRGen
182
183#endif // CLANG_LIB_CIR_ADDRESS_H
bool isKnownNonNull() const
Whether the pointer is known not to be null.
Definition Address.h:168
Address withPointer(mlir::Value newPtr) const
Return address with different pointer, but same element type and alignment.
Definition Address.h:83
mlir::ptr::MemorySpaceAttrInterface getAddressSpace() const
Definition Address.h:133
mlir::Value getPointer() const
Definition Address.h:98
Address(mlir::Value pointer, clang::CharUnits alignment)
Definition Address.h:68
mlir::Type getElementType() const
Definition Address.h:125
static Address invalid()
Definition Address.h:76
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:174
clang::CharUnits getAlignment() const
Definition Address.h:138
Address withAlignment(clang::CharUnits newAlignment) const
Return address with different alignment, but same pointer and element type.
Definition Address.h:89
mlir::Value getBasePointer() const
Definition Address.h:103
mlir::Type getType() const
Definition Address.h:117
Address(std::nullptr_t)
Definition Address.h:46
Address(mlir::Value pointer, mlir::Type elementType, clang::CharUnits alignment, bool isKnownNonNull)
Definition Address.h:53
bool isValid() const
Definition Address.h:77
Address(mlir::Value pointer, mlir::Type elementType, clang::CharUnits alignment)
Definition Address.h:49
OpTy getDefiningOp() const
Definition Address.h:147
cir::AllocaOp getUnderlyingAllocaOp() const
Return the underlying alloca for this address, if any.
Definition Address.h:157
mlir::Operation * getDefiningOp() const
Get the operation which defines this address.
Definition Address.h:141
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition Address.h:112
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:3390
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()