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