Skip to content

Commit 66f4e3f

Browse files
[SandboxIR] Implement missing PHINode functions (llvm#101734)
replaceIncomingBlockWith and removeIncomingValueIf are both straightforward and done. I'll defer copyIncomingBlocks until a couple of other changes that also handle blocks go in.
1 parent 642259a commit 66f4e3f

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,12 +1607,11 @@ class PHINode final : public Instruction {
16071607
return cast<llvm::PHINode>(Val)->hasConstantOrUndefValue();
16081608
}
16091609
bool isComplete() const { return cast<llvm::PHINode>(Val)->isComplete(); }
1610-
// TODO: Implement the below functions:
1611-
// void replaceIncomingBlockWith (const BasicBlock *Old, BasicBlock *New);
1610+
void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New);
1611+
void removeIncomingValueIf(function_ref<bool(unsigned)> Predicate);
1612+
// TODO: Implement
16121613
// void copyIncomingBlocks(iterator_range<const_block_iterator> BBRange,
16131614
// uint32_t ToIdx = 0)
1614-
// void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate,
1615-
// bool DeletePHIIfEmpty=true)
16161615
#ifndef NDEBUG
16171616
void verify() const final {
16181617
assert(isa<llvm::PHINode>(Val) && "Expected PHINode!");

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,6 @@ Value *PHINode::removeIncomingValue(unsigned Idx) {
11451145
auto &Tracker = Ctx.getTracker();
11461146
if (Tracker.isTracking())
11471147
Tracker.track(std::make_unique<PHIRemoveIncoming>(*this, Idx, Tracker));
1148-
11491148
llvm::Value *LLVMV =
11501149
cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
11511150
/*DeletePHIIfEmpty=*/false);
@@ -1177,6 +1176,27 @@ Value *PHINode::hasConstantValue() const {
11771176
llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
11781177
return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
11791178
}
1179+
void PHINode::replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) {
1180+
assert(New && Old && "Sandbox IR PHI node got a null basic block!");
1181+
for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
1182+
Idx != NumOps; ++Idx)
1183+
if (getIncomingBlock(Idx) == Old)
1184+
setIncomingBlock(Idx, New);
1185+
}
1186+
void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
1187+
// Avoid duplicate tracking by going through this->removeIncomingValue here at
1188+
// the expense of some performance. Copy PHI::removeIncomingValueIf more
1189+
// directly if performance becomes an issue.
1190+
1191+
// Removing the element at index X, moves the element previously at X + 1
1192+
// to X. Working from the end avoids complications from that.
1193+
unsigned Idx = getNumIncomingValues();
1194+
while (Idx > 0) {
1195+
if (Predicate(Idx - 1))
1196+
removeIncomingValue(Idx - 1);
1197+
--Idx;
1198+
}
1199+
}
11801200

11811201
static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
11821202
switch (Opc) {

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,10 +1925,17 @@ define void @foo(i32 %arg) {
19251925
br label %bb2
19261926
19271927
bb2:
1928-
%phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ]
1928+
%phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ]
19291929
br label %bb2
19301930
19311931
bb3:
1932+
br label %bb2
1933+
1934+
bb4:
1935+
br label %bb2
1936+
1937+
bb5:
1938+
br label %bb2
19321939
ret void
19331940
}
19341941
)IR");
@@ -2023,7 +2030,29 @@ define void @foo(i32 %arg) {
20232030
EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue());
20242031
// Check isComplete().
20252032
EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete());
2026-
2033+
// Check replaceIncomingValueIf
2034+
EXPECT_EQ(PHI->getNumIncomingValues(), 5u);
2035+
auto *RemainBB0 = PHI->getIncomingBlock(0);
2036+
auto *RemoveBB0 = PHI->getIncomingBlock(1);
2037+
auto *RemainBB1 = PHI->getIncomingBlock(2);
2038+
auto *RemoveBB1 = PHI->getIncomingBlock(3);
2039+
auto *RemainBB2 = PHI->getIncomingBlock(4);
2040+
PHI->removeIncomingValueIf([&](unsigned Idx) {
2041+
return PHI->getIncomingBlock(Idx) == RemoveBB0 ||
2042+
PHI->getIncomingBlock(Idx) == RemoveBB1;
2043+
});
2044+
EXPECT_EQ(PHI->getNumIncomingValues(), 3u);
2045+
EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0);
2046+
EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
2047+
EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
2048+
// Check replaceIncomingBlockWith
2049+
OrigBB = RemainBB0;
2050+
auto *NewBB = RemainBB1;
2051+
EXPECT_NE(NewBB, OrigBB);
2052+
PHI->replaceIncomingBlockWith(OrigBB, NewBB);
2053+
EXPECT_EQ(PHI->getIncomingBlock(0), NewBB);
2054+
EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
2055+
EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
20272056
// Check create().
20282057
auto *NewPHI = cast<sandboxir::PHINode>(
20292058
sandboxir::PHINode::create(PHI->getType(), 0, Br, Ctx, "NewPHI"));

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,15 @@ define void @foo(i8 %arg0, i8 %arg1, i8 %arg2) {
779779
EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
780780
EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
781781

782+
// Check removeIncomingValueIf(FromBB1).
783+
Ctx.save();
784+
PHI->removeIncomingValueIf(
785+
[&](unsigned Idx) { return PHI->getIncomingBlock(Idx) == BB1; });
786+
EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
787+
Ctx.revert();
788+
EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
789+
EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
790+
EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
782791
// Check removeIncomingValue() remove all.
783792
Ctx.save();
784793
PHI->removeIncomingValue(0u);

0 commit comments

Comments
 (0)