brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · a425eeb Raw
147 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This class provides a simple wrapper for a pair of a pointer and an10// alignment.11//12//===----------------------------------------------------------------------===//13 14#ifndef CLANG_LIB_CIR_ADDRESS_H15#define CLANG_LIB_CIR_ADDRESS_H16 17#include "mlir/IR/Value.h"18#include "clang/AST/CharUnits.h"19#include "clang/CIR/Dialect/IR/CIRAttrs.h"20#include "clang/CIR/Dialect/IR/CIRTypes.h"21#include "clang/CIR/MissingFeatures.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 dependency28class 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 type36  /// information in Address makes it more convenient to work with Address37  /// 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      : pointerAndKnownNonNull(pointer, false), elementType(elementType),49        alignment(alignment) {50    assert(pointer && "Pointer cannot be null");51    assert(elementType && "Element type cannot be null");52    assert(!alignment.isZero() && "Alignment cannot be zero");53 54    assert(mlir::isa<cir::PointerType>(pointer.getType()) &&55           "Expected cir.ptr type");56 57    assert(mlir::cast<cir::PointerType>(pointer.getType()).getPointee() ==58           elementType);59  }60 61  Address(mlir::Value pointer, clang::CharUnits alignment)62      : Address(pointer,63                mlir::cast<cir::PointerType>(pointer.getType()).getPointee(),64                alignment) {65    assert((!alignment.isZero() || pointer == nullptr) &&66           "creating valid address with invalid alignment");67  }68 69  static Address invalid() { return Address(nullptr); }70  bool isValid() const {71    return pointerAndKnownNonNull.getPointer() != nullptr;72  }73 74  /// Return address with different pointer, but same element type and75  /// alignment.76  Address withPointer(mlir::Value newPtr) const {77    return Address(newPtr, getElementType(), getAlignment());78  }79 80  /// Return address with different alignment, but same pointer and element81  /// type.82  Address withAlignment(clang::CharUnits newAlignment) const {83    return Address(getPointer(), getElementType(), newAlignment);84  }85 86  /// Return address with different element type, a bitcast pointer, and87  /// the same alignment.88  Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const;89 90  mlir::Value getPointer() const {91    assert(isValid());92    return pointerAndKnownNonNull.getPointer();93  }94 95  mlir::Value getBasePointer() const {96    // TODO(cir): Remove the version above when we catchup with OG codegen on97    // ptr auth.98    assert(isValid() && "pointer isn't valid");99    return getPointer();100  }101 102  /// Return the pointer contained in this class after authenticating it and103  /// adding offset to it if necessary.104  mlir::Value emitRawPointer() const {105    assert(!cir::MissingFeatures::addressPointerAuthInfo());106    return getBasePointer();107  }108 109  mlir::Type getType() const {110    assert(mlir::cast<cir::PointerType>(111               pointerAndKnownNonNull.getPointer().getType())112               .getPointee() == elementType);113 114    return mlir::cast<cir::PointerType>(getPointer().getType());115  }116 117  mlir::Type getElementType() const {118    assert(isValid());119    assert(mlir::cast<cir::PointerType>(120               pointerAndKnownNonNull.getPointer().getType())121               .getPointee() == elementType);122    return elementType;123  }124 125  cir::TargetAddressSpaceAttr getAddressSpace() const {126    auto ptrTy = mlir::dyn_cast<cir::PointerType>(getType());127    return ptrTy.getAddrSpace();128  }129 130  clang::CharUnits getAlignment() const { return alignment; }131 132  /// Get the operation which defines this address.133  mlir::Operation *getDefiningOp() const {134    if (!isValid())135      return nullptr;136    return getPointer().getDefiningOp();137  }138 139  template <typename OpTy> OpTy getDefiningOp() const {140    return mlir::dyn_cast_or_null<OpTy>(getDefiningOp());141  }142};143 144} // namespace clang::CIRGen145 146#endif // CLANG_LIB_CIR_ADDRESS_H147