[llvm] [SandboxIR][NFC] Move Constant and derived classes into a separate file (PR #110189)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 16:44:35 PDT 2024
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/110189
None
>From a3d6e25c5c338e6740a276d45ea598461820d87c Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Thu, 26 Sep 2024 09:32:37 -0700
Subject: [PATCH] [SandboxIR][NFC] Move Constant and derived classes into a
separate file
---
llvm/include/llvm/SandboxIR/Constant.h | 1283 +++++++++++++++++++++++
llvm/include/llvm/SandboxIR/SandboxIR.h | 1253 +---------------------
llvm/lib/SandboxIR/CMakeLists.txt | 1 +
llvm/lib/SandboxIR/Constant.cpp | 509 +++++++++
llvm/lib/SandboxIR/SandboxIR.cpp | 495 ---------
5 files changed, 1794 insertions(+), 1747 deletions(-)
create mode 100644 llvm/include/llvm/SandboxIR/Constant.h
create mode 100644 llvm/lib/SandboxIR/Constant.cpp
diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h
new file mode 100644
index 00000000000000..bc0e3d8849237a
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/Constant.h
@@ -0,0 +1,1283 @@
+//===- Constant.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SANDBOXIR_CONSTANT_H
+#define LLVM_SANDBOXIR_CONSTANT_H
+
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalIFunc.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/SandboxIR/Context.h"
+#include "llvm/SandboxIR/Type.h"
+#include "llvm/SandboxIR/User.h"
+
+namespace llvm::sandboxir {
+
+class BasicBlock;
+class Function;
+
+class Constant : public sandboxir::User {
+protected:
+ Constant(llvm::Constant *C, sandboxir::Context &SBCtx)
+ : sandboxir::User(ClassID::Constant, C, SBCtx) {}
+ Constant(ClassID ID, llvm::Constant *C, sandboxir::Context &SBCtx)
+ : sandboxir::User(ID, C, SBCtx) {}
+ friend class ConstantInt; // For constructor.
+ friend class Function; // For constructor
+ friend class Context; // For constructor.
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ switch (From->getSubclassID()) {
+#define DEF_CONST(ID, CLASS) case ClassID::ID:
+#include "llvm/SandboxIR/SandboxIRValues.def"
+ return true;
+ default:
+ return false;
+ }
+ }
+ sandboxir::Context &getParent() const { return getContext(); }
+ unsigned getUseOperandNo(const Use &Use) const override {
+ return getUseOperandNoDefault(Use);
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::Constant>(Val) && "Expected Constant!");
+ }
+ void dumpOS(raw_ostream &OS) const override;
+#endif
+};
+
+// TODO: This should inherit from ConstantData.
+class ConstantInt : public Constant {
+ ConstantInt(llvm::ConstantInt *C, Context &Ctx)
+ : Constant(ClassID::ConstantInt, C, Ctx) {}
+ friend class Context; // For constructor.
+
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ llvm_unreachable("ConstantInt has no operands!");
+ }
+
+public:
+ static ConstantInt *getTrue(Context &Ctx);
+ static ConstantInt *getFalse(Context &Ctx);
+ static ConstantInt *getBool(Context &Ctx, bool V);
+ static Constant *getTrue(Type *Ty);
+ static Constant *getFalse(Type *Ty);
+ static Constant *getBool(Type *Ty, bool V);
+
+ /// If Ty is a vector type, return a Constant with a splat of the given
+ /// value. Otherwise return a ConstantInt for the given value.
+ static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
+
+ /// Return a ConstantInt with the specified integer value for the specified
+ /// type. If the type is wider than 64 bits, the value will be zero-extended
+ /// to fit the type, unless IsSigned is true, in which case the value will
+ /// be interpreted as a 64-bit signed integer and sign-extended to fit
+ /// the type.
+ /// Get a ConstantInt for a specific value.
+ static ConstantInt *get(IntegerType *Ty, uint64_t V, bool IsSigned = false);
+
+ /// Return a ConstantInt with the specified value for the specified type. The
+ /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+ /// either getSExtValue() or getZExtValue() will yield a correctly sized and
+ /// signed value for the type Ty.
+ /// Get a ConstantInt for a specific signed value.
+ static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
+ static Constant *getSigned(Type *Ty, int64_t V);
+
+ /// Return a ConstantInt with the specified value and an implied Type. The
+ /// type is the integer type that corresponds to the bit width of the value.
+ static ConstantInt *get(Context &Ctx, const APInt &V);
+
+ /// Return a ConstantInt constructed from the string strStart with the given
+ /// radix.
+ static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t Radix);
+
+ /// If Ty is a vector type, return a Constant with a splat of the given
+ /// value. Otherwise return a ConstantInt for the given value.
+ static Constant *get(Type *Ty, const APInt &V);
+
+ /// Return the constant as an APInt value reference. This allows clients to
+ /// obtain a full-precision copy of the value.
+ /// Return the constant's value.
+ inline const APInt &getValue() const {
+ return cast<llvm::ConstantInt>(Val)->getValue();
+ }
+
+ /// getBitWidth - Return the scalar bitwidth of this constant.
+ unsigned getBitWidth() const {
+ return cast<llvm::ConstantInt>(Val)->getBitWidth();
+ }
+ /// Return the constant as a 64-bit unsigned integer value after it
+ /// has been zero extended as appropriate for the type of this constant. Note
+ /// that this method can assert if the value does not fit in 64 bits.
+ /// Return the zero extended value.
+ inline uint64_t getZExtValue() const {
+ return cast<llvm::ConstantInt>(Val)->getZExtValue();
+ }
+
+ /// Return the constant as a 64-bit integer value after it has been sign
+ /// extended as appropriate for the type of this constant. Note that
+ /// this method can assert if the value does not fit in 64 bits.
+ /// Return the sign extended value.
+ inline int64_t getSExtValue() const {
+ return cast<llvm::ConstantInt>(Val)->getSExtValue();
+ }
+
+ /// Return the constant as an llvm::MaybeAlign.
+ /// Note that this method can assert if the value does not fit in 64 bits or
+ /// is not a power of two.
+ inline MaybeAlign getMaybeAlignValue() const {
+ return cast<llvm::ConstantInt>(Val)->getMaybeAlignValue();
+ }
+
+ /// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
+ /// Note that this method can assert if the value does not fit in 64 bits or
+ /// is not a power of two.
+ inline Align getAlignValue() const {
+ return cast<llvm::ConstantInt>(Val)->getAlignValue();
+ }
+
+ /// A helper method that can be used to determine if the constant contained
+ /// within is equal to a constant. This only works for very small values,
+ /// because this is all that can be represented with all types.
+ /// Determine if this constant's value is same as an unsigned char.
+ bool equalsInt(uint64_t V) const {
+ return cast<llvm::ConstantInt>(Val)->equalsInt(V);
+ }
+
+ /// Variant of the getType() method to always return an IntegerType, which
+ /// reduces the amount of casting needed in parts of the compiler.
+ IntegerType *getIntegerType() const;
+
+ /// This static method returns true if the type Ty is big enough to
+ /// represent the value V. This can be used to avoid having the get method
+ /// assert when V is larger than Ty can represent. Note that there are two
+ /// versions of this method, one for unsigned and one for signed integers.
+ /// Although ConstantInt canonicalizes everything to an unsigned integer,
+ /// the signed version avoids callers having to convert a signed quantity
+ /// to the appropriate unsigned type before calling the method.
+ /// @returns true if V is a valid value for type Ty
+ /// Determine if the value is in range for the given type.
+ static bool isValueValidForType(Type *Ty, uint64_t V);
+ static bool isValueValidForType(Type *Ty, int64_t V);
+
+ bool isNegative() const { return cast<llvm::ConstantInt>(Val)->isNegative(); }
+
+ /// This is just a convenience method to make client code smaller for a
+ /// common code. It also correctly performs the comparison without the
+ /// potential for an assertion from getZExtValue().
+ bool isZero() const { return cast<llvm::ConstantInt>(Val)->isZero(); }
+
+ /// This is just a convenience method to make client code smaller for a
+ /// common case. It also correctly performs the comparison without the
+ /// potential for an assertion from getZExtValue().
+ /// Determine if the value is one.
+ bool isOne() const { return cast<llvm::ConstantInt>(Val)->isOne(); }
+
+ /// This function will return true iff every bit in this constant is set
+ /// to true.
+ /// @returns true iff this constant's bits are all set to true.
+ /// Determine if the value is all ones.
+ bool isMinusOne() const { return cast<llvm::ConstantInt>(Val)->isMinusOne(); }
+
+ /// This function will return true iff this constant represents the largest
+ /// value that may be represented by the constant's type.
+ /// @returns true iff this is the largest value that may be represented
+ /// by this type.
+ /// Determine if the value is maximal.
+ bool isMaxValue(bool IsSigned) const {
+ return cast<llvm::ConstantInt>(Val)->isMaxValue(IsSigned);
+ }
+
+ /// This function will return true iff this constant represents the smallest
+ /// value that may be represented by this constant's type.
+ /// @returns true if this is the smallest value that may be represented by
+ /// this type.
+ /// Determine if the value is minimal.
+ bool isMinValue(bool IsSigned) const {
+ return cast<llvm::ConstantInt>(Val)->isMinValue(IsSigned);
+ }
+
+ /// This function will return true iff this constant represents a value with
+ /// active bits bigger than 64 bits or a value greater than the given uint64_t
+ /// value.
+ /// @returns true iff this constant is greater or equal to the given number.
+ /// Determine if the value is greater or equal to the given number.
+ bool uge(uint64_t Num) const {
+ return cast<llvm::ConstantInt>(Val)->uge(Num);
+ }
+
+ /// getLimitedValue - If the value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ /// @returns the min of the value of the constant and the specified value
+ /// Get the constant's value with a saturation limit
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return cast<llvm::ConstantInt>(Val)->getLimitedValue(Limit);
+ }
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantInt;
+ }
+ unsigned getUseOperandNo(const Use &Use) const override {
+ llvm_unreachable("ConstantInt has no operands!");
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::ConstantInt>(Val) && "Expected a ConstantInst!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+// TODO: This should inherit from ConstantData.
+class ConstantFP final : public Constant {
+ ConstantFP(llvm::ConstantFP *C, Context &Ctx)
+ : Constant(ClassID::ConstantFP, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// This returns a ConstantFP, or a vector containing a splat of a ConstantFP,
+ /// for the specified value in the specified type. This should only be used
+ /// for simple constant values like 2.0/1.0 etc, that are known-valid both as
+ /// host double and as the target format.
+ static Constant *get(Type *Ty, double V);
+
+ /// If Ty is a vector type, return a Constant with a splat of the given
+ /// value. Otherwise return a ConstantFP for the given value.
+ static Constant *get(Type *Ty, const APFloat &V);
+
+ static Constant *get(Type *Ty, StringRef Str);
+
+ static ConstantFP *get(const APFloat &V, Context &Ctx);
+
+ static Constant *getNaN(Type *Ty, bool Negative = false,
+ uint64_t Payload = 0);
+ static Constant *getQNaN(Type *Ty, bool Negative = false,
+ APInt *Payload = nullptr);
+ static Constant *getSNaN(Type *Ty, bool Negative = false,
+ APInt *Payload = nullptr);
+ static Constant *getZero(Type *Ty, bool Negative = false);
+
+ static Constant *getNegativeZero(Type *Ty);
+ static Constant *getInfinity(Type *Ty, bool Negative = false);
+
+ /// Return true if Ty is big enough to represent V.
+ static bool isValueValidForType(Type *Ty, const APFloat &V);
+
+ inline const APFloat &getValueAPF() const {
+ return cast<llvm::ConstantFP>(Val)->getValueAPF();
+ }
+ inline const APFloat &getValue() const {
+ return cast<llvm::ConstantFP>(Val)->getValue();
+ }
+
+ /// Return true if the value is positive or negative zero.
+ bool isZero() const { return cast<llvm::ConstantFP>(Val)->isZero(); }
+
+ /// Return true if the sign bit is set.
+ bool isNegative() const { return cast<llvm::ConstantFP>(Val)->isNegative(); }
+
+ /// Return true if the value is infinity
+ bool isInfinity() const { return cast<llvm::ConstantFP>(Val)->isInfinity(); }
+
+ /// Return true if the value is a NaN.
+ bool isNaN() const { return cast<llvm::ConstantFP>(Val)->isNaN(); }
+
+ /// We don't rely on operator== working on double values, as it returns true
+ /// for things that are clearly not equal, like -0.0 and 0.0.
+ /// As such, this method can be used to do an exact bit-for-bit comparison of
+ /// two floating point values. The version with a double operand is retained
+ /// because it's so convenient to write isExactlyValue(2.0), but please use
+ /// it only for simple constants.
+ bool isExactlyValue(const APFloat &V) const {
+ return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
+ }
+
+ bool isExactlyValue(double V) const {
+ return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
+ }
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantFP;
+ }
+
+ // TODO: Better name: getOperandNo(const Use&). Should be private.
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("ConstantFP has no operands!");
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::ConstantFP>(Val) && "Expected a ConstantFP!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+/// Base class for aggregate constants (with operands).
+class ConstantAggregate : public Constant {
+protected:
+ ConstantAggregate(ClassID ID, llvm::Constant *C, Context &Ctx)
+ : Constant(ID, C, Ctx) {}
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ auto ID = From->getSubclassID();
+ return ID == ClassID::ConstantVector || ID == ClassID::ConstantStruct ||
+ ID == ClassID::ConstantArray;
+ }
+};
+
+class ConstantArray final : public ConstantAggregate {
+ ConstantArray(llvm::ConstantArray *C, Context &Ctx)
+ : ConstantAggregate(ClassID::ConstantArray, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static Constant *get(ArrayType *T, ArrayRef<Constant *> V);
+ ArrayType *getType() const;
+
+ // TODO: Missing functions: getType(), getTypeForElements(), getAnon(), get().
+
+ /// For isa/dyn_cast.
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::ConstantArray;
+ }
+};
+
+class ConstantStruct final : public ConstantAggregate {
+ ConstantStruct(llvm::ConstantStruct *C, Context &Ctx)
+ : ConstantAggregate(ClassID::ConstantStruct, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static Constant *get(StructType *T, ArrayRef<Constant *> V);
+
+ template <typename... Csts>
+ static std::enable_if_t<are_base_of<Constant, Csts...>::value, Constant *>
+ get(StructType *T, Csts *...Vs) {
+ return get(T, ArrayRef<Constant *>({Vs...}));
+ }
+ /// Return an anonymous struct that has the specified elements.
+ /// If the struct is possibly empty, then you must specify a context.
+ static Constant *getAnon(ArrayRef<Constant *> V, bool Packed = false) {
+ return get(getTypeForElements(V, Packed), V);
+ }
+ static Constant *getAnon(Context &Ctx, ArrayRef<Constant *> V,
+ bool Packed = false) {
+ return get(getTypeForElements(Ctx, V, Packed), V);
+ }
+ /// This version of the method allows an empty list.
+ static StructType *getTypeForElements(Context &Ctx, ArrayRef<Constant *> V,
+ bool Packed = false);
+ /// Return an anonymous struct type to use for a constant with the specified
+ /// set of elements. The list must not be empty.
+ static StructType *getTypeForElements(ArrayRef<Constant *> V,
+ bool Packed = false) {
+ assert(!V.empty() &&
+ "ConstantStruct::getTypeForElements cannot be called on empty list");
+ return getTypeForElements(V[0]->getContext(), V, Packed);
+ }
+
+ /// Specialization - reduce amount of casting.
+ inline StructType *getType() const {
+ return cast<StructType>(Value::getType());
+ }
+
+ /// For isa/dyn_cast.
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::ConstantStruct;
+ }
+};
+
+class ConstantVector final : public ConstantAggregate {
+ ConstantVector(llvm::ConstantVector *C, Context &Ctx)
+ : ConstantAggregate(ClassID::ConstantVector, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ // TODO: Missing functions: getSplat(), getType(), getSplatValue(), get().
+
+ /// For isa/dyn_cast.
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::ConstantVector;
+ }
+};
+
+// TODO: Inherit from ConstantData.
+class ConstantAggregateZero final : public Constant {
+ ConstantAggregateZero(llvm::ConstantAggregateZero *C, Context &Ctx)
+ : Constant(ClassID::ConstantAggregateZero, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static ConstantAggregateZero *get(Type *Ty);
+ /// If this CAZ has array or vector type, return a zero with the right element
+ /// type.
+ Constant *getSequentialElement() const;
+ /// If this CAZ has struct type, return a zero with the right element type for
+ /// the specified element.
+ Constant *getStructElement(unsigned Elt) const;
+ /// Return a zero of the right value for the specified GEP index if we can,
+ /// otherwise return null (e.g. if C is a ConstantExpr).
+ Constant *getElementValue(Constant *C) const;
+ /// Return a zero of the right value for the specified GEP index.
+ Constant *getElementValue(unsigned Idx) const;
+ /// Return the number of elements in the array, vector, or struct.
+ ElementCount getElementCount() const {
+ return cast<llvm::ConstantAggregateZero>(Val)->getElementCount();
+ }
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantAggregateZero;
+ }
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("ConstantAggregateZero has no operands!");
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::ConstantAggregateZero>(Val) && "Expected a CAZ!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+// TODO: Inherit from ConstantData.
+class ConstantPointerNull final : public Constant {
+ ConstantPointerNull(llvm::ConstantPointerNull *C, Context &Ctx)
+ : Constant(ClassID::ConstantPointerNull, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static ConstantPointerNull *get(PointerType *Ty);
+
+ PointerType *getType() const;
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantPointerNull;
+ }
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("ConstantPointerNull has no operands!");
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::ConstantPointerNull>(Val) && "Expected a CPNull!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+// TODO: Inherit from ConstantData.
+class UndefValue : public Constant {
+protected:
+ UndefValue(llvm::UndefValue *C, Context &Ctx)
+ : Constant(ClassID::UndefValue, C, Ctx) {}
+ UndefValue(ClassID ID, llvm::Constant *C, Context &Ctx)
+ : Constant(ID, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Static factory methods - Return an 'undef' object of the specified type.
+ static UndefValue *get(Type *T);
+
+ /// If this Undef has array or vector type, return a undef with the right
+ /// element type.
+ UndefValue *getSequentialElement() const;
+
+ /// If this undef has struct type, return a undef with the right element type
+ /// for the specified element.
+ UndefValue *getStructElement(unsigned Elt) const;
+
+ /// Return an undef of the right value for the specified GEP index if we can,
+ /// otherwise return null (e.g. if C is a ConstantExpr).
+ UndefValue *getElementValue(Constant *C) const;
+
+ /// Return an undef of the right value for the specified GEP index.
+ UndefValue *getElementValue(unsigned Idx) const;
+
+ /// Return the number of elements in the array, vector, or struct.
+ unsigned getNumElements() const {
+ return cast<llvm::UndefValue>(Val)->getNumElements();
+ }
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::UndefValue ||
+ From->getSubclassID() == ClassID::PoisonValue;
+ }
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("UndefValue has no operands!");
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::UndefValue>(Val) && "Expected an UndefValue!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class PoisonValue final : public UndefValue {
+ PoisonValue(llvm::PoisonValue *C, Context &Ctx)
+ : UndefValue(ClassID::PoisonValue, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Static factory methods - Return an 'poison' object of the specified type.
+ static PoisonValue *get(Type *T);
+
+ /// If this poison has array or vector type, return a poison with the right
+ /// element type.
+ PoisonValue *getSequentialElement() const;
+
+ /// If this poison has struct type, return a poison with the right element
+ /// type for the specified element.
+ PoisonValue *getStructElement(unsigned Elt) const;
+
+ /// Return an poison of the right value for the specified GEP index if we can,
+ /// otherwise return null (e.g. if C is a ConstantExpr).
+ PoisonValue *getElementValue(Constant *C) const;
+
+ /// Return an poison of the right value for the specified GEP index.
+ PoisonValue *getElementValue(unsigned Idx) const;
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::PoisonValue;
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::PoisonValue>(Val) && "Expected a PoisonValue!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class GlobalValue : public Constant {
+protected:
+ GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
+ : Constant(ID, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ using LinkageTypes = llvm::GlobalValue::LinkageTypes;
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ switch (From->getSubclassID()) {
+ case ClassID::Function:
+ case ClassID::GlobalVariable:
+ case ClassID::GlobalAlias:
+ case ClassID::GlobalIFunc:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ unsigned getAddressSpace() const {
+ return cast<llvm::GlobalValue>(Val)->getAddressSpace();
+ }
+ bool hasGlobalUnnamedAddr() const {
+ return cast<llvm::GlobalValue>(Val)->hasGlobalUnnamedAddr();
+ }
+
+ /// Returns true if this value's address is not significant in this module.
+ /// This attribute is intended to be used only by the code generator and LTO
+ /// to allow the linker to decide whether the global needs to be in the symbol
+ /// table. It should probably not be used in optimizations, as the value may
+ /// have uses outside the module; use hasGlobalUnnamedAddr() instead.
+ bool hasAtLeastLocalUnnamedAddr() const {
+ return cast<llvm::GlobalValue>(Val)->hasAtLeastLocalUnnamedAddr();
+ }
+
+ using UnnamedAddr = llvm::GlobalValue::UnnamedAddr;
+
+ UnnamedAddr getUnnamedAddr() const {
+ return cast<llvm::GlobalValue>(Val)->getUnnamedAddr();
+ }
+ void setUnnamedAddr(UnnamedAddr V);
+
+ static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
+ return llvm::GlobalValue::getMinUnnamedAddr(A, B);
+ }
+
+ bool hasComdat() const { return cast<llvm::GlobalValue>(Val)->hasComdat(); }
+
+ // TODO: We need a SandboxIR Comdat if we want to implement getComdat().
+ using VisibilityTypes = llvm::GlobalValue::VisibilityTypes;
+ VisibilityTypes getVisibility() const {
+ return cast<llvm::GlobalValue>(Val)->getVisibility();
+ }
+ bool hasDefaultVisibility() const {
+ return cast<llvm::GlobalValue>(Val)->hasDefaultVisibility();
+ }
+ bool hasHiddenVisibility() const {
+ return cast<llvm::GlobalValue>(Val)->hasHiddenVisibility();
+ }
+ bool hasProtectedVisibility() const {
+ return cast<llvm::GlobalValue>(Val)->hasProtectedVisibility();
+ }
+ void setVisibility(VisibilityTypes V);
+
+ // TODO: Add missing functions.
+};
+
+class GlobalObject : public GlobalValue {
+protected:
+ GlobalObject(ClassID ID, llvm::GlobalObject *C, Context &Ctx)
+ : GlobalValue(ID, C, Ctx) {}
+ friend class Context; // For constructor.
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+
+public:
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ switch (From->getSubclassID()) {
+ case ClassID::Function:
+ case ClassID::GlobalVariable:
+ case ClassID::GlobalIFunc:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ uint64_t getAlignment() const {
+ return cast<llvm::GlobalObject>(Val)->getAlignment();
+ }
+
+ /// Returns the alignment of the given variable or function.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ MaybeAlign getAlign() const {
+ return cast<llvm::GlobalObject>(Val)->getAlign();
+ }
+
+ // TODO: Add missing: setAlignment(Align)
+
+ /// Sets the alignment attribute of the GlobalObject.
+ /// This method will be deprecated as the alignment property should always be
+ /// defined.
+ void setAlignment(MaybeAlign Align);
+
+ unsigned getGlobalObjectSubClassData() const {
+ return cast<llvm::GlobalObject>(Val)->getGlobalObjectSubClassData();
+ }
+
+ void setGlobalObjectSubClassData(unsigned V);
+
+ /// Check if this global has a custom object file section.
+ ///
+ /// This is more efficient than calling getSection() and checking for an empty
+ /// string.
+ bool hasSection() const {
+ return cast<llvm::GlobalObject>(Val)->hasSection();
+ }
+
+ /// Get the custom section of this global if it has one.
+ ///
+ /// If this global does not have a custom section, this will be empty and the
+ /// default object file section (.text, .data, etc) will be used.
+ StringRef getSection() const {
+ return cast<llvm::GlobalObject>(Val)->getSection();
+ }
+
+ /// Change the section for this global.
+ ///
+ /// Setting the section to the empty string tells LLVM to choose an
+ /// appropriate default object file section.
+ void setSection(StringRef S);
+
+ bool hasComdat() const { return cast<llvm::GlobalObject>(Val)->hasComdat(); }
+
+ // TODO: implement get/setComdat(), etc. once we have a sandboxir::Comdat.
+
+ // TODO: We currently don't support Metadata in sandboxir so all
+ // Metadata-related functions are missing.
+
+ using VCallVisibility = llvm::GlobalObject::VCallVisibility;
+
+ VCallVisibility getVCallVisibility() const {
+ return cast<llvm::GlobalObject>(Val)->getVCallVisibility();
+ }
+
+ /// Returns true if the alignment of the value can be unilaterally
+ /// increased.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ bool canIncreaseAlignment() const {
+ return cast<llvm::GlobalObject>(Val)->canIncreaseAlignment();
+ }
+};
+
+/// Provides API functions, like getIterator() and getReverseIterator() to
+/// GlobalIFunc, Function, GlobalVariable and GlobalAlias. In LLVM IR these are
+/// provided by ilist_node.
+template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
+ typename LLVMParentT>
+class GlobalWithNodeAPI : public ParentT {
+ /// Helper for mapped_iterator.
+ struct LLVMGVToGV {
+ Context &Ctx;
+ LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
+ GlobalT &operator()(LLVMGlobalT &LLVMGV) const;
+ };
+
+public:
+ GlobalWithNodeAPI(Value::ClassID ID, LLVMParentT *C, Context &Ctx)
+ : ParentT(ID, C, Ctx) {}
+
+ Module *getParent() const {
+ llvm::Module *LLVMM = cast<LLVMGlobalT>(this->Val)->getParent();
+ return this->Ctx.getModule(LLVMM);
+ }
+
+ using iterator = mapped_iterator<
+ decltype(static_cast<LLVMGlobalT *>(nullptr)->getIterator()), LLVMGVToGV>;
+ using reverse_iterator = mapped_iterator<
+ decltype(static_cast<LLVMGlobalT *>(nullptr)->getReverseIterator()),
+ LLVMGVToGV>;
+ iterator getIterator() const {
+ auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
+ LLVMGVToGV ToGV(this->Ctx);
+ return map_iterator(LLVMGV->getIterator(), ToGV);
+ }
+ reverse_iterator getReverseIterator() const {
+ auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
+ LLVMGVToGV ToGV(this->Ctx);
+ return map_iterator(LLVMGV->getReverseIterator(), ToGV);
+ }
+};
+
+class GlobalIFunc final
+ : public GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
+ llvm::GlobalObject> {
+ GlobalIFunc(llvm::GlobalObject *C, Context &Ctx)
+ : GlobalWithNodeAPI(ClassID::GlobalIFunc, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::GlobalIFunc;
+ }
+
+ // TODO: Missing create() because we don't have a sandboxir::Module yet.
+
+ // TODO: Missing functions: copyAttributesFrom(), removeFromParent(),
+ // eraseFromParent()
+
+ void setResolver(Constant *Resolver);
+
+ Constant *getResolver() const;
+
+ // Return the resolver function after peeling off potential ConstantExpr
+ // indirection.
+ Function *getResolverFunction();
+ const Function *getResolverFunction() const {
+ return const_cast<GlobalIFunc *>(this)->getResolverFunction();
+ }
+
+ static bool isValidLinkage(LinkageTypes L) {
+ return llvm::GlobalIFunc::isValidLinkage(L);
+ }
+
+ // TODO: Missing applyAlongResolverPath().
+
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::GlobalIFunc>(Val) && "Expected a GlobalIFunc!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class GlobalVariable final
+ : public GlobalWithNodeAPI<GlobalVariable, llvm::GlobalVariable,
+ GlobalObject, llvm::GlobalObject> {
+ GlobalVariable(llvm::GlobalObject *C, Context &Ctx)
+ : GlobalWithNodeAPI(ClassID::GlobalVariable, C, Ctx) {}
+ friend class Context; // For constructor.
+
+ /// Helper for mapped_iterator.
+ struct LLVMGVToGV {
+ Context &Ctx;
+ LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
+ GlobalVariable &operator()(llvm::GlobalVariable &LLVMGV) const;
+ };
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::GlobalVariable;
+ }
+
+ /// Definitions have initializers, declarations don't.
+ ///
+ inline bool hasInitializer() const {
+ return cast<llvm::GlobalVariable>(Val)->hasInitializer();
+ }
+
+ /// hasDefinitiveInitializer - Whether the global variable has an initializer,
+ /// and any other instances of the global (this can happen due to weak
+ /// linkage) are guaranteed to have the same initializer.
+ ///
+ /// Note that if you want to transform a global, you must use
+ /// hasUniqueInitializer() instead, because of the *_odr linkage type.
+ ///
+ /// Example:
+ ///
+ /// @a = global SomeType* null - Initializer is both definitive and unique.
+ ///
+ /// @b = global weak SomeType* null - Initializer is neither definitive nor
+ /// unique.
+ ///
+ /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
+ /// unique.
+ inline bool hasDefinitiveInitializer() const {
+ return cast<llvm::GlobalVariable>(Val)->hasDefinitiveInitializer();
+ }
+
+ /// hasUniqueInitializer - Whether the global variable has an initializer, and
+ /// any changes made to the initializer will turn up in the final executable.
+ inline bool hasUniqueInitializer() const {
+ return cast<llvm::GlobalVariable>(Val)->hasUniqueInitializer();
+ }
+
+ /// getInitializer - Return the initializer for this global variable. It is
+ /// illegal to call this method if the global is external, because we cannot
+ /// tell what the value is initialized to!
+ ///
+ Constant *getInitializer() const;
+ /// setInitializer - Sets the initializer for this global variable, removing
+ /// any existing initializer if InitVal==NULL. The initializer must have the
+ /// type getValueType().
+ void setInitializer(Constant *InitVal);
+
+ // TODO: Add missing replaceInitializer(). Requires special tracker
+
+ /// If the value is a global constant, its value is immutable throughout the
+ /// runtime execution of the program. Assigning a value into the constant
+ /// leads to undefined behavior.
+ ///
+ bool isConstant() const {
+ return cast<llvm::GlobalVariable>(Val)->isConstant();
+ }
+ void setConstant(bool V);
+
+ bool isExternallyInitialized() const {
+ return cast<llvm::GlobalVariable>(Val)->isExternallyInitialized();
+ }
+ void setExternallyInitialized(bool Val);
+
+ // TODO: Missing copyAttributesFrom()
+
+ // TODO: Missing removeFromParent(), eraseFromParent(), dropAllReferences()
+
+ // TODO: Missing addDebugInfo(), getDebugInfo()
+
+ // TODO: Missing attribute setter functions: addAttribute(), setAttributes().
+ // There seems to be no removeAttribute() so we can't undo them.
+
+ /// Return true if the attribute exists.
+ bool hasAttribute(Attribute::AttrKind Kind) const {
+ return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
+ }
+
+ /// Return true if the attribute exists.
+ bool hasAttribute(StringRef Kind) const {
+ return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
+ }
+
+ /// Return true if any attributes exist.
+ bool hasAttributes() const {
+ return cast<llvm::GlobalVariable>(Val)->hasAttributes();
+ }
+
+ /// Return the attribute object.
+ Attribute getAttribute(Attribute::AttrKind Kind) const {
+ return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
+ }
+
+ /// Return the attribute object.
+ Attribute getAttribute(StringRef Kind) const {
+ return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
+ }
+
+ /// Return the attribute set for this global
+ AttributeSet getAttributes() const {
+ return cast<llvm::GlobalVariable>(Val)->getAttributes();
+ }
+
+ /// Return attribute set as list with index.
+ /// FIXME: This may not be required once ValueEnumerators
+ /// in bitcode-writer can enumerate attribute-set.
+ AttributeList getAttributesAsList(unsigned Index) const {
+ return cast<llvm::GlobalVariable>(Val)->getAttributesAsList(Index);
+ }
+
+ /// Check if section name is present
+ bool hasImplicitSection() const {
+ return cast<llvm::GlobalVariable>(Val)->hasImplicitSection();
+ }
+
+ /// Get the custom code model raw value of this global.
+ ///
+ unsigned getCodeModelRaw() const {
+ return cast<llvm::GlobalVariable>(Val)->getCodeModelRaw();
+ }
+
+ /// Get the custom code model of this global if it has one.
+ ///
+ /// If this global does not have a custom code model, the empty instance
+ /// will be returned.
+ std::optional<CodeModel::Model> getCodeModel() const {
+ return cast<llvm::GlobalVariable>(Val)->getCodeModel();
+ }
+
+ // TODO: Missing setCodeModel(). Requires custom tracker.
+
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::GlobalVariable>(Val) && "Expected a GlobalVariable!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class GlobalAlias final
+ : public GlobalWithNodeAPI<GlobalAlias, llvm::GlobalAlias, GlobalValue,
+ llvm::GlobalValue> {
+ GlobalAlias(llvm::GlobalAlias *C, Context &Ctx)
+ : GlobalWithNodeAPI(ClassID::GlobalAlias, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::GlobalAlias;
+ }
+
+ // TODO: Missing create() due to unimplemented sandboxir::Module.
+
+ // TODO: Missing copyAttributresFrom().
+ // TODO: Missing removeFromParent(), eraseFromParent().
+
+ void setAliasee(Constant *Aliasee);
+ Constant *getAliasee() const;
+
+ const GlobalObject *getAliaseeObject() const;
+ GlobalObject *getAliaseeObject() {
+ return const_cast<GlobalObject *>(
+ static_cast<const GlobalAlias *>(this)->getAliaseeObject());
+ }
+
+ static bool isValidLinkage(LinkageTypes L) {
+ return llvm::GlobalAlias::isValidLinkage(L);
+ }
+};
+
+class NoCFIValue final : public Constant {
+ NoCFIValue(llvm::NoCFIValue *C, Context &Ctx)
+ : Constant(ClassID::NoCFIValue, C, Ctx) {}
+ friend class Context; // For constructor.
+
+ Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
+ return getOperandUseDefault(OpIdx, Verify);
+ }
+
+public:
+ /// Return a NoCFIValue for the specified function.
+ static NoCFIValue *get(GlobalValue *GV);
+
+ GlobalValue *getGlobalValue() const;
+
+ /// NoCFIValue is always a pointer.
+ PointerType *getType() const;
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::NoCFIValue;
+ }
+
+ unsigned getUseOperandNo(const Use &Use) const final {
+ return getUseOperandNoDefault(Use);
+ }
+
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::NoCFIValue>(Val) && "Expected a NoCFIValue!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class ConstantPtrAuth final : public Constant {
+ ConstantPtrAuth(llvm::ConstantPtrAuth *C, Context &Ctx)
+ : Constant(ClassID::ConstantPtrAuth, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Return a pointer signed with the specified parameters.
+ static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
+ ConstantInt *Disc, Constant *AddrDisc);
+ /// The pointer that is signed in this ptrauth signed pointer.
+ Constant *getPointer() const;
+
+ /// The Key ID, an i32 constant.
+ ConstantInt *getKey() const;
+
+ /// The integer discriminator, an i64 constant, or 0.
+ ConstantInt *getDiscriminator() const;
+
+ /// The address discriminator if any, or the null constant.
+ /// If present, this must be a value equivalent to the storage location of
+ /// the only global-initializer user of the ptrauth signed pointer.
+ Constant *getAddrDiscriminator() const;
+
+ /// Whether there is any non-null address discriminator.
+ bool hasAddressDiscriminator() const {
+ return cast<llvm::ConstantPtrAuth>(Val)->hasAddressDiscriminator();
+ }
+
+ /// Whether the address uses a special address discriminator.
+ /// These discriminators can't be used in real pointer-auth values; they
+ /// can only be used in "prototype" values that indicate how some real
+ /// schema is supposed to be produced.
+ bool hasSpecialAddressDiscriminator(uint64_t Value) const {
+ return cast<llvm::ConstantPtrAuth>(Val)->hasSpecialAddressDiscriminator(
+ Value);
+ }
+
+ /// Check whether an authentication operation with key \p Key and (possibly
+ /// blended) discriminator \p Discriminator is known to be compatible with
+ /// this ptrauth signed pointer.
+ bool isKnownCompatibleWith(const Value *Key, const Value *Discriminator,
+ const DataLayout &DL) const {
+ return cast<llvm::ConstantPtrAuth>(Val)->isKnownCompatibleWith(
+ Key->Val, Discriminator->Val, DL);
+ }
+
+ /// Produce a new ptrauth expression signing the given value using
+ /// the same schema as is stored in one.
+ ConstantPtrAuth *getWithSameSchema(Constant *Pointer) const;
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantPtrAuth;
+ }
+};
+
+class ConstantExpr : public Constant {
+ ConstantExpr(llvm::ConstantExpr *C, Context &Ctx)
+ : Constant(ClassID::ConstantExpr, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantExpr;
+ }
+ // TODO: Missing functions.
+};
+
+class BlockAddress final : public Constant {
+ BlockAddress(llvm::BlockAddress *C, Context &Ctx)
+ : Constant(ClassID::BlockAddress, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Return a BlockAddress for the specified function and basic block.
+ static BlockAddress *get(Function *F, BasicBlock *BB);
+
+ /// Return a BlockAddress for the specified basic block. The basic
+ /// block must be embedded into a function.
+ static BlockAddress *get(BasicBlock *BB);
+
+ /// Lookup an existing \c BlockAddress constant for the given BasicBlock.
+ ///
+ /// \returns 0 if \c !BB->hasAddressTaken(), otherwise the \c BlockAddress.
+ static BlockAddress *lookup(const BasicBlock *BB);
+
+ Function *getFunction() const;
+ BasicBlock *getBasicBlock() const;
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::BlockAddress;
+ }
+};
+
+class DSOLocalEquivalent final : public Constant {
+ DSOLocalEquivalent(llvm::DSOLocalEquivalent *C, Context &Ctx)
+ : Constant(ClassID::DSOLocalEquivalent, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Return a DSOLocalEquivalent for the specified global value.
+ static DSOLocalEquivalent *get(GlobalValue *GV);
+
+ GlobalValue *getGlobalValue() const;
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::DSOLocalEquivalent;
+ }
+
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("DSOLocalEquivalent has no operands!");
+ }
+
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::DSOLocalEquivalent>(Val) &&
+ "Expected a DSOLocalEquivalent!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+// TODO: This should inherit from ConstantData.
+class ConstantTokenNone final : public Constant {
+ ConstantTokenNone(llvm::ConstantTokenNone *C, Context &Ctx)
+ : Constant(ClassID::ConstantTokenNone, C, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// Return the ConstantTokenNone.
+ static ConstantTokenNone *get(Context &Ctx);
+
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::ConstantTokenNone;
+ }
+
+ unsigned getUseOperandNo(const Use &Use) const final {
+ llvm_unreachable("ConstantTokenNone has no operands!");
+ }
+
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::ConstantTokenNone>(Val) &&
+ "Expected a ConstantTokenNone!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif
+};
+
+class Function : public GlobalWithNodeAPI<Function, llvm::Function,
+ GlobalObject, llvm::GlobalObject> {
+ /// Helper for mapped_iterator.
+ struct LLVMBBToBB {
+ Context &Ctx;
+ LLVMBBToBB(Context &Ctx) : Ctx(Ctx) {}
+ BasicBlock &operator()(llvm::BasicBlock &LLVMBB) const {
+ return *cast<BasicBlock>(Ctx.getValue(&LLVMBB));
+ }
+ };
+ /// Use Context::createFunction() instead.
+ Function(llvm::Function *F, sandboxir::Context &Ctx)
+ : GlobalWithNodeAPI(ClassID::Function, F, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ /// For isa/dyn_cast.
+ static bool classof(const sandboxir::Value *From) {
+ return From->getSubclassID() == ClassID::Function;
+ }
+
+ Module *getParent() {
+ return Ctx.getModule(cast<llvm::Function>(Val)->getParent());
+ }
+
+ Argument *getArg(unsigned Idx) const {
+ llvm::Argument *Arg = cast<llvm::Function>(Val)->getArg(Idx);
+ return cast<Argument>(Ctx.getValue(Arg));
+ }
+
+ size_t arg_size() const { return cast<llvm::Function>(Val)->arg_size(); }
+ bool arg_empty() const { return cast<llvm::Function>(Val)->arg_empty(); }
+
+ using iterator = mapped_iterator<llvm::Function::iterator, LLVMBBToBB>;
+ iterator begin() const {
+ LLVMBBToBB BBGetter(Ctx);
+ return iterator(cast<llvm::Function>(Val)->begin(), BBGetter);
+ }
+ iterator end() const {
+ LLVMBBToBB BBGetter(Ctx);
+ return iterator(cast<llvm::Function>(Val)->end(), BBGetter);
+ }
+ FunctionType *getFunctionType() const;
+
+#ifndef NDEBUG
+ void verify() const final {
+ assert(isa<llvm::Function>(Val) && "Expected Function!");
+ }
+ void dumpNameAndArgs(raw_ostream &OS) const;
+ void dumpOS(raw_ostream &OS) const final;
+#endif
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_CONSTANT_H
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 66de9ee078d619..02246c303ab614 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -110,6 +110,7 @@
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/SandboxIR/Argument.h"
+#include "llvm/SandboxIR/Constant.h"
#include "llvm/SandboxIR/Context.h"
#include "llvm/SandboxIR/Module.h"
#include "llvm/SandboxIR/Tracker.h"
@@ -190,1205 +191,6 @@ class CmpInst;
class ICmpInst;
class FCmpInst;
-class Constant : public sandboxir::User {
-protected:
- Constant(llvm::Constant *C, sandboxir::Context &SBCtx)
- : sandboxir::User(ClassID::Constant, C, SBCtx) {}
- Constant(ClassID ID, llvm::Constant *C, sandboxir::Context &SBCtx)
- : sandboxir::User(ID, C, SBCtx) {}
- friend class ConstantInt; // For constructor.
- friend class Function; // For constructor
- friend class Context; // For constructor.
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
- return getOperandUseDefault(OpIdx, Verify);
- }
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- switch (From->getSubclassID()) {
-#define DEF_CONST(ID, CLASS) case ClassID::ID:
-#include "llvm/SandboxIR/SandboxIRValues.def"
- return true;
- default:
- return false;
- }
- }
- sandboxir::Context &getParent() const { return getContext(); }
- unsigned getUseOperandNo(const Use &Use) const override {
- return getUseOperandNoDefault(Use);
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::Constant>(Val) && "Expected Constant!");
- }
- void dumpOS(raw_ostream &OS) const override;
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantInt : public Constant {
- ConstantInt(llvm::ConstantInt *C, Context &Ctx)
- : Constant(ClassID::ConstantInt, C, Ctx) {}
- friend class Context; // For constructor.
-
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
- llvm_unreachable("ConstantInt has no operands!");
- }
-
-public:
- static ConstantInt *getTrue(Context &Ctx);
- static ConstantInt *getFalse(Context &Ctx);
- static ConstantInt *getBool(Context &Ctx, bool V);
- static Constant *getTrue(Type *Ty);
- static Constant *getFalse(Type *Ty);
- static Constant *getBool(Type *Ty, bool V);
-
- /// If Ty is a vector type, return a Constant with a splat of the given
- /// value. Otherwise return a ConstantInt for the given value.
- static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
-
- /// Return a ConstantInt with the specified integer value for the specified
- /// type. If the type is wider than 64 bits, the value will be zero-extended
- /// to fit the type, unless IsSigned is true, in which case the value will
- /// be interpreted as a 64-bit signed integer and sign-extended to fit
- /// the type.
- /// Get a ConstantInt for a specific value.
- static ConstantInt *get(IntegerType *Ty, uint64_t V, bool IsSigned = false);
-
- /// Return a ConstantInt with the specified value for the specified type. The
- /// value V will be canonicalized to a an unsigned APInt. Accessing it with
- /// either getSExtValue() or getZExtValue() will yield a correctly sized and
- /// signed value for the type Ty.
- /// Get a ConstantInt for a specific signed value.
- static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
- static Constant *getSigned(Type *Ty, int64_t V);
-
- /// Return a ConstantInt with the specified value and an implied Type. The
- /// type is the integer type that corresponds to the bit width of the value.
- static ConstantInt *get(Context &Ctx, const APInt &V);
-
- /// Return a ConstantInt constructed from the string strStart with the given
- /// radix.
- static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t Radix);
-
- /// If Ty is a vector type, return a Constant with a splat of the given
- /// value. Otherwise return a ConstantInt for the given value.
- static Constant *get(Type *Ty, const APInt &V);
-
- /// Return the constant as an APInt value reference. This allows clients to
- /// obtain a full-precision copy of the value.
- /// Return the constant's value.
- inline const APInt &getValue() const {
- return cast<llvm::ConstantInt>(Val)->getValue();
- }
-
- /// getBitWidth - Return the scalar bitwidth of this constant.
- unsigned getBitWidth() const {
- return cast<llvm::ConstantInt>(Val)->getBitWidth();
- }
- /// Return the constant as a 64-bit unsigned integer value after it
- /// has been zero extended as appropriate for the type of this constant. Note
- /// that this method can assert if the value does not fit in 64 bits.
- /// Return the zero extended value.
- inline uint64_t getZExtValue() const {
- return cast<llvm::ConstantInt>(Val)->getZExtValue();
- }
-
- /// Return the constant as a 64-bit integer value after it has been sign
- /// extended as appropriate for the type of this constant. Note that
- /// this method can assert if the value does not fit in 64 bits.
- /// Return the sign extended value.
- inline int64_t getSExtValue() const {
- return cast<llvm::ConstantInt>(Val)->getSExtValue();
- }
-
- /// Return the constant as an llvm::MaybeAlign.
- /// Note that this method can assert if the value does not fit in 64 bits or
- /// is not a power of two.
- inline MaybeAlign getMaybeAlignValue() const {
- return cast<llvm::ConstantInt>(Val)->getMaybeAlignValue();
- }
-
- /// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
- /// Note that this method can assert if the value does not fit in 64 bits or
- /// is not a power of two.
- inline Align getAlignValue() const {
- return cast<llvm::ConstantInt>(Val)->getAlignValue();
- }
-
- /// A helper method that can be used to determine if the constant contained
- /// within is equal to a constant. This only works for very small values,
- /// because this is all that can be represented with all types.
- /// Determine if this constant's value is same as an unsigned char.
- bool equalsInt(uint64_t V) const {
- return cast<llvm::ConstantInt>(Val)->equalsInt(V);
- }
-
- /// Variant of the getType() method to always return an IntegerType, which
- /// reduces the amount of casting needed in parts of the compiler.
- IntegerType *getIntegerType() const;
-
- /// This static method returns true if the type Ty is big enough to
- /// represent the value V. This can be used to avoid having the get method
- /// assert when V is larger than Ty can represent. Note that there are two
- /// versions of this method, one for unsigned and one for signed integers.
- /// Although ConstantInt canonicalizes everything to an unsigned integer,
- /// the signed version avoids callers having to convert a signed quantity
- /// to the appropriate unsigned type before calling the method.
- /// @returns true if V is a valid value for type Ty
- /// Determine if the value is in range for the given type.
- static bool isValueValidForType(Type *Ty, uint64_t V);
- static bool isValueValidForType(Type *Ty, int64_t V);
-
- bool isNegative() const { return cast<llvm::ConstantInt>(Val)->isNegative(); }
-
- /// This is just a convenience method to make client code smaller for a
- /// common code. It also correctly performs the comparison without the
- /// potential for an assertion from getZExtValue().
- bool isZero() const { return cast<llvm::ConstantInt>(Val)->isZero(); }
-
- /// This is just a convenience method to make client code smaller for a
- /// common case. It also correctly performs the comparison without the
- /// potential for an assertion from getZExtValue().
- /// Determine if the value is one.
- bool isOne() const { return cast<llvm::ConstantInt>(Val)->isOne(); }
-
- /// This function will return true iff every bit in this constant is set
- /// to true.
- /// @returns true iff this constant's bits are all set to true.
- /// Determine if the value is all ones.
- bool isMinusOne() const { return cast<llvm::ConstantInt>(Val)->isMinusOne(); }
-
- /// This function will return true iff this constant represents the largest
- /// value that may be represented by the constant's type.
- /// @returns true iff this is the largest value that may be represented
- /// by this type.
- /// Determine if the value is maximal.
- bool isMaxValue(bool IsSigned) const {
- return cast<llvm::ConstantInt>(Val)->isMaxValue(IsSigned);
- }
-
- /// This function will return true iff this constant represents the smallest
- /// value that may be represented by this constant's type.
- /// @returns true if this is the smallest value that may be represented by
- /// this type.
- /// Determine if the value is minimal.
- bool isMinValue(bool IsSigned) const {
- return cast<llvm::ConstantInt>(Val)->isMinValue(IsSigned);
- }
-
- /// This function will return true iff this constant represents a value with
- /// active bits bigger than 64 bits or a value greater than the given uint64_t
- /// value.
- /// @returns true iff this constant is greater or equal to the given number.
- /// Determine if the value is greater or equal to the given number.
- bool uge(uint64_t Num) const {
- return cast<llvm::ConstantInt>(Val)->uge(Num);
- }
-
- /// getLimitedValue - If the value is smaller than the specified limit,
- /// return it, otherwise return the limit value. This causes the value
- /// to saturate to the limit.
- /// @returns the min of the value of the constant and the specified value
- /// Get the constant's value with a saturation limit
- uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
- return cast<llvm::ConstantInt>(Val)->getLimitedValue(Limit);
- }
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantInt;
- }
- unsigned getUseOperandNo(const Use &Use) const override {
- llvm_unreachable("ConstantInt has no operands!");
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::ConstantInt>(Val) && "Expected a ConstantInst!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantFP final : public Constant {
- ConstantFP(llvm::ConstantFP *C, Context &Ctx)
- : Constant(ClassID::ConstantFP, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// This returns a ConstantFP, or a vector containing a splat of a ConstantFP,
- /// for the specified value in the specified type. This should only be used
- /// for simple constant values like 2.0/1.0 etc, that are known-valid both as
- /// host double and as the target format.
- static Constant *get(Type *Ty, double V);
-
- /// If Ty is a vector type, return a Constant with a splat of the given
- /// value. Otherwise return a ConstantFP for the given value.
- static Constant *get(Type *Ty, const APFloat &V);
-
- static Constant *get(Type *Ty, StringRef Str);
-
- static ConstantFP *get(const APFloat &V, Context &Ctx);
-
- static Constant *getNaN(Type *Ty, bool Negative = false,
- uint64_t Payload = 0);
- static Constant *getQNaN(Type *Ty, bool Negative = false,
- APInt *Payload = nullptr);
- static Constant *getSNaN(Type *Ty, bool Negative = false,
- APInt *Payload = nullptr);
- static Constant *getZero(Type *Ty, bool Negative = false);
-
- static Constant *getNegativeZero(Type *Ty);
- static Constant *getInfinity(Type *Ty, bool Negative = false);
-
- /// Return true if Ty is big enough to represent V.
- static bool isValueValidForType(Type *Ty, const APFloat &V);
-
- inline const APFloat &getValueAPF() const {
- return cast<llvm::ConstantFP>(Val)->getValueAPF();
- }
- inline const APFloat &getValue() const {
- return cast<llvm::ConstantFP>(Val)->getValue();
- }
-
- /// Return true if the value is positive or negative zero.
- bool isZero() const { return cast<llvm::ConstantFP>(Val)->isZero(); }
-
- /// Return true if the sign bit is set.
- bool isNegative() const { return cast<llvm::ConstantFP>(Val)->isNegative(); }
-
- /// Return true if the value is infinity
- bool isInfinity() const { return cast<llvm::ConstantFP>(Val)->isInfinity(); }
-
- /// Return true if the value is a NaN.
- bool isNaN() const { return cast<llvm::ConstantFP>(Val)->isNaN(); }
-
- /// We don't rely on operator== working on double values, as it returns true
- /// for things that are clearly not equal, like -0.0 and 0.0.
- /// As such, this method can be used to do an exact bit-for-bit comparison of
- /// two floating point values. The version with a double operand is retained
- /// because it's so convenient to write isExactlyValue(2.0), but please use
- /// it only for simple constants.
- bool isExactlyValue(const APFloat &V) const {
- return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
- }
-
- bool isExactlyValue(double V) const {
- return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
- }
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantFP;
- }
-
- // TODO: Better name: getOperandNo(const Use&). Should be private.
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("ConstantFP has no operands!");
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::ConstantFP>(Val) && "Expected a ConstantFP!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-/// Base class for aggregate constants (with operands).
-class ConstantAggregate : public Constant {
-protected:
- ConstantAggregate(ClassID ID, llvm::Constant *C, Context &Ctx)
- : Constant(ID, C, Ctx) {}
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- auto ID = From->getSubclassID();
- return ID == ClassID::ConstantVector || ID == ClassID::ConstantStruct ||
- ID == ClassID::ConstantArray;
- }
-};
-
-class ConstantArray final : public ConstantAggregate {
- ConstantArray(llvm::ConstantArray *C, Context &Ctx)
- : ConstantAggregate(ClassID::ConstantArray, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- static Constant *get(ArrayType *T, ArrayRef<Constant *> V);
- ArrayType *getType() const;
-
- // TODO: Missing functions: getType(), getTypeForElements(), getAnon(), get().
-
- /// For isa/dyn_cast.
- static bool classof(const Value *From) {
- return From->getSubclassID() == ClassID::ConstantArray;
- }
-};
-
-class ConstantStruct final : public ConstantAggregate {
- ConstantStruct(llvm::ConstantStruct *C, Context &Ctx)
- : ConstantAggregate(ClassID::ConstantStruct, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- static Constant *get(StructType *T, ArrayRef<Constant *> V);
-
- template <typename... Csts>
- static std::enable_if_t<are_base_of<Constant, Csts...>::value, Constant *>
- get(StructType *T, Csts *...Vs) {
- return get(T, ArrayRef<Constant *>({Vs...}));
- }
- /// Return an anonymous struct that has the specified elements.
- /// If the struct is possibly empty, then you must specify a context.
- static Constant *getAnon(ArrayRef<Constant *> V, bool Packed = false) {
- return get(getTypeForElements(V, Packed), V);
- }
- static Constant *getAnon(Context &Ctx, ArrayRef<Constant *> V,
- bool Packed = false) {
- return get(getTypeForElements(Ctx, V, Packed), V);
- }
- /// This version of the method allows an empty list.
- static StructType *getTypeForElements(Context &Ctx, ArrayRef<Constant *> V,
- bool Packed = false);
- /// Return an anonymous struct type to use for a constant with the specified
- /// set of elements. The list must not be empty.
- static StructType *getTypeForElements(ArrayRef<Constant *> V,
- bool Packed = false) {
- assert(!V.empty() &&
- "ConstantStruct::getTypeForElements cannot be called on empty list");
- return getTypeForElements(V[0]->getContext(), V, Packed);
- }
-
- /// Specialization - reduce amount of casting.
- inline StructType *getType() const {
- return cast<StructType>(Value::getType());
- }
-
- /// For isa/dyn_cast.
- static bool classof(const Value *From) {
- return From->getSubclassID() == ClassID::ConstantStruct;
- }
-};
-
-class ConstantVector final : public ConstantAggregate {
- ConstantVector(llvm::ConstantVector *C, Context &Ctx)
- : ConstantAggregate(ClassID::ConstantVector, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- // TODO: Missing functions: getSplat(), getType(), getSplatValue(), get().
-
- /// For isa/dyn_cast.
- static bool classof(const Value *From) {
- return From->getSubclassID() == ClassID::ConstantVector;
- }
-};
-
-// TODO: Inherit from ConstantData.
-class ConstantAggregateZero final : public Constant {
- ConstantAggregateZero(llvm::ConstantAggregateZero *C, Context &Ctx)
- : Constant(ClassID::ConstantAggregateZero, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- static ConstantAggregateZero *get(Type *Ty);
- /// If this CAZ has array or vector type, return a zero with the right element
- /// type.
- Constant *getSequentialElement() const;
- /// If this CAZ has struct type, return a zero with the right element type for
- /// the specified element.
- Constant *getStructElement(unsigned Elt) const;
- /// Return a zero of the right value for the specified GEP index if we can,
- /// otherwise return null (e.g. if C is a ConstantExpr).
- Constant *getElementValue(Constant *C) const;
- /// Return a zero of the right value for the specified GEP index.
- Constant *getElementValue(unsigned Idx) const;
- /// Return the number of elements in the array, vector, or struct.
- ElementCount getElementCount() const {
- return cast<llvm::ConstantAggregateZero>(Val)->getElementCount();
- }
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantAggregateZero;
- }
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("ConstantAggregateZero has no operands!");
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::ConstantAggregateZero>(Val) && "Expected a CAZ!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-// TODO: Inherit from ConstantData.
-class ConstantPointerNull final : public Constant {
- ConstantPointerNull(llvm::ConstantPointerNull *C, Context &Ctx)
- : Constant(ClassID::ConstantPointerNull, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- static ConstantPointerNull *get(PointerType *Ty);
-
- PointerType *getType() const;
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantPointerNull;
- }
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("ConstantPointerNull has no operands!");
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::ConstantPointerNull>(Val) && "Expected a CPNull!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-// TODO: Inherit from ConstantData.
-class UndefValue : public Constant {
-protected:
- UndefValue(llvm::UndefValue *C, Context &Ctx)
- : Constant(ClassID::UndefValue, C, Ctx) {}
- UndefValue(ClassID ID, llvm::Constant *C, Context &Ctx)
- : Constant(ID, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Static factory methods - Return an 'undef' object of the specified type.
- static UndefValue *get(Type *T);
-
- /// If this Undef has array or vector type, return a undef with the right
- /// element type.
- UndefValue *getSequentialElement() const;
-
- /// If this undef has struct type, return a undef with the right element type
- /// for the specified element.
- UndefValue *getStructElement(unsigned Elt) const;
-
- /// Return an undef of the right value for the specified GEP index if we can,
- /// otherwise return null (e.g. if C is a ConstantExpr).
- UndefValue *getElementValue(Constant *C) const;
-
- /// Return an undef of the right value for the specified GEP index.
- UndefValue *getElementValue(unsigned Idx) const;
-
- /// Return the number of elements in the array, vector, or struct.
- unsigned getNumElements() const {
- return cast<llvm::UndefValue>(Val)->getNumElements();
- }
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::UndefValue ||
- From->getSubclassID() == ClassID::PoisonValue;
- }
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("UndefValue has no operands!");
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::UndefValue>(Val) && "Expected an UndefValue!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-class PoisonValue final : public UndefValue {
- PoisonValue(llvm::PoisonValue *C, Context &Ctx)
- : UndefValue(ClassID::PoisonValue, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Static factory methods - Return an 'poison' object of the specified type.
- static PoisonValue *get(Type *T);
-
- /// If this poison has array or vector type, return a poison with the right
- /// element type.
- PoisonValue *getSequentialElement() const;
-
- /// If this poison has struct type, return a poison with the right element
- /// type for the specified element.
- PoisonValue *getStructElement(unsigned Elt) const;
-
- /// Return an poison of the right value for the specified GEP index if we can,
- /// otherwise return null (e.g. if C is a ConstantExpr).
- PoisonValue *getElementValue(Constant *C) const;
-
- /// Return an poison of the right value for the specified GEP index.
- PoisonValue *getElementValue(unsigned Idx) const;
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::PoisonValue;
- }
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::PoisonValue>(Val) && "Expected a PoisonValue!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-class GlobalValue : public Constant {
-protected:
- GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
- : Constant(ID, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- using LinkageTypes = llvm::GlobalValue::LinkageTypes;
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- switch (From->getSubclassID()) {
- case ClassID::Function:
- case ClassID::GlobalVariable:
- case ClassID::GlobalAlias:
- case ClassID::GlobalIFunc:
- return true;
- default:
- return false;
- }
- }
-
- unsigned getAddressSpace() const {
- return cast<llvm::GlobalValue>(Val)->getAddressSpace();
- }
- bool hasGlobalUnnamedAddr() const {
- return cast<llvm::GlobalValue>(Val)->hasGlobalUnnamedAddr();
- }
-
- /// Returns true if this value's address is not significant in this module.
- /// This attribute is intended to be used only by the code generator and LTO
- /// to allow the linker to decide whether the global needs to be in the symbol
- /// table. It should probably not be used in optimizations, as the value may
- /// have uses outside the module; use hasGlobalUnnamedAddr() instead.
- bool hasAtLeastLocalUnnamedAddr() const {
- return cast<llvm::GlobalValue>(Val)->hasAtLeastLocalUnnamedAddr();
- }
-
- using UnnamedAddr = llvm::GlobalValue::UnnamedAddr;
-
- UnnamedAddr getUnnamedAddr() const {
- return cast<llvm::GlobalValue>(Val)->getUnnamedAddr();
- }
- void setUnnamedAddr(UnnamedAddr V);
-
- static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
- return llvm::GlobalValue::getMinUnnamedAddr(A, B);
- }
-
- bool hasComdat() const { return cast<llvm::GlobalValue>(Val)->hasComdat(); }
-
- // TODO: We need a SandboxIR Comdat if we want to implement getComdat().
- using VisibilityTypes = llvm::GlobalValue::VisibilityTypes;
- VisibilityTypes getVisibility() const {
- return cast<llvm::GlobalValue>(Val)->getVisibility();
- }
- bool hasDefaultVisibility() const {
- return cast<llvm::GlobalValue>(Val)->hasDefaultVisibility();
- }
- bool hasHiddenVisibility() const {
- return cast<llvm::GlobalValue>(Val)->hasHiddenVisibility();
- }
- bool hasProtectedVisibility() const {
- return cast<llvm::GlobalValue>(Val)->hasProtectedVisibility();
- }
- void setVisibility(VisibilityTypes V);
-
- // TODO: Add missing functions.
-};
-
-class GlobalObject : public GlobalValue {
-protected:
- GlobalObject(ClassID ID, llvm::GlobalObject *C, Context &Ctx)
- : GlobalValue(ID, C, Ctx) {}
- friend class Context; // For constructor.
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
- return getOperandUseDefault(OpIdx, Verify);
- }
-
-public:
- unsigned getUseOperandNo(const Use &Use) const final {
- return getUseOperandNoDefault(Use);
- }
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- switch (From->getSubclassID()) {
- case ClassID::Function:
- case ClassID::GlobalVariable:
- case ClassID::GlobalIFunc:
- return true;
- default:
- return false;
- }
- }
-
- /// FIXME: Remove this function once transition to Align is over.
- uint64_t getAlignment() const {
- return cast<llvm::GlobalObject>(Val)->getAlignment();
- }
-
- /// Returns the alignment of the given variable or function.
- ///
- /// Note that for functions this is the alignment of the code, not the
- /// alignment of a function pointer.
- MaybeAlign getAlign() const {
- return cast<llvm::GlobalObject>(Val)->getAlign();
- }
-
- // TODO: Add missing: setAlignment(Align)
-
- /// Sets the alignment attribute of the GlobalObject.
- /// This method will be deprecated as the alignment property should always be
- /// defined.
- void setAlignment(MaybeAlign Align);
-
- unsigned getGlobalObjectSubClassData() const {
- return cast<llvm::GlobalObject>(Val)->getGlobalObjectSubClassData();
- }
-
- void setGlobalObjectSubClassData(unsigned V);
-
- /// Check if this global has a custom object file section.
- ///
- /// This is more efficient than calling getSection() and checking for an empty
- /// string.
- bool hasSection() const {
- return cast<llvm::GlobalObject>(Val)->hasSection();
- }
-
- /// Get the custom section of this global if it has one.
- ///
- /// If this global does not have a custom section, this will be empty and the
- /// default object file section (.text, .data, etc) will be used.
- StringRef getSection() const {
- return cast<llvm::GlobalObject>(Val)->getSection();
- }
-
- /// Change the section for this global.
- ///
- /// Setting the section to the empty string tells LLVM to choose an
- /// appropriate default object file section.
- void setSection(StringRef S);
-
- bool hasComdat() const { return cast<llvm::GlobalObject>(Val)->hasComdat(); }
-
- // TODO: implement get/setComdat(), etc. once we have a sandboxir::Comdat.
-
- // TODO: We currently don't support Metadata in sandboxir so all
- // Metadata-related functions are missing.
-
- using VCallVisibility = llvm::GlobalObject::VCallVisibility;
-
- VCallVisibility getVCallVisibility() const {
- return cast<llvm::GlobalObject>(Val)->getVCallVisibility();
- }
-
- /// Returns true if the alignment of the value can be unilaterally
- /// increased.
- ///
- /// Note that for functions this is the alignment of the code, not the
- /// alignment of a function pointer.
- bool canIncreaseAlignment() const {
- return cast<llvm::GlobalObject>(Val)->canIncreaseAlignment();
- }
-};
-
-/// Provides API functions, like getIterator() and getReverseIterator() to
-/// GlobalIFunc, Function, GlobalVariable and GlobalAlias. In LLVM IR these are
-/// provided by ilist_node.
-template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
- typename LLVMParentT>
-class GlobalWithNodeAPI : public ParentT {
- /// Helper for mapped_iterator.
- struct LLVMGVToGV {
- Context &Ctx;
- LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
- GlobalT &operator()(LLVMGlobalT &LLVMGV) const;
- };
-
-public:
- GlobalWithNodeAPI(Value::ClassID ID, LLVMParentT *C, Context &Ctx)
- : ParentT(ID, C, Ctx) {}
-
- Module *getParent() const {
- llvm::Module *LLVMM = cast<LLVMGlobalT>(this->Val)->getParent();
- return this->Ctx.getModule(LLVMM);
- }
-
- using iterator = mapped_iterator<
- decltype(static_cast<LLVMGlobalT *>(nullptr)->getIterator()), LLVMGVToGV>;
- using reverse_iterator = mapped_iterator<
- decltype(static_cast<LLVMGlobalT *>(nullptr)->getReverseIterator()),
- LLVMGVToGV>;
- iterator getIterator() const {
- auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
- LLVMGVToGV ToGV(this->Ctx);
- return map_iterator(LLVMGV->getIterator(), ToGV);
- }
- reverse_iterator getReverseIterator() const {
- auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
- LLVMGVToGV ToGV(this->Ctx);
- return map_iterator(LLVMGV->getReverseIterator(), ToGV);
- }
-};
-
-class GlobalIFunc final
- : public GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
- llvm::GlobalObject> {
- GlobalIFunc(llvm::GlobalObject *C, Context &Ctx)
- : GlobalWithNodeAPI(ClassID::GlobalIFunc, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::GlobalIFunc;
- }
-
- // TODO: Missing create() because we don't have a sandboxir::Module yet.
-
- // TODO: Missing functions: copyAttributesFrom(), removeFromParent(),
- // eraseFromParent()
-
- void setResolver(Constant *Resolver);
-
- Constant *getResolver() const;
-
- // Return the resolver function after peeling off potential ConstantExpr
- // indirection.
- Function *getResolverFunction();
- const Function *getResolverFunction() const {
- return const_cast<GlobalIFunc *>(this)->getResolverFunction();
- }
-
- static bool isValidLinkage(LinkageTypes L) {
- return llvm::GlobalIFunc::isValidLinkage(L);
- }
-
- // TODO: Missing applyAlongResolverPath().
-
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::GlobalIFunc>(Val) && "Expected a GlobalIFunc!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-class GlobalVariable final
- : public GlobalWithNodeAPI<GlobalVariable, llvm::GlobalVariable,
- GlobalObject, llvm::GlobalObject> {
- GlobalVariable(llvm::GlobalObject *C, Context &Ctx)
- : GlobalWithNodeAPI(ClassID::GlobalVariable, C, Ctx) {}
- friend class Context; // For constructor.
-
- /// Helper for mapped_iterator.
- struct LLVMGVToGV {
- Context &Ctx;
- LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
- GlobalVariable &operator()(llvm::GlobalVariable &LLVMGV) const;
- };
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::GlobalVariable;
- }
-
- /// Definitions have initializers, declarations don't.
- ///
- inline bool hasInitializer() const {
- return cast<llvm::GlobalVariable>(Val)->hasInitializer();
- }
-
- /// hasDefinitiveInitializer - Whether the global variable has an initializer,
- /// and any other instances of the global (this can happen due to weak
- /// linkage) are guaranteed to have the same initializer.
- ///
- /// Note that if you want to transform a global, you must use
- /// hasUniqueInitializer() instead, because of the *_odr linkage type.
- ///
- /// Example:
- ///
- /// @a = global SomeType* null - Initializer is both definitive and unique.
- ///
- /// @b = global weak SomeType* null - Initializer is neither definitive nor
- /// unique.
- ///
- /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
- /// unique.
- inline bool hasDefinitiveInitializer() const {
- return cast<llvm::GlobalVariable>(Val)->hasDefinitiveInitializer();
- }
-
- /// hasUniqueInitializer - Whether the global variable has an initializer, and
- /// any changes made to the initializer will turn up in the final executable.
- inline bool hasUniqueInitializer() const {
- return cast<llvm::GlobalVariable>(Val)->hasUniqueInitializer();
- }
-
- /// getInitializer - Return the initializer for this global variable. It is
- /// illegal to call this method if the global is external, because we cannot
- /// tell what the value is initialized to!
- ///
- Constant *getInitializer() const;
- /// setInitializer - Sets the initializer for this global variable, removing
- /// any existing initializer if InitVal==NULL. The initializer must have the
- /// type getValueType().
- void setInitializer(Constant *InitVal);
-
- // TODO: Add missing replaceInitializer(). Requires special tracker
-
- /// If the value is a global constant, its value is immutable throughout the
- /// runtime execution of the program. Assigning a value into the constant
- /// leads to undefined behavior.
- ///
- bool isConstant() const {
- return cast<llvm::GlobalVariable>(Val)->isConstant();
- }
- void setConstant(bool V);
-
- bool isExternallyInitialized() const {
- return cast<llvm::GlobalVariable>(Val)->isExternallyInitialized();
- }
- void setExternallyInitialized(bool Val);
-
- // TODO: Missing copyAttributesFrom()
-
- // TODO: Missing removeFromParent(), eraseFromParent(), dropAllReferences()
-
- // TODO: Missing addDebugInfo(), getDebugInfo()
-
- // TODO: Missing attribute setter functions: addAttribute(), setAttributes().
- // There seems to be no removeAttribute() so we can't undo them.
-
- /// Return true if the attribute exists.
- bool hasAttribute(Attribute::AttrKind Kind) const {
- return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
- }
-
- /// Return true if the attribute exists.
- bool hasAttribute(StringRef Kind) const {
- return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
- }
-
- /// Return true if any attributes exist.
- bool hasAttributes() const {
- return cast<llvm::GlobalVariable>(Val)->hasAttributes();
- }
-
- /// Return the attribute object.
- Attribute getAttribute(Attribute::AttrKind Kind) const {
- return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
- }
-
- /// Return the attribute object.
- Attribute getAttribute(StringRef Kind) const {
- return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
- }
-
- /// Return the attribute set for this global
- AttributeSet getAttributes() const {
- return cast<llvm::GlobalVariable>(Val)->getAttributes();
- }
-
- /// Return attribute set as list with index.
- /// FIXME: This may not be required once ValueEnumerators
- /// in bitcode-writer can enumerate attribute-set.
- AttributeList getAttributesAsList(unsigned Index) const {
- return cast<llvm::GlobalVariable>(Val)->getAttributesAsList(Index);
- }
-
- /// Check if section name is present
- bool hasImplicitSection() const {
- return cast<llvm::GlobalVariable>(Val)->hasImplicitSection();
- }
-
- /// Get the custom code model raw value of this global.
- ///
- unsigned getCodeModelRaw() const {
- return cast<llvm::GlobalVariable>(Val)->getCodeModelRaw();
- }
-
- /// Get the custom code model of this global if it has one.
- ///
- /// If this global does not have a custom code model, the empty instance
- /// will be returned.
- std::optional<CodeModel::Model> getCodeModel() const {
- return cast<llvm::GlobalVariable>(Val)->getCodeModel();
- }
-
- // TODO: Missing setCodeModel(). Requires custom tracker.
-
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::GlobalVariable>(Val) && "Expected a GlobalVariable!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-class GlobalAlias final
- : public GlobalWithNodeAPI<GlobalAlias, llvm::GlobalAlias, GlobalValue,
- llvm::GlobalValue> {
- GlobalAlias(llvm::GlobalAlias *C, Context &Ctx)
- : GlobalWithNodeAPI(ClassID::GlobalAlias, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::GlobalAlias;
- }
-
- // TODO: Missing create() due to unimplemented sandboxir::Module.
-
- // TODO: Missing copyAttributresFrom().
- // TODO: Missing removeFromParent(), eraseFromParent().
-
- void setAliasee(Constant *Aliasee);
- Constant *getAliasee() const;
-
- const GlobalObject *getAliaseeObject() const;
- GlobalObject *getAliaseeObject() {
- return const_cast<GlobalObject *>(
- static_cast<const GlobalAlias *>(this)->getAliaseeObject());
- }
-
- static bool isValidLinkage(LinkageTypes L) {
- return llvm::GlobalAlias::isValidLinkage(L);
- }
-};
-
-class NoCFIValue final : public Constant {
- NoCFIValue(llvm::NoCFIValue *C, Context &Ctx)
- : Constant(ClassID::NoCFIValue, C, Ctx) {}
- friend class Context; // For constructor.
-
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
- return getOperandUseDefault(OpIdx, Verify);
- }
-
-public:
- /// Return a NoCFIValue for the specified function.
- static NoCFIValue *get(GlobalValue *GV);
-
- GlobalValue *getGlobalValue() const;
-
- /// NoCFIValue is always a pointer.
- PointerType *getType() const;
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::NoCFIValue;
- }
-
- unsigned getUseOperandNo(const Use &Use) const final {
- return getUseOperandNoDefault(Use);
- }
-
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::NoCFIValue>(Val) && "Expected a NoCFIValue!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-class ConstantPtrAuth final : public Constant {
- ConstantPtrAuth(llvm::ConstantPtrAuth *C, Context &Ctx)
- : Constant(ClassID::ConstantPtrAuth, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Return a pointer signed with the specified parameters.
- static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
- ConstantInt *Disc, Constant *AddrDisc);
- /// The pointer that is signed in this ptrauth signed pointer.
- Constant *getPointer() const;
-
- /// The Key ID, an i32 constant.
- ConstantInt *getKey() const;
-
- /// The integer discriminator, an i64 constant, or 0.
- ConstantInt *getDiscriminator() const;
-
- /// The address discriminator if any, or the null constant.
- /// If present, this must be a value equivalent to the storage location of
- /// the only global-initializer user of the ptrauth signed pointer.
- Constant *getAddrDiscriminator() const;
-
- /// Whether there is any non-null address discriminator.
- bool hasAddressDiscriminator() const {
- return cast<llvm::ConstantPtrAuth>(Val)->hasAddressDiscriminator();
- }
-
- /// Whether the address uses a special address discriminator.
- /// These discriminators can't be used in real pointer-auth values; they
- /// can only be used in "prototype" values that indicate how some real
- /// schema is supposed to be produced.
- bool hasSpecialAddressDiscriminator(uint64_t Value) const {
- return cast<llvm::ConstantPtrAuth>(Val)->hasSpecialAddressDiscriminator(
- Value);
- }
-
- /// Check whether an authentication operation with key \p Key and (possibly
- /// blended) discriminator \p Discriminator is known to be compatible with
- /// this ptrauth signed pointer.
- bool isKnownCompatibleWith(const Value *Key, const Value *Discriminator,
- const DataLayout &DL) const {
- return cast<llvm::ConstantPtrAuth>(Val)->isKnownCompatibleWith(
- Key->Val, Discriminator->Val, DL);
- }
-
- /// Produce a new ptrauth expression signing the given value using
- /// the same schema as is stored in one.
- ConstantPtrAuth *getWithSameSchema(Constant *Pointer) const;
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantPtrAuth;
- }
-};
-
-class ConstantExpr : public Constant {
- ConstantExpr(llvm::ConstantExpr *C, Context &Ctx)
- : Constant(ClassID::ConstantExpr, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantExpr;
- }
- // TODO: Missing functions.
-};
-
-class BlockAddress final : public Constant {
- BlockAddress(llvm::BlockAddress *C, Context &Ctx)
- : Constant(ClassID::BlockAddress, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Return a BlockAddress for the specified function and basic block.
- static BlockAddress *get(Function *F, BasicBlock *BB);
-
- /// Return a BlockAddress for the specified basic block. The basic
- /// block must be embedded into a function.
- static BlockAddress *get(BasicBlock *BB);
-
- /// Lookup an existing \c BlockAddress constant for the given BasicBlock.
- ///
- /// \returns 0 if \c !BB->hasAddressTaken(), otherwise the \c BlockAddress.
- static BlockAddress *lookup(const BasicBlock *BB);
-
- Function *getFunction() const;
- BasicBlock *getBasicBlock() const;
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::BlockAddress;
- }
-};
-
-class DSOLocalEquivalent final : public Constant {
- DSOLocalEquivalent(llvm::DSOLocalEquivalent *C, Context &Ctx)
- : Constant(ClassID::DSOLocalEquivalent, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Return a DSOLocalEquivalent for the specified global value.
- static DSOLocalEquivalent *get(GlobalValue *GV);
-
- GlobalValue *getGlobalValue() const;
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::DSOLocalEquivalent;
- }
-
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("DSOLocalEquivalent has no operands!");
- }
-
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::DSOLocalEquivalent>(Val) &&
- "Expected a DSOLocalEquivalent!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantTokenNone final : public Constant {
- ConstantTokenNone(llvm::ConstantTokenNone *C, Context &Ctx)
- : Constant(ClassID::ConstantTokenNone, C, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// Return the ConstantTokenNone.
- static ConstantTokenNone *get(Context &Ctx);
-
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::ConstantTokenNone;
- }
-
- unsigned getUseOperandNo(const Use &Use) const final {
- llvm_unreachable("ConstantTokenNone has no operands!");
- }
-
-#ifndef NDEBUG
- void verify() const override {
- assert(isa<llvm::ConstantTokenNone>(Val) &&
- "Expected a ConstantTokenNone!");
- }
- void dumpOS(raw_ostream &OS) const override {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
- }
-#endif
-};
-
/// Iterator for `Instruction`s in a `BasicBlock.
/// \Returns an sandboxir::Instruction & when derereferenced.
class BBIterator {
@@ -4196,59 +2998,6 @@ class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {
}
};
-class Function : public GlobalWithNodeAPI<Function, llvm::Function,
- GlobalObject, llvm::GlobalObject> {
- /// Helper for mapped_iterator.
- struct LLVMBBToBB {
- Context &Ctx;
- LLVMBBToBB(Context &Ctx) : Ctx(Ctx) {}
- BasicBlock &operator()(llvm::BasicBlock &LLVMBB) const {
- return *cast<BasicBlock>(Ctx.getValue(&LLVMBB));
- }
- };
- /// Use Context::createFunction() instead.
- Function(llvm::Function *F, sandboxir::Context &Ctx)
- : GlobalWithNodeAPI(ClassID::Function, F, Ctx) {}
- friend class Context; // For constructor.
-
-public:
- /// For isa/dyn_cast.
- static bool classof(const sandboxir::Value *From) {
- return From->getSubclassID() == ClassID::Function;
- }
-
- Module *getParent() {
- return Ctx.getModule(cast<llvm::Function>(Val)->getParent());
- }
-
- Argument *getArg(unsigned Idx) const {
- llvm::Argument *Arg = cast<llvm::Function>(Val)->getArg(Idx);
- return cast<Argument>(Ctx.getValue(Arg));
- }
-
- size_t arg_size() const { return cast<llvm::Function>(Val)->arg_size(); }
- bool arg_empty() const { return cast<llvm::Function>(Val)->arg_empty(); }
-
- using iterator = mapped_iterator<llvm::Function::iterator, LLVMBBToBB>;
- iterator begin() const {
- LLVMBBToBB BBGetter(Ctx);
- return iterator(cast<llvm::Function>(Val)->begin(), BBGetter);
- }
- iterator end() const {
- LLVMBBToBB BBGetter(Ctx);
- return iterator(cast<llvm::Function>(Val)->end(), BBGetter);
- }
- FunctionType *getFunctionType() const;
-
-#ifndef NDEBUG
- void verify() const final {
- assert(isa<llvm::Function>(Val) && "Expected Function!");
- }
- void dumpNameAndArgs(raw_ostream &OS) const;
- void dumpOS(raw_ostream &OS) const final;
-#endif
-};
-
} // namespace sandboxir
} // namespace llvm
diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt
index d9259db970da58..52afeb395a9a07 100644
--- a/llvm/lib/SandboxIR/CMakeLists.txt
+++ b/llvm/lib/SandboxIR/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMSandboxIR
Argument.cpp
+ Constant.cpp
Context.cpp
Module.cpp
Pass.cpp
diff --git a/llvm/lib/SandboxIR/Constant.cpp b/llvm/lib/SandboxIR/Constant.cpp
new file mode 100644
index 00000000000000..83b33f72f19d40
--- /dev/null
+++ b/llvm/lib/SandboxIR/Constant.cpp
@@ -0,0 +1,509 @@
+//===- Constant.cpp - The Constant classes of Sandbox IR ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/SandboxIR/Constant.h"
+#include "llvm/SandboxIR/Context.h"
+#include "llvm/SandboxIR/SandboxIR.h" // TODO: Try to remove this
+
+namespace llvm::sandboxir {
+
+#ifndef NDEBUG
+void Constant::dumpOS(raw_ostream &OS) const {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+}
+#endif // NDEBUG
+
+ConstantInt *ConstantInt::getTrue(Context &Ctx) {
+ auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
+ return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getFalse(Context &Ctx) {
+ auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
+ return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
+ auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
+ return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::getTrue(Type *Ty) {
+ auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+Constant *ConstantInt::getFalse(Type *Ty) {
+ auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+Constant *ConstantInt::getBool(Type *Ty, bool V) {
+ auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
+ auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
+ return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
+ auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
+ return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
+ auto *LLVMC =
+ llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
+ return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
+ auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
+ auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
+ return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
+ auto *LLVMC =
+ llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
+ return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::get(Type *Ty, const APInt &V) {
+ auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+IntegerType *ConstantInt::getIntegerType() const {
+ auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
+ return cast<IntegerType>(Ctx.getType(LLVMTy));
+}
+
+bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
+ return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
+}
+bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
+ return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
+}
+
+Constant *ConstantFP::get(Type *Ty, double V) {
+ auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+
+Constant *ConstantFP::get(Type *Ty, const APFloat &V) {
+ auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+
+Constant *ConstantFP::get(Type *Ty, StringRef Str) {
+ auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, Str);
+ return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+
+ConstantFP *ConstantFP::get(const APFloat &V, Context &Ctx) {
+ auto *LLVMC = llvm::ConstantFP::get(Ctx.LLVMCtx, V);
+ return cast<ConstantFP>(Ctx.getOrCreateConstant(LLVMC));
+}
+
+Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
+ auto *LLVMC = llvm::ConstantFP::getNaN(Ty->LLVMTy, Negative, Payload);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
+ auto *LLVMC = llvm::ConstantFP::getQNaN(Ty->LLVMTy, Negative, Payload);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
+ auto *LLVMC = llvm::ConstantFP::getSNaN(Ty->LLVMTy, Negative, Payload);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantFP::getZero(Type *Ty, bool Negative) {
+ auto *LLVMC = llvm::ConstantFP::getZero(Ty->LLVMTy, Negative);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantFP::getNegativeZero(Type *Ty) {
+ auto *LLVMC = llvm::ConstantFP::getNegativeZero(Ty->LLVMTy);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
+ auto *LLVMC = llvm::ConstantFP::getInfinity(Ty->LLVMTy, Negative);
+ return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+bool ConstantFP::isValueValidForType(Type *Ty, const APFloat &V) {
+ return llvm::ConstantFP::isValueValidForType(Ty->LLVMTy, V);
+}
+
+Constant *ConstantArray::get(ArrayType *T, ArrayRef<Constant *> V) {
+ auto &Ctx = T->getContext();
+ SmallVector<llvm::Constant *> LLVMValues;
+ LLVMValues.reserve(V.size());
+ for (auto *Elm : V)
+ LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
+ auto *LLVMC =
+ llvm::ConstantArray::get(cast<llvm::ArrayType>(T->LLVMTy), LLVMValues);
+ return cast<ConstantArray>(Ctx.getOrCreateConstant(LLVMC));
+}
+
+ArrayType *ConstantArray::getType() const {
+ return cast<ArrayType>(
+ Ctx.getType(cast<llvm::ConstantArray>(Val)->getType()));
+}
+
+Constant *ConstantStruct::get(StructType *T, ArrayRef<Constant *> V) {
+ auto &Ctx = T->getContext();
+ SmallVector<llvm::Constant *> LLVMValues;
+ LLVMValues.reserve(V.size());
+ for (auto *Elm : V)
+ LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
+ auto *LLVMC =
+ llvm::ConstantStruct::get(cast<llvm::StructType>(T->LLVMTy), LLVMValues);
+ return cast<ConstantStruct>(Ctx.getOrCreateConstant(LLVMC));
+}
+
+StructType *ConstantStruct::getTypeForElements(Context &Ctx,
+ ArrayRef<Constant *> V,
+ bool Packed) {
+ unsigned VecSize = V.size();
+ SmallVector<Type *, 16> EltTypes;
+ EltTypes.reserve(VecSize);
+ for (Constant *Elm : V)
+ EltTypes.push_back(Elm->getType());
+ return StructType::get(Ctx, EltTypes, Packed);
+}
+
+ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
+ auto *LLVMC = llvm::ConstantAggregateZero::get(Ty->LLVMTy);
+ return cast<ConstantAggregateZero>(
+ Ty->getContext().getOrCreateConstant(LLVMC));
+}
+
+Constant *ConstantAggregateZero::getSequentialElement() const {
+ return cast<Constant>(Ctx.getValue(
+ cast<llvm::ConstantAggregateZero>(Val)->getSequentialElement()));
+}
+Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
+ return cast<Constant>(Ctx.getValue(
+ cast<llvm::ConstantAggregateZero>(Val)->getStructElement(Elt)));
+}
+Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
+ return cast<Constant>(
+ Ctx.getValue(cast<llvm::ConstantAggregateZero>(Val)->getElementValue(
+ cast<llvm::Constant>(C->Val))));
+}
+Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
+ return cast<Constant>(Ctx.getValue(
+ cast<llvm::ConstantAggregateZero>(Val)->getElementValue(Idx)));
+}
+
+ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
+ auto *LLVMC =
+ llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty->LLVMTy));
+ return cast<ConstantPointerNull>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+
+PointerType *ConstantPointerNull::getType() const {
+ return cast<PointerType>(
+ Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));
+}
+
+UndefValue *UndefValue::get(Type *T) {
+ auto *LLVMC = llvm::UndefValue::get(T->LLVMTy);
+ return cast<UndefValue>(T->getContext().getOrCreateConstant(LLVMC));
+}
+
+UndefValue *UndefValue::getSequentialElement() const {
+ return cast<UndefValue>(Ctx.getOrCreateConstant(
+ cast<llvm::UndefValue>(Val)->getSequentialElement()));
+}
+
+UndefValue *UndefValue::getStructElement(unsigned Elt) const {
+ return cast<UndefValue>(Ctx.getOrCreateConstant(
+ cast<llvm::UndefValue>(Val)->getStructElement(Elt)));
+}
+
+UndefValue *UndefValue::getElementValue(Constant *C) const {
+ return cast<UndefValue>(
+ Ctx.getOrCreateConstant(cast<llvm::UndefValue>(Val)->getElementValue(
+ cast<llvm::Constant>(C->Val))));
+}
+
+UndefValue *UndefValue::getElementValue(unsigned Idx) const {
+ return cast<UndefValue>(Ctx.getOrCreateConstant(
+ cast<llvm::UndefValue>(Val)->getElementValue(Idx)));
+}
+
+PoisonValue *PoisonValue::get(Type *T) {
+ auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy);
+ return cast<PoisonValue>(T->getContext().getOrCreateConstant(LLVMC));
+}
+
+PoisonValue *PoisonValue::getSequentialElement() const {
+ return cast<PoisonValue>(Ctx.getOrCreateConstant(
+ cast<llvm::PoisonValue>(Val)->getSequentialElement()));
+}
+
+PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
+ return cast<PoisonValue>(Ctx.getOrCreateConstant(
+ cast<llvm::PoisonValue>(Val)->getStructElement(Elt)));
+}
+
+PoisonValue *PoisonValue::getElementValue(Constant *C) const {
+ return cast<PoisonValue>(
+ Ctx.getOrCreateConstant(cast<llvm::PoisonValue>(Val)->getElementValue(
+ cast<llvm::Constant>(C->Val))));
+}
+
+PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
+ return cast<PoisonValue>(Ctx.getOrCreateConstant(
+ cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
+}
+
+void GlobalObject::setAlignment(MaybeAlign Align) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>(
+ this);
+ cast<llvm::GlobalObject>(Val)->setAlignment(Align);
+}
+
+void GlobalObject::setGlobalObjectSubClassData(unsigned V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getGlobalObjectSubClassData,
+ &GlobalObject::setGlobalObjectSubClassData>>(this);
+ cast<llvm::GlobalObject>(Val)->setGlobalObjectSubClassData(V);
+}
+
+void GlobalObject::setSection(StringRef S) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(
+ this);
+ cast<llvm::GlobalObject>(Val)->setSection(S);
+}
+
+template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
+ typename LLVMParentT>
+GlobalT &GlobalWithNodeAPI<GlobalT, LLVMGlobalT, ParentT, LLVMParentT>::
+ LLVMGVToGV::operator()(LLVMGlobalT &LLVMGV) const {
+ return cast<GlobalT>(*Ctx.getValue(&LLVMGV));
+}
+
+// Explicit instantiations.
+template class GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
+ llvm::GlobalObject>;
+template class GlobalWithNodeAPI<Function, llvm::Function, GlobalObject,
+ llvm::GlobalObject>;
+template class GlobalWithNodeAPI<GlobalVariable, llvm::GlobalVariable,
+ GlobalObject, llvm::GlobalObject>;
+template class GlobalWithNodeAPI<GlobalAlias, llvm::GlobalAlias, GlobalValue,
+ llvm::GlobalValue>;
+
+void GlobalIFunc::setResolver(Constant *Resolver) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalIFunc::getResolver, &GlobalIFunc::setResolver>>(
+ this);
+ cast<llvm::GlobalIFunc>(Val)->setResolver(
+ cast<llvm::Constant>(Resolver->Val));
+}
+
+Constant *GlobalIFunc::getResolver() const {
+ return Ctx.getOrCreateConstant(cast<llvm::GlobalIFunc>(Val)->getResolver());
+}
+
+Function *GlobalIFunc::getResolverFunction() {
+ return cast<Function>(Ctx.getOrCreateConstant(
+ cast<llvm::GlobalIFunc>(Val)->getResolverFunction()));
+}
+
+GlobalVariable &
+GlobalVariable::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const {
+ return cast<GlobalVariable>(*Ctx.getValue(&LLVMGV));
+}
+
+Constant *GlobalVariable::getInitializer() const {
+ return Ctx.getOrCreateConstant(
+ cast<llvm::GlobalVariable>(Val)->getInitializer());
+}
+
+void GlobalVariable::setInitializer(Constant *InitVal) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&GlobalVariable::getInitializer,
+ &GlobalVariable::setInitializer>>(this);
+ cast<llvm::GlobalVariable>(Val)->setInitializer(
+ cast<llvm::Constant>(InitVal->Val));
+}
+
+void GlobalVariable::setConstant(bool V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&GlobalVariable::isConstant,
+ &GlobalVariable::setConstant>>(this);
+ cast<llvm::GlobalVariable>(Val)->setConstant(V);
+}
+
+void GlobalVariable::setExternallyInitialized(bool V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalVariable::isExternallyInitialized,
+ &GlobalVariable::setExternallyInitialized>>(this);
+ cast<llvm::GlobalVariable>(Val)->setExternallyInitialized(V);
+}
+
+void GlobalAlias::setAliasee(Constant *Aliasee) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&GlobalAlias::getAliasee, &GlobalAlias::setAliasee>>(
+ this);
+ cast<llvm::GlobalAlias>(Val)->setAliasee(cast<llvm::Constant>(Aliasee->Val));
+}
+
+Constant *GlobalAlias::getAliasee() const {
+ return cast<Constant>(
+ Ctx.getOrCreateConstant(cast<llvm::GlobalAlias>(Val)->getAliasee()));
+}
+
+const GlobalObject *GlobalAlias::getAliaseeObject() const {
+ return cast<GlobalObject>(Ctx.getOrCreateConstant(
+ cast<llvm::GlobalAlias>(Val)->getAliaseeObject()));
+}
+
+void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,
+ &GlobalValue::setUnnamedAddr>>(this);
+ cast<llvm::GlobalValue>(Val)->setUnnamedAddr(V);
+}
+
+void GlobalValue::setVisibility(VisibilityTypes V) {
+ Ctx.getTracker()
+ .emplaceIfTracking<GenericSetter<&GlobalValue::getVisibility,
+ &GlobalValue::setVisibility>>(this);
+ cast<llvm::GlobalValue>(Val)->setVisibility(V);
+}
+
+NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
+ auto *LLVMC = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(GV->Val));
+ return cast<NoCFIValue>(GV->getContext().getOrCreateConstant(LLVMC));
+}
+
+GlobalValue *NoCFIValue::getGlobalValue() const {
+ auto *LLVMC = cast<llvm::NoCFIValue>(Val)->getGlobalValue();
+ return cast<GlobalValue>(Ctx.getOrCreateConstant(LLVMC));
+}
+
+PointerType *NoCFIValue::getType() const {
+ return cast<PointerType>(Ctx.getType(cast<llvm::NoCFIValue>(Val)->getType()));
+}
+
+ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
+ ConstantInt *Disc, Constant *AddrDisc) {
+ auto *LLVMC = llvm::ConstantPtrAuth::get(
+ cast<llvm::Constant>(Ptr->Val), cast<llvm::ConstantInt>(Key->Val),
+ cast<llvm::ConstantInt>(Disc->Val), cast<llvm::Constant>(AddrDisc->Val));
+ return cast<ConstantPtrAuth>(Ptr->getContext().getOrCreateConstant(LLVMC));
+}
+
+Constant *ConstantPtrAuth::getPointer() const {
+ return Ctx.getOrCreateConstant(
+ cast<llvm::ConstantPtrAuth>(Val)->getPointer());
+}
+
+ConstantInt *ConstantPtrAuth::getKey() const {
+ return cast<ConstantInt>(
+ Ctx.getOrCreateConstant(cast<llvm::ConstantPtrAuth>(Val)->getKey()));
+}
+
+ConstantInt *ConstantPtrAuth::getDiscriminator() const {
+ return cast<ConstantInt>(Ctx.getOrCreateConstant(
+ cast<llvm::ConstantPtrAuth>(Val)->getDiscriminator()));
+}
+
+Constant *ConstantPtrAuth::getAddrDiscriminator() const {
+ return Ctx.getOrCreateConstant(
+ cast<llvm::ConstantPtrAuth>(Val)->getAddrDiscriminator());
+}
+
+ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
+ auto *LLVMC = cast<llvm::ConstantPtrAuth>(Val)->getWithSameSchema(
+ cast<llvm::Constant>(Pointer->Val));
+ return cast<ConstantPtrAuth>(Ctx.getOrCreateConstant(LLVMC));
+}
+
+BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
+ auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),
+ cast<llvm::BasicBlock>(BB->Val));
+ return cast<BlockAddress>(F->getContext().getOrCreateConstant(LLVMC));
+}
+
+BlockAddress *BlockAddress::get(BasicBlock *BB) {
+ auto *LLVMC = llvm::BlockAddress::get(cast<llvm::BasicBlock>(BB->Val));
+ return cast<BlockAddress>(BB->getContext().getOrCreateConstant(LLVMC));
+}
+
+BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
+ auto *LLVMC = llvm::BlockAddress::lookup(cast<llvm::BasicBlock>(BB->Val));
+ return cast_or_null<BlockAddress>(BB->getContext().getValue(LLVMC));
+}
+
+Function *BlockAddress::getFunction() const {
+ return cast<Function>(
+ Ctx.getValue(cast<llvm::BlockAddress>(Val)->getFunction()));
+}
+
+BasicBlock *BlockAddress::getBasicBlock() const {
+ return cast<BasicBlock>(
+ Ctx.getValue(cast<llvm::BlockAddress>(Val)->getBasicBlock()));
+}
+
+DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
+ auto *LLVMC = llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(GV->Val));
+ return cast<DSOLocalEquivalent>(GV->getContext().getValue(LLVMC));
+}
+
+GlobalValue *DSOLocalEquivalent::getGlobalValue() const {
+ return cast<GlobalValue>(
+ Ctx.getValue(cast<llvm::DSOLocalEquivalent>(Val)->getGlobalValue()));
+}
+
+FunctionType *Function::getFunctionType() const {
+ return cast<FunctionType>(
+ Ctx.getType(cast<llvm::Function>(Val)->getFunctionType()));
+}
+
+#ifndef NDEBUG
+void Function::dumpNameAndArgs(raw_ostream &OS) const {
+ auto *F = cast<llvm::Function>(Val);
+ OS << *F->getReturnType() << " @" << F->getName() << "(";
+ interleave(
+ F->args(),
+ [this, &OS](const llvm::Argument &LLVMArg) {
+ auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
+ if (SBArg == nullptr)
+ OS << "NULL";
+ else
+ SBArg->printAsOperand(OS);
+ },
+ [&] { OS << ", "; });
+ OS << ")";
+}
+
+void Function::dumpOS(raw_ostream &OS) const {
+ dumpNameAndArgs(OS);
+ OS << " {\n";
+ auto *LLVMF = cast<llvm::Function>(Val);
+ interleave(
+ *LLVMF,
+ [this, &OS](const llvm::BasicBlock &LLVMBB) {
+ auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
+ if (BB == nullptr)
+ OS << "NULL";
+ else
+ OS << *BB;
+ },
+ [&OS] { OS << "\n"; });
+ OS << "}\n";
+}
+#endif // NDEBUG
+
+} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 12cac66480b0c3..42df9df8119733 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2085,506 +2085,11 @@ Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
}
-#ifndef NDEBUG
-void Constant::dumpOS(raw_ostream &OS) const {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
-}
-#endif // NDEBUG
-
-ConstantInt *ConstantInt::getTrue(Context &Ctx) {
- auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
- return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getFalse(Context &Ctx) {
- auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
- return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
- auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
- return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::getTrue(Type *Ty) {
- auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-Constant *ConstantInt::getFalse(Type *Ty) {
- auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-Constant *ConstantInt::getBool(Type *Ty, bool V) {
- auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
- auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
- return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
- auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
- return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
- auto *LLVMC =
- llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
- return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
- auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
- auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
- return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
- auto *LLVMC =
- llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
- return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::get(Type *Ty, const APInt &V) {
- auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-IntegerType *ConstantInt::getIntegerType() const {
- auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
- return cast<IntegerType>(Ctx.getType(LLVMTy));
-}
-
-bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
- return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
-}
-bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
- return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
-}
-
-Constant *ConstantFP::get(Type *Ty, double V) {
- auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-Constant *ConstantFP::get(Type *Ty, const APFloat &V) {
- auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-Constant *ConstantFP::get(Type *Ty, StringRef Str) {
- auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, Str);
- return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-ConstantFP *ConstantFP::get(const APFloat &V, Context &Ctx) {
- auto *LLVMC = llvm::ConstantFP::get(Ctx.LLVMCtx, V);
- return cast<ConstantFP>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
- auto *LLVMC = llvm::ConstantFP::getNaN(Ty->LLVMTy, Negative, Payload);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
- auto *LLVMC = llvm::ConstantFP::getQNaN(Ty->LLVMTy, Negative, Payload);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
- auto *LLVMC = llvm::ConstantFP::getSNaN(Ty->LLVMTy, Negative, Payload);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getZero(Type *Ty, bool Negative) {
- auto *LLVMC = llvm::ConstantFP::getZero(Ty->LLVMTy, Negative);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getNegativeZero(Type *Ty) {
- auto *LLVMC = llvm::ConstantFP::getNegativeZero(Ty->LLVMTy);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
- auto *LLVMC = llvm::ConstantFP::getInfinity(Ty->LLVMTy, Negative);
- return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-bool ConstantFP::isValueValidForType(Type *Ty, const APFloat &V) {
- return llvm::ConstantFP::isValueValidForType(Ty->LLVMTy, V);
-}
-
-Constant *ConstantArray::get(ArrayType *T, ArrayRef<Constant *> V) {
- auto &Ctx = T->getContext();
- SmallVector<llvm::Constant *> LLVMValues;
- LLVMValues.reserve(V.size());
- for (auto *Elm : V)
- LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
- auto *LLVMC =
- llvm::ConstantArray::get(cast<llvm::ArrayType>(T->LLVMTy), LLVMValues);
- return cast<ConstantArray>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-ArrayType *ConstantArray::getType() const {
- return cast<ArrayType>(
- Ctx.getType(cast<llvm::ConstantArray>(Val)->getType()));
-}
-
-Constant *ConstantStruct::get(StructType *T, ArrayRef<Constant *> V) {
- auto &Ctx = T->getContext();
- SmallVector<llvm::Constant *> LLVMValues;
- LLVMValues.reserve(V.size());
- for (auto *Elm : V)
- LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
- auto *LLVMC =
- llvm::ConstantStruct::get(cast<llvm::StructType>(T->LLVMTy), LLVMValues);
- return cast<ConstantStruct>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-StructType *ConstantStruct::getTypeForElements(Context &Ctx,
- ArrayRef<Constant *> V,
- bool Packed) {
- unsigned VecSize = V.size();
- SmallVector<Type *, 16> EltTypes;
- EltTypes.reserve(VecSize);
- for (Constant *Elm : V)
- EltTypes.push_back(Elm->getType());
- return StructType::get(Ctx, EltTypes, Packed);
-}
-
-ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
- auto *LLVMC = llvm::ConstantAggregateZero::get(Ty->LLVMTy);
- return cast<ConstantAggregateZero>(
- Ty->getContext().getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantAggregateZero::getSequentialElement() const {
- return cast<Constant>(Ctx.getValue(
- cast<llvm::ConstantAggregateZero>(Val)->getSequentialElement()));
-}
-Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
- return cast<Constant>(Ctx.getValue(
- cast<llvm::ConstantAggregateZero>(Val)->getStructElement(Elt)));
-}
-Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
- return cast<Constant>(
- Ctx.getValue(cast<llvm::ConstantAggregateZero>(Val)->getElementValue(
- cast<llvm::Constant>(C->Val))));
-}
-Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
- return cast<Constant>(Ctx.getValue(
- cast<llvm::ConstantAggregateZero>(Val)->getElementValue(Idx)));
-}
-
-ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
- auto *LLVMC =
- llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty->LLVMTy));
- return cast<ConstantPointerNull>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-
-PointerType *ConstantPointerNull::getType() const {
- return cast<PointerType>(
- Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));
-}
-
-UndefValue *UndefValue::get(Type *T) {
- auto *LLVMC = llvm::UndefValue::get(T->LLVMTy);
- return cast<UndefValue>(T->getContext().getOrCreateConstant(LLVMC));
-}
-
-UndefValue *UndefValue::getSequentialElement() const {
- return cast<UndefValue>(Ctx.getOrCreateConstant(
- cast<llvm::UndefValue>(Val)->getSequentialElement()));
-}
-
-UndefValue *UndefValue::getStructElement(unsigned Elt) const {
- return cast<UndefValue>(Ctx.getOrCreateConstant(
- cast<llvm::UndefValue>(Val)->getStructElement(Elt)));
-}
-
-UndefValue *UndefValue::getElementValue(Constant *C) const {
- return cast<UndefValue>(
- Ctx.getOrCreateConstant(cast<llvm::UndefValue>(Val)->getElementValue(
- cast<llvm::Constant>(C->Val))));
-}
-
-UndefValue *UndefValue::getElementValue(unsigned Idx) const {
- return cast<UndefValue>(Ctx.getOrCreateConstant(
- cast<llvm::UndefValue>(Val)->getElementValue(Idx)));
-}
-
-PoisonValue *PoisonValue::get(Type *T) {
- auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy);
- return cast<PoisonValue>(T->getContext().getOrCreateConstant(LLVMC));
-}
-
-PoisonValue *PoisonValue::getSequentialElement() const {
- return cast<PoisonValue>(Ctx.getOrCreateConstant(
- cast<llvm::PoisonValue>(Val)->getSequentialElement()));
-}
-
-PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
- return cast<PoisonValue>(Ctx.getOrCreateConstant(
- cast<llvm::PoisonValue>(Val)->getStructElement(Elt)));
-}
-
-PoisonValue *PoisonValue::getElementValue(Constant *C) const {
- return cast<PoisonValue>(
- Ctx.getOrCreateConstant(cast<llvm::PoisonValue>(Val)->getElementValue(
- cast<llvm::Constant>(C->Val))));
-}
-
-PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
- return cast<PoisonValue>(Ctx.getOrCreateConstant(
- cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
-}
-
-void GlobalObject::setAlignment(MaybeAlign Align) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalObject::getAlign, &GlobalObject::setAlignment>>(
- this);
- cast<llvm::GlobalObject>(Val)->setAlignment(Align);
-}
-
-void GlobalObject::setGlobalObjectSubClassData(unsigned V) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalObject::getGlobalObjectSubClassData,
- &GlobalObject::setGlobalObjectSubClassData>>(this);
- cast<llvm::GlobalObject>(Val)->setGlobalObjectSubClassData(V);
-}
-
-void GlobalObject::setSection(StringRef S) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(
- this);
- cast<llvm::GlobalObject>(Val)->setSection(S);
-}
-
-template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
- typename LLVMParentT>
-GlobalT &GlobalWithNodeAPI<GlobalT, LLVMGlobalT, ParentT, LLVMParentT>::
- LLVMGVToGV::operator()(LLVMGlobalT &LLVMGV) const {
- return cast<GlobalT>(*Ctx.getValue(&LLVMGV));
-}
-
-namespace llvm::sandboxir {
-// Explicit instantiations.
-template class GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
- llvm::GlobalObject>;
-template class GlobalWithNodeAPI<Function, llvm::Function, GlobalObject,
- llvm::GlobalObject>;
-template class GlobalWithNodeAPI<GlobalVariable, llvm::GlobalVariable,
- GlobalObject, llvm::GlobalObject>;
-template class GlobalWithNodeAPI<GlobalAlias, llvm::GlobalAlias, GlobalValue,
- llvm::GlobalValue>;
-} // namespace llvm::sandboxir
-
-void GlobalIFunc::setResolver(Constant *Resolver) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalIFunc::getResolver, &GlobalIFunc::setResolver>>(
- this);
- cast<llvm::GlobalIFunc>(Val)->setResolver(
- cast<llvm::Constant>(Resolver->Val));
-}
-
-Constant *GlobalIFunc::getResolver() const {
- return Ctx.getOrCreateConstant(cast<llvm::GlobalIFunc>(Val)->getResolver());
-}
-
-Function *GlobalIFunc::getResolverFunction() {
- return cast<Function>(Ctx.getOrCreateConstant(
- cast<llvm::GlobalIFunc>(Val)->getResolverFunction()));
-}
-
-GlobalVariable &
-GlobalVariable::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const {
- return cast<GlobalVariable>(*Ctx.getValue(&LLVMGV));
-}
-
-Constant *GlobalVariable::getInitializer() const {
- return Ctx.getOrCreateConstant(
- cast<llvm::GlobalVariable>(Val)->getInitializer());
-}
-
-void GlobalVariable::setInitializer(Constant *InitVal) {
- Ctx.getTracker()
- .emplaceIfTracking<GenericSetter<&GlobalVariable::getInitializer,
- &GlobalVariable::setInitializer>>(this);
- cast<llvm::GlobalVariable>(Val)->setInitializer(
- cast<llvm::Constant>(InitVal->Val));
-}
-
-void GlobalVariable::setConstant(bool V) {
- Ctx.getTracker()
- .emplaceIfTracking<GenericSetter<&GlobalVariable::isConstant,
- &GlobalVariable::setConstant>>(this);
- cast<llvm::GlobalVariable>(Val)->setConstant(V);
-}
-
-void GlobalVariable::setExternallyInitialized(bool V) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalVariable::isExternallyInitialized,
- &GlobalVariable::setExternallyInitialized>>(this);
- cast<llvm::GlobalVariable>(Val)->setExternallyInitialized(V);
-}
-
-void GlobalAlias::setAliasee(Constant *Aliasee) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&GlobalAlias::getAliasee, &GlobalAlias::setAliasee>>(
- this);
- cast<llvm::GlobalAlias>(Val)->setAliasee(cast<llvm::Constant>(Aliasee->Val));
-}
-
-Constant *GlobalAlias::getAliasee() const {
- return cast<Constant>(
- Ctx.getOrCreateConstant(cast<llvm::GlobalAlias>(Val)->getAliasee()));
-}
-
-const GlobalObject *GlobalAlias::getAliaseeObject() const {
- return cast<GlobalObject>(Ctx.getOrCreateConstant(
- cast<llvm::GlobalAlias>(Val)->getAliaseeObject()));
-}
-
-void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
- Ctx.getTracker()
- .emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,
- &GlobalValue::setUnnamedAddr>>(this);
- cast<llvm::GlobalValue>(Val)->setUnnamedAddr(V);
-}
-
-void GlobalValue::setVisibility(VisibilityTypes V) {
- Ctx.getTracker()
- .emplaceIfTracking<GenericSetter<&GlobalValue::getVisibility,
- &GlobalValue::setVisibility>>(this);
- cast<llvm::GlobalValue>(Val)->setVisibility(V);
-}
-
-NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
- auto *LLVMC = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(GV->Val));
- return cast<NoCFIValue>(GV->getContext().getOrCreateConstant(LLVMC));
-}
-
-GlobalValue *NoCFIValue::getGlobalValue() const {
- auto *LLVMC = cast<llvm::NoCFIValue>(Val)->getGlobalValue();
- return cast<GlobalValue>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-PointerType *NoCFIValue::getType() const {
- return cast<PointerType>(Ctx.getType(cast<llvm::NoCFIValue>(Val)->getType()));
-}
-
-ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
- ConstantInt *Disc, Constant *AddrDisc) {
- auto *LLVMC = llvm::ConstantPtrAuth::get(
- cast<llvm::Constant>(Ptr->Val), cast<llvm::ConstantInt>(Key->Val),
- cast<llvm::ConstantInt>(Disc->Val), cast<llvm::Constant>(AddrDisc->Val));
- return cast<ConstantPtrAuth>(Ptr->getContext().getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantPtrAuth::getPointer() const {
- return Ctx.getOrCreateConstant(
- cast<llvm::ConstantPtrAuth>(Val)->getPointer());
-}
-
-ConstantInt *ConstantPtrAuth::getKey() const {
- return cast<ConstantInt>(
- Ctx.getOrCreateConstant(cast<llvm::ConstantPtrAuth>(Val)->getKey()));
-}
-
-ConstantInt *ConstantPtrAuth::getDiscriminator() const {
- return cast<ConstantInt>(Ctx.getOrCreateConstant(
- cast<llvm::ConstantPtrAuth>(Val)->getDiscriminator()));
-}
-
-Constant *ConstantPtrAuth::getAddrDiscriminator() const {
- return Ctx.getOrCreateConstant(
- cast<llvm::ConstantPtrAuth>(Val)->getAddrDiscriminator());
-}
-
-ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
- auto *LLVMC = cast<llvm::ConstantPtrAuth>(Val)->getWithSameSchema(
- cast<llvm::Constant>(Pointer->Val));
- return cast<ConstantPtrAuth>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
- auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),
- cast<llvm::BasicBlock>(BB->Val));
- return cast<BlockAddress>(F->getContext().getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::get(BasicBlock *BB) {
- auto *LLVMC = llvm::BlockAddress::get(cast<llvm::BasicBlock>(BB->Val));
- return cast<BlockAddress>(BB->getContext().getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
- auto *LLVMC = llvm::BlockAddress::lookup(cast<llvm::BasicBlock>(BB->Val));
- return cast_or_null<BlockAddress>(BB->getContext().getValue(LLVMC));
-}
-
-Function *BlockAddress::getFunction() const {
- return cast<Function>(
- Ctx.getValue(cast<llvm::BlockAddress>(Val)->getFunction()));
-}
-
-BasicBlock *BlockAddress::getBasicBlock() const {
- return cast<BasicBlock>(
- Ctx.getValue(cast<llvm::BlockAddress>(Val)->getBasicBlock()));
-}
-
-DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
- auto *LLVMC = llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(GV->Val));
- return cast<DSOLocalEquivalent>(GV->getContext().getValue(LLVMC));
-}
-
-GlobalValue *DSOLocalEquivalent::getGlobalValue() const {
- return cast<GlobalValue>(
- Ctx.getValue(cast<llvm::DSOLocalEquivalent>(Val)->getGlobalValue()));
-}
-
ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
}
-FunctionType *Function::getFunctionType() const {
- return cast<FunctionType>(
- Ctx.getType(cast<llvm::Function>(Val)->getFunctionType()));
-}
-
-#ifndef NDEBUG
-void Function::dumpNameAndArgs(raw_ostream &OS) const {
- auto *F = cast<llvm::Function>(Val);
- OS << *F->getReturnType() << " @" << F->getName() << "(";
- interleave(
- F->args(),
- [this, &OS](const llvm::Argument &LLVMArg) {
- auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
- if (SBArg == nullptr)
- OS << "NULL";
- else
- SBArg->printAsOperand(OS);
- },
- [&] { OS << ", "; });
- OS << ")";
-}
-void Function::dumpOS(raw_ostream &OS) const {
- dumpNameAndArgs(OS);
- OS << " {\n";
- auto *LLVMF = cast<llvm::Function>(Val);
- interleave(
- *LLVMF,
- [this, &OS](const llvm::BasicBlock &LLVMBB) {
- auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
- if (BB == nullptr)
- OS << "NULL";
- else
- OS << *BB;
- },
- [&OS] { OS << "\n"; });
- OS << "}\n";
-}
-#endif // NDEBUG
-
BasicBlock::iterator::pointer
BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
return cast_or_null<Instruction>(Ctx->getValue(&*It));
More information about the llvm-commits
mailing list