@@ -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