Skip to content

Commit 8e768bd

Browse files
committed
[SandboxVec][VecUtils] Implement VecUtils::getLowest()
VecUtils::getLowest(Valse) returns the lowest instruction in the BB among Vals. If the instructions are not in the same BB, or if none of them is an instruction it returns nullptr.
1 parent fd08713 commit 8e768bd

File tree

3 files changed

+79
-13
lines changed

3 files changed

+79
-13
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class VecUtils {
100100
}
101101
return FixedVectorType::get(ElemTy, NumElts);
102102
}
103+
/// \Returns the instruction in \p Instrs that is lowest in the BB. Expects
104+
/// that all instructions are in the same BB.
103105
static Instruction *getLowest(ArrayRef<Instruction *> Instrs) {
104106
Instruction *LowestI = Instrs.front();
105107
for (auto *I : drop_begin(Instrs)) {
@@ -108,6 +110,33 @@ class VecUtils {
108110
}
109111
return LowestI;
110112
}
113+
/// \Returns the lowest instruction in \p Vals, or nullptr if no instructions
114+
/// are found or if not in the same BB.
115+
static Instruction *getLowest(ArrayRef<Value *> Vals) {
116+
// Find the first Instruction in Vals.
117+
auto It = find_if(Vals, [](Value *V) { return isa<Instruction>(V); });
118+
// If we couldn't find an instruction return nullptr.
119+
if (It == Vals.end())
120+
return nullptr;
121+
Instruction *FirstI = cast<Instruction>(*It);
122+
// Now look for the lowest instruction in Vals starting from one position
123+
// after FirstI.
124+
Instruction *LowestI = FirstI;
125+
auto *LowestBB = LowestI->getParent();
126+
for (auto *V : make_range(std::next(It), Vals.end())) {
127+
auto *I = dyn_cast<Instruction>(V);
128+
// Skip non-instructions.
129+
if (I == nullptr)
130+
continue;
131+
// If the instructions are in different BBs return nullptr.
132+
if (I->getParent() != LowestBB)
133+
return nullptr;
134+
// If `LowestI` comes before `I` then `I` is the new lowest.
135+
if (LowestI->comesBefore(I))
136+
LowestI = I;
137+
}
138+
return LowestI;
139+
}
111140
/// If all values in \p Bndl are of the same scalar type then return it,
112141
/// otherwise return nullptr.
113142
static Type *tryGetCommonScalarType(ArrayRef<Value *> Bndl) {

llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ static SmallVector<Value *, 4> getOperand(ArrayRef<Value *> Bndl,
4545

4646
static BasicBlock::iterator
4747
getInsertPointAfterInstrs(ArrayRef<Value *> Instrs) {
48-
// TODO: Use the VecUtils function for getting the bottom instr once it lands.
49-
auto *BotI = cast<Instruction>(
50-
*std::max_element(Instrs.begin(), Instrs.end(), [](auto *V1, auto *V2) {
51-
return cast<Instruction>(V1)->comesBefore(cast<Instruction>(V2));
52-
}));
48+
auto *BotI = VecUtils::getLowest(Instrs);
5349
// If Bndl contains Arguments or Constants, use the beginning of the BB.
5450
return std::next(BotI->getIterator());
5551
}

llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ struct VecUtilsTest : public testing::Test {
5050
}
5151
};
5252

53+
sandboxir::BasicBlock &getBasicBlockByName(sandboxir::Function &F,
54+
StringRef Name) {
55+
for (sandboxir::BasicBlock &BB : F)
56+
if (BB.getName() == Name)
57+
return BB;
58+
llvm_unreachable("Expected to find basic block!");
59+
}
60+
5361
TEST_F(VecUtilsTest, GetNumElements) {
5462
sandboxir::Context Ctx(C);
5563
auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx);
@@ -415,21 +423,33 @@ TEST_F(VecUtilsTest, GetLowest) {
415423
parseIR(R"IR(
416424
define void @foo(i8 %v) {
417425
bb0:
418-
%A = add i8 %v, %v
419-
%B = add i8 %v, %v
420-
%C = add i8 %v, %v
426+
br label %bb1
427+
bb1:
428+
%A = add i8 %v, 1
429+
%B = add i8 %v, 2
430+
%C = add i8 %v, 3
421431
ret void
422432
}
423433
)IR");
424434
Function &LLVMF = *M->getFunction("foo");
425435

426436
sandboxir::Context Ctx(C);
427437
auto &F = *Ctx.createFunction(&LLVMF);
428-
auto &BB = *F.begin();
429-
auto It = BB.begin();
430-
auto *IA = &*It++;
431-
auto *IB = &*It++;
432-
auto *IC = &*It++;
438+
auto &BB0 = getBasicBlockByName(F, "bb0");
439+
auto It = BB0.begin();
440+
auto *BB0I = cast<sandboxir::BranchInst>(&*It++);
441+
442+
auto &BB = getBasicBlockByName(F, "bb1");
443+
It = BB.begin();
444+
auto *IA = cast<sandboxir::Instruction>(&*It++);
445+
auto *C1 = cast<sandboxir::Constant>(IA->getOperand(1));
446+
auto *IB = cast<sandboxir::Instruction>(&*It++);
447+
auto *C2 = cast<sandboxir::Constant>(IB->getOperand(1));
448+
auto *IC = cast<sandboxir::Instruction>(&*It++);
449+
auto *C3 = cast<sandboxir::Constant>(IC->getOperand(1));
450+
// Check getLowest(ArrayRef<Instruction *>)
451+
SmallVector<sandboxir::Instruction *> A({IA});
452+
EXPECT_EQ(sandboxir::VecUtils::getLowest(A), IA);
433453
SmallVector<sandboxir::Instruction *> ABC({IA, IB, IC});
434454
EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC), IC);
435455
SmallVector<sandboxir::Instruction *> ACB({IA, IC, IB});
@@ -438,6 +458,27 @@ define void @foo(i8 %v) {
438458
EXPECT_EQ(sandboxir::VecUtils::getLowest(CAB), IC);
439459
SmallVector<sandboxir::Instruction *> CBA({IC, IB, IA});
440460
EXPECT_EQ(sandboxir::VecUtils::getLowest(CBA), IC);
461+
462+
// Check getLowest(ArrayRef<Value *>)
463+
SmallVector<sandboxir::Value *> C1Only({C1});
464+
EXPECT_EQ(sandboxir::VecUtils::getLowest(C1Only), nullptr);
465+
SmallVector<sandboxir::Value *> AOnly({IA});
466+
EXPECT_EQ(sandboxir::VecUtils::getLowest(AOnly), IA);
467+
SmallVector<sandboxir::Value *> AC1({IA, C1});
468+
EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1), IA);
469+
SmallVector<sandboxir::Value *> C1A({C1, IA});
470+
EXPECT_EQ(sandboxir::VecUtils::getLowest(C1A), IA);
471+
SmallVector<sandboxir::Value *> AC1B({IA, C1, IB});
472+
EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1B), IB);
473+
SmallVector<sandboxir::Value *> ABC1({IA, IB, C1});
474+
EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC1), IB);
475+
SmallVector<sandboxir::Value *> AC1C2({IA, C1, C2});
476+
EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1C2), IA);
477+
SmallVector<sandboxir::Value *> C1C2C3({C1, C2, C3});
478+
EXPECT_EQ(sandboxir::VecUtils::getLowest(C1C2C3), nullptr);
479+
480+
SmallVector<sandboxir::Value *> DiffBBs({BB0I, IA});
481+
EXPECT_EQ(sandboxir::VecUtils::getLowest(DiffBBs), nullptr);
441482
}
442483

443484
TEST_F(VecUtilsTest, GetCommonScalarType) {

0 commit comments

Comments
 (0)