forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SandboxIR][NFC] Move BasicBlock class into a separate file (llvm#110194
- Loading branch information
Showing
6 changed files
with
280 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
//===- BasicBlock.h ---------------------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_SANDBOXIR_BASICBLOCK_H | ||
#define LLVM_SANDBOXIR_BASICBLOCK_H | ||
|
||
#include "llvm/IR/BasicBlock.h" | ||
#include "llvm/SandboxIR/Value.h" | ||
|
||
namespace llvm::sandboxir { | ||
|
||
class BasicBlock; | ||
class Function; | ||
class Instruction; | ||
|
||
/// Iterator for `Instruction`s in a `BasicBlock. | ||
/// \Returns an sandboxir::Instruction & when derereferenced. | ||
class BBIterator { | ||
public: | ||
using difference_type = std::ptrdiff_t; | ||
using value_type = Instruction; | ||
using pointer = value_type *; | ||
using reference = value_type &; | ||
using iterator_category = std::bidirectional_iterator_tag; | ||
|
||
private: | ||
llvm::BasicBlock *BB; | ||
llvm::BasicBlock::iterator It; | ||
Context *Ctx; | ||
pointer getInstr(llvm::BasicBlock::iterator It) const; | ||
|
||
public: | ||
BBIterator() : BB(nullptr), Ctx(nullptr) {} | ||
BBIterator(llvm::BasicBlock *BB, llvm::BasicBlock::iterator It, Context *Ctx) | ||
: BB(BB), It(It), Ctx(Ctx) {} | ||
reference operator*() const { return *getInstr(It); } | ||
BBIterator &operator++(); | ||
BBIterator operator++(int) { | ||
auto Copy = *this; | ||
++*this; | ||
return Copy; | ||
} | ||
BBIterator &operator--(); | ||
BBIterator operator--(int) { | ||
auto Copy = *this; | ||
--*this; | ||
return Copy; | ||
} | ||
bool operator==(const BBIterator &Other) const { | ||
assert(Ctx == Other.Ctx && "BBIterators in different context!"); | ||
return It == Other.It; | ||
} | ||
bool operator!=(const BBIterator &Other) const { return !(*this == Other); } | ||
/// \Returns the SBInstruction that corresponds to this iterator, or null if | ||
/// the instruction is not found in the IR-to-SandboxIR tables. | ||
pointer get() const { return getInstr(It); } | ||
/// \Returns the parent BB. | ||
BasicBlock *getNodeParent() const; | ||
}; | ||
|
||
/// Contains a list of sandboxir::Instruction's. | ||
class BasicBlock : public Value { | ||
/// Builds a graph that contains all values in \p BB in their original form | ||
/// i.e., no vectorization is taking place here. | ||
void buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB); | ||
friend class Context; // For `buildBasicBlockFromIR` | ||
friend class Instruction; // For LLVM Val. | ||
|
||
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx) | ||
: Value(ClassID::Block, BB, SBCtx) { | ||
buildBasicBlockFromLLVMIR(BB); | ||
} | ||
|
||
public: | ||
~BasicBlock() = default; | ||
/// For isa/dyn_cast. | ||
static bool classof(const Value *From) { | ||
return From->getSubclassID() == Value::ClassID::Block; | ||
} | ||
Function *getParent() const; | ||
using iterator = BBIterator; | ||
iterator begin() const; | ||
iterator end() const { | ||
auto *BB = cast<llvm::BasicBlock>(Val); | ||
return iterator(BB, BB->end(), &Ctx); | ||
} | ||
std::reverse_iterator<iterator> rbegin() const { | ||
return std::make_reverse_iterator(end()); | ||
} | ||
std::reverse_iterator<iterator> rend() const { | ||
return std::make_reverse_iterator(begin()); | ||
} | ||
Context &getContext() const { return Ctx; } | ||
Instruction *getTerminator() const; | ||
bool empty() const { return begin() == end(); } | ||
Instruction &front() const; | ||
Instruction &back() const; | ||
|
||
#ifndef NDEBUG | ||
void verify() const final; | ||
void dumpOS(raw_ostream &OS) const final; | ||
#endif | ||
}; | ||
|
||
} // namespace llvm::sandboxir | ||
|
||
#endif // LLVM_SANDBOXIR_BASICBLOCK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
//===- BasicBlock.cpp - The BasicBlock class of Sandbox IR ----------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/SandboxIR/BasicBlock.h" | ||
#include "llvm/SandboxIR/Context.h" | ||
#include "llvm/SandboxIR/SandboxIR.h" // TODO: remove this | ||
|
||
namespace llvm::sandboxir { | ||
|
||
BBIterator &BBIterator::operator++() { | ||
auto ItE = BB->end(); | ||
assert(It != ItE && "Already at end!"); | ||
++It; | ||
if (It == ItE) | ||
return *this; | ||
Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It)); | ||
unsigned Num = NextI.getNumOfIRInstrs(); | ||
assert(Num > 0 && "Bad getNumOfIRInstrs()"); | ||
It = std::next(It, Num - 1); | ||
return *this; | ||
} | ||
|
||
BBIterator &BBIterator::operator--() { | ||
assert(It != BB->begin() && "Already at begin!"); | ||
if (It == BB->end()) { | ||
--It; | ||
return *this; | ||
} | ||
Instruction &CurrI = **this; | ||
unsigned Num = CurrI.getNumOfIRInstrs(); | ||
assert(Num > 0 && "Bad getNumOfIRInstrs()"); | ||
assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!"); | ||
It = std::prev(It, Num); | ||
return *this; | ||
} | ||
|
||
BasicBlock *BBIterator::getNodeParent() const { | ||
llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent(); | ||
return cast<BasicBlock>(Ctx->getValue(Parent)); | ||
} | ||
|
||
BasicBlock::iterator::pointer | ||
BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const { | ||
return cast_or_null<Instruction>(Ctx->getValue(&*It)); | ||
} | ||
|
||
Function *BasicBlock::getParent() const { | ||
auto *BB = cast<llvm::BasicBlock>(Val); | ||
auto *F = BB->getParent(); | ||
if (F == nullptr) | ||
// Detached | ||
return nullptr; | ||
return cast_or_null<Function>(Ctx.getValue(F)); | ||
} | ||
|
||
void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) { | ||
for (llvm::Instruction &IRef : reverse(*LLVMBB)) { | ||
llvm::Instruction *I = &IRef; | ||
Ctx.getOrCreateValue(I); | ||
for (auto [OpIdx, Op] : enumerate(I->operands())) { | ||
// Skip instruction's label operands | ||
if (isa<llvm::BasicBlock>(Op)) | ||
continue; | ||
// Skip metadata | ||
if (isa<llvm::MetadataAsValue>(Op)) | ||
continue; | ||
// Skip asm | ||
if (isa<llvm::InlineAsm>(Op)) | ||
continue; | ||
Ctx.getOrCreateValue(Op); | ||
} | ||
} | ||
#if !defined(NDEBUG) | ||
verify(); | ||
#endif | ||
} | ||
|
||
BasicBlock::iterator BasicBlock::begin() const { | ||
llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val); | ||
llvm::BasicBlock::iterator It = BB->begin(); | ||
if (!BB->empty()) { | ||
auto *V = Ctx.getValue(&*BB->begin()); | ||
assert(V != nullptr && "No SandboxIR for BB->begin()!"); | ||
auto *I = cast<Instruction>(V); | ||
unsigned Num = I->getNumOfIRInstrs(); | ||
assert(Num >= 1u && "Bad getNumOfIRInstrs()"); | ||
It = std::next(It, Num - 1); | ||
} | ||
return iterator(BB, It, &Ctx); | ||
} | ||
|
||
Instruction *BasicBlock::getTerminator() const { | ||
auto *TerminatorV = | ||
Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator()); | ||
return cast_or_null<Instruction>(TerminatorV); | ||
} | ||
|
||
Instruction &BasicBlock::front() const { | ||
auto *BB = cast<llvm::BasicBlock>(Val); | ||
assert(!BB->empty() && "Empty block!"); | ||
auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin())); | ||
assert(SBI != nullptr && "Expected Instr!"); | ||
return *SBI; | ||
} | ||
|
||
Instruction &BasicBlock::back() const { | ||
auto *BB = cast<llvm::BasicBlock>(Val); | ||
assert(!BB->empty() && "Empty block!"); | ||
auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin())); | ||
assert(SBI != nullptr && "Expected Instr!"); | ||
return *SBI; | ||
} | ||
|
||
#ifndef NDEBUG | ||
void BasicBlock::dumpOS(raw_ostream &OS) const { | ||
llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val); | ||
const auto &Name = BB->getName(); | ||
OS << Name; | ||
if (!Name.empty()) | ||
OS << ":\n"; | ||
// If there are Instructions in the BB that are not mapped to SandboxIR, then | ||
// use a crash-proof dump. | ||
if (any_of(*BB, [this](llvm::Instruction &I) { | ||
return Ctx.getValue(&I) == nullptr; | ||
})) { | ||
OS << "<Crash-proof mode!>\n"; | ||
DenseSet<Instruction *> Visited; | ||
for (llvm::Instruction &IRef : *BB) { | ||
Value *SBV = Ctx.getValue(&IRef); | ||
if (SBV == nullptr) | ||
OS << IRef << " *** No SandboxIR ***\n"; | ||
else { | ||
auto *SBI = dyn_cast<Instruction>(SBV); | ||
if (SBI == nullptr) { | ||
OS << IRef << " *** Not a SBInstruction!!! ***\n"; | ||
} else { | ||
if (Visited.insert(SBI).second) | ||
OS << *SBI << "\n"; | ||
} | ||
} | ||
} | ||
} else { | ||
for (auto &SBI : *this) { | ||
SBI.dumpOS(OS); | ||
OS << "\n"; | ||
} | ||
} | ||
} | ||
|
||
void BasicBlock::verify() const { | ||
assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!"); | ||
for (const auto &I : *this) { | ||
I.verify(); | ||
} | ||
} | ||
#endif // NDEBUG | ||
|
||
} // namespace llvm::sandboxir |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
add_llvm_component_library(LLVMSandboxIR | ||
Argument.cpp | ||
BasicBlock.cpp | ||
Constant.cpp | ||
Context.cpp | ||
Module.cpp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.