llvm/llvm/lib/IR/Constants.cpp

//===-- Constants.cpp - Implement Constant nodes --------------------------===//
//
// 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 implements the Constant* classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Constants.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

usingnamespacellvm;
usingnamespacePatternMatch;

// As set of temporary options to help migrate how splats are represented.
static cl::opt<bool> UseConstantIntForFixedLengthSplat(
    "use-constant-int-for-fixed-length-splat", cl::init(false), cl::Hidden,
    cl::desc("Use ConstantInt's native fixed-length vector splat support."));
static cl::opt<bool> UseConstantFPForFixedLengthSplat(
    "use-constant-fp-for-fixed-length-splat", cl::init(false), cl::Hidden,
    cl::desc("Use ConstantFP's native fixed-length vector splat support."));
static cl::opt<bool> UseConstantIntForScalableSplat(
    "use-constant-int-for-scalable-splat", cl::init(false), cl::Hidden,
    cl::desc("Use ConstantInt's native scalable vector splat support."));
static cl::opt<bool> UseConstantFPForScalableSplat(
    "use-constant-fp-for-scalable-splat", cl::init(false), cl::Hidden,
    cl::desc("Use ConstantFP's native scalable vector splat support."));

//===----------------------------------------------------------------------===//
//                              Constant Class
//===----------------------------------------------------------------------===//

bool Constant::isNegativeZeroValue() const {}

// Return true iff this constant is positive zero (floating point), negative
// zero (floating point), or a null value.
bool Constant::isZeroValue() const {}

bool Constant::isNullValue() const {}

bool Constant::isAllOnesValue() const {}

bool Constant::isOneValue() const {}

bool Constant::isNotOneValue() const {}

bool Constant::isMinSignedValue() const {}

bool Constant::isNotMinSignedValue() const {}

bool Constant::isFiniteNonZeroFP() const {}

bool Constant::isNormalFP() const {}

bool Constant::hasExactInverseFP() const {}

bool Constant::isNaN() const {}

bool Constant::isElementWiseEqual(Value *Y) const {}

static bool
containsUndefinedElement(const Constant *C,
                         function_ref<bool(const Constant *)> HasFn) {}

bool Constant::containsUndefOrPoisonElement() const {}

bool Constant::containsPoisonElement() const {}

bool Constant::containsUndefElement() const {}

bool Constant::containsConstantExpression() const {}

/// Constructor to create a '0' constant of arbitrary type.
Constant *Constant::getNullValue(Type *Ty) {}

Constant *Constant::getIntegerValue(Type *Ty, const APInt &V) {}

Constant *Constant::getAllOnesValue(Type *Ty) {}

Constant *Constant::getAggregateElement(unsigned Elt) const {}

Constant *Constant::getAggregateElement(Constant *Elt) const {}

void Constant::destroyConstant() {}

void llvm::deleteConstant(Constant *C) {}

/// Check if C contains a GlobalValue for which Predicate is true.
static bool
ConstHasGlobalValuePredicate(const Constant *C,
                             bool (*Predicate)(const GlobalValue *)) {}

bool Constant::isThreadDependent() const {}

bool Constant::isDLLImportDependent() const {}

bool Constant::isConstantUsed() const {}

bool Constant::needsDynamicRelocation() const {}

bool Constant::needsRelocation() const {}

Constant::PossibleRelocationsTy Constant::getRelocationInfo() const {}

/// Return true if the specified constantexpr is dead. This involves
/// recursively traversing users of the constantexpr.
/// If RemoveDeadUsers is true, also remove dead users at the same time.
static bool constantIsDead(const Constant *C, bool RemoveDeadUsers) {}

void Constant::removeDeadConstantUsers() const {}

bool Constant::hasOneLiveUse() const {}

bool Constant::hasZeroLiveUses() const {}

bool Constant::hasNLiveUses(unsigned N) const {}

Constant *Constant::replaceUndefsWith(Constant *C, Constant *Replacement) {}

Constant *Constant::mergeUndefsWith(Constant *C, Constant *Other) {}

bool Constant::isManifestConstant() const {}

//===----------------------------------------------------------------------===//
//                                ConstantInt
//===----------------------------------------------------------------------===//

ConstantInt::ConstantInt(Type *Ty, const APInt &V)
    :{}

ConstantInt *ConstantInt::getTrue(LLVMContext &Context) {}

ConstantInt *ConstantInt::getFalse(LLVMContext &Context) {}

ConstantInt *ConstantInt::getBool(LLVMContext &Context, bool V) {}

Constant *ConstantInt::getTrue(Type *Ty) {}

Constant *ConstantInt::getFalse(Type *Ty) {}

Constant *ConstantInt::getBool(Type *Ty, bool V) {}

// Get a ConstantInt from an APInt.
ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) {}

// Get a ConstantInt vector with each lane set to the same APInt.
ConstantInt *ConstantInt::get(LLVMContext &Context, ElementCount EC,
                              const APInt &V) {}

Constant *ConstantInt::get(Type *Ty, uint64_t V, bool isSigned) {}

ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool isSigned) {}

Constant *ConstantInt::get(Type *Ty, const APInt& V) {}

ConstantInt *ConstantInt::get(IntegerType* Ty, StringRef Str, uint8_t radix) {}

/// Remove the constant from the constant table.
void ConstantInt::destroyConstantImpl() {}

//===----------------------------------------------------------------------===//
//                                ConstantFP
//===----------------------------------------------------------------------===//

Constant *ConstantFP::get(Type *Ty, double V) {}

Constant *ConstantFP::get(Type *Ty, const APFloat &V) {}

Constant *ConstantFP::get(Type *Ty, StringRef Str) {}

Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {}

Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {}

Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {}

Constant *ConstantFP::getZero(Type *Ty, bool Negative) {}


// ConstantFP accessors.
ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {}

// Get a ConstantFP vector with each lane set to the same APFloat.
ConstantFP *ConstantFP::get(LLVMContext &Context, ElementCount EC,
                            const APFloat &V) {}

Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {}

ConstantFP::ConstantFP(Type *Ty, const APFloat &V)
    :{}

bool ConstantFP::isExactlyValue(const APFloat &V) const {}

/// Remove the constant from the constant table.
void ConstantFP::destroyConstantImpl() {}

//===----------------------------------------------------------------------===//
//                   ConstantAggregateZero Implementation
//===----------------------------------------------------------------------===//

Constant *ConstantAggregateZero::getSequentialElement() const {}

Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {}

Constant *ConstantAggregateZero::getElementValue(Constant *C) const {}

Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {}

ElementCount ConstantAggregateZero::getElementCount() const {}

//===----------------------------------------------------------------------===//
//                         UndefValue Implementation
//===----------------------------------------------------------------------===//

UndefValue *UndefValue::getSequentialElement() const {}

UndefValue *UndefValue::getStructElement(unsigned Elt) const {}

UndefValue *UndefValue::getElementValue(Constant *C) const {}

UndefValue *UndefValue::getElementValue(unsigned Idx) const {}

unsigned UndefValue::getNumElements() const {}

//===----------------------------------------------------------------------===//
//                         PoisonValue Implementation
//===----------------------------------------------------------------------===//

PoisonValue *PoisonValue::getSequentialElement() const {}

PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {}

PoisonValue *PoisonValue::getElementValue(Constant *C) const {}

PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {}

//===----------------------------------------------------------------------===//
//                            ConstantXXX Classes
//===----------------------------------------------------------------------===//

template <typename ItTy, typename EltTy>
static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) {}

template <typename SequentialTy, typename ElementTy>
static Constant *getIntSequenceIfElementsMatch(ArrayRef<Constant *> V) {}

template <typename SequentialTy, typename ElementTy>
static Constant *getFPSequenceIfElementsMatch(ArrayRef<Constant *> V) {}

template <typename SequenceTy>
static Constant *getSequenceIfElementsMatch(Constant *C,
                                            ArrayRef<Constant *> V) {}

ConstantAggregate::ConstantAggregate(Type *T, ValueTy VT,
                                     ArrayRef<Constant *> V,
                                     AllocInfo AllocInfo)
    :{}

ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V,
                             AllocInfo AllocInfo)
    :{}

Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) {}

Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {}

StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
                                               ArrayRef<Constant*> V,
                                               bool Packed) {}


StructType *ConstantStruct::getTypeForElements(ArrayRef<Constant*> V,
                                               bool Packed) {}

ConstantStruct::ConstantStruct(StructType *T, ArrayRef<Constant *> V,
                               AllocInfo AllocInfo)
    :{}

// ConstantStruct accessors.
Constant *ConstantStruct::get(StructType *ST, ArrayRef<Constant*> V) {}

ConstantVector::ConstantVector(VectorType *T, ArrayRef<Constant *> V,
                               AllocInfo AllocInfo)
    :{}

// ConstantVector accessors.
Constant *ConstantVector::get(ArrayRef<Constant*> V) {}

Constant *ConstantVector::getImpl(ArrayRef<Constant*> V) {}

Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {}

ConstantTokenNone *ConstantTokenNone::get(LLVMContext &Context) {}

/// Remove the constant from the constant table.
void ConstantTokenNone::destroyConstantImpl() {}

// Utility function for determining if a ConstantExpr is a CastOp or not. This
// can't be inline because we don't want to #include Instruction.h into
// Constant.h
bool ConstantExpr::isCast() const {}

ArrayRef<int> ConstantExpr::getShuffleMask() const {}

Constant *ConstantExpr::getShuffleMaskForBitcode() const {}

Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
                                        bool OnlyIfReduced, Type *SrcTy) const {}


//===----------------------------------------------------------------------===//
//                      isValueValidForType implementations

bool ConstantInt::isValueValidForType(Type *Ty, uint64_t Val) {}

bool ConstantInt::isValueValidForType(Type *Ty, int64_t Val) {}

bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) {}


//===----------------------------------------------------------------------===//
//                      Factory Function Implementation

ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {}

/// Remove the constant from the constant table.
void ConstantAggregateZero::destroyConstantImpl() {}

/// Remove the constant from the constant table.
void ConstantArray::destroyConstantImpl() {}


//---- ConstantStruct::get() implementation...
//

/// Remove the constant from the constant table.
void ConstantStruct::destroyConstantImpl() {}

/// Remove the constant from the constant table.
void ConstantVector::destroyConstantImpl() {}

Constant *Constant::getSplatValue(bool AllowPoison) const {}

Constant *ConstantVector::getSplatValue(bool AllowPoison) const {}

const APInt &Constant::getUniqueInteger() const {}

ConstantRange Constant::toConstantRange() const {}

//---- ConstantPointerNull::get() implementation.
//

ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {}

/// Remove the constant from the constant table.
void ConstantPointerNull::destroyConstantImpl() {}

//---- ConstantTargetNone::get() implementation.
//

ConstantTargetNone *ConstantTargetNone::get(TargetExtType *Ty) {}

/// Remove the constant from the constant table.
void ConstantTargetNone::destroyConstantImpl() {}

UndefValue *UndefValue::get(Type *Ty) {}

/// Remove the constant from the constant table.
void UndefValue::destroyConstantImpl() {}

PoisonValue *PoisonValue::get(Type *Ty) {}

/// Remove the constant from the constant table.
void PoisonValue::destroyConstantImpl() {}

BlockAddress *BlockAddress::get(BasicBlock *BB) {}

BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {}

BlockAddress::BlockAddress(Function *F, BasicBlock *BB)
    :{}

BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {}

/// Remove the constant from the constant table.
void BlockAddress::destroyConstantImpl() {}

Value *BlockAddress::handleOperandChangeImpl(Value *From, Value *To) {}

DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {}

DSOLocalEquivalent::DSOLocalEquivalent(GlobalValue *GV)
    :{}

/// Remove the constant from the constant table.
void DSOLocalEquivalent::destroyConstantImpl() {}

Value *DSOLocalEquivalent::handleOperandChangeImpl(Value *From, Value *To) {}

NoCFIValue *NoCFIValue::get(GlobalValue *GV) {}

NoCFIValue::NoCFIValue(GlobalValue *GV)
    :{}

/// Remove the constant from the constant table.
void NoCFIValue::destroyConstantImpl() {}

Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {}

//---- ConstantPtrAuth::get() implementations.
//

ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
                                      ConstantInt *Disc, Constant *AddrDisc) {}

ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {}

ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key,
                                 ConstantInt *Disc, Constant *AddrDisc)
    :{}

/// Remove the constant from the constant table.
void ConstantPtrAuth::destroyConstantImpl() {}

Value *ConstantPtrAuth::handleOperandChangeImpl(Value *From, Value *ToV) {}

bool ConstantPtrAuth::hasSpecialAddressDiscriminator(uint64_t Value) const {}

bool ConstantPtrAuth::isKnownCompatibleWith(const Value *Key,
                                            const Value *Discriminator,
                                            const DataLayout &DL) const {}

//---- ConstantExpr::get() implementations.
//

/// This is a utility function to handle folding of casts and lookup of the
/// cast in the ExprConstants map. It is used by the various get* methods below.
static Constant *getFoldedCast(Instruction::CastOps opc, Constant *C, Type *Ty,
                               bool OnlyIfReduced = false) {}

Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty,
                                bool OnlyIfReduced) {}

Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) {}

Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) {}

Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S,
                                                         Type *Ty) {}

Constant *ConstantExpr::getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced) {}

Constant *ConstantExpr::getPtrToInt(Constant *C, Type *DstTy,
                                    bool OnlyIfReduced) {}

Constant *ConstantExpr::getIntToPtr(Constant *C, Type *DstTy,
                                    bool OnlyIfReduced) {}

Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy,
                                   bool OnlyIfReduced) {}

Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
                                         bool OnlyIfReduced) {}

Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
                            unsigned Flags, Type *OnlyIfReducedTy) {}

bool ConstantExpr::isDesirableBinOp(unsigned Opcode) {}

bool ConstantExpr::isSupportedBinOp(unsigned Opcode) {}

bool ConstantExpr::isDesirableCastOp(unsigned Opcode) {}

bool ConstantExpr::isSupportedCastOp(unsigned Opcode) {}

Constant *ConstantExpr::getSizeOf(Type* Ty) {}

Constant *ConstantExpr::getAlignOf(Type* Ty) {}

Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
                                         ArrayRef<Value *> Idxs,
                                         GEPNoWrapFlags NW,
                                         std::optional<ConstantRange> InRange,
                                         Type *OnlyIfReducedTy) {}

Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx,
                                          Type *OnlyIfReducedTy) {}

Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
                                         Constant *Idx, Type *OnlyIfReducedTy) {}

Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
                                         ArrayRef<int> Mask,
                                         Type *OnlyIfReducedTy) {}

Constant *ConstantExpr::getNeg(Constant *C, bool HasNSW) {}

Constant *ConstantExpr::getNot(Constant *C) {}

Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2,
                               bool HasNUW, bool HasNSW) {}

Constant *ConstantExpr::getSub(Constant *C1, Constant *C2,
                               bool HasNUW, bool HasNSW) {}

Constant *ConstantExpr::getMul(Constant *C1, Constant *C2,
                               bool HasNUW, bool HasNSW) {}

Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {}

Constant *ConstantExpr::getExactLogBase2(Constant *C) {}

Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty,
                                         bool AllowRHSConstant, bool NSZ) {}

Constant *ConstantExpr::getIntrinsicIdentity(Intrinsic::ID ID, Type *Ty) {}

Constant *ConstantExpr::getIdentity(Instruction *I, Type *Ty,
                                    bool AllowRHSConstant, bool NSZ) {}

Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty,
                                         bool AllowLHSConstant) {}

/// Remove the constant from the constant table.
void ConstantExpr::destroyConstantImpl() {}

const char *ConstantExpr::getOpcodeName() const {}

GetElementPtrConstantExpr::GetElementPtrConstantExpr(
    Type *SrcElementTy, Constant *C, ArrayRef<Constant *> IdxList, Type *DestTy,
    std::optional<ConstantRange> InRange, AllocInfo AllocInfo)
    :{}

Type *GetElementPtrConstantExpr::getSourceElementType() const {}

Type *GetElementPtrConstantExpr::getResultElementType() const {}

std::optional<ConstantRange> GetElementPtrConstantExpr::getInRange() const {}

//===----------------------------------------------------------------------===//
//                       ConstantData* implementations

Type *ConstantDataSequential::getElementType() const {}

StringRef ConstantDataSequential::getRawDataValues() const {}

bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {}

unsigned ConstantDataSequential::getNumElements() const {}


uint64_t ConstantDataSequential::getElementByteSize() const {}

/// Return the start of the specified element.
const char *ConstantDataSequential::getElementPointer(unsigned Elt) const {}


/// Return true if the array is empty or all zeros.
static bool isAllZeros(StringRef Arr) {}

/// This is the underlying implementation of all of the
/// ConstantDataSequential::get methods.  They all thunk down to here, providing
/// the correct element type.  We take the bytes in as a StringRef because
/// we *want* an underlying "char*" to avoid TBAA type punning violations.
Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {}

void ConstantDataSequential::destroyConstantImpl() {}

/// getFP() constructors - Return a constant of array type with a float
/// element type taken from argument `ElementType', and count taken from
/// argument `Elts'.  The amount of bits of the contained type must match the
/// number of bits of the type contained in the passed in ArrayRef.
/// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
/// that this can return a ConstantAggregateZero object.
Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {}
Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {}
Constant *ConstantDataArray::getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {}

Constant *ConstantDataArray::getString(LLVMContext &Context,
                                       StringRef Str, bool AddNull) {}

/// get() constructors - Return a constant with vector type with an element
/// count and element type matching the ArrayRef passed in.  Note that this
/// can return a ConstantAggregateZero object.
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint8_t> Elts){}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint16_t> Elts){}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint32_t> Elts){}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<uint64_t> Elts){}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<float> Elts) {}
Constant *ConstantDataVector::get(LLVMContext &Context, ArrayRef<double> Elts) {}

/// getFP() constructors - Return a constant of vector type with a float
/// element type taken from argument `ElementType', and count taken from
/// argument `Elts'.  The amount of bits of the contained type must match the
/// number of bits of the type contained in the passed in ArrayRef.
/// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
/// that this can return a ConstantAggregateZero object.
Constant *ConstantDataVector::getFP(Type *ElementType,
                                    ArrayRef<uint16_t> Elts) {}
Constant *ConstantDataVector::getFP(Type *ElementType,
                                    ArrayRef<uint32_t> Elts) {}
Constant *ConstantDataVector::getFP(Type *ElementType,
                                    ArrayRef<uint64_t> Elts) {}

Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {}


uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {}

APInt ConstantDataSequential::getElementAsAPInt(unsigned Elt) const {}

APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {}

float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {}

double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {}

Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {}

bool ConstantDataSequential::isString(unsigned CharSize) const {}

bool ConstantDataSequential::isCString() const {}

bool ConstantDataVector::isSplatData() const {}

bool ConstantDataVector::isSplat() const {}

Constant *ConstantDataVector::getSplatValue() const {}

//===----------------------------------------------------------------------===//
//                handleOperandChange implementations

/// Update this constant array to change uses of
/// 'From' to be uses of 'To'.  This must update the uniquing data structures
/// etc.
///
/// Note that we intentionally replace all uses of From with To here.  Consider
/// a large array that uses 'From' 1000 times.  By handling this case all here,
/// ConstantArray::handleOperandChange is only invoked once, and that
/// single invocation handles all 1000 uses.  Handling them one at a time would
/// work, but would be really slow because it would have to unique each updated
/// array instance.
///
void Constant::handleOperandChange(Value *From, Value *To) {}

Value *ConstantArray::handleOperandChangeImpl(Value *From, Value *To) {}

Value *ConstantStruct::handleOperandChangeImpl(Value *From, Value *To) {}

Value *ConstantVector::handleOperandChangeImpl(Value *From, Value *To) {}

Value *ConstantExpr::handleOperandChangeImpl(Value *From, Value *ToV) {}

Instruction *ConstantExpr::getAsInstruction() const {}