#include "llvm/IR/Value.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DerivedUser.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/TypedPointerType.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
usingnamespacellvm;
static cl::opt<unsigned> UseDerefAtPointSemantics(
"use-dereferenceable-at-point-semantics", cl::Hidden, cl::init(false),
cl::desc("Deref attributes and metadata infer facts at definition only"));
static inline Type *checkType(Type *Ty) { … }
Value::Value(Type *ty, unsigned scid)
: … { … }
Value::~Value() { … }
void Value::deleteValue() { … }
void Value::destroyValueName() { … }
bool Value::hasNUses(unsigned N) const { … }
bool Value::hasNUsesOrMore(unsigned N) const { … }
bool Value::hasOneUser() const { … }
static bool isUnDroppableUser(const User *U) { … }
Use *Value::getSingleUndroppableUse() { … }
User *Value::getUniqueUndroppableUser() { … }
bool Value::hasNUndroppableUses(unsigned int N) const { … }
bool Value::hasNUndroppableUsesOrMore(unsigned int N) const { … }
void Value::dropDroppableUses(
llvm::function_ref<bool(const Use *)> ShouldDrop) { … }
void Value::dropDroppableUsesIn(User &Usr) { … }
void Value::dropDroppableUse(Use &U) { … }
bool Value::isUsedInBasicBlock(const BasicBlock *BB) const { … }
unsigned Value::getNumUses() const { … }
static bool getSymTab(Value *V, ValueSymbolTable *&ST) { … }
ValueName *Value::getValueName() const { … }
void Value::setValueName(ValueName *VN) { … }
StringRef Value::getName() const { … }
void Value::setNameImpl(const Twine &NewName) { … }
void Value::setName(const Twine &NewName) { … }
void Value::takeName(Value *V) { … }
#ifndef NDEBUG
std::string Value::getNameOrAsOperand() const {
if (!getName().empty())
return std::string(getName());
std::string BBName;
raw_string_ostream OS(BBName);
printAsOperand(OS, false);
return OS.str();
}
#endif
void Value::assertModuleIsMaterializedImpl() const { … }
#ifndef NDEBUG
static bool contains(SmallPtrSetImpl<ConstantExpr *> &Cache, ConstantExpr *Expr,
Constant *C) {
if (!Cache.insert(Expr).second)
return false;
for (auto &O : Expr->operands()) {
if (O == C)
return true;
auto *CE = dyn_cast<ConstantExpr>(O);
if (!CE)
continue;
if (contains(Cache, CE, C))
return true;
}
return false;
}
static bool contains(Value *Expr, Value *V) {
if (Expr == V)
return true;
auto *C = dyn_cast<Constant>(V);
if (!C)
return false;
auto *CE = dyn_cast<ConstantExpr>(Expr);
if (!CE)
return false;
SmallPtrSet<ConstantExpr *, 4> Cache;
return contains(Cache, CE, C);
}
#endif
void Value::doRAUW(Value *New, ReplaceMetadataUses ReplaceMetaUses) { … }
void Value::replaceAllUsesWith(Value *New) { … }
void Value::replaceNonMetadataUsesWith(Value *New) { … }
void Value::replaceUsesWithIf(Value *New,
llvm::function_ref<bool(Use &U)> ShouldReplace) { … }
static void replaceDbgUsesOutsideBlock(Value *V, Value *New, BasicBlock *BB) { … }
void Value::replaceUsesOutsideBlock(Value *New, BasicBlock *BB) { … }
namespace {
enum PointerStripKind { … };
template <PointerStripKind StripKind> static void NoopCallback(const Value *) { … }
template <PointerStripKind StripKind>
static const Value *stripPointerCastsAndOffsets(
const Value *V,
function_ref<void(const Value *)> Func = NoopCallback<StripKind>) { … }
}
const Value *Value::stripPointerCasts() const { … }
const Value *Value::stripPointerCastsAndAliases() const { … }
const Value *Value::stripPointerCastsSameRepresentation() const { … }
const Value *Value::stripInBoundsConstantOffsets() const { … }
const Value *Value::stripPointerCastsForAliasAnalysis() const { … }
const Value *Value::stripAndAccumulateConstantOffsets(
const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
bool AllowInvariantGroup,
function_ref<bool(Value &, APInt &)> ExternalAnalysis) const { … }
const Value *
Value::stripInBoundsOffsets(function_ref<void(const Value *)> Func) const { … }
bool Value::canBeFreed() const { … }
uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
bool &CanBeNull,
bool &CanBeFreed) const { … }
Align Value::getPointerAlignment(const DataLayout &DL) const { … }
static std::optional<int64_t>
getOffsetFromIndex(const GEPOperator *GEP, unsigned Idx, const DataLayout &DL) { … }
std::optional<int64_t> Value::getPointerOffsetFrom(const Value *Other,
const DataLayout &DL) const { … }
const Value *Value::DoPHITranslation(const BasicBlock *CurBB,
const BasicBlock *PredBB) const { … }
LLVMContext &Value::getContext() const { … }
void Value::reverseUseList() { … }
bool Value::isSwiftError() const { … }
void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { … }
void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) { … }
void ValueHandleBase::AddToUseList() { … }
void ValueHandleBase::RemoveFromUseList() { … }
void ValueHandleBase::ValueIsDeleted(Value *V) { … }
void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { … }
void CallbackVH::anchor() { … }