diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 552dc84864c..3deb0efdafd 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -539,8 +539,14 @@ class PatLeaf // 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 : 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 + : 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 c278e0921ec..2b928727f37 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; -def i32immSExt8 : ImmLeaf; -def i64immSExt8 : ImmLeaf; +let FastIselShouldIgnore = 1 in { // FastIsel should ignore all simm8 instrs. + def i16immSExt8 : ImmLeaf; + def i32immSExt8 : ImmLeaf; + def i64immSExt8 : ImmLeaf; +} + def i64immSExt32 : ImmLeaf; diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index ce821765a2c..e3d47aa49a0 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.