xref: /llvm-project/llvm/lib/SandboxIR/Value.cpp (revision 2018f4ccf28bd017ede1c092ab8de11fa474e68a)
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