diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-04-21 15:59:56 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-04-21 15:59:56 +0000 |
commit | e8660ea63d010af3afd8c56812e4602081cf19e4 (patch) | |
tree | 2f78f540137b0ec5e727d8673e0ee48f8e2f4b64 /test/TableGen | |
parent | 4f4553914f61a7366e121ecb5f7087bb462f35f2 (diff) | |
download | llvm-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.td | 41 |
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. -----------------------===// // |