[clang] Add test for CWG190 "Layout-compatible POD-struct types" (#121668)
[llvm-project.git] / llvm / lib / SandboxIR / BasicBlock.cpp
blob983a5e8b8825efc2eef5f805316565dd899accda
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 //===----------------------------------------------------------------------===//
9 #include "llvm/SandboxIR/BasicBlock.h"
10 #include "llvm/SandboxIR/Context.h"
11 #include "llvm/SandboxIR/Function.h"
12 #include "llvm/SandboxIR/Instruction.h"
14 namespace llvm::sandboxir {
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;
29 BBIterator &BBIterator::operator--() {
30 assert(It != BB->begin() && "Already at begin!");
31 if (It == BB->end()) {
32 --It;
33 return *this;
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;
43 BasicBlock *BBIterator::getNodeParent() const {
44 llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent();
45 return cast<BasicBlock>(Ctx->getValue(Parent));
48 BasicBlock::iterator::pointer
49 BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
50 return cast_or_null<Instruction>(Ctx->getValue(&*It));
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));
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 // Skip metadata
71 if (isa<llvm::MetadataAsValue>(Op))
72 continue;
73 // Skip asm
74 if (isa<llvm::InlineAsm>(Op))
75 continue;
76 Ctx.getOrCreateValue(Op);
79 #if !defined(NDEBUG)
80 verify();
81 #endif
84 BasicBlock::iterator BasicBlock::begin() const {
85 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
86 llvm::BasicBlock::iterator It = BB->begin();
87 if (!BB->empty()) {
88 auto *V = Ctx.getValue(&*BB->begin());
89 assert(V != nullptr && "No SandboxIR for BB->begin()!");
90 auto *I = cast<Instruction>(V);
91 unsigned Num = I->getNumOfIRInstrs();
92 assert(Num >= 1u && "Bad getNumOfIRInstrs()");
93 It = std::next(It, Num - 1);
95 return iterator(BB, It, &Ctx);
98 Instruction *BasicBlock::getTerminator() const {
99 auto *TerminatorV =
100 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
101 return cast_or_null<Instruction>(TerminatorV);
104 Instruction &BasicBlock::front() const {
105 auto *BB = cast<llvm::BasicBlock>(Val);
106 assert(!BB->empty() && "Empty block!");
107 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
108 assert(SBI != nullptr && "Expected Instr!");
109 return *SBI;
112 Instruction &BasicBlock::back() const {
113 auto *BB = cast<llvm::BasicBlock>(Val);
114 assert(!BB->empty() && "Empty block!");
115 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
116 assert(SBI != nullptr && "Expected Instr!");
117 return *SBI;
120 #ifndef NDEBUG
121 void BasicBlock::dumpOS(raw_ostream &OS) const {
122 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
123 const auto &Name = BB->getName();
124 OS << Name;
125 if (!Name.empty())
126 OS << ":\n";
127 // If there are Instructions in the BB that are not mapped to SandboxIR, then
128 // use a crash-proof dump.
129 if (any_of(*BB, [this](llvm::Instruction &I) {
130 return Ctx.getValue(&I) == nullptr;
131 })) {
132 OS << "<Crash-proof mode!>\n";
133 DenseSet<Instruction *> Visited;
134 for (llvm::Instruction &IRef : *BB) {
135 Value *SBV = Ctx.getValue(&IRef);
136 if (SBV == nullptr)
137 OS << IRef << " *** No SandboxIR ***\n";
138 else {
139 auto *SBI = dyn_cast<Instruction>(SBV);
140 if (SBI == nullptr) {
141 OS << IRef << " *** Not a SBInstruction!!! ***\n";
142 } else {
143 if (Visited.insert(SBI).second)
144 OS << *SBI << "\n";
148 } else {
149 for (auto &SBI : *this) {
150 SBI.dumpOS(OS);
151 OS << "\n";
156 void BasicBlock::verify() const {
157 assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!");
158 for (const auto &I : *this) {
159 I.verify();
162 #endif // NDEBUG
164 } // namespace llvm::sandboxir