Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(357)

Side by Side Diff: src/IceOperand.cpp

Issue 650613003: Subzero: Speed up VariablesMetadata initialization. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Split Definitions[] into first plus the rest Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===// 1 //===- subzero/src/IceOperand.cpp - High-level operand implementation -----===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the Operand class and its target-independent 10 // This file implements the Operand class and its target-independent
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 178
179 Variable Variable::asType(Type Ty) { 179 Variable Variable::asType(Type Ty) {
180 // Note: This returns a Variable, even if the "this" object is a 180 // Note: This returns a Variable, even if the "this" object is a
181 // subclass of Variable. 181 // subclass of Variable.
182 Variable V(kVariable, Ty, Number, Name); 182 Variable V(kVariable, Ty, Number, Name);
183 V.RegNum = RegNum; 183 V.RegNum = RegNum;
184 V.StackOffset = StackOffset; 184 V.StackOffset = StackOffset;
185 return V; 185 return V;
186 } 186 }
187 187
188 void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node, 188 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr,
189 bool IsFromDef, bool IsImplicit) { 189 const CfgNode *Node, bool IsFromDef,
190 bool IsImplicit) {
191 (void)TrackingKind;
190 if (MultiBlock == MBS_MultiBlock) 192 if (MultiBlock == MBS_MultiBlock)
191 return; 193 return;
192 // TODO(stichnot): If the use occurs as a source operand in the 194 // TODO(stichnot): If the use occurs as a source operand in the
193 // first instruction of the block, and its definition is in this 195 // first instruction of the block, and its definition is in this
194 // block's only predecessor, we might consider not marking this as a 196 // block's only predecessor, we might consider not marking this as a
195 // separate use. This may also apply if it's the first instruction 197 // separate use. This may also apply if it's the first instruction
196 // of the block that actually uses a Variable. 198 // of the block that actually uses a Variable.
197 assert(Node); 199 assert(Node);
198 bool MakeMulti = false; 200 bool MakeMulti = false;
199 if (IsImplicit) 201 if (IsImplicit)
(...skipping 20 matching lines...) Expand all
220 break; 222 break;
221 } 223 }
222 } 224 }
223 225
224 if (MakeMulti) { 226 if (MakeMulti) {
225 MultiBlock = MBS_MultiBlock; 227 MultiBlock = MBS_MultiBlock;
226 SingleUseNode = NULL; 228 SingleUseNode = NULL;
227 } 229 }
228 } 230 }
229 231
230 void VariableTracking::markDef(const Inst *Instr, const CfgNode *Node) { 232 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr,
233 const CfgNode *Node) {
231 // TODO(stichnot): If the definition occurs in the last instruction 234 // TODO(stichnot): If the definition occurs in the last instruction
232 // of the block, consider not marking this as a separate use. But 235 // of the block, consider not marking this as a separate use. But
233 // be careful not to omit all uses of the variable if markDef() and 236 // be careful not to omit all uses of the variable if markDef() and
234 // markUse() both use this optimization. 237 // markUse() both use this optimization.
235 assert(Node); 238 assert(Node);
236 // Verify that instructions are added in increasing order. 239 // Verify that instructions are added in increasing order.
237 assert(Definitions.empty() || 240 #ifndef NDEBUG
238 Instr->getNumber() >= Definitions.back()->getNumber()); 241 if (TrackingKind == VMK_All) {
239 Definitions.push_back(Instr); 242 const Inst *LastInstruction =
243 Definitions.empty() ? FirstOrSingleDefinition : Definitions.back();
244 assert(LastInstruction == NULL ||
245 Instr->getNumber() >= LastInstruction->getNumber());
246 }
247 #endif
240 const bool IsFromDef = true; 248 const bool IsFromDef = true;
241 const bool IsImplicit = false; 249 const bool IsImplicit = false;
242 markUse(Instr, Node, IsFromDef, IsImplicit); 250 markUse(TrackingKind, Instr, Node, IsFromDef, IsImplicit);
251 if (TrackingKind == VMK_Uses)
252 return;
253 if (FirstOrSingleDefinition == NULL)
254 FirstOrSingleDefinition = Instr;
255 else if (TrackingKind == VMK_All)
256 Definitions.push_back(Instr);
243 switch (MultiDef) { 257 switch (MultiDef) {
244 case MDS_Unknown: 258 case MDS_Unknown:
245 assert(SingleDefNode == NULL); 259 assert(SingleDefNode == NULL);
246 MultiDef = MDS_SingleDef; 260 MultiDef = MDS_SingleDef;
247 SingleDefNode = Node; 261 SingleDefNode = Node;
248 break; 262 break;
249 case MDS_SingleDef: 263 case MDS_SingleDef:
250 assert(SingleDefNode); 264 assert(SingleDefNode);
251 if (Node == SingleDefNode) { 265 if (Node == SingleDefNode) {
252 MultiDef = MDS_MultiDefSingleBlock; 266 MultiDef = MDS_MultiDefSingleBlock;
(...skipping 15 matching lines...) Expand all
268 } 282 }
269 } 283 }
270 284
271 const Inst *VariableTracking::getFirstDefinition() const { 285 const Inst *VariableTracking::getFirstDefinition() const {
272 switch (MultiDef) { 286 switch (MultiDef) {
273 case MDS_Unknown: 287 case MDS_Unknown:
274 case MDS_MultiDefMultiBlock: 288 case MDS_MultiDefMultiBlock:
275 return NULL; 289 return NULL;
276 case MDS_SingleDef: 290 case MDS_SingleDef:
277 case MDS_MultiDefSingleBlock: 291 case MDS_MultiDefSingleBlock:
278 assert(!Definitions.empty()); 292 assert(FirstOrSingleDefinition);
279 return Definitions[0]; 293 return FirstOrSingleDefinition;
280 } 294 }
281 } 295 }
282 296
283 const Inst *VariableTracking::getSingleDefinition() const { 297 const Inst *VariableTracking::getSingleDefinition() const {
284 switch (MultiDef) { 298 switch (MultiDef) {
285 case MDS_Unknown: 299 case MDS_Unknown:
286 case MDS_MultiDefMultiBlock: 300 case MDS_MultiDefMultiBlock:
287 case MDS_MultiDefSingleBlock: 301 case MDS_MultiDefSingleBlock:
288 return NULL; 302 return NULL;
289 case MDS_SingleDef: 303 case MDS_SingleDef:
290 assert(!Definitions.empty()); 304 assert(FirstOrSingleDefinition);
291 return Definitions[0]; 305 return FirstOrSingleDefinition;
292 } 306 }
293 } 307 }
294 308
295 void VariablesMetadata::init() { 309 void VariablesMetadata::init(MetadataKind TrackingKind) {
296 TimerMarker T(TimerStack::TT_vmetadata, Func); 310 TimerMarker T(TimerStack::TT_vmetadata, Func);
311 Kind = TrackingKind;
297 Metadata.clear(); 312 Metadata.clear();
298 Metadata.resize(Func->getNumVariables()); 313 Metadata.resize(Func->getNumVariables());
299 314
300 // Mark implicit args as being used in the entry node. 315 // Mark implicit args as being used in the entry node.
301 for (Variable *Var : Func->getImplicitArgs()) { 316 for (Variable *Var : Func->getImplicitArgs()) {
302 const Inst *NoInst = NULL; 317 const Inst *NoInst = NULL;
303 const CfgNode *EntryNode = Func->getEntryNode(); 318 const CfgNode *EntryNode = Func->getEntryNode();
304 const bool IsFromDef = false; 319 const bool IsFromDef = false;
305 const bool IsImplicit = true; 320 const bool IsImplicit = true;
306 Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit); 321 Metadata[Var->getIndex()]
322 .markUse(Kind, NoInst, EntryNode, IsFromDef, IsImplicit);
307 } 323 }
308 324
309 for (CfgNode *Node : Func->getNodes()) { 325 for (CfgNode *Node : Func->getNodes()) {
310 for (Inst *I : Node->getInsts()) { 326 for (Inst *I : Node->getInsts()) {
311 if (I->isDeleted()) 327 if (I->isDeleted())
312 continue; 328 continue;
313 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { 329 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) {
314 // A FakeKill instruction indicates certain Variables (usually 330 // A FakeKill instruction indicates certain Variables (usually
315 // physical scratch registers) are redefined, so we register 331 // physical scratch registers) are redefined, so we register
316 // them as defs. 332 // them as defs.
317 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { 333 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) {
318 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum)); 334 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum));
319 SizeT VarNum = Var->getIndex(); 335 SizeT VarNum = Var->getIndex();
320 assert(VarNum < Metadata.size()); 336 assert(VarNum < Metadata.size());
321 Metadata[VarNum].markDef(Kill, Node); 337 Metadata[VarNum].markDef(Kind, Kill, Node);
322 } 338 }
323 continue; // no point in executing the rest 339 continue; // no point in executing the rest
324 } 340 }
325 if (Variable *Dest = I->getDest()) { 341 if (Variable *Dest = I->getDest()) {
326 SizeT DestNum = Dest->getIndex(); 342 SizeT DestNum = Dest->getIndex();
327 assert(DestNum < Metadata.size()); 343 assert(DestNum < Metadata.size());
328 Metadata[DestNum].markDef(I, Node); 344 Metadata[DestNum].markDef(Kind, I, Node);
329 } 345 }
330 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { 346 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) {
331 Operand *Src = I->getSrc(SrcNum); 347 Operand *Src = I->getSrc(SrcNum);
332 SizeT NumVars = Src->getNumVars(); 348 SizeT NumVars = Src->getNumVars();
333 for (SizeT J = 0; J < NumVars; ++J) { 349 for (SizeT J = 0; J < NumVars; ++J) {
334 const Variable *Var = Src->getVar(J); 350 const Variable *Var = Src->getVar(J);
335 SizeT VarNum = Var->getIndex(); 351 SizeT VarNum = Var->getIndex();
336 assert(VarNum < Metadata.size()); 352 assert(VarNum < Metadata.size());
337 const bool IsFromDef = false; 353 const bool IsFromDef = false;
338 const bool IsImplicit = false; 354 const bool IsImplicit = false;
339 Metadata[VarNum].markUse(I, Node, IsFromDef, IsImplicit); 355 Metadata[VarNum].markUse(Kind, I, Node, IsFromDef, IsImplicit);
340 } 356 }
341 } 357 }
342 } 358 }
343 } 359 }
344 } 360 }
345 361
346 bool VariablesMetadata::isMultiDef(const Variable *Var) const { 362 bool VariablesMetadata::isMultiDef(const Variable *Var) const {
363 assert(Kind != VMK_Uses);
347 if (Var->getIsArg()) 364 if (Var->getIsArg())
348 return false; 365 return false;
349 if (!isTracked(Var)) 366 if (!isTracked(Var))
350 return true; // conservative answer 367 return true; // conservative answer
351 SizeT VarNum = Var->getIndex(); 368 SizeT VarNum = Var->getIndex();
352 // Conservatively return true if the state is unknown. 369 // Conservatively return true if the state is unknown.
353 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; 370 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef;
354 } 371 }
355 372
356 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { 373 bool VariablesMetadata::isMultiBlock(const Variable *Var) const {
357 if (Var->getIsArg()) 374 if (Var->getIsArg())
358 return true; 375 return true;
359 if (!isTracked(Var)) 376 if (!isTracked(Var))
360 return true; // conservative answer 377 return true; // conservative answer
361 SizeT VarNum = Var->getIndex(); 378 SizeT VarNum = Var->getIndex();
362 // Conservatively return true if the state is unknown. 379 // Conservatively return true if the state is unknown.
363 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; 380 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock;
364 } 381 }
365 382
366 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { 383 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
384 assert(Kind != VMK_Uses);
367 if (!isTracked(Var)) 385 if (!isTracked(Var))
368 return NULL; // conservative answer 386 return NULL; // conservative answer
369 SizeT VarNum = Var->getIndex(); 387 SizeT VarNum = Var->getIndex();
370 return Metadata[VarNum].getFirstDefinition(); 388 return Metadata[VarNum].getFirstDefinition();
371 } 389 }
372 390
373 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { 391 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const {
392 assert(Kind != VMK_Uses);
374 if (!isTracked(Var)) 393 if (!isTracked(Var))
375 return NULL; // conservative answer 394 return NULL; // conservative answer
376 SizeT VarNum = Var->getIndex(); 395 SizeT VarNum = Var->getIndex();
377 return Metadata[VarNum].getSingleDefinition(); 396 return Metadata[VarNum].getSingleDefinition();
378 } 397 }
379 398
380 const InstDefList & 399 const InstDefList &
381 VariablesMetadata::getDefinitions(const Variable *Var) const { 400 VariablesMetadata::getLatterDefinitions(const Variable *Var) const {
401 assert(Kind == VMK_All);
382 if (!isTracked(Var)) 402 if (!isTracked(Var))
383 return NoDefinitions; 403 return NoDefinitions;
384 SizeT VarNum = Var->getIndex(); 404 SizeT VarNum = Var->getIndex();
385 return Metadata[VarNum].getDefinitions(); 405 return Metadata[VarNum].getLatterDefinitions();
386 } 406 }
387 407
388 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { 408 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
389 if (!isTracked(Var)) 409 if (!isTracked(Var))
390 return NULL; // conservative answer 410 return NULL; // conservative answer
391 SizeT VarNum = Var->getIndex(); 411 SizeT VarNum = Var->getIndex();
392 return Metadata[VarNum].getNode(); 412 return Metadata[VarNum].getNode();
393 } 413 }
394 414
395 const InstDefList VariablesMetadata::NoDefinitions; 415 const InstDefList VariablesMetadata::NoDefinitions;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 484
465 Ostream &operator<<(Ostream &Str, const RegWeight &W) { 485 Ostream &operator<<(Ostream &Str, const RegWeight &W) {
466 if (W.getWeight() == RegWeight::Inf) 486 if (W.getWeight() == RegWeight::Inf)
467 Str << "Inf"; 487 Str << "Inf";
468 else 488 else
469 Str << W.getWeight(); 489 Str << W.getWeight();
470 return Str; 490 return Str;
471 } 491 }
472 492
473 } // end of namespace Ice 493 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | src/IceRegAlloc.cpp » ('j') | src/IceRegAlloc.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698