| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|