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