Skip to content

Commit 6fca138

Browse files
authored
[BasicBlockUtils] Add BasicBlock printer (#163066)
1 parent 1e8834e commit 6fca138

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/IR/BasicBlock.h"
2222
#include "llvm/IR/Dominators.h"
2323
#include "llvm/Support/Compiler.h"
24+
#include "llvm/Support/Printable.h"
2425
#include <cassert>
2526

2627
namespace llvm {
@@ -611,6 +612,10 @@ LLVM_ABI void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder);
611612
// br/brcond/unreachable/ret
612613
LLVM_ABI bool hasOnlySimpleTerminator(const Function &F);
613614

615+
/// Print BasicBlock \p BB as an operand or print "<nullptr>" if \p BB is a
616+
/// nullptr.
617+
LLVM_ABI Printable printBasicBlock(const BasicBlock *BB);
618+
614619
} // end namespace llvm
615620

616621
#endif // LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,3 +1793,13 @@ bool llvm::hasOnlySimpleTerminator(const Function &F) {
17931793
}
17941794
return true;
17951795
}
1796+
1797+
Printable llvm::printBasicBlock(const BasicBlock *BB) {
1798+
return Printable([BB](raw_ostream &OS) {
1799+
if (!BB) {
1800+
OS << "<nullptr>";
1801+
return;
1802+
}
1803+
BB->printAsOperand(OS);
1804+
});
1805+
}

llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,3 +716,32 @@ attributes #0 = { presplitcoroutine }
716716
EXPECT_FALSE(llvm::isPresplitCoroSuspendExitEdge(
717717
*ExitN.getSinglePredecessor(), ExitN));
718718
}
719+
720+
TEST(BasicBlockUtils, BasicBlockPrintable) {
721+
std::string S;
722+
std::string SCheck;
723+
llvm::raw_string_ostream OS{S};
724+
llvm::raw_string_ostream OSCheck{SCheck};
725+
726+
LLVMContext C;
727+
std::unique_ptr<Module> M = parseIR(C, R"IR(
728+
define void @foo() {
729+
br label %bb0
730+
bb0:
731+
br label %.exit
732+
.exit:
733+
ret void
734+
}
735+
)IR");
736+
737+
Function *F = M->getFunction("foo");
738+
for (const BasicBlock &BB : *F) {
739+
OS << printBasicBlock(&BB);
740+
BB.printAsOperand(OSCheck);
741+
EXPECT_EQ(OS.str(), OSCheck.str());
742+
S.clear();
743+
SCheck.clear();
744+
}
745+
OS << printBasicBlock(nullptr);
746+
EXPECT_EQ(OS.str(), "<nullptr>");
747+
}

0 commit comments

Comments
 (0)