Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/SandboxIR/Region.cpp
213766 views
1
//===- Region.cpp ---------------------------------------------------------===//
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/Region.h"
10
#include "llvm/SandboxIR/Function.h"
11
12
namespace llvm::sandboxir {
13
14
InstructionCost ScoreBoard::getCost(Instruction *I) const {
15
auto *LLVMI = cast<llvm::Instruction>(I->Val);
16
SmallVector<const llvm::Value *> Operands(LLVMI->operands());
17
return TTI.getInstructionCost(LLVMI, Operands, CostKind);
18
}
19
20
void ScoreBoard::remove(Instruction *I) {
21
auto Cost = getCost(I);
22
if (Rgn.contains(I))
23
// If `I` is one the newly added ones, then we should adjust `AfterCost`
24
AfterCost -= Cost;
25
else
26
// If `I` is one of the original instructions (outside the region) then it
27
// is part of the original code, so adjust `BeforeCost`.
28
BeforeCost += Cost;
29
}
30
31
#ifndef NDEBUG
32
void ScoreBoard::dump() const { dump(dbgs()); }
33
#endif
34
35
Region::Region(Context &Ctx, TargetTransformInfo &TTI)
36
: Ctx(Ctx), Scoreboard(*this, TTI) {
37
LLVMContext &LLVMCtx = Ctx.LLVMCtx;
38
auto *RegionStrMD = MDString::get(LLVMCtx, RegionStr);
39
RegionMDN = MDNode::getDistinct(LLVMCtx, {RegionStrMD});
40
41
CreateInstCB = Ctx.registerCreateInstrCallback(
42
[this](Instruction *NewInst) { add(NewInst); });
43
EraseInstCB = Ctx.registerEraseInstrCallback([this](Instruction *ErasedInst) {
44
remove(ErasedInst);
45
removeFromAux(ErasedInst);
46
});
47
}
48
49
Region::~Region() {
50
Ctx.unregisterCreateInstrCallback(CreateInstCB);
51
Ctx.unregisterEraseInstrCallback(EraseInstCB);
52
}
53
54
void Region::addImpl(Instruction *I, bool IgnoreCost) {
55
Insts.insert(I);
56
// TODO: Consider tagging instructions lazily.
57
cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, RegionMDN);
58
if (!IgnoreCost)
59
// Keep track of the instruction cost.
60
Scoreboard.add(I);
61
}
62
63
void Region::setAux(ArrayRef<Instruction *> Aux) {
64
this->Aux = SmallVector<Instruction *>(Aux);
65
auto &LLVMCtx = Ctx.LLVMCtx;
66
for (auto [Idx, I] : enumerate(Aux)) {
67
llvm::ConstantInt *IdxC =
68
llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), Idx, false);
69
assert(cast<llvm::Instruction>(I->Val)->getMetadata(AuxMDKind) == nullptr &&
70
"Instruction already in Aux!");
71
cast<llvm::Instruction>(I->Val)->setMetadata(
72
AuxMDKind, MDNode::get(LLVMCtx, ConstantAsMetadata::get(IdxC)));
73
// Aux instrs should always be in a region.
74
addImpl(I, /*DontTrackCost=*/true);
75
}
76
}
77
78
void Region::setAux(unsigned Idx, Instruction *I) {
79
assert((Idx >= Aux.size() || Aux[Idx] == nullptr) &&
80
"There is already an Instruction at Idx in Aux!");
81
unsigned ExpectedSz = Idx + 1;
82
if (Aux.size() < ExpectedSz) {
83
auto SzBefore = Aux.size();
84
Aux.resize(ExpectedSz);
85
// Initialize the gap with nullptr.
86
for (unsigned Idx = SzBefore; Idx + 1 < ExpectedSz; ++Idx)
87
Aux[Idx] = nullptr;
88
}
89
Aux[Idx] = I;
90
// Aux instrs should always be in a region.
91
addImpl(I, /*DontTrackCost=*/true);
92
}
93
94
void Region::dropAuxMetadata(Instruction *I) {
95
auto *LLVMI = cast<llvm::Instruction>(I->Val);
96
LLVMI->setMetadata(AuxMDKind, nullptr);
97
}
98
99
void Region::removeFromAux(Instruction *I) {
100
auto It = find(Aux, I);
101
if (It == Aux.end())
102
return;
103
dropAuxMetadata(I);
104
Aux.erase(It);
105
}
106
107
void Region::clearAux() {
108
for (unsigned Idx : seq<unsigned>(0, Aux.size()))
109
dropAuxMetadata(Aux[Idx]);
110
Aux.clear();
111
}
112
113
void Region::remove(Instruction *I) {
114
// Keep track of the instruction cost. This need to be done *before* we remove
115
// `I` from the region.
116
Scoreboard.remove(I);
117
118
Insts.remove(I);
119
cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, nullptr);
120
}
121
122
#ifndef NDEBUG
123
bool Region::operator==(const Region &Other) const {
124
if (Insts.size() != Other.Insts.size())
125
return false;
126
if (!std::is_permutation(Insts.begin(), Insts.end(), Other.Insts.begin()))
127
return false;
128
return true;
129
}
130
131
void Region::dump(raw_ostream &OS) const {
132
for (auto *I : Insts)
133
OS << *I << "\n";
134
if (!Aux.empty()) {
135
OS << "\nAux:\n";
136
for (auto *I : Aux) {
137
if (I == nullptr)
138
OS << "NULL\n";
139
else
140
OS << *I << "\n";
141
}
142
}
143
}
144
145
void Region::dump() const {
146
dump(dbgs());
147
dbgs() << "\n";
148
}
149
#endif // NDEBUG
150
151
SmallVector<std::unique_ptr<Region>>
152
Region::createRegionsFromMD(Function &F, TargetTransformInfo &TTI) {
153
SmallVector<std::unique_ptr<Region>> Regions;
154
DenseMap<MDNode *, Region *> MDNToRegion;
155
auto &Ctx = F.getContext();
156
for (BasicBlock &BB : F) {
157
for (Instruction &Inst : BB) {
158
auto *LLVMI = cast<llvm::Instruction>(Inst.Val);
159
Region *R = nullptr;
160
if (auto *MDN = LLVMI->getMetadata(MDKind)) {
161
auto [It, Inserted] = MDNToRegion.try_emplace(MDN);
162
if (Inserted) {
163
Regions.push_back(std::make_unique<Region>(Ctx, TTI));
164
R = Regions.back().get();
165
It->second = R;
166
} else {
167
R = It->second;
168
}
169
R->addImpl(&Inst, /*IgnoreCost=*/true);
170
}
171
if (auto *AuxMDN = LLVMI->getMetadata(AuxMDKind)) {
172
llvm::Constant *IdxC =
173
dyn_cast<ConstantAsMetadata>(AuxMDN->getOperand(0))->getValue();
174
auto Idx = cast<llvm::ConstantInt>(IdxC)->getSExtValue();
175
if (R == nullptr) {
176
errs() << "No region specified for Aux: '" << *LLVMI << "'\n";
177
exit(1);
178
}
179
R->setAux(Idx, &Inst);
180
}
181
}
182
}
183
#ifndef NDEBUG
184
// Check that there are no gaps in the Aux vector.
185
for (auto &RPtr : Regions)
186
for (auto *I : RPtr->getAux())
187
assert(I != nullptr && "Gap in Aux!");
188
#endif
189
return Regions;
190
}
191
192
} // namespace llvm::sandboxir
193
194