| 1 | //===- Value.cpp - The Value class of Sandbox IR --------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/SandboxIR/Value.h" |
| 10 | #include "llvm/SandboxIR/Context.h" |
| 11 | #include "llvm/SandboxIR/User.h" |
| 12 | #include <sstream> |
| 13 | |
| 14 | namespace llvm::sandboxir { |
| 15 | |
| 16 | Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx) |
| 17 | : SubclassID(SubclassID), Val(Val), Ctx(Ctx) { |
| 18 | #ifndef NDEBUG |
| 19 | UID = Ctx.getNumValues(); |
| 20 | #endif |
| 21 | } |
| 22 | |
| 23 | Value::use_iterator Value::use_begin() { |
| 24 | llvm::Use *LLVMUse = nullptr; |
| 25 | if (Val->use_begin() != Val->use_end()) |
| 26 | LLVMUse = &*Val->use_begin(); |
| 27 | User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Val: Ctx.getValue( |
| 28 | V: Val->use_begin()->getUser())) |
| 29 | : nullptr; |
| 30 | return use_iterator(Use(LLVMUse, User, Ctx)); |
| 31 | } |
| 32 | |
| 33 | Value::user_iterator Value::user_begin() { |
| 34 | auto UseBegin = Val->use_begin(); |
| 35 | auto UseEnd = Val->use_end(); |
| 36 | bool AtEnd = UseBegin == UseEnd; |
| 37 | llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin; |
| 38 | User *User = |
| 39 | AtEnd ? nullptr |
| 40 | : cast_or_null<sandboxir::User>(Val: Ctx.getValue(V: &*LLVMUse->getUser())); |
| 41 | return user_iterator(Use(LLVMUse, User, Ctx), UseToUser()); |
| 42 | } |
| 43 | |
| 44 | unsigned Value::getNumUses() const { return range_size(Range: Val->users()); } |
| 45 | |
| 46 | Type *Value::getType() const { return Ctx.getType(LLVMTy: Val->getType()); } |
| 47 | |
| 48 | void Value::replaceUsesWithIf( |
| 49 | Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) { |
| 50 | assert(getType() == OtherV->getType() && "Can't replace with different type" ); |
| 51 | llvm::Value *OtherVal = OtherV->Val; |
| 52 | // We are delegating RUWIf to LLVM IR's RUWIf. |
| 53 | Val->replaceUsesWithIf( |
| 54 | New: OtherVal, ShouldReplace: [&ShouldReplace, this, OtherV](llvm::Use &LLVMUse) -> bool { |
| 55 | User *DstU = cast_or_null<User>(Val: Ctx.getValue(V: LLVMUse.getUser())); |
| 56 | if (DstU == nullptr) |
| 57 | return false; |
| 58 | Use UseToReplace(&LLVMUse, DstU, Ctx); |
| 59 | if (!ShouldReplace(UseToReplace)) |
| 60 | return false; |
| 61 | Ctx.getTracker().emplaceIfTracking<UseSet>(Args: UseToReplace); |
| 62 | Ctx.runSetUseCallbacks(U: UseToReplace, NewSrc: OtherV); |
| 63 | return true; |
| 64 | }); |
| 65 | } |
| 66 | |
| 67 | void Value::replaceAllUsesWith(Value *Other) { |
| 68 | assert(getType() == Other->getType() && |
| 69 | "Replacing with Value of different type!" ); |
| 70 | auto &Tracker = Ctx.getTracker(); |
| 71 | for (auto Use : uses()) { |
| 72 | Ctx.runSetUseCallbacks(U: Use, NewSrc: Other); |
| 73 | if (Tracker.isTracking()) |
| 74 | Tracker.track(Change: std::make_unique<UseSet>(args&: Use)); |
| 75 | } |
| 76 | // We are delegating RAUW to LLVM IR's RAUW. |
| 77 | Val->replaceAllUsesWith(V: Other->Val); |
| 78 | } |
| 79 | |
| 80 | #ifndef NDEBUG |
| 81 | std::string Value::getUid() const { |
| 82 | std::stringstream SS; |
| 83 | SS << "SB" << UID << "." ; |
| 84 | return SS.str(); |
| 85 | } |
| 86 | |
| 87 | void Value::dumpCommonHeader(raw_ostream &OS) const { |
| 88 | OS << getUid() << " " << getSubclassIDStr(SubclassID) << " " ; |
| 89 | } |
| 90 | |
| 91 | void Value::dumpCommonFooter(raw_ostream &OS) const { |
| 92 | OS.indent(2) << "Val: " ; |
| 93 | if (Val) |
| 94 | OS << *Val; |
| 95 | else |
| 96 | OS << "NULL" ; |
| 97 | OS << "\n" ; |
| 98 | } |
| 99 | |
| 100 | void Value::dumpCommonPrefix(raw_ostream &OS) const { |
| 101 | if (Val) |
| 102 | OS << *Val; |
| 103 | else |
| 104 | OS << "NULL " ; |
| 105 | } |
| 106 | |
| 107 | void Value::dumpCommonSuffix(raw_ostream &OS) const { |
| 108 | OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")" ; |
| 109 | } |
| 110 | |
| 111 | void Value::printAsOperandCommon(raw_ostream &OS) const { |
| 112 | if (Val) |
| 113 | Val->printAsOperand(OS); |
| 114 | else |
| 115 | OS << "NULL " ; |
| 116 | } |
| 117 | |
| 118 | void Value::dump() const { |
| 119 | dumpOS(dbgs()); |
| 120 | dbgs() << "\n" ; |
| 121 | } |
| 122 | #endif // NDEBUG |
| 123 | |
| 124 | } // namespace llvm::sandboxir |
| 125 | |