125 lines
3.6 KiB
C++
125 lines
3.6 KiB
C++
//===- Value.cpp - The Value class 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/Value.h"
|
|
#include "llvm/SandboxIR/Context.h"
|
|
#include "llvm/SandboxIR/User.h"
|
|
#include <sstream>
|
|
|
|
namespace llvm::sandboxir {
|
|
|
|
Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
|
|
: SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
|
|
#ifndef NDEBUG
|
|
UID = Ctx.getNumValues();
|
|
#endif
|
|
}
|
|
|
|
Value::use_iterator Value::use_begin() {
|
|
llvm::Use *LLVMUse = nullptr;
|
|
if (!Val->uses().empty())
|
|
LLVMUse = &*Val->use_begin();
|
|
User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
|
|
Val->use_begin()->getUser()))
|
|
: nullptr;
|
|
return use_iterator(Use(LLVMUse, User, Ctx));
|
|
}
|
|
|
|
Value::user_iterator Value::user_begin() {
|
|
auto UseBegin = Val->use_begin();
|
|
auto UseEnd = Val->use_end();
|
|
bool AtEnd = UseBegin == UseEnd;
|
|
llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
|
|
User *User =
|
|
AtEnd ? nullptr
|
|
: cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
|
|
return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
|
|
}
|
|
|
|
unsigned Value::getNumUses() const { return range_size(Val->users()); }
|
|
|
|
Type *Value::getType() const { return Ctx.getType(Val->getType()); }
|
|
|
|
void Value::replaceUsesWithIf(
|
|
Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
|
|
assert(getType() == OtherV->getType() && "Can't replace with different type");
|
|
llvm::Value *OtherVal = OtherV->Val;
|
|
// We are delegating RUWIf to LLVM IR's RUWIf.
|
|
Val->replaceUsesWithIf(
|
|
OtherVal, [&ShouldReplace, this, OtherV](llvm::Use &LLVMUse) -> bool {
|
|
User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
|
|
if (DstU == nullptr)
|
|
return false;
|
|
Use UseToReplace(&LLVMUse, DstU, Ctx);
|
|
if (!ShouldReplace(UseToReplace))
|
|
return false;
|
|
Ctx.getTracker().emplaceIfTracking<UseSet>(UseToReplace);
|
|
Ctx.runSetUseCallbacks(UseToReplace, OtherV);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
void Value::replaceAllUsesWith(Value *Other) {
|
|
assert(getType() == Other->getType() &&
|
|
"Replacing with Value of different type!");
|
|
auto &Tracker = Ctx.getTracker();
|
|
for (auto Use : uses()) {
|
|
Ctx.runSetUseCallbacks(Use, Other);
|
|
if (Tracker.isTracking())
|
|
Tracker.track(std::make_unique<UseSet>(Use));
|
|
}
|
|
// We are delegating RAUW to LLVM IR's RAUW.
|
|
Val->replaceAllUsesWith(Other->Val);
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
std::string Value::getUid() const {
|
|
std::stringstream SS;
|
|
SS << "SB" << UID << ".";
|
|
return SS.str();
|
|
}
|
|
|
|
void Value::dumpCommonHeader(raw_ostream &OS) const {
|
|
OS << getUid() << " " << getSubclassIDStr(SubclassID) << " ";
|
|
}
|
|
|
|
void Value::dumpCommonFooter(raw_ostream &OS) const {
|
|
OS.indent(2) << "Val: ";
|
|
if (Val)
|
|
OS << *Val;
|
|
else
|
|
OS << "NULL";
|
|
OS << "\n";
|
|
}
|
|
|
|
void Value::dumpCommonPrefix(raw_ostream &OS) const {
|
|
if (Val)
|
|
OS << *Val;
|
|
else
|
|
OS << "NULL ";
|
|
}
|
|
|
|
void Value::dumpCommonSuffix(raw_ostream &OS) const {
|
|
OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")";
|
|
}
|
|
|
|
void Value::printAsOperandCommon(raw_ostream &OS) const {
|
|
if (Val)
|
|
Val->printAsOperand(OS);
|
|
else
|
|
OS << "NULL ";
|
|
}
|
|
|
|
void Value::dump() const {
|
|
dumpOS(dbgs());
|
|
dbgs() << "\n";
|
|
}
|
|
#endif // NDEBUG
|
|
|
|
} // namespace llvm::sandboxir
|