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