1*7330f729Sjoerg //===-- Address.h - An aligned address -------------------------*- C++ -*-===//
2*7330f729Sjoerg //
3*7330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*7330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7330f729Sjoerg //
7*7330f729Sjoerg //===----------------------------------------------------------------------===//
8*7330f729Sjoerg //
9*7330f729Sjoerg // This class provides a simple wrapper for a pair of a pointer and an
10*7330f729Sjoerg // alignment.
11*7330f729Sjoerg //
12*7330f729Sjoerg //===----------------------------------------------------------------------===//
13*7330f729Sjoerg
14*7330f729Sjoerg #ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
15*7330f729Sjoerg #define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
16*7330f729Sjoerg
17*7330f729Sjoerg #include "llvm/IR/Constants.h"
18*7330f729Sjoerg #include "clang/AST/CharUnits.h"
19*7330f729Sjoerg
20*7330f729Sjoerg namespace clang {
21*7330f729Sjoerg namespace CodeGen {
22*7330f729Sjoerg
23*7330f729Sjoerg /// An aligned address.
24*7330f729Sjoerg class Address {
25*7330f729Sjoerg llvm::Value *Pointer;
26*7330f729Sjoerg CharUnits Alignment;
27*7330f729Sjoerg public:
Address(llvm::Value * pointer,CharUnits alignment)28*7330f729Sjoerg Address(llvm::Value *pointer, CharUnits alignment)
29*7330f729Sjoerg : Pointer(pointer), Alignment(alignment) {
30*7330f729Sjoerg assert((!alignment.isZero() || pointer == nullptr) &&
31*7330f729Sjoerg "creating valid address with invalid alignment");
32*7330f729Sjoerg }
33*7330f729Sjoerg
invalid()34*7330f729Sjoerg static Address invalid() { return Address(nullptr, CharUnits()); }
isValid()35*7330f729Sjoerg bool isValid() const { return Pointer != nullptr; }
36*7330f729Sjoerg
getPointer()37*7330f729Sjoerg llvm::Value *getPointer() const {
38*7330f729Sjoerg assert(isValid());
39*7330f729Sjoerg return Pointer;
40*7330f729Sjoerg }
41*7330f729Sjoerg
42*7330f729Sjoerg /// Return the type of the pointer value.
getType()43*7330f729Sjoerg llvm::PointerType *getType() const {
44*7330f729Sjoerg return llvm::cast<llvm::PointerType>(getPointer()->getType());
45*7330f729Sjoerg }
46*7330f729Sjoerg
47*7330f729Sjoerg /// Return the type of the values stored in this address.
48*7330f729Sjoerg ///
49*7330f729Sjoerg /// When IR pointer types lose their element type, we should simply
50*7330f729Sjoerg /// store it in Address instead for the convenience of writing code.
getElementType()51*7330f729Sjoerg llvm::Type *getElementType() const {
52*7330f729Sjoerg return getType()->getElementType();
53*7330f729Sjoerg }
54*7330f729Sjoerg
55*7330f729Sjoerg /// Return the address space that this address resides in.
getAddressSpace()56*7330f729Sjoerg unsigned getAddressSpace() const {
57*7330f729Sjoerg return getType()->getAddressSpace();
58*7330f729Sjoerg }
59*7330f729Sjoerg
60*7330f729Sjoerg /// Return the IR name of the pointer value.
getName()61*7330f729Sjoerg llvm::StringRef getName() const {
62*7330f729Sjoerg return getPointer()->getName();
63*7330f729Sjoerg }
64*7330f729Sjoerg
65*7330f729Sjoerg /// Return the alignment of this pointer.
getAlignment()66*7330f729Sjoerg CharUnits getAlignment() const {
67*7330f729Sjoerg assert(isValid());
68*7330f729Sjoerg return Alignment;
69*7330f729Sjoerg }
70*7330f729Sjoerg };
71*7330f729Sjoerg
72*7330f729Sjoerg /// A specialization of Address that requires the address to be an
73*7330f729Sjoerg /// LLVM Constant.
74*7330f729Sjoerg class ConstantAddress : public Address {
75*7330f729Sjoerg public:
ConstantAddress(llvm::Constant * pointer,CharUnits alignment)76*7330f729Sjoerg ConstantAddress(llvm::Constant *pointer, CharUnits alignment)
77*7330f729Sjoerg : Address(pointer, alignment) {}
78*7330f729Sjoerg
invalid()79*7330f729Sjoerg static ConstantAddress invalid() {
80*7330f729Sjoerg return ConstantAddress(nullptr, CharUnits());
81*7330f729Sjoerg }
82*7330f729Sjoerg
getPointer()83*7330f729Sjoerg llvm::Constant *getPointer() const {
84*7330f729Sjoerg return llvm::cast<llvm::Constant>(Address::getPointer());
85*7330f729Sjoerg }
86*7330f729Sjoerg
getBitCast(llvm::Type * ty)87*7330f729Sjoerg ConstantAddress getBitCast(llvm::Type *ty) const {
88*7330f729Sjoerg return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty),
89*7330f729Sjoerg getAlignment());
90*7330f729Sjoerg }
91*7330f729Sjoerg
getElementBitCast(llvm::Type * ty)92*7330f729Sjoerg ConstantAddress getElementBitCast(llvm::Type *ty) const {
93*7330f729Sjoerg return getBitCast(ty->getPointerTo(getAddressSpace()));
94*7330f729Sjoerg }
95*7330f729Sjoerg
isaImpl(Address addr)96*7330f729Sjoerg static bool isaImpl(Address addr) {
97*7330f729Sjoerg return llvm::isa<llvm::Constant>(addr.getPointer());
98*7330f729Sjoerg }
castImpl(Address addr)99*7330f729Sjoerg static ConstantAddress castImpl(Address addr) {
100*7330f729Sjoerg return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()),
101*7330f729Sjoerg addr.getAlignment());
102*7330f729Sjoerg }
103*7330f729Sjoerg };
104*7330f729Sjoerg
105*7330f729Sjoerg }
106*7330f729Sjoerg
107*7330f729Sjoerg // Present a minimal LLVM-like casting interface.
cast(CodeGen::Address addr)108*7330f729Sjoerg template <class U> inline U cast(CodeGen::Address addr) {
109*7330f729Sjoerg return U::castImpl(addr);
110*7330f729Sjoerg }
isa(CodeGen::Address addr)111*7330f729Sjoerg template <class U> inline bool isa(CodeGen::Address addr) {
112*7330f729Sjoerg return U::isaImpl(addr);
113*7330f729Sjoerg }
114*7330f729Sjoerg
115*7330f729Sjoerg }
116*7330f729Sjoerg
117*7330f729Sjoerg #endif
118