Skip to content

Commit f925040

Browse files
committed
[TableGen] Move formation of MoveSiblingMatcher earlier in ContractNodes. NFC
ContractNodes recursively walks forward through a linked list. During this recursion, Matchers are combined into other Matchers. Previously the formation of MoveSiblingMatcher was after the recursive call so it occurred as we were unwinding. If a MoveSiblingMatcher was formed, we would recursively walk forward to the end of the linked list again which isn't efficient. To make this more efficient, move the formation of MoveSiblingMatcher to the forward pass. Add additional rules to unfold MoveSiblingMatcher if it would be more efficient to use CheckChildType, CheckChildInteger, CheckChildSame, etc. As an added benefit, this makes the function tail recursive which the compiler can better optimize.
1 parent fec6d16 commit f925040

File tree

1 file changed

+158
-24
lines changed

1 file changed

+158
-24
lines changed

llvm/utils/TableGen/DAGISelMatcherOpt.cpp

Lines changed: 158 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,164 @@ static void ContractNodes(std::unique_ptr<Matcher> &MatcherPtr,
7575
}
7676
}
7777

78+
// Turn MoveParent->MoveChild into MoveSibling.
79+
if (auto *MP = dyn_cast<MoveParentMatcher>(N)) {
80+
if (auto *MC = dyn_cast<MoveChildMatcher>(MP->getNext())) {
81+
auto *MS = new MoveSiblingMatcher(MC->getChildNo());
82+
MS->setNext(MC->takeNext());
83+
MatcherPtr.reset(MS);
84+
return ContractNodes(MatcherPtr, CGP);
85+
}
86+
}
87+
88+
// Uncontract MoveSibling if it will help form other child operations.
89+
if (auto *MS = dyn_cast<MoveSiblingMatcher>(N)) {
90+
if (auto *RM = dyn_cast<RecordMatcher>(MS->getNext())) {
91+
// Turn MoveSibling->Record->MoveParent into MoveParent->RecordChild.
92+
if (auto *MP = dyn_cast<MoveParentMatcher>(RM->getNext())) {
93+
if (MS->getSiblingNo() < 8) { // Only have RecordChild0...7
94+
auto *NewMP = new MoveParentMatcher();
95+
auto *NewRCM = new RecordChildMatcher(
96+
MS->getSiblingNo(), RM->getWhatFor(), RM->getResultNo());
97+
NewMP->setNext(NewRCM);
98+
NewRCM->setNext(MP->takeNext());
99+
MatcherPtr.reset(NewMP);
100+
return ContractNodes(MatcherPtr, CGP);
101+
}
102+
}
103+
104+
// Turn MoveSibling->Record->CheckType->MoveParent into
105+
// MoveParent->RecordChild->CheckChildType.
106+
if (auto *CT = dyn_cast<CheckTypeMatcher>(RM->getNext())) {
107+
if (auto *MP = dyn_cast<MoveParentMatcher>(CT->getNext())) {
108+
if (MS->getSiblingNo() < 8 && // Only have CheckChildType0...7
109+
CT->getResNo() == 0) { // CheckChildType checks res #0
110+
auto *NewMP = new MoveParentMatcher();
111+
auto *NewRCM = new RecordChildMatcher(
112+
MS->getSiblingNo(), RM->getWhatFor(), RM->getResultNo());
113+
auto *NewCCT =
114+
new CheckChildTypeMatcher(MS->getSiblingNo(), CT->getType());
115+
NewMP->setNext(NewRCM);
116+
NewRCM->setNext(NewCCT);
117+
NewCCT->setNext(MP->takeNext());
118+
MatcherPtr.reset(NewMP);
119+
return ContractNodes(MatcherPtr, CGP);
120+
}
121+
}
122+
}
123+
}
124+
125+
// Turn MoveSibling->CheckType->MoveParent into MoveParent->CheckChildType.
126+
if (auto *CT = dyn_cast<CheckTypeMatcher>(MS->getNext())) {
127+
if (auto *MP = dyn_cast<MoveParentMatcher>(CT->getNext())) {
128+
if (MS->getSiblingNo() < 8 && // Only have CheckChildType0...7
129+
CT->getResNo() == 0) { // CheckChildType checks res #0
130+
auto *NewMP = new MoveParentMatcher();
131+
auto *NewCCT =
132+
new CheckChildTypeMatcher(MS->getSiblingNo(), CT->getType());
133+
NewMP->setNext(NewCCT);
134+
NewCCT->setNext(MP->takeNext());
135+
MatcherPtr.reset(NewMP);
136+
return ContractNodes(MatcherPtr, CGP);
137+
}
138+
}
139+
}
140+
141+
// Turn MoveSibling->CheckInteger->MoveParent into
142+
// MoveParent->CheckChildInteger.
143+
if (auto *CI = dyn_cast<CheckIntegerMatcher>(MS->getNext())) {
144+
if (auto *MP = dyn_cast<MoveParentMatcher>(CI->getNext())) {
145+
if (MS->getSiblingNo() < 5) { // Only have CheckChildInteger0...4
146+
auto *NewMP = new MoveParentMatcher();
147+
auto *NewCCI =
148+
new CheckChildIntegerMatcher(MS->getSiblingNo(), CI->getValue());
149+
NewMP->setNext(NewCCI);
150+
NewCCI->setNext(MP->takeNext());
151+
MatcherPtr.reset(NewMP);
152+
return ContractNodes(MatcherPtr, CGP);
153+
}
154+
}
155+
156+
// Turn MoveSibling->CheckInteger->CheckType->MoveParent into
157+
// MoveParent->CheckChildInteger->CheckType.
158+
if (auto *CT = dyn_cast<CheckTypeMatcher>(CI->getNext())) {
159+
if (auto *MP = dyn_cast<MoveParentMatcher>(CT->getNext())) {
160+
if (MS->getSiblingNo() < 5 && // Only have CheckChildInteger0...4
161+
CT->getResNo() == 0) { // CheckChildType checks res #0
162+
auto *NewMP = new MoveParentMatcher();
163+
auto *NewCCI = new CheckChildIntegerMatcher(MS->getSiblingNo(),
164+
CI->getValue());
165+
auto *NewCCT =
166+
new CheckChildTypeMatcher(MS->getSiblingNo(), CT->getType());
167+
NewMP->setNext(NewCCI);
168+
NewCCI->setNext(NewCCT);
169+
NewCCT->setNext(MP->takeNext());
170+
MatcherPtr.reset(NewMP);
171+
return ContractNodes(MatcherPtr, CGP);
172+
}
173+
}
174+
}
175+
}
176+
177+
// Turn MoveSibling->CheckCondCode->MoveParent into
178+
// MoveParent->CheckChild2CondCode.
179+
if (auto *CCC = dyn_cast<CheckCondCodeMatcher>(MS->getNext())) {
180+
if (auto *MP = dyn_cast<MoveParentMatcher>(CCC->getNext())) {
181+
if (MS->getSiblingNo() == 2) { // Only have CheckChild2CondCode
182+
auto *NewMP = new MoveParentMatcher();
183+
auto *NewCCCC =
184+
new CheckChild2CondCodeMatcher(CCC->getCondCodeName());
185+
NewMP->setNext(NewCCCC);
186+
NewCCCC->setNext(MP->takeNext());
187+
MatcherPtr.reset(NewMP);
188+
return ContractNodes(MatcherPtr, CGP);
189+
}
190+
}
191+
}
192+
193+
// Turn MoveSibling->CheckSame->MoveParent into
194+
// MoveParent->CheckChildSame.
195+
if (auto *CS = dyn_cast<CheckSameMatcher>(MS->getNext())) {
196+
if (auto *MP = dyn_cast<MoveParentMatcher>(CS->getNext())) {
197+
if (MS->getSiblingNo() < 4) { // Only have CheckChildSame0...3
198+
auto *NewMP = new MoveParentMatcher();
199+
auto *NewCCS = new CheckChildSameMatcher(MS->getSiblingNo(),
200+
CS->getMatchNumber());
201+
NewMP->setNext(NewCCS);
202+
NewCCS->setNext(MP->takeNext());
203+
MatcherPtr.reset(NewMP);
204+
return ContractNodes(MatcherPtr, CGP);
205+
}
206+
}
207+
208+
// Turn MoveSibling->CheckSame->CheckType->MoveParent into
209+
// MoveParent->CheckChildSame->CheckChildType.
210+
if (auto *CT = dyn_cast<CheckTypeMatcher>(CS->getNext())) {
211+
if (auto *MP = dyn_cast<MoveParentMatcher>(CT->getNext())) {
212+
if (MS->getSiblingNo() < 4 && // Only have CheckChildSame0...3
213+
CT->getResNo() == 0) { // CheckChildType checks res #0
214+
auto *NewMP = new MoveParentMatcher();
215+
auto *NewCCS = new CheckChildSameMatcher(MS->getSiblingNo(),
216+
CS->getMatchNumber());
217+
auto *NewCCT =
218+
new CheckChildTypeMatcher(MS->getSiblingNo(), CT->getType());
219+
NewMP->setNext(NewCCS);
220+
NewCCS->setNext(NewCCT);
221+
NewCCT->setNext(MP->takeNext());
222+
MatcherPtr.reset(NewMP);
223+
return ContractNodes(MatcherPtr, CGP);
224+
}
225+
}
226+
}
227+
}
228+
229+
// Turn MoveSibling->MoveParent into MoveParent.
230+
if (auto *MP = dyn_cast<MoveParentMatcher>(MS->getNext())) {
231+
MatcherPtr.reset(MS->takeNext());
232+
return ContractNodes(MatcherPtr, CGP);
233+
}
234+
}
235+
78236
// Zap movechild -> moveparent.
79237
if (MoveChildMatcher *MC = dyn_cast<MoveChildMatcher>(N))
80238
if (MoveParentMatcher *MP = dyn_cast<MoveParentMatcher>(MC->getNext())) {
@@ -153,30 +311,6 @@ static void ContractNodes(std::unique_ptr<Matcher> &MatcherPtr,
153311
}
154312

155313
ContractNodes(N->getNextPtr(), CGP);
156-
157-
// If we have a MoveParent followed by a MoveChild, we convert it to
158-
// MoveSibling.
159-
if (auto *MP = dyn_cast<MoveParentMatcher>(N)) {
160-
if (auto *MC = dyn_cast<MoveChildMatcher>(MP->getNext())) {
161-
auto *MS = new MoveSiblingMatcher(MC->getChildNo());
162-
MS->setNext(MC->takeNext());
163-
MatcherPtr.reset(MS);
164-
return ContractNodes(MatcherPtr, CGP);
165-
}
166-
if (auto *RC = dyn_cast<RecordChildMatcher>(MP->getNext())) {
167-
if (auto *MC = dyn_cast<MoveChildMatcher>(RC->getNext())) {
168-
if (RC->getChildNo() == MC->getChildNo()) {
169-
auto *MS = new MoveSiblingMatcher(MC->getChildNo());
170-
auto *RM = new RecordMatcher(RC->getWhatFor(), RC->getResultNo());
171-
// Insert the new node.
172-
RM->setNext(MC->takeNext());
173-
MS->setNext(RM);
174-
MatcherPtr.reset(MS);
175-
return ContractNodes(MatcherPtr, CGP);
176-
}
177-
}
178-
}
179-
}
180314
}
181315

182316
/// FindNodeWithKind - Scan a series of matchers looking for a matcher with a

0 commit comments

Comments
 (0)