llvm.org GIT mirror llvm / f690e9b
[FastISel] Permit instructions to be skipped for FastISel generation. Some ISA's such as microMIPS32(R6) have instructions which are near identical for code generation purposes, e.g. xor and xor16. These instructions take the same value types for operands and return values, have the same instruction predicates and map to the same ISD opcode. (These instructions do differ by register classes.) In such cases, the FastISel generator rejects the instruction definition. This patch borrows the 'FastIselShouldIgnore' bit from rL129692 and enables applying it to an instruction definition. Reviewers: mcrosier Differential Revision: https://reviews.llvm.org/D46953 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332983 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Dardis 1 year, 4 months ago
5 changed file(s) with 52 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
567567 /// can be queried via the getNamedOperandIdx() function which is generated
568568 /// by TableGen.
569569 bit UseNamedOperandTable = 0;
570
571 /// Should FastISel ignore this instruction. For certain ISAs, they have
572 /// instructions which map to the same ISD Opcode, value type operands and
573 /// instruction selection predicates. FastISel cannot handle such cases, but
574 /// SelectionDAG can.
575 bit FastISelShouldIgnore = 0;
570576 }
571577
572578 /// PseudoInstExpansion - Expansion information for a pseudo-instruction.
0 // RUN: llvm-tblgen --gen-fast-isel -I %p/../../include %s 2>&1 | FileCheck %s
1
2 include "llvm/Target/Target.td"
3
4 //===- Define the necessary boilerplate for our test target. --------------===//
5
6 def MyTargetISA : InstrInfo;
7 def MyTarget : Target { let InstructionSet = MyTargetISA; }
8
9 def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
10 def R1 : Register<"r0"> { let Namespace = "MyTarget"; }
11 def GPR32M : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
12 def GPR32MOp : RegisterOperand;
13
14 def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0, R1)>;
15 def GPR32Op : RegisterOperand;
16
17 class I Pat> : Instruction {
18 let Namespace = "MyTarget";
19 let OutOperandList = OOps;
20 let InOperandList = IOps;
21 let Pattern = Pat;
22 }
23
24 def HasA : Predicate<"Subtarget->hasA()">;
25
26 let Predicates = [HasA] in {
27
28 def ADD : I<(outs GPR32Op:$rd), (ins GPR32Op:$rs, GPR32Op:$rt),
29 [(set GPR32Op:$rd, (add GPR32Op:$rs, GPR32Op:$rt))]>;
30
31 let FastISelShouldIgnore = 1 in
32 def ADD_M : I<(outs GPR32MOp:$rd), (ins GPR32MOp:$rs, GPR32MOp:$rt),
33 [(set GPR32MOp:$rd, (add GPR32MOp:$rs, GPR32MOp:$rt))]>;
34 }
35
36 // CHECK-NOT: error: Duplicate predicate in FastISel table!
326326 isInsertSubreg = R->getValueAsBit("isInsertSubreg");
327327 isConvergent = R->getValueAsBit("isConvergent");
328328 hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
329 FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
329330
330331 bool Unset;
331332 mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
257257 bool isInsertSubreg : 1;
258258 bool isConvergent : 1;
259259 bool hasNoSchedulingInfo : 1;
260 bool FastISelShouldIgnore : 1;
260261
261262 std::string DeprecatedReason;
262263 bool HasComplexDeprecationPredicate;
450450 continue;
451451 CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
452452 if (II.Operands.empty())
453 continue;
454
455 // Allow instructions to be marked as unavailable for FastISel for
456 // certain cases, i.e. an ISA has two 'and' instruction which differ
457 // by what registers they can use but are otherwise identical for
458 // codegen purposes.
459 if (II.FastISelShouldIgnore)
453460 continue;
454461
455462 // For now, ignore multi-instruction patterns.