Skip to content

Commit 91be65b

Browse files
committed
GlobalISel: Try to make legalize rules more useful for vectors
Mostly keep the existing functions on scalars, but add versions which also operate based on the vector element size. llvm-svn: 353430
1 parent bae220c commit 91be65b

File tree

7 files changed

+323
-38
lines changed

7 files changed

+323
-38
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,27 @@ LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
215215
/// True iff the specified type index is a scalar that's narrower than the given
216216
/// size.
217217
LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
218+
218219
/// True iff the specified type index is a scalar that's wider than the given
219220
/// size.
220221
LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
222+
223+
/// True iff the specified type index is a scalar or vector with an element type
224+
/// that's narrower than the given size.
225+
LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
226+
227+
/// True iff the specified type index is a scalar or a vector with an element
228+
/// type that's wider than the given size.
229+
LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
230+
221231
/// True iff the specified type index is a scalar whose size is not a power of
222232
/// 2.
223233
LegalityPredicate sizeNotPow2(unsigned TypeIdx);
234+
235+
/// True iff the specified type index is a scalar or vector whose element size
236+
/// is not a power of 2.
237+
LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
238+
224239
/// True iff the specified type indices are both the same bit size.
225240
LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
226241
/// True iff the specified MMO index has a size that is not a power of 2
@@ -237,10 +252,20 @@ LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,
237252
namespace LegalizeMutations {
238253
/// Select this specific type for the given type index.
239254
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
255+
240256
/// Keep the same type as the given type index.
241257
LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
242-
/// Widen the type for the given type index to the next power of 2.
243-
LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
258+
259+
/// Keep the same scalar or element type as the given type index.
260+
LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
261+
262+
/// Keep the same scalar or element type as the given type.
263+
LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
264+
265+
/// Widen the scalar type or vector element type for the given type index to the
266+
/// next power of 2.
267+
LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
268+
244269
/// Add more elements to the type for the given type index to the next power of
245270
/// 2.
246271
LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
@@ -618,8 +643,19 @@ class LegalizeRuleSet {
618643
LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
619644
unsigned MinSize = 0) {
620645
using namespace LegalityPredicates;
621-
return actionIf(LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
622-
LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize));
646+
return actionIf(
647+
LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
648+
LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
649+
}
650+
651+
/// Widen the scalar or vector element type to the next power of two that is
652+
/// at least MinSize. No effect if the scalar size is a power of two.
653+
LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
654+
unsigned MinSize = 0) {
655+
using namespace LegalityPredicates;
656+
return actionIf(
657+
LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
658+
LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
623659
}
624660

625661
LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
@@ -634,6 +670,15 @@ class LegalizeRuleSet {
634670
LegalizeMutations::scalarize(TypeIdx));
635671
}
636672

673+
/// Ensure the scalar is at least as wide as Ty.
674+
LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
675+
using namespace LegalityPredicates;
676+
using namespace LegalizeMutations;
677+
return actionIf(LegalizeAction::WidenScalar,
678+
scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
679+
changeElementTo(typeIdx(TypeIdx), Ty));
680+
}
681+
637682
/// Ensure the scalar is at least as wide as Ty.
638683
LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
639684
using namespace LegalityPredicates;
@@ -643,6 +688,15 @@ class LegalizeRuleSet {
643688
changeTo(typeIdx(TypeIdx), Ty));
644689
}
645690

691+
/// Ensure the scalar is at most as wide as Ty.
692+
LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
693+
using namespace LegalityPredicates;
694+
using namespace LegalizeMutations;
695+
return actionIf(LegalizeAction::NarrowScalar,
696+
scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
697+
changeElementTo(typeIdx(TypeIdx), Ty));
698+
}
699+
646700
/// Ensure the scalar is at most as wide as Ty.
647701
LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
648702
using namespace LegalityPredicates;
@@ -659,12 +713,12 @@ class LegalizeRuleSet {
659713
const LLT &Ty) {
660714
using namespace LegalityPredicates;
661715
using namespace LegalizeMutations;
662-
return actionIf(LegalizeAction::NarrowScalar,
663-
[=](const LegalityQuery &Query) {
664-
return widerThan(TypeIdx, Ty.getSizeInBits()) &&
665-
Predicate(Query);
666-
},
667-
changeTo(typeIdx(TypeIdx), Ty));
716+
return actionIf(
717+
LegalizeAction::NarrowScalar,
718+
[=](const LegalityQuery &Query) {
719+
return widerThan(TypeIdx, Ty.getSizeInBits()) && Predicate(Query);
720+
},
721+
changeElementTo(typeIdx(TypeIdx), Ty));
668722
}
669723

670724
/// Limit the range of scalar sizes to MinTy and MaxTy.
@@ -674,6 +728,12 @@ class LegalizeRuleSet {
674728
return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
675729
}
676730

731+
/// Limit the range of scalar sizes to MinTy and MaxTy.
732+
LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT &MinTy,
733+
const LLT &MaxTy) {
734+
return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
735+
}
736+
677737
/// Widen the scalar to match the size of another.
678738
LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
679739
typeIdx(TypeIdx);

llvm/include/llvm/Support/LowLevelTypeImpl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ class LLT {
115115
return isVector() ? getElementType() : *this;
116116
}
117117

118+
/// If this type is a vector, return a vector with the same number of elements
119+
/// but the new element type. Otherwise, return the new element type.
120+
LLT changeElementType(LLT NewEltTy) const {
121+
return isVector() ? LLT::vector(getNumElements(), NewEltTy) : NewEltTy;
122+
}
123+
124+
/// If this type is a vector, return a vector with the same number of elements
125+
/// but the new element size. Otherwise, return the new element type. Invalid
126+
/// for pointer types. For pointer types, use changeElementType.
127+
LLT changeElementSize(unsigned NewEltSize) const {
128+
assert(!getScalarType().isPointer() &&
129+
"invalid to directly change element size for pointers");
130+
return isVector() ? LLT::vector(getNumElements(), NewEltSize)
131+
: LLT::scalar(NewEltSize);
132+
}
133+
118134
unsigned getScalarSizeInBits() const {
119135
assert(RawData != 0 && "Invalid Type");
120136
if (!IsVector) {

llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,22 +79,45 @@ LegalityPredicate LegalityPredicates::isPointer(unsigned TypeIdx,
7979
LegalityPredicate LegalityPredicates::narrowerThan(unsigned TypeIdx,
8080
unsigned Size) {
8181
return [=](const LegalityQuery &Query) {
82-
const LLT &QueryTy = Query.Types[TypeIdx];
82+
const LLT QueryTy = Query.Types[TypeIdx];
8383
return QueryTy.isScalar() && QueryTy.getSizeInBits() < Size;
8484
};
8585
}
8686

8787
LegalityPredicate LegalityPredicates::widerThan(unsigned TypeIdx,
8888
unsigned Size) {
8989
return [=](const LegalityQuery &Query) {
90-
const LLT &QueryTy = Query.Types[TypeIdx];
90+
const LLT QueryTy = Query.Types[TypeIdx];
9191
return QueryTy.isScalar() && QueryTy.getSizeInBits() > Size;
9292
};
9393
}
9494

95+
LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx,
96+
unsigned Size) {
97+
return [=](const LegalityQuery &Query) {
98+
const LLT QueryTy = Query.Types[TypeIdx];
99+
return QueryTy.getScalarSizeInBits() < Size;
100+
};
101+
}
102+
103+
LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx,
104+
unsigned Size) {
105+
return [=](const LegalityQuery &Query) {
106+
const LLT QueryTy = Query.Types[TypeIdx];
107+
return QueryTy.getScalarSizeInBits() > Size;
108+
};
109+
}
110+
111+
LegalityPredicate LegalityPredicates::scalarOrEltSizeNotPow2(unsigned TypeIdx) {
112+
return [=](const LegalityQuery &Query) {
113+
const LLT QueryTy = Query.Types[TypeIdx];
114+
return !isPowerOf2_32(QueryTy.getScalarSizeInBits());
115+
};
116+
}
117+
95118
LegalityPredicate LegalityPredicates::sizeNotPow2(unsigned TypeIdx) {
96119
return [=](const LegalityQuery &Query) {
97-
const LLT &QueryTy = Query.Types[TypeIdx];
120+
const LLT QueryTy = Query.Types[TypeIdx];
98121
return QueryTy.isScalar() && !isPowerOf2_32(QueryTy.getSizeInBits());
99122
};
100123
}

llvm/lib/CodeGen/GlobalISel/LegalizeMutations.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,30 @@ LegalizeMutation LegalizeMutations::changeTo(unsigned TypeIdx,
2626
};
2727
}
2828

29-
LegalizeMutation LegalizeMutations::widenScalarToNextPow2(unsigned TypeIdx,
30-
unsigned Min) {
29+
LegalizeMutation LegalizeMutations::changeElementTo(unsigned TypeIdx,
30+
unsigned FromTypeIdx) {
3131
return [=](const LegalityQuery &Query) {
32-
unsigned NewSizeInBits =
33-
1 << Log2_32_Ceil(Query.Types[TypeIdx].getSizeInBits());
34-
if (NewSizeInBits < Min)
35-
NewSizeInBits = Min;
36-
return std::make_pair(TypeIdx, LLT::scalar(NewSizeInBits));
32+
const LLT OldTy = Query.Types[TypeIdx];
33+
const LLT NewTy = Query.Types[FromTypeIdx];
34+
return std::make_pair(TypeIdx, OldTy.changeElementType(NewTy));
35+
};
36+
}
37+
38+
LegalizeMutation LegalizeMutations::changeElementTo(unsigned TypeIdx,
39+
LLT NewEltTy) {
40+
return [=](const LegalityQuery &Query) {
41+
const LLT OldTy = Query.Types[TypeIdx];
42+
return std::make_pair(TypeIdx, OldTy.changeElementType(NewEltTy));
43+
};
44+
}
45+
46+
LegalizeMutation LegalizeMutations::widenScalarOrEltToNextPow2(unsigned TypeIdx,
47+
unsigned Min) {
48+
return [=](const LegalityQuery &Query) {
49+
const LLT Ty = Query.Types[TypeIdx];
50+
unsigned NewEltSizeInBits =
51+
std::max(1u << Log2_32_Ceil(Ty.getScalarSizeInBits()), Min);
52+
return std::make_pair(TypeIdx, Ty.changeElementSize(NewEltSizeInBits));
3753
};
3854
}
3955

llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -435,29 +435,18 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST,
435435

436436
// FIXME: Doesn't handle extract of illegal sizes.
437437
getActionDefinitionsBuilder({G_EXTRACT, G_INSERT})
438-
.legalIf([=](const LegalityQuery &Query) {
438+
.legalIf([=](const LegalityQuery &Query) {
439439
const LLT &Ty0 = Query.Types[0];
440440
const LLT &Ty1 = Query.Types[1];
441441
return (Ty0.getSizeInBits() % 16 == 0) &&
442442
(Ty1.getSizeInBits() % 16 == 0);
443443
})
444-
.widenScalarIf(
445-
[=](const LegalityQuery &Query) {
446-
const LLT &Ty1 = Query.Types[1];
447-
return (Ty1.getScalarSizeInBits() < 16);
448-
},
449-
// TODO Use generic LegalizeMutation
450-
[](const LegalityQuery &Query) {
451-
LLT Ty1 = Query.Types[1];
452-
unsigned NewEltSizeInBits =
453-
std::max(1 << Log2_32_Ceil(Ty1.getScalarSizeInBits()), 16);
454-
if (Ty1.isVector()) {
455-
return std::make_pair(1, LLT::vector(Ty1.getNumElements(),
456-
NewEltSizeInBits));
457-
}
458-
459-
return std::make_pair(1, LLT::scalar(NewEltSizeInBits));
460-
});
444+
.widenScalarIf(
445+
[=](const LegalityQuery &Query) {
446+
const LLT Ty1 = Query.Types[1];
447+
return (Ty1.getScalarSizeInBits() < 16);
448+
},
449+
LegalizeMutations::widenScalarOrEltToNextPow2(1, 16));
461450

462451
// TODO: vectors of pointers
463452
getActionDefinitionsBuilder(G_BUILD_VECTOR)

0 commit comments

Comments
 (0)