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