llvm.org GIT mirror llvm / 1518afd
Implement major new fastisel functionality: the matcher can now handle immediates with value constraints on them (when defined as ImmLeaf's). This is particularly important for X86-64, where almost all reg/imm instructions take a i64immSExt32 immediate operand, which has a value constraint. Before this patch we ended up iseling the examples into such amazing code as: movabsq $7, %rax imulq %rax, %rdi movq %rdi, %rax ret now we produce: imulq $7, %rdi, %rax ret This dramatically shrinks the generated code at -O0 on x86-64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129691 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 9 years ago
3 changed file(s) with 255 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
9292 ; CHECK: leal (,%rdi,8), %eax
9393 }
9494
95
96 ; rdar://9289507 - folding of immediates into 64-bit operations.
97 define i64 @test8(i64 %x) nounwind ssp {
98 entry:
99 %add = add nsw i64 %x, 7
100 ret i64 %add
101
102 ; CHECK: test8:
103 ; CHECK: addq $7, %rdi
104 }
105
106 define i64 @test9(i64 %x) nounwind ssp {
107 entry:
108 %add = mul nsw i64 %x, 7
109 ret i64 %add
110 ; CHECK: test9:
111 ; CHECK: imulq $7, %rdi, %rax
112 }
256256 /// isAlwaysTrue - Return true if this is a noop predicate.
257257 bool isAlwaysTrue() const;
258258
259 bool isImmediatePattern() const { return !getImmCode().empty(); }
260
261 /// getImmediatePredicateCode - Return the code that evaluates this pattern if
262 /// this is an immediate predicate. It is an error to call this on a
263 /// non-immediate pattern.
264 std::string getImmediatePredicateCode() const {
265 std::string Result = getImmCode();
266 assert(!Result.empty() && "Isn't an immediate pattern!");
267 return Result;
268 }
269
259270
260271 bool operator==(const TreePredicateFn &RHS) const {
261272 return PatFragRec == RHS.PatFragRec;
3434 std::string SubRegNo;
3535 std::vector* PhysRegs;
3636 };
37
38 /// ImmPredicateSet - This uniques predicates (represented as a string) and
39 /// gives them unique (small) integer ID's that start at 0.
40 class ImmPredicateSet {
41 DenseMap ImmIDs;
42 std::vector PredsByName;
43 public:
44
45 unsigned getIDFor(TreePredicateFn Pred) {
46 unsigned &Entry = ImmIDs[Pred.getOrigPatFragRecord()];
47 if (Entry == 0) {
48 PredsByName.push_back(Pred);
49 Entry = PredsByName.size();
50 }
51 return Entry-1;
52 }
53
54 const TreePredicateFn &getPredicate(unsigned i) {
55 assert(i < PredsByName.size());
56 return PredsByName[i];
57 }
58
59 typedef std::vector::const_iterator iterator;
60 iterator begin() const { return PredsByName.begin(); }
61 iterator end() const { return PredsByName.end(); }
62
63 };
3764
3865 /// OperandsSignature - This class holds a description of a list of operand
3966 /// types. It has utility methods for emitting text based on the operands.
4774 OpKind() : Repr(OK_Invalid) {}
4875
4976 bool operator<(OpKind RHS) const { return Repr < RHS.Repr; }
77 bool operator==(OpKind RHS) const { return Repr == RHS.Repr; }
5078
5179 static OpKind getReg() { OpKind K; K.Repr = OK_Reg; return K; }
5280 static OpKind getFP() { OpKind K; K.Repr = OK_FP; return K; }
53 static OpKind getImm() { OpKind K; K.Repr = OK_Imm; return K; }
81 static OpKind getImm(unsigned V) {
82 assert((unsigned)OK_Imm+V < 128 &&
83 "Too many integer predicates for the 'Repr' char");
84 OpKind K; K.Repr = OK_Imm+V; return K;
85 }
5486
5587 bool isReg() const { return Repr == OK_Reg; }
5688 bool isFP() const { return Repr == OK_FP; }
57 bool isImm() const { return Repr == OK_Imm; }
58
59 void printManglingSuffix(raw_ostream &OS) const {
89 bool isImm() const { return Repr >= OK_Imm; }
90
91 unsigned getImmCode() const { assert(isImm()); return Repr-OK_Imm; }
92
93 void printManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
94 bool StripImmCodes) const {
6095 if (isReg())
6196 OS << 'r';
6297 else if (isFP())
6398 OS << 'f';
64 else
99 else {
65100 OS << 'i';
101 if (!StripImmCodes)
102 if (unsigned Code = getImmCode())
103 OS << "_" << ImmPredicates.getPredicate(Code-1).getFnName();
104 }
66105 }
67106 };
107
68108
69109 SmallVector Operands;
70110
71111 bool operator<(const OperandsSignature &O) const {
72112 return Operands < O.Operands;
73113 }
114 bool operator==(const OperandsSignature &O) const {
115 return Operands == O.Operands;
116 }
74117
75118 bool empty() const { return Operands.empty(); }
76119
120 bool hasAnyImmediateCodes() const {
121 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
122 if (Operands[i].isImm() && Operands[i].getImmCode() != 0)
123 return true;
124 return false;
125 }
126
127 /// getWithoutImmCodes - Return a copy of this with any immediate codes forced
128 /// to zero.
129 OperandsSignature getWithoutImmCodes() const {
130 OperandsSignature Result;
131 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
132 if (!Operands[i].isImm())
133 Result.Operands.push_back(Operands[i]);
134 else
135 Result.Operands.push_back(OpKind::getImm(0));
136 return Result;
137 }
138
139 void emitImmediatePredicate(raw_ostream &OS, ImmPredicateSet &ImmPredicates) {
140 bool EmittedAnything = false;
141 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
142 if (!Operands[i].isImm()) continue;
143
144 unsigned Code = Operands[i].getImmCode();
145 if (Code == 0) continue;
146
147 if (EmittedAnything)
148 OS << " &&\n ";
149
150 TreePredicateFn PredFn = ImmPredicates.getPredicate(Code-1);
151
152 // Emit the type check.
153 OS << "VT == "
154 << getEnumName(PredFn.getOrigPatFragRecord()->getTree(0)->getType(0))
155 << " && ";
156
157
158 OS << PredFn.getFnName() << "(imm" << i <<')';
159 EmittedAnything = true;
160 }
161 }
162
77163 /// initialize - Examine the given pattern and initialize the contents
78164 /// of the Operands array accordingly. Return true if all the operands
79165 /// are supported, false otherwise.
80166 ///
81167 bool initialize(TreePatternNode *InstPatNode, const CodeGenTarget &Target,
82 MVT::SimpleValueType VT) {
83
84 if (!InstPatNode->isLeaf()) {
85 if (InstPatNode->getOperator()->getName() == "imm") {
86 Operands.push_back(OpKind::getImm());
87 return true;
88 }
89 if (InstPatNode->getOperator()->getName() == "fpimm") {
90 Operands.push_back(OpKind::getFP());
91 return true;
92 }
168 MVT::SimpleValueType VT,
169 ImmPredicateSet &ImmediatePredicates) {
170 if (InstPatNode->isLeaf())
171 return false;
172
173 if (InstPatNode->getOperator()->getName() == "imm") {
174 Operands.push_back(OpKind::getImm(0));
175 return true;
176 }
177
178 if (InstPatNode->getOperator()->getName() == "fpimm") {
179 Operands.push_back(OpKind::getFP());
180 return true;
93181 }
94182
95183 const CodeGenRegisterClass *DstRC = 0;
97185 for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
98186 TreePatternNode *Op = InstPatNode->getChild(i);
99187
188 // Handle imm operands specially.
189 if (!Op->isLeaf() && Op->getOperator()->getName() == "imm") {
190 unsigned PredNo = 0;
191 if (!Op->getPredicateFns().empty()) {
192 // If there is more than one predicate weighing in on this operand
193 // then we don't handle it. This doesn't typically happen for
194 // immediates anyway.
195 if (Op->getPredicateFns().size() > 1 ||
196 !Op->getPredicateFns()[0].isImmediatePattern())
197 return false;
198
199 PredNo = ImmediatePredicates.getIDFor(Op->getPredicateFns()[0])+1;
200 }
201
202 // Handle unmatched immediate sizes here.
203 //if (Op->getType(0) != VT)
204 // return false;
205
206 Operands.push_back(OpKind::getImm(PredNo));
207 continue;
208 }
209
210
100211 // For now, filter out any operand with a predicate.
101212 // For now, filter out any operand with multiple values.
102213 if (!Op->getPredicateFns().empty() || Op->getNumTypes() != 1)
103214 return false;
104215
105216 if (!Op->isLeaf()) {
106 if (Op->getOperator()->getName() == "imm") {
107 Operands.push_back(OpKind::getImm());
108 continue;
109 }
110 if (Op->getOperator()->getName() == "fpimm") {
217 if (Op->getOperator()->getName() == "fpimm") {
111218 Operands.push_back(OpKind::getFP());
112219 continue;
113220 }
215322 }
216323
217324
218 void PrintManglingSuffix(raw_ostream &OS,
219 const std::vector &PR) const {
325 void PrintManglingSuffix(raw_ostream &OS, const std::vector &PR,
326 ImmPredicateSet &ImmPredicates,
327 bool StripImmCodes = false) const {
220328 for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
221329 if (PR[i] != "")
222330 // Implicit physical register operand. e.g. Instruction::Mul expect to
225333 // like a binary instruction except for the very inner FastEmitInst_*
226334 // call.
227335 continue;
228 Operands[i].printManglingSuffix(OS);
229 }
230 }
231
232 void PrintManglingSuffix(raw_ostream &OS) const {
336 Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
337 }
338 }
339
340 void PrintManglingSuffix(raw_ostream &OS, ImmPredicateSet &ImmPredicates,
341 bool StripImmCodes = false) const {
233342 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
234 Operands[i].printManglingSuffix(OS);
343 Operands[i].printManglingSuffix(OS, ImmPredicates, StripImmCodes);
235344 }
236345 };
237346
245354
246355 OperandsOpcodeTypeRetPredMap SimplePatterns;
247356
357 std::map >
358 SignaturesWithConstantForms;
359
248360 std::string InstNS;
249
361 ImmPredicateSet ImmediatePredicates;
250362 public:
251363 explicit FastISelMap(std::string InstNS);
252364
253 void CollectPatterns(CodeGenDAGPatterns &CGP);
254 void PrintFunctionDefinitions(raw_ostream &OS);
365 void collectPatterns(CodeGenDAGPatterns &CGP);
366 void printImmediatePredicates(raw_ostream &OS);
367 void printFunctionDefinitions(raw_ostream &OS);
255368 };
256369
257370 }
271384 : InstNS(instns) {
272385 }
273386
274 void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
387 void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) {
275388 const CodeGenTarget &Target = CGP.getTargetInfo();
276389
277390 // Determine the target's namespace name.
360473
361474 // Check all the operands.
362475 OperandsSignature Operands;
363 if (!Operands.initialize(InstPatNode, Target, VT))
476 if (!Operands.initialize(InstPatNode, Target, VT, ImmediatePredicates))
364477 continue;
365478
366479 std::vector* PhysRegInputs = new std::vector();
408521 SubRegNo,
409522 PhysRegInputs
410523 };
411 if (SimplePatterns[Operands][OpcodeName][VT][RetVT]
412 .count(PredicateCheck))
413 throw TGError(Pattern.getSrcRecord()->getLoc(), "Duplicate record!");
524
525 if (SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck))
526 throw TGError(Pattern.getSrcRecord()->getLoc(),
527 "Duplicate record in FastISel table!");
414528
415529 SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo;
530
531 // If any of the operands were immediates with predicates on them, strip
532 // them down to a signature that doesn't have predicates so that we can
533 // associate them with the stripped predicate version.
534 if (Operands.hasAnyImmediateCodes()) {
535 SignaturesWithConstantForms[Operands.getWithoutImmCodes()]
536 .push_back(Operands);
537 }
416538 }
417539 }
418540
419 void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) {
541 void FastISelMap::printImmediatePredicates(raw_ostream &OS) {
542 if (ImmediatePredicates.begin() == ImmediatePredicates.end())
543 return;
544
545 OS << "\n// FastEmit Immediate Predicate functions.\n";
546 for (ImmPredicateSet::iterator I = ImmediatePredicates.begin(),
547 E = ImmediatePredicates.end(); I != E; ++I) {
548 OS << "static bool " << I->getFnName() << "(int64_t Imm) {\n";
549 OS << I->getImmediatePredicateCode() << "\n}\n";
550 }
551
552 OS << "\n\n";
553 }
554
555
556 void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
420557 // Now emit code for all the patterns that we collected.
421558 for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(),
422559 OE = SimplePatterns.end(); OI != OE; ++OI) {
447584 << getLegalCName(Opcode)
448585 << "_" << getLegalCName(getName(VT))
449586 << "_" << getLegalCName(getName(RetVT)) << "_";
450 Operands.PrintManglingSuffix(OS);
587 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
451588 OS << "(";
452589 Operands.PrintParameters(OS);
453590 OS << ") {\n";
478615
479616 OS << " return FastEmitInst_";
480617 if (Memo.SubRegNo.empty()) {
481 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
618 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
619 ImmediatePredicates, true);
482620 OS << "(" << InstNS << Memo.Name << ", ";
483621 OS << InstNS << Memo.RC->getName() << "RegisterClass";
484622 if (!Operands.empty())
487625 OS << ");\n";
488626 } else {
489627 OS << "extractsubreg(" << getName(RetVT);
490 OS << ", Op0, Op0IsKill, ";
491 OS << Memo.SubRegNo;
492 OS << ");\n";
628 OS << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n";
493629 }
494630
495631 if (HasPred)
507643 OS << "unsigned FastEmit_"
508644 << getLegalCName(Opcode) << "_"
509645 << getLegalCName(getName(VT)) << "_";
510 Operands.PrintManglingSuffix(OS);
646 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
511647 OS << "(MVT RetVT";
512648 if (!Operands.empty())
513649 OS << ", ";
519655 OS << " case " << getName(RetVT) << ": return FastEmit_"
520656 << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT))
521657 << "_" << getLegalCName(getName(RetVT)) << "_";
522 Operands.PrintManglingSuffix(OS);
658 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
523659 OS << "(";
524660 Operands.PrintArguments(OS);
525661 OS << ");\n";
531667 OS << "unsigned FastEmit_"
532668 << getLegalCName(Opcode) << "_"
533669 << getLegalCName(getName(VT)) << "_";
534 Operands.PrintManglingSuffix(OS);
670 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
535671 OS << "(MVT RetVT";
536672 if (!Operands.empty())
537673 OS << ", ";
571707 OS << " return FastEmitInst_";
572708
573709 if (Memo.SubRegNo.empty()) {
574 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs);
710 Operands.PrintManglingSuffix(OS, *Memo.PhysRegs,
711 ImmediatePredicates, true);
575712 OS << "(" << InstNS << Memo.Name << ", ";
576713 OS << InstNS << Memo.RC->getName() << "RegisterClass";
577714 if (!Operands.empty())
599736 // Emit one function for the opcode that demultiplexes based on the type.
600737 OS << "unsigned FastEmit_"
601738 << getLegalCName(Opcode) << "_";
602 Operands.PrintManglingSuffix(OS);
739 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
603740 OS << "(MVT VT, MVT RetVT";
604741 if (!Operands.empty())
605742 OS << ", ";
612749 std::string TypeName = getName(VT);
613750 OS << " case " << TypeName << ": return FastEmit_"
614751 << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
615 Operands.PrintManglingSuffix(OS);
752 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
616753 OS << "(RetVT";
617754 if (!Operands.empty())
618755 OS << ", ";
631768 // Emit one function for the operand signature that demultiplexes based
632769 // on opcode and type.
633770 OS << "unsigned FastEmit_";
634 Operands.PrintManglingSuffix(OS);
771 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
635772 OS << "(MVT VT, MVT RetVT, unsigned Opcode";
636773 if (!Operands.empty())
637774 OS << ", ";
638775 Operands.PrintParameters(OS);
639776 OS << ") {\n";
777
778 // If there are any forms of this signature available that operand on
779 // constrained forms of the immediate (e.g. 32-bit sext immediate in a
780 // 64-bit operand), check them first.
781
782 std::map >::iterator MI
783 = SignaturesWithConstantForms.find(Operands);
784 if (MI != SignaturesWithConstantForms.end()) {
785 // Unique any duplicates out of the list.
786 std::sort(MI->second.begin(), MI->second.end());
787 MI->second.erase(std::unique(MI->second.begin(), MI->second.end()),
788 MI->second.end());
789
790 // Check each in order it was seen. It would be nice to have a good
791 // relative ordering between them, but we're not going for optimality
792 // here.
793 for (unsigned i = 0, e = MI->second.size(); i != e; ++i) {
794 OS << " if (";
795 MI->second[i].emitImmediatePredicate(OS, ImmediatePredicates);
796 OS << ")\n if (unsigned Reg = FastEmit_";
797 MI->second[i].PrintManglingSuffix(OS, ImmediatePredicates);
798 OS << "(VT, RetVT, Opcode";
799 if (!MI->second[i].empty())
800 OS << ", ";
801 MI->second[i].PrintArguments(OS);
802 OS << "))\n return Reg;\n\n";
803 }
804
805 // Done with this, remove it.
806 SignaturesWithConstantForms.erase(MI);
807 }
808
640809 OS << " switch (Opcode) {\n";
641810 for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
642811 I != E; ++I) {
644813
645814 OS << " case " << Opcode << ": return FastEmit_"
646815 << getLegalCName(Opcode) << "_";
647 Operands.PrintManglingSuffix(OS);
816 Operands.PrintManglingSuffix(OS, ImmediatePredicates);
648817 OS << "(VT, RetVT";
649818 if (!Operands.empty())
650819 OS << ", ";
656825 OS << "}\n";
657826 OS << "\n";
658827 }
828
829 // TODO: SignaturesWithConstantForms should be empty here.
659830 }
660831
661832 void FastISelEmitter::run(raw_ostream &OS) {
669840 Target.getName() + " target", OS);
670841
671842 FastISelMap F(InstNS);
672 F.CollectPatterns(CGP);
673 F.PrintFunctionDefinitions(OS);
843 F.collectPatterns(CGP);
844 F.printImmediatePredicates(OS);
845 F.printFunctionDefinitions(OS);
674846 }
675847
676848 FastISelEmitter::FastISelEmitter(RecordKeeper &R)
677 : Records(R),
678 CGP(R) {
849 : Records(R), CGP(R) {
679850 }
680851