Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/SandboxIR/BasicBlock.cpp
213765 views
1
//===- BasicBlock.cpp - The BasicBlock 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/BasicBlock.h"
10
#include "llvm/SandboxIR/Context.h"
11
#include "llvm/SandboxIR/Function.h"
12
#include "llvm/SandboxIR/Instruction.h"
13
14
namespace llvm::sandboxir {
15
16
BBIterator &BBIterator::operator++() {
17
auto ItE = BB->end();
18
assert(It != ItE && "Already at end!");
19
++It;
20
if (It == ItE)
21
return *this;
22
Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));
23
unsigned Num = NextI.getNumOfIRInstrs();
24
assert(Num > 0 && "Bad getNumOfIRInstrs()");
25
It = std::next(It, Num - 1);
26
return *this;
27
}
28
29
BBIterator &BBIterator::operator--() {
30
assert(It != BB->begin() && "Already at begin!");
31
if (It == BB->end()) {
32
--It;
33
return *this;
34
}
35
Instruction &CurrI = **this;
36
unsigned Num = CurrI.getNumOfIRInstrs();
37
assert(Num > 0 && "Bad getNumOfIRInstrs()");
38
assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");
39
It = std::prev(It, Num);
40
return *this;
41
}
42
43
BasicBlock *BBIterator::getNodeParent() const {
44
llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent();
45
return cast<BasicBlock>(Ctx->getValue(Parent));
46
}
47
48
BasicBlock::iterator::pointer
49
BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
50
return cast_or_null<Instruction>(Ctx->getValue(&*It));
51
}
52
53
Function *BasicBlock::getParent() const {
54
auto *BB = cast<llvm::BasicBlock>(Val);
55
auto *F = BB->getParent();
56
if (F == nullptr)
57
// Detached
58
return nullptr;
59
return cast_or_null<Function>(Ctx.getValue(F));
60
}
61
62
void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
63
for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
64
llvm::Instruction *I = &IRef;
65
Ctx.getOrCreateValue(I);
66
for (auto [OpIdx, Op] : enumerate(I->operands())) {
67
// Skip instruction's label operands
68
if (isa<llvm::BasicBlock>(Op))
69
continue;
70
Ctx.getOrCreateValue(Op);
71
}
72
}
73
#if !defined(NDEBUG)
74
verify();
75
#endif
76
}
77
78
BasicBlock::iterator BasicBlock::begin() const {
79
llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
80
llvm::BasicBlock::iterator It = BB->begin();
81
if (!BB->empty()) {
82
auto *V = Ctx.getValue(&*BB->begin());
83
assert(V != nullptr && "No SandboxIR for BB->begin()!");
84
auto *I = cast<Instruction>(V);
85
unsigned Num = I->getNumOfIRInstrs();
86
assert(Num >= 1u && "Bad getNumOfIRInstrs()");
87
It = std::next(It, Num - 1);
88
}
89
return iterator(BB, It, &Ctx);
90
}
91
92
Instruction *BasicBlock::getTerminator() const {
93
auto *TerminatorV =
94
Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
95
return cast_or_null<Instruction>(TerminatorV);
96
}
97
98
Instruction &BasicBlock::front() const {
99
auto *BB = cast<llvm::BasicBlock>(Val);
100
assert(!BB->empty() && "Empty block!");
101
auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
102
assert(SBI != nullptr && "Expected Instr!");
103
return *SBI;
104
}
105
106
Instruction &BasicBlock::back() const {
107
auto *BB = cast<llvm::BasicBlock>(Val);
108
assert(!BB->empty() && "Empty block!");
109
auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
110
assert(SBI != nullptr && "Expected Instr!");
111
return *SBI;
112
}
113
114
#ifndef NDEBUG
115
void BasicBlock::dumpOS(raw_ostream &OS) const {
116
llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
117
const auto &Name = BB->getName();
118
OS << Name;
119
if (!Name.empty())
120
OS << ":\n";
121
// If there are Instructions in the BB that are not mapped to SandboxIR, then
122
// use a crash-proof dump.
123
if (any_of(*BB, [this](llvm::Instruction &I) {
124
return Ctx.getValue(&I) == nullptr;
125
})) {
126
OS << "<Crash-proof mode!>\n";
127
DenseSet<Instruction *> Visited;
128
for (llvm::Instruction &IRef : *BB) {
129
Value *SBV = Ctx.getValue(&IRef);
130
if (SBV == nullptr)
131
OS << IRef << " *** No SandboxIR ***\n";
132
else {
133
auto *SBI = dyn_cast<Instruction>(SBV);
134
if (SBI == nullptr) {
135
OS << IRef << " *** Not a SBInstruction!!! ***\n";
136
} else {
137
if (Visited.insert(SBI).second)
138
OS << *SBI << "\n";
139
}
140
}
141
}
142
} else {
143
for (auto &SBI : *this) {
144
SBI.dumpOS(OS);
145
OS << "\n";
146
}
147
}
148
}
149
150
void BasicBlock::verify() const {
151
assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!");
152
for (const auto &I : *this) {
153
I.verify();
154
}
155
}
156
#endif // NDEBUG
157
158
} // namespace llvm::sandboxir
159
160