Skip to content

Commit 9e3800d

Browse files
committed
[LV][NFC] Refactor code for extracting first active element
Refactor the code to extract the first active element of a vector in the early exit block, in preparation for PR #130766. I've replaced the VPInstruction::ExtractFirstActive nodes with a combination of a new VPInstruction::FirstActiveLane node and a Instruction::ExtractElement node.
1 parent 055db3e commit 9e3800d

File tree

4 files changed

+33
-19
lines changed

4 files changed

+33
-19
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,8 @@ class VPInstruction : public VPRecipeWithIRFlags,
879879
// Returns a scalar boolean value, which is true if any lane of its (only
880880
// boolean) vector operand is true.
881881
AnyOf,
882-
// Extracts the first active lane of a vector, where the first operand is
883-
// the predicate, and the second operand is the vector to extract.
884-
ExtractFirstActive,
882+
// Calculates the first active lane index of the vector predicate operand.
883+
FirstActiveLane,
885884
};
886885

887886
private:

llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
5050
return SetResultTyFromOp();
5151

5252
switch (Opcode) {
53+
case Instruction::ExtractElement: {
54+
Type *ResTy = inferScalarType(R->getOperand(0));
55+
VPValue *OtherV = R->getOperand(1);
56+
CachedTypes[OtherV] = ResTy;
57+
return ResTy;
58+
}
5359
case Instruction::Select: {
5460
Type *ResTy = inferScalarType(R->getOperand(1));
5561
VPValue *OtherV = R->getOperand(2);
@@ -78,7 +84,8 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
7884
case VPInstruction::CanonicalIVIncrementForPart:
7985
case VPInstruction::AnyOf:
8086
return SetResultTyFromOp();
81-
case VPInstruction::ExtractFirstActive:
87+
case VPInstruction::FirstActiveLane:
88+
return Type::getIntNTy(Ctx, 64);
8289
case VPInstruction::ExtractFromEnd: {
8390
Type *BaseTy = inferScalarType(R->getOperand(0));
8491
if (auto *VecTy = dyn_cast<VectorType>(BaseTy))

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,11 @@ Value *VPInstruction::generate(VPTransformState &State) {
461461
Value *A = State.get(getOperand(0));
462462
return Builder.CreateNot(A, Name);
463463
}
464+
case Instruction::ExtractElement: {
465+
Value *Vec = State.get(getOperand(0));
466+
Value *Idx = State.get(getOperand(1), true);
467+
return Builder.CreateExtractElement(Vec, Idx, Name);
468+
}
464469
case Instruction::ICmp: {
465470
bool OnlyFirstLaneUsed = vputils::onlyFirstLaneUsed(this);
466471
Value *A = State.get(getOperand(0), OnlyFirstLaneUsed);
@@ -705,12 +710,10 @@ Value *VPInstruction::generate(VPTransformState &State) {
705710
Value *A = State.get(getOperand(0));
706711
return Builder.CreateOrReduce(A);
707712
}
708-
case VPInstruction::ExtractFirstActive: {
709-
Value *Vec = State.get(getOperand(0));
710-
Value *Mask = State.get(getOperand(1));
711-
Value *Ctz = Builder.CreateCountTrailingZeroElems(
712-
Builder.getInt64Ty(), Mask, true, "first.active.lane");
713-
return Builder.CreateExtractElement(Vec, Ctz, "early.exit.value");
713+
case VPInstruction::FirstActiveLane: {
714+
Value *Mask = State.get(getOperand(0));
715+
return Builder.CreateCountTrailingZeroElems(Builder.getInt64Ty(), Mask,
716+
true, Name);
714717
}
715718
default:
716719
llvm_unreachable("Unsupported opcode for instruction");
@@ -753,7 +756,8 @@ InstructionCost VPInstruction::computeCost(ElementCount VF,
753756

754757
bool VPInstruction::isVectorToScalar() const {
755758
return getOpcode() == VPInstruction::ExtractFromEnd ||
756-
getOpcode() == VPInstruction::ExtractFirstActive ||
759+
getOpcode() == Instruction::ExtractElement ||
760+
getOpcode() == VPInstruction::FirstActiveLane ||
757761
getOpcode() == VPInstruction::ComputeReductionResult ||
758762
getOpcode() == VPInstruction::AnyOf;
759763
}
@@ -812,13 +816,14 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const {
812816
if (Instruction::isBinaryOp(getOpcode()))
813817
return false;
814818
switch (getOpcode()) {
819+
case Instruction::ExtractElement:
815820
case Instruction::ICmp:
816821
case Instruction::Select:
817822
case VPInstruction::AnyOf:
818823
case VPInstruction::CalculateTripCountMinusVF:
819824
case VPInstruction::CanonicalIVIncrementForPart:
820825
case VPInstruction::ExtractFromEnd:
821-
case VPInstruction::ExtractFirstActive:
826+
case VPInstruction::FirstActiveLane:
822827
case VPInstruction::FirstOrderRecurrenceSplice:
823828
case VPInstruction::LogicalAnd:
824829
case VPInstruction::Not:
@@ -927,7 +932,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
927932
case VPInstruction::Broadcast:
928933
O << "broadcast";
929934
break;
930-
931935
case VPInstruction::ExtractFromEnd:
932936
O << "extract-from-end";
933937
break;
@@ -943,8 +947,8 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
943947
case VPInstruction::AnyOf:
944948
O << "any-of";
945949
break;
946-
case VPInstruction::ExtractFirstActive:
947-
O << "extract-first-active";
950+
case VPInstruction::FirstActiveLane:
951+
O << "first-active-lane";
948952
break;
949953
default:
950954
O << Instruction::getOpcodeName(getOpcode());

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,10 +2157,14 @@ void VPlanTransforms::handleUncountableEarlyExit(
21572157
ExitIRI->extractLastLaneOfOperand(MiddleBuilder);
21582158
}
21592159
// Add the incoming value from the early exit.
2160-
if (!IncomingFromEarlyExit->isLiveIn())
2161-
IncomingFromEarlyExit =
2162-
EarlyExitB.createNaryOp(VPInstruction::ExtractFirstActive,
2163-
{IncomingFromEarlyExit, EarlyExitTakenCond});
2160+
if (!IncomingFromEarlyExit->isLiveIn()) {
2161+
VPValue *FirstActiveLane = EarlyExitB.createNaryOp(
2162+
VPInstruction::FirstActiveLane, {EarlyExitTakenCond}, nullptr,
2163+
"first.active.lane");
2164+
IncomingFromEarlyExit = EarlyExitB.createNaryOp(
2165+
Instruction::ExtractElement, {IncomingFromEarlyExit, FirstActiveLane},
2166+
nullptr, "early.exit.value");
2167+
}
21642168
ExitIRI->addOperand(IncomingFromEarlyExit);
21652169
}
21662170
MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {IsEarlyExitTaken});

0 commit comments

Comments
 (0)