1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
|
//===-- llvm/Constant.h - Constant class definition -------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the Constant class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_CONSTANT_H
#define LLVM_IR_CONSTANT_H
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
namespace llvm {
class APInt;
/// This is an important base class in LLVM. It provides the common facilities
/// of all constant values in an LLVM program. A constant is a value that is
/// immutable at runtime. Functions are constants because their address is
/// immutable. Same with global variables.
///
/// All constants share the capabilities provided in this class. All constants
/// can have a null value. They can have an operand list. Constants can be
/// simple (integer and floating point values), complex (arrays and structures),
/// or expression based (computations yielding a constant value composed of
/// only certain operators and other constant values).
///
/// Note that Constants are immutable (once created they never change)
/// and are fully shared by structural equivalence. This means that two
/// structurally equivalent constants will always have the same address.
/// Constants are created on demand as needed and never deleted: thus clients
/// don't have to worry about the lifetime of the objects.
/// LLVM Constant Representation
class Constant : public User {
protected:
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
~Constant() = default;
public:
void operator=(const Constant &) = delete;
Constant(const Constant &) = delete;
/// Return true if this is the value that would be returned by getNullValue.
bool isNullValue() const;
/// Returns true if the value is one.
bool isOneValue() const;
/// Return true if the value is not the one value, or,
/// for vectors, does not contain one value elements.
bool isNotOneValue() const;
/// Return true if this is the value that would be returned by
/// getAllOnesValue.
bool isAllOnesValue() const;
/// Return true if the value is what would be returned by
/// getZeroValueForNegation.
bool isNegativeZeroValue() const;
/// Return true if the value is negative zero or null value.
bool isZeroValue() const;
/// Return true if the value is not the smallest signed value, or,
/// for vectors, does not contain smallest signed value elements.
bool isNotMinSignedValue() const;
/// Return true if the value is the smallest signed value.
bool isMinSignedValue() const;
/// Return true if this is a finite and non-zero floating-point scalar
/// constant or a fixed width vector constant with all finite and non-zero
/// elements.
bool isFiniteNonZeroFP() const;
/// Return true if this is a normal (as opposed to denormal, infinity, nan,
/// or zero) floating-point scalar constant or a vector constant with all
/// normal elements. See APFloat::isNormal.
bool isNormalFP() const;
/// Return true if this scalar has an exact multiplicative inverse or this
/// vector has an exact multiplicative inverse for each element in the vector.
bool hasExactInverseFP() const;
/// Return true if this is a floating-point NaN constant or a vector
/// floating-point constant with all NaN elements.
bool isNaN() const;
/// Return true if this constant and a constant 'Y' are element-wise equal.
/// This is identical to just comparing the pointers, with the exception that
/// for vectors, if only one of the constants has an `undef` element in some
/// lane, the constants still match.
bool isElementWiseEqual(Value *Y) const;
/// Return true if this is a vector constant that includes any undef or
/// poison elements. Since it is impossible to inspect a scalable vector
/// element- wise at compile time, this function returns true only if the
/// entire vector is undef or poison.
bool containsUndefOrPoisonElement() const;
/// Return true if this is a vector constant that includes any poison
/// elements.
bool containsPoisonElement() const;
/// Return true if this is a fixed width vector constant that includes
/// any constant expressions.
bool containsConstantExpression() const;
/// Return true if evaluation of this constant could trap. This is true for
/// things like constant expressions that could divide by zero.
bool canTrap() const;
/// Return true if the value can vary between threads.
bool isThreadDependent() const;
/// Return true if the value is dependent on a dllimport variable.
bool isDLLImportDependent() const;
/// Return true if the constant has users other than constant expressions and
/// other dangling things.
bool isConstantUsed() const;
/// This method classifies the entry according to whether or not it may
/// generate a relocation entry (either static or dynamic). This must be
/// conservative, so if it might codegen to a relocatable entry, it should say
/// so.
///
/// FIXME: This really should not be in IR.
bool needsRelocation() const;
bool needsDynamicRelocation() const;
/// For aggregates (struct/array/vector) return the constant that corresponds
/// to the specified element if possible, or null if not. This can return null
/// if the element index is a ConstantExpr, if 'this' is a constant expr or
/// if the constant does not fit into an uint64_t.
Constant *getAggregateElement(unsigned Elt) const;
Constant *getAggregateElement(Constant *Elt) const;
/// If all elements of the vector constant have the same value, return that
/// value. Otherwise, return nullptr. Ignore undefined elements by setting
/// AllowUndefs to true.
Constant *getSplatValue(bool AllowUndefs = false) const;
/// If C is a constant integer then return its value, otherwise C must be a
/// vector of constant integers, all equal, and the common value is returned.
const APInt &getUniqueInteger() const;
/// Called if some element of this constant is no longer valid.
/// At this point only other constants may be on the use_list for this
/// constant. Any constants on our Use list must also be destroy'd. The
/// implementation must be sure to remove the constant from the list of
/// available cached constants. Implementations should implement
/// destroyConstantImpl to remove constants from any pools/maps they are
/// contained it.
void destroyConstant();
//// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
static_assert(ConstantFirstVal == 0, "V->getValueID() >= ConstantFirstVal always succeeds");
return V->getValueID() <= ConstantLastVal;
}
/// This method is a special form of User::replaceUsesOfWith
/// (which does not work on constants) that does work
/// on constants. Basically this method goes through the trouble of building
/// a new constant that is equivalent to the current one, with all uses of
/// From replaced with uses of To. After this construction is completed, all
/// of the users of 'this' are replaced to use the new constant, and then
/// 'this' is deleted. In general, you should not call this method, instead,
/// use Value::replaceAllUsesWith, which automatically dispatches to this
/// method as needed.
///
void handleOperandChange(Value *, Value *);
static Constant *getNullValue(Type* Ty);
/// @returns the value for an integer or vector of integer constant of the
/// given type that has all its bits set to true.
/// Get the all ones value
static Constant *getAllOnesValue(Type* Ty);
/// Return the value for an integer or pointer constant, or a vector thereof,
/// with the given scalar value.
static Constant *getIntegerValue(Type *Ty, const APInt &V);
/// If there are any dead constant users dangling off of this constant, remove
/// them. This method is useful for clients that want to check to see if a
/// global is unused, but don't want to deal with potentially dead constants
/// hanging off of the globals.
void removeDeadConstantUsers() const;
/// Return true if the constant has exactly one live use.
///
/// This returns the same result as calling Value::hasOneUse after
/// Constant::removeDeadConstantUsers, but doesn't remove dead constants.
bool hasOneLiveUse() const;
/// Return true if the constant has no live uses.
///
/// This returns the same result as calling Value::use_empty after
/// Constant::removeDeadConstantUsers, but doesn't remove dead constants.
bool hasZeroLiveUses() const;
const Constant *stripPointerCasts() const {
return cast<Constant>(Value::stripPointerCasts());
}
Constant *stripPointerCasts() {
return const_cast<Constant*>(
static_cast<const Constant *>(this)->stripPointerCasts());
}
/// Try to replace undefined constant C or undefined elements in C with
/// Replacement. If no changes are made, the constant C is returned.
static Constant *replaceUndefsWith(Constant *C, Constant *Replacement);
/// Merges undefs of a Constant with another Constant, along with the
/// undefs already present. Other doesn't have to be the same type as C, but
/// both must either be scalars or vectors with the same element count. If no
/// changes are made, the constant C is returned.
static Constant *mergeUndefsWith(Constant *C, Constant *Other);
/// Return true if a constant is ConstantData or a ConstantAggregate or
/// ConstantExpr that contain only ConstantData.
bool isManifestConstant() const;
private:
enum PossibleRelocationsTy {
/// This constant requires no relocations. That is, it holds simple
/// constants (like integrals).
NoRelocation = 0,
/// This constant holds static relocations that can be resolved by the
/// static linker.
LocalRelocation = 1,
/// This constant holds dynamic relocations that the dynamic linker will
/// need to resolve.
GlobalRelocation = 2,
};
/// Determine what potential relocations may be needed by this constant.
PossibleRelocationsTy getRelocationInfo() const;
bool hasNLiveUses(unsigned N) const;
};
} // end namespace llvm
#endif // LLVM_IR_CONSTANT_H
|