aboutsummaryrefslogtreecommitdiff
path: root/test/TableGen
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-04-21 15:59:56 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-04-21 15:59:56 +0000
commite8660ea63d010af3afd8c56812e4602081cf19e4 (patch)
tree2f78f540137b0ec5e727d8673e0ee48f8e2f4b64 /test/TableGen
parent4f4553914f61a7366e121ecb5f7087bb462f35f2 (diff)
downloadllvm-e8660ea63d010af3afd8c56812e4602081cf19e4.tar.gz
[globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
Summary: The SelectionDAG importer now imports rules with Predicate's attached via Requires, PredicateControl, etc. These predicates are implemented as bitset's to allow multiple predicates to be tested together. However, unlike the MC layer subtarget features, each target only pays for it's own predicates (e.g. AArch64 doesn't have 192 feature bits just because X86 needs a lot). Both AArch64 and X86 derive at least one predicate from the MachineFunction or Function so they must re-initialize AvailableFeatures before each function. They also declare locals in <Target>InstructionSelector so that computeAvailableFeatures() can use the code from SelectionDAG without modification. Reviewers: rovka, qcolombet, aditya_nandakumar, t.p.northover, ab Reviewed By: rovka Subscribers: aemerson, rengolin, dberris, kristof.beyls, llvm-commits, igorb Differential Revision: https://reviews.llvm.org/D31418 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300993 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/TableGen')
-rw-r--r--test/TableGen/GlobalISelEmitter.td41
1 files changed, 38 insertions, 3 deletions
diff --git a/test/TableGen/GlobalISelEmitter.td b/test/TableGen/GlobalISelEmitter.td
index 25be435df2d..375af14e876 100644
--- a/test/TableGen/GlobalISelEmitter.td
+++ b/test/TableGen/GlobalISelEmitter.td
@@ -29,7 +29,31 @@ def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
def Z : OperandWithDefaultOps <i32, (ops R0)>;
def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
-//===- Test the function definition boilerplate. --------------------------===//
+def HasA : Predicate<"Subtarget->hasA()">;
+def HasB : Predicate<"Subtarget->hasB()">;
+
+//===- Test the function boilerplate. -------------------------------------===//
+
+// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
+// CHECK-NEXT: Feature_HasABit = 0,
+// CHECK-NEXT: Feature_HasBBit = 1,
+// CHECK-NEXT: };
+
+// CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
+// CHECK-NEXT: "Feature_HasA",
+// CHECK-NEXT: "Feature_HasB",
+// CHECK-NEXT: nullptr
+// CHECK-NEXT: };
+
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
+// CHECK-NEXT: computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
+// CHECK-NEXT: PredicateBitset Features;
+// CHECK-NEXT: if (Subtarget->hasA())
+// CHECK-NEXT: Features[Feature_HasABit] = 1;
+// CHECK-NEXT: if (Subtarget->hasB())
+// CHECK-NEXT: Features[Feature_HasBBit] = 1;
+// CHECK-NEXT: return Features;
+// CHECK-NEXT: }
// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
// CHECK: MachineFunction &MF = *I.getParent()->getParent();
@@ -103,6 +127,9 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
//===- Test a nested instruction match. -----------------------------------===//
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -142,6 +169,9 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
// We also get a second rule by commutativity.
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -181,11 +211,15 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
[(set GPR32:$dst,
- (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>;
+ (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
+ Requires<[HasA]>;
//===- Test another simple pattern with regclass operands. ----------------===//
// CHECK-LABEL: if ([&]() {
+// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
+// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT: return false;
// CHECK-NEXT: MachineInstr &MI0 = I;
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
// CHECK-NEXT: return false;
@@ -213,7 +247,8 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
// CHECK-NEXT: }()) { return true; }
def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
- [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>;
+ [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
+ Requires<[HasA, HasB]>;
//===- Test a pattern with ComplexPattern operands. -----------------------===//
//