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

Side by Side Diff: src/IceInst.h

Issue 802183004: Subzero: Use CFG-local arena allocation for relevant containers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Typo fix Created 6 years 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/IceGlobalContext.h ('k') | src/IceInstX8632.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/IceInst.h - High-level instructions ----------*- C++ -*-===// 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
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 declares the Inst class and its target-independent 10 // This file declares the Inst class and its target-independent
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 // Alloca instruction. This captures the size in bytes as getSrc(0), 223 // Alloca instruction. This captures the size in bytes as getSrc(0),
224 // and the required alignment in bytes. The alignment must be either 224 // and the required alignment in bytes. The alignment must be either
225 // 0 (no alignment required) or a power of 2. 225 // 0 (no alignment required) or a power of 2.
226 class InstAlloca : public InstHighLevel { 226 class InstAlloca : public InstHighLevel {
227 InstAlloca(const InstAlloca &) = delete; 227 InstAlloca(const InstAlloca &) = delete;
228 InstAlloca &operator=(const InstAlloca &) = delete; 228 InstAlloca &operator=(const InstAlloca &) = delete;
229 229
230 public: 230 public:
231 static InstAlloca *create(Cfg *Func, Operand *ByteCount, 231 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
232 uint32_t AlignInBytes, Variable *Dest) { 232 uint32_t AlignInBytes, Variable *Dest) {
233 return new (Func->allocateInst<InstAlloca>()) 233 return new (Func->allocate<InstAlloca>())
234 InstAlloca(Func, ByteCount, AlignInBytes, Dest); 234 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
235 } 235 }
236 uint32_t getAlignInBytes() const { return AlignInBytes; } 236 uint32_t getAlignInBytes() const { return AlignInBytes; }
237 Operand *getSizeInBytes() const { return getSrc(0); } 237 Operand *getSizeInBytes() const { return getSrc(0); }
238 void dump(const Cfg *Func) const override; 238 void dump(const Cfg *Func) const override;
239 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } 239 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
240 240
241 private: 241 private:
242 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, 242 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
243 Variable *Dest); 243 Variable *Dest);
(...skipping 10 matching lines...) Expand all
254 public: 254 public:
255 enum OpKind { 255 enum OpKind {
256 #define X(tag, str, commutative) tag, 256 #define X(tag, str, commutative) tag,
257 ICEINSTARITHMETIC_TABLE 257 ICEINSTARITHMETIC_TABLE
258 #undef X 258 #undef X
259 _num 259 _num
260 }; 260 };
261 261
262 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest, 262 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
263 Operand *Source1, Operand *Source2) { 263 Operand *Source1, Operand *Source2) {
264 return new (Func->allocateInst<InstArithmetic>()) 264 return new (Func->allocate<InstArithmetic>())
265 InstArithmetic(Func, Op, Dest, Source1, Source2); 265 InstArithmetic(Func, Op, Dest, Source1, Source2);
266 } 266 }
267 OpKind getOp() const { return Op; } 267 OpKind getOp() const { return Op; }
268 static const char *getOpName(OpKind Op); 268 static const char *getOpName(OpKind Op);
269 bool isCommutative() const; 269 bool isCommutative() const;
270 void dump(const Cfg *Func) const override; 270 void dump(const Cfg *Func) const override;
271 static bool classof(const Inst *Inst) { 271 static bool classof(const Inst *Inst) {
272 return Inst->getKind() == Arithmetic; 272 return Inst->getKind() == Arithmetic;
273 } 273 }
274 274
(...skipping 10 matching lines...) Expand all
285 // abstraction for some of the lowering. E.g., if Phi instruction 285 // abstraction for some of the lowering. E.g., if Phi instruction
286 // lowering happens before target lowering, or for representing an 286 // lowering happens before target lowering, or for representing an
287 // Inttoptr instruction, or as an intermediate step for lowering a 287 // Inttoptr instruction, or as an intermediate step for lowering a
288 // Load instruction. 288 // Load instruction.
289 class InstAssign : public InstHighLevel { 289 class InstAssign : public InstHighLevel {
290 InstAssign(const InstAssign &) = delete; 290 InstAssign(const InstAssign &) = delete;
291 InstAssign &operator=(const InstAssign &) = delete; 291 InstAssign &operator=(const InstAssign &) = delete;
292 292
293 public: 293 public:
294 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { 294 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
295 return new (Func->allocateInst<InstAssign>()) 295 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
296 InstAssign(Func, Dest, Source);
297 } 296 }
298 bool isSimpleAssign() const override { return true; } 297 bool isSimpleAssign() const override { return true; }
299 void dump(const Cfg *Func) const override; 298 void dump(const Cfg *Func) const override;
300 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } 299 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
301 300
302 private: 301 private:
303 InstAssign(Cfg *Func, Variable *Dest, Operand *Source); 302 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
304 ~InstAssign() override {} 303 ~InstAssign() override {}
305 }; 304 };
306 305
307 // Branch instruction. This represents both conditional and 306 // Branch instruction. This represents both conditional and
308 // unconditional branches. 307 // unconditional branches.
309 class InstBr : public InstHighLevel { 308 class InstBr : public InstHighLevel {
310 InstBr(const InstBr &) = delete; 309 InstBr(const InstBr &) = delete;
311 InstBr &operator=(const InstBr &) = delete; 310 InstBr &operator=(const InstBr &) = delete;
312 311
313 public: 312 public:
314 // Create a conditional branch. If TargetTrue==TargetFalse, it is 313 // Create a conditional branch. If TargetTrue==TargetFalse, it is
315 // optimized to an unconditional branch. 314 // optimized to an unconditional branch.
316 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, 315 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
317 CfgNode *TargetFalse) { 316 CfgNode *TargetFalse) {
318 return new (Func->allocateInst<InstBr>()) 317 return new (Func->allocate<InstBr>())
319 InstBr(Func, Source, TargetTrue, TargetFalse); 318 InstBr(Func, Source, TargetTrue, TargetFalse);
320 } 319 }
321 // Create an unconditional branch. 320 // Create an unconditional branch.
322 static InstBr *create(Cfg *Func, CfgNode *Target) { 321 static InstBr *create(Cfg *Func, CfgNode *Target) {
323 return new (Func->allocateInst<InstBr>()) InstBr(Func, Target); 322 return new (Func->allocate<InstBr>()) InstBr(Func, Target);
324 } 323 }
325 bool isUnconditional() const { return getTargetTrue() == NULL; } 324 bool isUnconditional() const { return getTargetTrue() == NULL; }
326 Operand *getCondition() const { 325 Operand *getCondition() const {
327 assert(!isUnconditional()); 326 assert(!isUnconditional());
328 return getSrc(0); 327 return getSrc(0);
329 } 328 }
330 CfgNode *getTargetTrue() const { return TargetTrue; } 329 CfgNode *getTargetTrue() const { return TargetTrue; }
331 CfgNode *getTargetFalse() const { return TargetFalse; } 330 CfgNode *getTargetFalse() const { return TargetFalse; }
332 CfgNode *getTargetUnconditional() const { 331 CfgNode *getTargetUnconditional() const {
333 assert(isUnconditional()); 332 assert(isUnconditional());
(...skipping 23 matching lines...) Expand all
357 InstCall &operator=(const InstCall &) = delete; 356 InstCall &operator=(const InstCall &) = delete;
358 357
359 public: 358 public:
360 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, 359 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
361 Operand *CallTarget, bool HasTailCall) { 360 Operand *CallTarget, bool HasTailCall) {
362 // Set HasSideEffects to true so that the call instruction can't be 361 // Set HasSideEffects to true so that the call instruction can't be
363 // dead-code eliminated. IntrinsicCalls can override this if the 362 // dead-code eliminated. IntrinsicCalls can override this if the
364 // particular intrinsic is deletable and has no side-effects. 363 // particular intrinsic is deletable and has no side-effects.
365 const bool HasSideEffects = true; 364 const bool HasSideEffects = true;
366 const InstKind Kind = Inst::Call; 365 const InstKind Kind = Inst::Call;
367 return new (Func->allocateInst<InstCall>()) InstCall( 366 return new (Func->allocate<InstCall>()) InstCall(
368 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind); 367 Func, NumArgs, Dest, CallTarget, HasTailCall, HasSideEffects, Kind);
369 } 368 }
370 void addArg(Operand *Arg) { addSource(Arg); } 369 void addArg(Operand *Arg) { addSource(Arg); }
371 Operand *getCallTarget() const { return getSrc(0); } 370 Operand *getCallTarget() const { return getSrc(0); }
372 Operand *getArg(SizeT I) const { return getSrc(I + 1); } 371 Operand *getArg(SizeT I) const { return getSrc(I + 1); }
373 SizeT getNumArgs() const { return getSrcSize() - 1; } 372 SizeT getNumArgs() const { return getSrcSize() - 1; }
374 bool isTailcall() const { return HasTailCall; } 373 bool isTailcall() const { return HasTailCall; }
375 void dump(const Cfg *Func) const; 374 void dump(const Cfg *Func) const;
376 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } 375 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
377 Type getReturnType() const; 376 Type getReturnType() const;
(...skipping 21 matching lines...) Expand all
399 #define X(tag, str) tag, 398 #define X(tag, str) tag,
400 ICEINSTCAST_TABLE 399 ICEINSTCAST_TABLE
401 #undef X 400 #undef X
402 _num 401 _num
403 }; 402 };
404 403
405 static const char *getCastName(OpKind Kind); 404 static const char *getCastName(OpKind Kind);
406 405
407 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, 406 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
408 Operand *Source) { 407 Operand *Source) {
409 return new (Func->allocateInst<InstCast>()) 408 return new (Func->allocate<InstCast>())
410 InstCast(Func, CastKind, Dest, Source); 409 InstCast(Func, CastKind, Dest, Source);
411 } 410 }
412 OpKind getCastKind() const { return CastKind; } 411 OpKind getCastKind() const { return CastKind; }
413 void dump(const Cfg *Func) const override; 412 void dump(const Cfg *Func) const override;
414 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } 413 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
415 414
416 private: 415 private:
417 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); 416 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
418 ~InstCast() override {} 417 ~InstCast() override {}
419 const OpKind CastKind; 418 const OpKind CastKind;
420 }; 419 };
421 420
422 // ExtractElement instruction. 421 // ExtractElement instruction.
423 class InstExtractElement : public InstHighLevel { 422 class InstExtractElement : public InstHighLevel {
424 InstExtractElement(const InstExtractElement &) = delete; 423 InstExtractElement(const InstExtractElement &) = delete;
425 InstExtractElement &operator=(const InstExtractElement &) = delete; 424 InstExtractElement &operator=(const InstExtractElement &) = delete;
426 425
427 public: 426 public:
428 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 427 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
429 Operand *Source2) { 428 Operand *Source2) {
430 return new (Func->allocateInst<InstExtractElement>()) 429 return new (Func->allocate<InstExtractElement>())
431 InstExtractElement(Func, Dest, Source1, Source2); 430 InstExtractElement(Func, Dest, Source1, Source2);
432 } 431 }
433 432
434 void dump(const Cfg *Func) const override; 433 void dump(const Cfg *Func) const override;
435 static bool classof(const Inst *Inst) { 434 static bool classof(const Inst *Inst) {
436 return Inst->getKind() == ExtractElement; 435 return Inst->getKind() == ExtractElement;
437 } 436 }
438 437
439 private: 438 private:
440 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, 439 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
(...skipping 10 matching lines...) Expand all
451 public: 450 public:
452 enum FCond { 451 enum FCond {
453 #define X(tag, str) tag, 452 #define X(tag, str) tag,
454 ICEINSTFCMP_TABLE 453 ICEINSTFCMP_TABLE
455 #undef X 454 #undef X
456 _num 455 _num
457 }; 456 };
458 457
459 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, 458 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
460 Operand *Source1, Operand *Source2) { 459 Operand *Source1, Operand *Source2) {
461 return new (Func->allocateInst<InstFcmp>()) 460 return new (Func->allocate<InstFcmp>())
462 InstFcmp(Func, Condition, Dest, Source1, Source2); 461 InstFcmp(Func, Condition, Dest, Source1, Source2);
463 } 462 }
464 FCond getCondition() const { return Condition; } 463 FCond getCondition() const { return Condition; }
465 void dump(const Cfg *Func) const override; 464 void dump(const Cfg *Func) const override;
466 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } 465 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
467 466
468 private: 467 private:
469 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, 468 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
470 Operand *Source2); 469 Operand *Source2);
471 ~InstFcmp() override {} 470 ~InstFcmp() override {}
472 const FCond Condition; 471 const FCond Condition;
473 }; 472 };
474 473
475 // Integer comparison instruction. The source operands are captured 474 // Integer comparison instruction. The source operands are captured
476 // in getSrc(0) and getSrc(1). 475 // in getSrc(0) and getSrc(1).
477 class InstIcmp : public InstHighLevel { 476 class InstIcmp : public InstHighLevel {
478 InstIcmp(const InstIcmp &) = delete; 477 InstIcmp(const InstIcmp &) = delete;
479 InstIcmp &operator=(const InstIcmp &) = delete; 478 InstIcmp &operator=(const InstIcmp &) = delete;
480 479
481 public: 480 public:
482 enum ICond { 481 enum ICond {
483 #define X(tag, str) tag, 482 #define X(tag, str) tag,
484 ICEINSTICMP_TABLE 483 ICEINSTICMP_TABLE
485 #undef X 484 #undef X
486 _num 485 _num
487 }; 486 };
488 487
489 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, 488 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
490 Operand *Source1, Operand *Source2) { 489 Operand *Source1, Operand *Source2) {
491 return new (Func->allocateInst<InstIcmp>()) 490 return new (Func->allocate<InstIcmp>())
492 InstIcmp(Func, Condition, Dest, Source1, Source2); 491 InstIcmp(Func, Condition, Dest, Source1, Source2);
493 } 492 }
494 ICond getCondition() const { return Condition; } 493 ICond getCondition() const { return Condition; }
495 void dump(const Cfg *Func) const override; 494 void dump(const Cfg *Func) const override;
496 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } 495 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
497 496
498 private: 497 private:
499 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, 498 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
500 Operand *Source2); 499 Operand *Source2);
501 ~InstIcmp() override {} 500 ~InstIcmp() override {}
502 const ICond Condition; 501 const ICond Condition;
503 }; 502 };
504 503
505 // InsertElement instruction. 504 // InsertElement instruction.
506 class InstInsertElement : public InstHighLevel { 505 class InstInsertElement : public InstHighLevel {
507 InstInsertElement(const InstInsertElement &) = delete; 506 InstInsertElement(const InstInsertElement &) = delete;
508 InstInsertElement &operator=(const InstInsertElement &) = delete; 507 InstInsertElement &operator=(const InstInsertElement &) = delete;
509 508
510 public: 509 public:
511 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 510 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
512 Operand *Source2, Operand *Source3) { 511 Operand *Source2, Operand *Source3) {
513 return new (Func->allocateInst<InstInsertElement>()) 512 return new (Func->allocate<InstInsertElement>())
514 InstInsertElement(Func, Dest, Source1, Source2, Source3); 513 InstInsertElement(Func, Dest, Source1, Source2, Source3);
515 } 514 }
516 515
517 void dump(const Cfg *Func) const override; 516 void dump(const Cfg *Func) const override;
518 static bool classof(const Inst *Inst) { 517 static bool classof(const Inst *Inst) {
519 return Inst->getKind() == InsertElement; 518 return Inst->getKind() == InsertElement;
520 } 519 }
521 520
522 private: 521 private:
523 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, 522 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
524 Operand *Source2, Operand *Source3); 523 Operand *Source2, Operand *Source3);
525 ~InstInsertElement() override {} 524 ~InstInsertElement() override {}
526 }; 525 };
527 526
528 // Call to an intrinsic function. The call target is captured as getSrc(0), 527 // Call to an intrinsic function. The call target is captured as getSrc(0),
529 // and arg I is captured as getSrc(I+1). 528 // and arg I is captured as getSrc(I+1).
530 class InstIntrinsicCall : public InstCall { 529 class InstIntrinsicCall : public InstCall {
531 InstIntrinsicCall(const InstIntrinsicCall &) = delete; 530 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
532 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete; 531 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
533 532
534 public: 533 public:
535 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, 534 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
536 Operand *CallTarget, 535 Operand *CallTarget,
537 const Intrinsics::IntrinsicInfo &Info) { 536 const Intrinsics::IntrinsicInfo &Info) {
538 return new (Func->allocateInst<InstIntrinsicCall>()) 537 return new (Func->allocate<InstIntrinsicCall>())
539 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); 538 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
540 } 539 }
541 static bool classof(const Inst *Inst) { 540 static bool classof(const Inst *Inst) {
542 return Inst->getKind() == IntrinsicCall; 541 return Inst->getKind() == IntrinsicCall;
543 } 542 }
544 543
545 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } 544 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
546 545
547 private: 546 private:
548 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, 547 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
549 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) 548 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
550 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, 549 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
551 Inst::IntrinsicCall), 550 Inst::IntrinsicCall),
552 Info(Info) {} 551 Info(Info) {}
553 ~InstIntrinsicCall() override {} 552 ~InstIntrinsicCall() override {}
554 const Intrinsics::IntrinsicInfo Info; 553 const Intrinsics::IntrinsicInfo Info;
555 }; 554 };
556 555
557 // Load instruction. The source address is captured in getSrc(0). 556 // Load instruction. The source address is captured in getSrc(0).
558 class InstLoad : public InstHighLevel { 557 class InstLoad : public InstHighLevel {
559 InstLoad(const InstLoad &) = delete; 558 InstLoad(const InstLoad &) = delete;
560 InstLoad &operator=(const InstLoad &) = delete; 559 InstLoad &operator=(const InstLoad &) = delete;
561 560
562 public: 561 public:
563 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, 562 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
564 uint32_t Align = 1) { 563 uint32_t Align = 1) {
565 // TODO(kschimpf) Stop ignoring alignment specification. 564 // TODO(kschimpf) Stop ignoring alignment specification.
566 (void)Align; 565 (void)Align;
567 return new (Func->allocateInst<InstLoad>()) 566 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
568 InstLoad(Func, Dest, SourceAddr);
569 } 567 }
570 Operand *getSourceAddress() const { return getSrc(0); } 568 Operand *getSourceAddress() const { return getSrc(0); }
571 void dump(const Cfg *Func) const override; 569 void dump(const Cfg *Func) const override;
572 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } 570 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
573 571
574 private: 572 private:
575 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); 573 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
576 ~InstLoad() override {} 574 ~InstLoad() override {}
577 }; 575 };
578 576
579 // Phi instruction. For incoming edge I, the node is Labels[I] and 577 // Phi instruction. For incoming edge I, the node is Labels[I] and
580 // the Phi source operand is getSrc(I). 578 // the Phi source operand is getSrc(I).
581 class InstPhi : public InstHighLevel { 579 class InstPhi : public InstHighLevel {
582 InstPhi(const InstPhi &) = delete; 580 InstPhi(const InstPhi &) = delete;
583 InstPhi &operator=(const InstPhi &) = delete; 581 InstPhi &operator=(const InstPhi &) = delete;
584 582
585 public: 583 public:
586 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { 584 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
587 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); 585 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
588 } 586 }
589 void addArgument(Operand *Source, CfgNode *Label); 587 void addArgument(Operand *Source, CfgNode *Label);
590 Operand *getOperandForTarget(CfgNode *Target) const; 588 Operand *getOperandForTarget(CfgNode *Target) const;
591 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; } 589 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
592 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target, 590 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
593 Liveness *Liveness); 591 Liveness *Liveness);
594 Inst *lower(Cfg *Func); 592 Inst *lower(Cfg *Func);
595 void dump(const Cfg *Func) const override; 593 void dump(const Cfg *Func) const override;
596 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } 594 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
597 595
(...skipping 13 matching lines...) Expand all
611 609
612 // Ret instruction. The return value is captured in getSrc(0), but if 610 // Ret instruction. The return value is captured in getSrc(0), but if
613 // there is no return value (void-type function), then 611 // there is no return value (void-type function), then
614 // getSrcSize()==0 and hasRetValue()==false. 612 // getSrcSize()==0 and hasRetValue()==false.
615 class InstRet : public InstHighLevel { 613 class InstRet : public InstHighLevel {
616 InstRet(const InstRet &) = delete; 614 InstRet(const InstRet &) = delete;
617 InstRet &operator=(const InstRet &) = delete; 615 InstRet &operator=(const InstRet &) = delete;
618 616
619 public: 617 public:
620 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) { 618 static InstRet *create(Cfg *Func, Operand *RetValue = NULL) {
621 return new (Func->allocateInst<InstRet>()) InstRet(Func, RetValue); 619 return new (Func->allocate<InstRet>()) InstRet(Func, RetValue);
622 } 620 }
623 bool hasRetValue() const { return getSrcSize(); } 621 bool hasRetValue() const { return getSrcSize(); }
624 Operand *getRetValue() const { 622 Operand *getRetValue() const {
625 assert(hasRetValue()); 623 assert(hasRetValue());
626 return getSrc(0); 624 return getSrc(0);
627 } 625 }
628 NodeList getTerminatorEdges() const override { return NodeList(); } 626 NodeList getTerminatorEdges() const override { return NodeList(); }
629 void dump(const Cfg *Func) const override; 627 void dump(const Cfg *Func) const override;
630 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } 628 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
631 629
632 private: 630 private:
633 InstRet(Cfg *Func, Operand *RetValue); 631 InstRet(Cfg *Func, Operand *RetValue);
634 ~InstRet() override {} 632 ~InstRet() override {}
635 }; 633 };
636 634
637 // Select instruction. The condition, true, and false operands are captured. 635 // Select instruction. The condition, true, and false operands are captured.
638 class InstSelect : public InstHighLevel { 636 class InstSelect : public InstHighLevel {
639 InstSelect(const InstSelect &) = delete; 637 InstSelect(const InstSelect &) = delete;
640 InstSelect &operator=(const InstSelect &) = delete; 638 InstSelect &operator=(const InstSelect &) = delete;
641 639
642 public: 640 public:
643 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, 641 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
644 Operand *SourceTrue, Operand *SourceFalse) { 642 Operand *SourceTrue, Operand *SourceFalse) {
645 return new (Func->allocateInst<InstSelect>()) 643 return new (Func->allocate<InstSelect>())
646 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); 644 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
647 } 645 }
648 Operand *getCondition() const { return getSrc(0); } 646 Operand *getCondition() const { return getSrc(0); }
649 Operand *getTrueOperand() const { return getSrc(1); } 647 Operand *getTrueOperand() const { return getSrc(1); }
650 Operand *getFalseOperand() const { return getSrc(2); } 648 Operand *getFalseOperand() const { return getSrc(2); }
651 void dump(const Cfg *Func) const override; 649 void dump(const Cfg *Func) const override;
652 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } 650 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
653 651
654 private: 652 private:
655 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, 653 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
656 Operand *Source2); 654 Operand *Source2);
657 ~InstSelect() override {} 655 ~InstSelect() override {}
658 }; 656 };
659 657
660 // Store instruction. The address operand is captured, along with the 658 // Store instruction. The address operand is captured, along with the
661 // data operand to be stored into the address. 659 // data operand to be stored into the address.
662 class InstStore : public InstHighLevel { 660 class InstStore : public InstHighLevel {
663 InstStore(const InstStore &) = delete; 661 InstStore(const InstStore &) = delete;
664 InstStore &operator=(const InstStore &) = delete; 662 InstStore &operator=(const InstStore &) = delete;
665 663
666 public: 664 public:
667 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, 665 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
668 uint32_t align = 1) { 666 uint32_t align = 1) {
669 // TODO(kschimpf) Stop ignoring alignment specification. 667 // TODO(kschimpf) Stop ignoring alignment specification.
670 (void)align; 668 (void)align;
671 return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr); 669 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
672 } 670 }
673 Operand *getAddr() const { return getSrc(1); } 671 Operand *getAddr() const { return getSrc(1); }
674 Operand *getData() const { return getSrc(0); } 672 Operand *getData() const { return getSrc(0); }
675 void dump(const Cfg *Func) const override; 673 void dump(const Cfg *Func) const override;
676 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } 674 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
677 675
678 private: 676 private:
679 InstStore(Cfg *Func, Operand *Data, Operand *Addr); 677 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
680 ~InstStore() override {} 678 ~InstStore() override {}
681 }; 679 };
682 680
683 // Switch instruction. The single source operand is captured as 681 // Switch instruction. The single source operand is captured as
684 // getSrc(0). 682 // getSrc(0).
685 class InstSwitch : public InstHighLevel { 683 class InstSwitch : public InstHighLevel {
686 InstSwitch(const InstSwitch &) = delete; 684 InstSwitch(const InstSwitch &) = delete;
687 InstSwitch &operator=(const InstSwitch &) = delete; 685 InstSwitch &operator=(const InstSwitch &) = delete;
688 686
689 public: 687 public:
690 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, 688 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source,
691 CfgNode *LabelDefault) { 689 CfgNode *LabelDefault) {
692 return new (Func->allocateInst<InstSwitch>()) 690 return new (Func->allocate<InstSwitch>())
693 InstSwitch(Func, NumCases, Source, LabelDefault); 691 InstSwitch(Func, NumCases, Source, LabelDefault);
694 } 692 }
695 Operand *getComparison() const { return getSrc(0); } 693 Operand *getComparison() const { return getSrc(0); }
696 CfgNode *getLabelDefault() const { return LabelDefault; } 694 CfgNode *getLabelDefault() const { return LabelDefault; }
697 SizeT getNumCases() const { return NumCases; } 695 SizeT getNumCases() const { return NumCases; }
698 uint64_t getValue(SizeT I) const { 696 uint64_t getValue(SizeT I) const {
699 assert(I < NumCases); 697 assert(I < NumCases);
700 return Values[I]; 698 return Values[I];
701 } 699 }
702 CfgNode *getLabel(SizeT I) const { 700 CfgNode *getLabel(SizeT I) const {
(...skipping 22 matching lines...) Expand all
725 }; 723 };
726 724
727 // Unreachable instruction. This is a terminator instruction with no 725 // Unreachable instruction. This is a terminator instruction with no
728 // operands. 726 // operands.
729 class InstUnreachable : public InstHighLevel { 727 class InstUnreachable : public InstHighLevel {
730 InstUnreachable(const InstUnreachable &) = delete; 728 InstUnreachable(const InstUnreachable &) = delete;
731 InstUnreachable &operator=(const InstUnreachable &) = delete; 729 InstUnreachable &operator=(const InstUnreachable &) = delete;
732 730
733 public: 731 public:
734 static InstUnreachable *create(Cfg *Func) { 732 static InstUnreachable *create(Cfg *Func) {
735 return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func); 733 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
736 } 734 }
737 NodeList getTerminatorEdges() const override { return NodeList(); } 735 NodeList getTerminatorEdges() const override { return NodeList(); }
738 void dump(const Cfg *Func) const override; 736 void dump(const Cfg *Func) const override;
739 static bool classof(const Inst *Inst) { 737 static bool classof(const Inst *Inst) {
740 return Inst->getKind() == Unreachable; 738 return Inst->getKind() == Unreachable;
741 } 739 }
742 740
743 private: 741 private:
744 InstUnreachable(Cfg *Func); 742 InstUnreachable(Cfg *Func);
745 ~InstUnreachable() override {} 743 ~InstUnreachable() override {}
(...skipping 10 matching lines...) Expand all
756 // dest variable of the instruction that actually produces the FakeDef 754 // dest variable of the instruction that actually produces the FakeDef
757 // dest. Otherwise, the original instruction could be dead-code 755 // dest. Otherwise, the original instruction could be dead-code
758 // eliminated if its dest operand is unused, and therefore the FakeDef 756 // eliminated if its dest operand is unused, and therefore the FakeDef
759 // dest wouldn't be properly initialized. 757 // dest wouldn't be properly initialized.
760 class InstFakeDef : public InstHighLevel { 758 class InstFakeDef : public InstHighLevel {
761 InstFakeDef(const InstFakeDef &) = delete; 759 InstFakeDef(const InstFakeDef &) = delete;
762 InstFakeDef &operator=(const InstFakeDef &) = delete; 760 InstFakeDef &operator=(const InstFakeDef &) = delete;
763 761
764 public: 762 public:
765 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) { 763 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
766 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src); 764 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
767 } 765 }
768 void emit(const Cfg *Func) const override; 766 void emit(const Cfg *Func) const override;
769 void emitIAS(const Cfg * /* Func */) const override {} 767 void emitIAS(const Cfg * /* Func */) const override {}
770 void dump(const Cfg *Func) const override; 768 void dump(const Cfg *Func) const override;
771 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } 769 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
772 770
773 private: 771 private:
774 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); 772 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
775 ~InstFakeDef() override {} 773 ~InstFakeDef() override {}
776 }; 774 };
777 775
778 // FakeUse instruction. This creates a fake use of a variable, to 776 // FakeUse instruction. This creates a fake use of a variable, to
779 // keep the instruction that produces that variable from being 777 // keep the instruction that produces that variable from being
780 // dead-code eliminated. This is useful in a variety of lowering 778 // dead-code eliminated. This is useful in a variety of lowering
781 // situations. The FakeUse instruction has no dest, so it can itself 779 // situations. The FakeUse instruction has no dest, so it can itself
782 // never be dead-code eliminated. 780 // never be dead-code eliminated.
783 class InstFakeUse : public InstHighLevel { 781 class InstFakeUse : public InstHighLevel {
784 InstFakeUse(const InstFakeUse &) = delete; 782 InstFakeUse(const InstFakeUse &) = delete;
785 InstFakeUse &operator=(const InstFakeUse &) = delete; 783 InstFakeUse &operator=(const InstFakeUse &) = delete;
786 784
787 public: 785 public:
788 static InstFakeUse *create(Cfg *Func, Variable *Src) { 786 static InstFakeUse *create(Cfg *Func, Variable *Src) {
789 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src); 787 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src);
790 } 788 }
791 void emit(const Cfg *Func) const override; 789 void emit(const Cfg *Func) const override;
792 void emitIAS(const Cfg * /* Func */) const override {} 790 void emitIAS(const Cfg * /* Func */) const override {}
793 void dump(const Cfg *Func) const override; 791 void dump(const Cfg *Func) const override;
794 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } 792 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
795 793
796 private: 794 private:
797 InstFakeUse(Cfg *Func, Variable *Src); 795 InstFakeUse(Cfg *Func, Variable *Src);
798 ~InstFakeUse() override {} 796 ~InstFakeUse() override {}
799 }; 797 };
800 798
801 // FakeKill instruction. This "kills" a set of variables by modeling 799 // FakeKill instruction. This "kills" a set of variables by modeling
802 // a trivial live range at this instruction for each (implicit) 800 // a trivial live range at this instruction for each (implicit)
803 // variable. The primary use is to indicate that scratch registers 801 // variable. The primary use is to indicate that scratch registers
804 // are killed after a call, so that the register allocator won't 802 // are killed after a call, so that the register allocator won't
805 // assign a scratch register to a variable whose live range spans a 803 // assign a scratch register to a variable whose live range spans a
806 // call. 804 // call.
807 // 805 //
808 // The FakeKill instruction also holds a pointer to the instruction 806 // The FakeKill instruction also holds a pointer to the instruction
809 // that kills the set of variables, so that if that linked instruction 807 // that kills the set of variables, so that if that linked instruction
810 // gets dead-code eliminated, the FakeKill instruction will as well. 808 // gets dead-code eliminated, the FakeKill instruction will as well.
811 class InstFakeKill : public InstHighLevel { 809 class InstFakeKill : public InstHighLevel {
812 InstFakeKill(const InstFakeKill &) = delete; 810 InstFakeKill(const InstFakeKill &) = delete;
813 InstFakeKill &operator=(const InstFakeKill &) = delete; 811 InstFakeKill &operator=(const InstFakeKill &) = delete;
814 812
815 public: 813 public:
816 static InstFakeKill *create(Cfg *Func, const Inst *Linked) { 814 static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
817 return new (Func->allocateInst<InstFakeKill>()) InstFakeKill(Func, Linked); 815 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
818 } 816 }
819 const Inst *getLinked() const { return Linked; } 817 const Inst *getLinked() const { return Linked; }
820 void emit(const Cfg *Func) const override; 818 void emit(const Cfg *Func) const override;
821 void emitIAS(const Cfg * /* Func */) const override {} 819 void emitIAS(const Cfg * /* Func */) const override {}
822 void dump(const Cfg *Func) const override; 820 void dump(const Cfg *Func) const override;
823 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } 821 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
824 822
825 private: 823 private:
826 InstFakeKill(Cfg *Func, const Inst *Linked); 824 InstFakeKill(Cfg *Func, const Inst *Linked);
827 ~InstFakeKill() override {} 825 ~InstFakeKill() override {}
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 static void noteHead(Ice::Inst *, Ice::Inst *) {} 864 static void noteHead(Ice::Inst *, Ice::Inst *) {}
867 void deleteNode(Ice::Inst *) {} 865 void deleteNode(Ice::Inst *) {}
868 866
869 private: 867 private:
870 mutable ilist_half_node<Ice::Inst> Sentinel; 868 mutable ilist_half_node<Ice::Inst> Sentinel;
871 }; 869 };
872 870
873 } // end of namespace llvm 871 } // end of namespace llvm
874 872
875 #endif // SUBZERO_SRC_ICEINST_H 873 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceInstX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698