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](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 return true; 63 }); 64 } 65 66 void Value::replaceAllUsesWith(Value *Other) { 67 assert(getType() == Other->getType() && 68 "Replacing with Value of different type!"); 69 auto &Tracker = Ctx.getTracker(); 70 if (Tracker.isTracking()) { 71 for (auto Use : uses()) 72 Tracker.track(std::make_unique<UseSet>(Use)); 73 } 74 // We are delegating RAUW to LLVM IR's RAUW. 75 Val->replaceAllUsesWith(Other->Val); 76 } 77 78 #ifndef NDEBUG 79 std::string Value::getUid() const { 80 std::stringstream SS; 81 SS << "SB" << UID << "."; 82 return SS.str(); 83 } 84 85 void Value::dumpCommonHeader(raw_ostream &OS) const { 86 OS << getUid() << " " << getSubclassIDStr(SubclassID) << " "; 87 } 88 89 void Value::dumpCommonFooter(raw_ostream &OS) const { 90 OS.indent(2) << "Val: "; 91 if (Val) 92 OS << *Val; 93 else 94 OS << "NULL"; 95 OS << "\n"; 96 } 97 98 void Value::dumpCommonPrefix(raw_ostream &OS) const { 99 if (Val) 100 OS << *Val; 101 else 102 OS << "NULL "; 103 } 104 105 void Value::dumpCommonSuffix(raw_ostream &OS) const { 106 OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")"; 107 } 108 109 void Value::printAsOperandCommon(raw_ostream &OS) const { 110 if (Val) 111 Val->printAsOperand(OS); 112 else 113 OS << "NULL "; 114 } 115 116 void Value::dump() const { 117 dumpOS(dbgs()); 118 dbgs() << "\n"; 119 } 120 #endif // NDEBUG 121 122 } // namespace llvm::sandboxir 123