Path: blob/main/contrib/llvm-project/llvm/lib/SandboxIR/BasicBlock.cpp
213765 views
//===- BasicBlock.cpp - The BasicBlock class of Sandbox IR ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/SandboxIR/BasicBlock.h"9#include "llvm/SandboxIR/Context.h"10#include "llvm/SandboxIR/Function.h"11#include "llvm/SandboxIR/Instruction.h"1213namespace llvm::sandboxir {1415BBIterator &BBIterator::operator++() {16auto ItE = BB->end();17assert(It != ItE && "Already at end!");18++It;19if (It == ItE)20return *this;21Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));22unsigned Num = NextI.getNumOfIRInstrs();23assert(Num > 0 && "Bad getNumOfIRInstrs()");24It = std::next(It, Num - 1);25return *this;26}2728BBIterator &BBIterator::operator--() {29assert(It != BB->begin() && "Already at begin!");30if (It == BB->end()) {31--It;32return *this;33}34Instruction &CurrI = **this;35unsigned Num = CurrI.getNumOfIRInstrs();36assert(Num > 0 && "Bad getNumOfIRInstrs()");37assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");38It = std::prev(It, Num);39return *this;40}4142BasicBlock *BBIterator::getNodeParent() const {43llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent();44return cast<BasicBlock>(Ctx->getValue(Parent));45}4647BasicBlock::iterator::pointer48BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {49return cast_or_null<Instruction>(Ctx->getValue(&*It));50}5152Function *BasicBlock::getParent() const {53auto *BB = cast<llvm::BasicBlock>(Val);54auto *F = BB->getParent();55if (F == nullptr)56// Detached57return nullptr;58return cast_or_null<Function>(Ctx.getValue(F));59}6061void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {62for (llvm::Instruction &IRef : reverse(*LLVMBB)) {63llvm::Instruction *I = &IRef;64Ctx.getOrCreateValue(I);65for (auto [OpIdx, Op] : enumerate(I->operands())) {66// Skip instruction's label operands67if (isa<llvm::BasicBlock>(Op))68continue;69Ctx.getOrCreateValue(Op);70}71}72#if !defined(NDEBUG)73verify();74#endif75}7677BasicBlock::iterator BasicBlock::begin() const {78llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);79llvm::BasicBlock::iterator It = BB->begin();80if (!BB->empty()) {81auto *V = Ctx.getValue(&*BB->begin());82assert(V != nullptr && "No SandboxIR for BB->begin()!");83auto *I = cast<Instruction>(V);84unsigned Num = I->getNumOfIRInstrs();85assert(Num >= 1u && "Bad getNumOfIRInstrs()");86It = std::next(It, Num - 1);87}88return iterator(BB, It, &Ctx);89}9091Instruction *BasicBlock::getTerminator() const {92auto *TerminatorV =93Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());94return cast_or_null<Instruction>(TerminatorV);95}9697Instruction &BasicBlock::front() const {98auto *BB = cast<llvm::BasicBlock>(Val);99assert(!BB->empty() && "Empty block!");100auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));101assert(SBI != nullptr && "Expected Instr!");102return *SBI;103}104105Instruction &BasicBlock::back() const {106auto *BB = cast<llvm::BasicBlock>(Val);107assert(!BB->empty() && "Empty block!");108auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));109assert(SBI != nullptr && "Expected Instr!");110return *SBI;111}112113#ifndef NDEBUG114void BasicBlock::dumpOS(raw_ostream &OS) const {115llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);116const auto &Name = BB->getName();117OS << Name;118if (!Name.empty())119OS << ":\n";120// If there are Instructions in the BB that are not mapped to SandboxIR, then121// use a crash-proof dump.122if (any_of(*BB, [this](llvm::Instruction &I) {123return Ctx.getValue(&I) == nullptr;124})) {125OS << "<Crash-proof mode!>\n";126DenseSet<Instruction *> Visited;127for (llvm::Instruction &IRef : *BB) {128Value *SBV = Ctx.getValue(&IRef);129if (SBV == nullptr)130OS << IRef << " *** No SandboxIR ***\n";131else {132auto *SBI = dyn_cast<Instruction>(SBV);133if (SBI == nullptr) {134OS << IRef << " *** Not a SBInstruction!!! ***\n";135} else {136if (Visited.insert(SBI).second)137OS << *SBI << "\n";138}139}140}141} else {142for (auto &SBI : *this) {143SBI.dumpOS(OS);144OS << "\n";145}146}147}148149void BasicBlock::verify() const {150assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!");151for (const auto &I : *this) {152I.verify();153}154}155#endif // NDEBUG156157} // namespace llvm::sandboxir158159160