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>(Ctx.getValue( 28 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>(Ctx.getValue(&*LLVMUse->getUser())); 41 return user_iterator(Use(LLVMUse, User, Ctx), UseToUser()); 42 } 43 44 unsigned Value::getNumUses() const { return range_size(Val->users()); } 45 46 Type *Value::getType() const { return Ctx.getType(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 OtherVal, [&ShouldReplace, this, OtherV](llvm::Use &LLVMUse) -> bool { 55 User *DstU = cast_or_null<User>(Ctx.getValue(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>(UseToReplace); 62 Ctx.runSetUseCallbacks(UseToReplace, 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(Use, Other); 73 if (Tracker.isTracking()) 74 Tracker.track(std::make_unique<UseSet>(Use)); 75 } 76 // We are delegating RAUW to LLVM IR's RAUW. 77 Val->replaceAllUsesWith(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