llvm.org GIT mirror llvm / 46bbc7c
New Revision: 155749 URL: http://llvm.org/viewvc/llvm-project?rev=155749&view=rev Log: Reapply 155668: Fix the SD scheduler to avoid gluing the same node twice. This time, also fix the caller of AddGlue to properly handle incomplete chains. AddGlue had failure modes, but shamefully hid them from its caller. It's luck ran out. Fixes rdar://11314175: BuildSchedUnits assert. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_31@156376 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 8 years ago
1 changed file(s) with 59 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
130130 }
131131 }
132132
133 static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
134 SmallVector VTs;
135 SDNode *GlueDestNode = Glue.getNode();
136
137 // Don't add glue from a node to itself.
138 if (GlueDestNode == N) return;
139
140 // Don't add glue to something that already has it, either as a use or value.
141 if (N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue ||
142 N->getValueType(N->getNumValues() - 1) == MVT::Glue) {
143 return;
144 }
145 for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
146 VTs.push_back(N->getValueType(I));
147
148 if (AddGlue)
149 VTs.push_back(MVT::Glue);
150
133 // Helper for AddGlue to clone node operands.
134 static void CloneNodeWithValues(SDNode *N, SelectionDAG *DAG,
135 SmallVectorImpl &VTs,
136 SDValue ExtraOper = SDValue()) {
151137 SmallVector Ops;
152138 for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
153139 Ops.push_back(N->getOperand(I));
154140
155 if (GlueDestNode)
156 Ops.push_back(Glue);
141 if (ExtraOper.getNode())
142 Ops.push_back(ExtraOper);
157143
158144 SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size());
159145 MachineSDNode::mmo_iterator Begin = 0, End = 0;
170156 // Reset the memory references
171157 if (MN)
172158 MN->setMemRefs(Begin, End);
159 }
160
161 static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) {
162 SmallVector VTs;
163 SDNode *GlueDestNode = Glue.getNode();
164
165 // Don't add glue from a node to itself.
166 if (GlueDestNode == N) return false;
167
168 // Don't add a glue operand to something that already uses glue.
169 if (GlueDestNode &&
170 N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) {
171 return false;
172 }
173 // Don't add glue to something that already has a glue value.
174 if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return false;
175
176 for (unsigned I = 0, E = N->getNumValues(); I != E; ++I)
177 VTs.push_back(N->getValueType(I));
178
179 if (AddGlue)
180 VTs.push_back(MVT::Glue);
181
182 CloneNodeWithValues(N, DAG, VTs, Glue);
183
184 return true;
185 }
186
187 // Cleanup after unsuccessful AddGlue. Use the standard method of morphing the
188 // node even though simply shrinking the value list is sufficient.
189 static void RemoveUnusedGlue(SDNode *N, SelectionDAG *DAG) {
190 assert((N->getValueType(N->getNumValues() - 1) == MVT::Glue &&
191 !N->hasAnyUseOfValue(N->getNumValues() - 1)) &&
192 "expected an unused glue value");
193
194 SmallVector VTs;
195 for (unsigned I = 0, E = N->getNumValues()-1; I != E; ++I)
196 VTs.push_back(N->getValueType(I));
197
198 CloneNodeWithValues(N, DAG, VTs);
173199 }
174200
175201 /// ClusterNeighboringLoads - Force nearby loads together by "gluing" them.
239265 // Cluster loads by adding MVT::Glue outputs and inputs. This also
240266 // ensure they are scheduled in order of increasing addresses.
241267 SDNode *Lead = Loads[0];
242 AddGlue(Lead, SDValue(0, 0), true, DAG);
243
244 SDValue InGlue = SDValue(Lead, Lead->getNumValues() - 1);
268 SDValue InGlue = SDValue(0, 0);
269 if (AddGlue(Lead, InGlue, true, DAG))
270 InGlue = SDValue(Lead, Lead->getNumValues() - 1);
245271 for (unsigned I = 1, E = Loads.size(); I != E; ++I) {
246272 bool OutGlue = I < E - 1;
247273 SDNode *Load = Loads[I];
248274
249 AddGlue(Load, InGlue, OutGlue, DAG);
250
251 if (OutGlue)
252 InGlue = SDValue(Load, Load->getNumValues() - 1);
253
254 ++LoadsClustered;
275 // If AddGlue fails, we could leave an unsused glue value. This should not
276 // cause any
277 if (AddGlue(Load, InGlue, OutGlue, DAG)) {
278 if (OutGlue)
279 InGlue = SDValue(Load, Load->getNumValues() - 1);
280
281 ++LoadsClustered;
282 }
283 else if (!OutGlue && InGlue.getNode())
284 RemoveUnusedGlue(InGlue.getNode(), DAG);
255285 }
256286 }
257287