aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td8
-rw-r--r--lib/Target/X86/X86InstrInfo.td9
-rw-r--r--utils/TableGen/FastISelEmitter.cpp12
3 files changed, 23 insertions, 6 deletions
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 552dc84864..3deb0efdaf 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -539,8 +539,14 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
// is preferred over using PatLeaf because it allows the code generator to
// reason more about the constraint.
-class ImmLeaf<ValueType vt, code pred> : PatFrag<(ops), (vt imm)> {
+//
+// If FastIsel should ignore all instructions that have an operand of this type,
+// the FastIselShouldIgnore flag can be set. This is an optimization to reduce
+// the code size of the generated fast instruction selector.
+class ImmLeaf<ValueType vt, code pred>
+ : PatFrag<(ops), (vt imm)> {
let ImmediateCode = pred;
+ bit FastIselShouldIgnore = 0;
}
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index c278e0921e..2b928727f3 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -481,9 +481,12 @@ def X86_COND_O : PatLeaf<(i8 13)>;
def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
def X86_COND_S : PatLeaf<(i8 15)>;
-def i16immSExt8 : ImmLeaf<i16, [{ return Imm == (char)Imm; }]>;
-def i32immSExt8 : ImmLeaf<i32, [{ return Imm == (char)Imm; }]>;
-def i64immSExt8 : ImmLeaf<i64, [{ return Imm == (char)Imm; }]>;
+let FastIselShouldIgnore = 1 in { // FastIsel should ignore all simm8 instrs.
+ def i16immSExt8 : ImmLeaf<i16, [{ return Imm == (char)Imm; }]>;
+ def i32immSExt8 : ImmLeaf<i32, [{ return Imm == (char)Imm; }]>;
+ def i64immSExt8 : ImmLeaf<i64, [{ return Imm == (char)Imm; }]>;
+}
+
def i64immSExt32 : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>;
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index ce821765a2..e3d47aa49a 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -190,14 +190,22 @@ struct OperandsSignature {
if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") {
unsigned PredNo = 0;
if (!Op->getPredicateFns().empty()) {
+ TreePredicateFn PredFn = Op->getPredicateFns()[0];
// If there is more than one predicate weighing in on this operand
// then we don't handle it. This doesn't typically happen for
// immediates anyway.
if (Op->getPredicateFns().size() > 1 ||
- !Op->getPredicateFns()[0].isImmediatePattern())
+ !PredFn.isImmediatePattern())
+ return false;
+ // Ignore any instruction with 'FastIselShouldIgnore', these are
+ // not needed and just bloat the fast instruction selector. For
+ // example, X86 doesn't need to generate code to match ADD16ri8 since
+ // ADD16ri will do just fine.
+ Record *Rec = PredFn.getOrigPatFragRecord()->getRecord();
+ if (Rec->getValueAsBit("FastIselShouldIgnore"))
return false;
- PredNo = ImmediatePredicates.getIDFor(Op->getPredicateFns()[0])+1;
+ PredNo = ImmediatePredicates.getIDFor(PredFn)+1;
}
// Handle unmatched immediate sizes here.