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

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: 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
« no previous file with comments | « src/IceOperand.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 if (TrackingKind == VMK_All) {
238 Instr->getNumber() >= Definitions.back()->getNumber()); 241 assert(Definitions.empty() ||
239 Definitions.push_back(Instr); 242 Instr->getNumber() >= Definitions.back()->getNumber());
243 }
240 const bool IsFromDef = true; 244 const bool IsFromDef = true;
241 const bool IsImplicit = false; 245 const bool IsImplicit = false;
242 markUse(Instr, Node, IsFromDef, IsImplicit); 246 markUse(TrackingKind, Instr, Node, IsFromDef, IsImplicit);
247 if (TrackingKind == VMK_Uses)
248 return;
249 if (FirstDefinition == NULL)
jvoung (off chromium) 2014/10/15 17:44:54 Looks like this could be put under "if (TrackingKi
Jim Stichnoth 2014/10/15 21:29:43 Renamed the field to FirstOrSingleDefinition to cl
250 FirstDefinition = Instr;
251 if (TrackingKind == VMK_All)
252 Definitions.push_back(Instr);
243 switch (MultiDef) { 253 switch (MultiDef) {
244 case MDS_Unknown: 254 case MDS_Unknown:
245 assert(SingleDefNode == NULL); 255 assert(SingleDefNode == NULL);
246 MultiDef = MDS_SingleDef; 256 MultiDef = MDS_SingleDef;
247 SingleDefNode = Node; 257 SingleDefNode = Node;
248 break; 258 break;
249 case MDS_SingleDef: 259 case MDS_SingleDef:
250 assert(SingleDefNode); 260 assert(SingleDefNode);
251 if (Node == SingleDefNode) { 261 if (Node == SingleDefNode) {
252 MultiDef = MDS_MultiDefSingleBlock; 262 MultiDef = MDS_MultiDefSingleBlock;
(...skipping 15 matching lines...) Expand all
268 } 278 }
269 } 279 }
270 280
271 const Inst *VariableTracking::getFirstDefinition() const { 281 const Inst *VariableTracking::getFirstDefinition() const {
272 switch (MultiDef) { 282 switch (MultiDef) {
273 case MDS_Unknown: 283 case MDS_Unknown:
274 case MDS_MultiDefMultiBlock: 284 case MDS_MultiDefMultiBlock:
275 return NULL; 285 return NULL;
276 case MDS_SingleDef: 286 case MDS_SingleDef:
277 case MDS_MultiDefSingleBlock: 287 case MDS_MultiDefSingleBlock:
278 assert(!Definitions.empty()); 288 assert(FirstDefinition);
279 return Definitions[0]; 289 return FirstDefinition;
280 } 290 }
281 } 291 }
282 292
283 const Inst *VariableTracking::getSingleDefinition() const { 293 const Inst *VariableTracking::getSingleDefinition() const {
284 switch (MultiDef) { 294 switch (MultiDef) {
285 case MDS_Unknown: 295 case MDS_Unknown:
286 case MDS_MultiDefMultiBlock: 296 case MDS_MultiDefMultiBlock:
287 case MDS_MultiDefSingleBlock: 297 case MDS_MultiDefSingleBlock:
288 return NULL; 298 return NULL;
289 case MDS_SingleDef: 299 case MDS_SingleDef:
290 assert(!Definitions.empty()); 300 assert(FirstDefinition);
291 return Definitions[0]; 301 return FirstDefinition;
292 } 302 }
293 } 303 }
294 304
295 void VariablesMetadata::init() { 305 void VariablesMetadata::init(MetadataKind TrackingKind) {
296 TimerMarker T(TimerStack::TT_vmetadata, Func); 306 TimerMarker T(TimerStack::TT_vmetadata, Func);
307 Kind = TrackingKind;
297 Metadata.clear(); 308 Metadata.clear();
298 Metadata.resize(Func->getNumVariables()); 309 Metadata.resize(Func->getNumVariables());
299 310
300 // Mark implicit args as being used in the entry node. 311 // Mark implicit args as being used in the entry node.
301 for (Variable *Var : Func->getImplicitArgs()) { 312 for (Variable *Var : Func->getImplicitArgs()) {
302 const Inst *NoInst = NULL; 313 const Inst *NoInst = NULL;
303 const CfgNode *EntryNode = Func->getEntryNode(); 314 const CfgNode *EntryNode = Func->getEntryNode();
304 const bool IsFromDef = false; 315 const bool IsFromDef = false;
305 const bool IsImplicit = true; 316 const bool IsImplicit = true;
306 Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit); 317 Metadata[Var->getIndex()]
318 .markUse(Kind, NoInst, EntryNode, IsFromDef, IsImplicit);
307 } 319 }
308 320
309 for (CfgNode *Node : Func->getNodes()) { 321 for (CfgNode *Node : Func->getNodes()) {
310 for (Inst *I : Node->getInsts()) { 322 for (Inst *I : Node->getInsts()) {
311 if (I->isDeleted()) 323 if (I->isDeleted())
312 continue; 324 continue;
313 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { 325 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) {
314 // A FakeKill instruction indicates certain Variables (usually 326 // A FakeKill instruction indicates certain Variables (usually
315 // physical scratch registers) are redefined, so we register 327 // physical scratch registers) are redefined, so we register
316 // them as defs. 328 // them as defs.
317 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { 329 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) {
318 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum)); 330 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum));
319 SizeT VarNum = Var->getIndex(); 331 SizeT VarNum = Var->getIndex();
320 assert(VarNum < Metadata.size()); 332 assert(VarNum < Metadata.size());
321 Metadata[VarNum].markDef(Kill, Node); 333 Metadata[VarNum].markDef(Kind, Kill, Node);
322 } 334 }
323 continue; // no point in executing the rest 335 continue; // no point in executing the rest
324 } 336 }
325 if (Variable *Dest = I->getDest()) { 337 if (Variable *Dest = I->getDest()) {
326 SizeT DestNum = Dest->getIndex(); 338 SizeT DestNum = Dest->getIndex();
327 assert(DestNum < Metadata.size()); 339 assert(DestNum < Metadata.size());
328 Metadata[DestNum].markDef(I, Node); 340 Metadata[DestNum].markDef(Kind, I, Node);
329 } 341 }
330 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { 342 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) {
331 Operand *Src = I->getSrc(SrcNum); 343 Operand *Src = I->getSrc(SrcNum);
332 SizeT NumVars = Src->getNumVars(); 344 SizeT NumVars = Src->getNumVars();
333 for (SizeT J = 0; J < NumVars; ++J) { 345 for (SizeT J = 0; J < NumVars; ++J) {
334 const Variable *Var = Src->getVar(J); 346 const Variable *Var = Src->getVar(J);
335 SizeT VarNum = Var->getIndex(); 347 SizeT VarNum = Var->getIndex();
336 assert(VarNum < Metadata.size()); 348 assert(VarNum < Metadata.size());
337 const bool IsFromDef = false; 349 const bool IsFromDef = false;
338 const bool IsImplicit = false; 350 const bool IsImplicit = false;
339 Metadata[VarNum].markUse(I, Node, IsFromDef, IsImplicit); 351 Metadata[VarNum].markUse(Kind, I, Node, IsFromDef, IsImplicit);
340 } 352 }
341 } 353 }
342 } 354 }
343 } 355 }
344 } 356 }
345 357
346 bool VariablesMetadata::isMultiDef(const Variable *Var) const { 358 bool VariablesMetadata::isMultiDef(const Variable *Var) const {
359 assert(Kind != VMK_Uses);
347 if (Var->getIsArg()) 360 if (Var->getIsArg())
348 return false; 361 return false;
349 if (!isTracked(Var)) 362 if (!isTracked(Var))
350 return true; // conservative answer 363 return true; // conservative answer
351 SizeT VarNum = Var->getIndex(); 364 SizeT VarNum = Var->getIndex();
352 // Conservatively return true if the state is unknown. 365 // Conservatively return true if the state is unknown.
353 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; 366 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef;
354 } 367 }
355 368
356 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { 369 bool VariablesMetadata::isMultiBlock(const Variable *Var) const {
357 if (Var->getIsArg()) 370 if (Var->getIsArg())
358 return true; 371 return true;
359 if (!isTracked(Var)) 372 if (!isTracked(Var))
360 return true; // conservative answer 373 return true; // conservative answer
361 SizeT VarNum = Var->getIndex(); 374 SizeT VarNum = Var->getIndex();
362 // Conservatively return true if the state is unknown. 375 // Conservatively return true if the state is unknown.
363 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; 376 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock;
364 } 377 }
365 378
366 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { 379 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
380 assert(Kind == VMK_All);
367 if (!isTracked(Var)) 381 if (!isTracked(Var))
368 return NULL; // conservative answer 382 return NULL; // conservative answer
369 SizeT VarNum = Var->getIndex(); 383 SizeT VarNum = Var->getIndex();
370 return Metadata[VarNum].getFirstDefinition(); 384 return Metadata[VarNum].getFirstDefinition();
371 } 385 }
372 386
373 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { 387 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const {
388 assert(Kind != VMK_Uses);
374 if (!isTracked(Var)) 389 if (!isTracked(Var))
375 return NULL; // conservative answer 390 return NULL; // conservative answer
376 SizeT VarNum = Var->getIndex(); 391 SizeT VarNum = Var->getIndex();
377 return Metadata[VarNum].getSingleDefinition(); 392 return Metadata[VarNum].getSingleDefinition();
378 } 393 }
379 394
380 const InstDefList & 395 const InstDefList &
381 VariablesMetadata::getDefinitions(const Variable *Var) const { 396 VariablesMetadata::getDefinitions(const Variable *Var) const {
397 assert(Kind == VMK_All);
382 if (!isTracked(Var)) 398 if (!isTracked(Var))
383 return NoDefinitions; 399 return NoDefinitions;
384 SizeT VarNum = Var->getIndex(); 400 SizeT VarNum = Var->getIndex();
385 return Metadata[VarNum].getDefinitions(); 401 return Metadata[VarNum].getDefinitions();
386 } 402 }
387 403
388 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { 404 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
389 if (!isTracked(Var)) 405 if (!isTracked(Var))
390 return NULL; // conservative answer 406 return NULL; // conservative answer
391 SizeT VarNum = Var->getIndex(); 407 SizeT VarNum = Var->getIndex();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 480
465 Ostream &operator<<(Ostream &Str, const RegWeight &W) { 481 Ostream &operator<<(Ostream &Str, const RegWeight &W) {
466 if (W.getWeight() == RegWeight::Inf) 482 if (W.getWeight() == RegWeight::Inf)
467 Str << "Inf"; 483 Str << "Inf";
468 else 484 else
469 Str << W.getWeight(); 485 Str << W.getWeight();
470 return Str; 486 return Str;
471 } 487 }
472 488
473 } // end of namespace Ice 489 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698