brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · b45c046 Raw
159 lines · cpp
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-exception6//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 14namespace llvm::sandboxir {15 16BBIterator &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 29BBIterator &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 43BasicBlock *BBIterator::getNodeParent() const {44  llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent();45  return cast<BasicBlock>(Ctx->getValue(Parent));46}47 48BasicBlock::iterator::pointer49BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {50  return cast_or_null<Instruction>(Ctx->getValue(&*It));51}52 53Function *BasicBlock::getParent() const {54  auto *BB = cast<llvm::BasicBlock>(Val);55  auto *F = BB->getParent();56  if (F == nullptr)57    // Detached58    return nullptr;59  return cast_or_null<Function>(Ctx.getValue(F));60}61 62void 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 operands68      if (isa<llvm::BasicBlock>(Op))69        continue;70      Ctx.getOrCreateValue(Op);71    }72  }73#if !defined(NDEBUG)74  verify();75#endif76}77 78BasicBlock::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 92Instruction *BasicBlock::getTerminator() const {93  auto *TerminatorV =94      Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());95  return cast_or_null<Instruction>(TerminatorV);96}97 98Instruction &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 106Instruction &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 NDEBUG115void 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, then122  // 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 150void BasicBlock::verify() const {151  assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!");152  for (const auto &I : *this) {153    I.verify();154  }155}156#endif // NDEBUG157 158} // namespace llvm::sandboxir159