| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 158   // operand can contain 0 or 1 Variable (and target-specific operands | 158   // operand can contain 0 or 1 Variable (and target-specific operands | 
| 159   // could contain more than 1 Variable).  All the variables in an | 159   // could contain more than 1 Variable).  All the variables in an | 
| 160   // instruction are conceptually flattened and each variable is | 160   // instruction are conceptually flattened and each variable is | 
| 161   // mapped to one bit position of the LiveRangesEnded bit vector. | 161   // mapped to one bit position of the LiveRangesEnded bit vector. | 
| 162   // Only the first CHAR_BIT * sizeof(LREndedBits) variables are | 162   // Only the first CHAR_BIT * sizeof(LREndedBits) variables are | 
| 163   // tracked this way. | 163   // tracked this way. | 
| 164   typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry | 164   typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry | 
| 165   LREndedBits LiveRangesEnded; | 165   LREndedBits LiveRangesEnded; | 
| 166 | 166 | 
| 167 private: | 167 private: | 
| 168   Inst(const Inst &) LLVM_DELETED_FUNCTION; | 168   Inst(const Inst &) = delete; | 
| 169   Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION; | 169   Inst &operator=(const Inst &) = delete; | 
| 170 }; | 170 }; | 
| 171 | 171 | 
| 172 class InstHighLevel : public Inst { | 172 class InstHighLevel : public Inst { | 
| 173   InstHighLevel(const InstHighLevel &) LLVM_DELETED_FUNCTION; | 173   InstHighLevel(const InstHighLevel &) = delete; | 
| 174   InstHighLevel &operator=(const InstHighLevel &) LLVM_DELETED_FUNCTION; | 174   InstHighLevel &operator=(const InstHighLevel &) = delete; | 
| 175 | 175 | 
| 176 protected: | 176 protected: | 
| 177   InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 177   InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 
| 178       : Inst(Func, Kind, MaxSrcs, Dest) {} | 178       : Inst(Func, Kind, MaxSrcs, Dest) {} | 
| 179   void emit(const Cfg * /*Func*/) const override { | 179   void emit(const Cfg * /*Func*/) const override { | 
| 180     llvm_unreachable("emit() called on a non-lowered instruction"); | 180     llvm_unreachable("emit() called on a non-lowered instruction"); | 
| 181   } | 181   } | 
| 182   void emitIAS(const Cfg * /*Func*/) const override { | 182   void emitIAS(const Cfg * /*Func*/) const override { | 
| 183     llvm_unreachable("emitIAS() called on a non-lowered instruction"); | 183     llvm_unreachable("emitIAS() called on a non-lowered instruction"); | 
| 184   } | 184   } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 196         InstAlloca(Func, ByteCount, AlignInBytes, Dest); | 196         InstAlloca(Func, ByteCount, AlignInBytes, Dest); | 
| 197   } | 197   } | 
| 198   uint32_t getAlignInBytes() const { return AlignInBytes; } | 198   uint32_t getAlignInBytes() const { return AlignInBytes; } | 
| 199   Operand *getSizeInBytes() const { return getSrc(0); } | 199   Operand *getSizeInBytes() const { return getSrc(0); } | 
| 200   void dump(const Cfg *Func) const override; | 200   void dump(const Cfg *Func) const override; | 
| 201   static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } | 201   static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } | 
| 202 | 202 | 
| 203 private: | 203 private: | 
| 204   InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, | 204   InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, | 
| 205              Variable *Dest); | 205              Variable *Dest); | 
| 206   InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION; | 206   InstAlloca(const InstAlloca &) = delete; | 
| 207   InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION; | 207   InstAlloca &operator=(const InstAlloca &) = delete; | 
| 208   ~InstAlloca() override {} | 208   ~InstAlloca() override {} | 
| 209   const uint32_t AlignInBytes; | 209   const uint32_t AlignInBytes; | 
| 210 }; | 210 }; | 
| 211 | 211 | 
| 212 // Binary arithmetic instruction.  The source operands are captured in | 212 // Binary arithmetic instruction.  The source operands are captured in | 
| 213 // getSrc(0) and getSrc(1). | 213 // getSrc(0) and getSrc(1). | 
| 214 class InstArithmetic : public InstHighLevel { | 214 class InstArithmetic : public InstHighLevel { | 
| 215 public: | 215 public: | 
| 216   enum OpKind { | 216   enum OpKind { | 
| 217 #define X(tag, str, commutative) tag, | 217 #define X(tag, str, commutative) tag, | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 229   static const char *getOpName(OpKind Op); | 229   static const char *getOpName(OpKind Op); | 
| 230   bool isCommutative() const; | 230   bool isCommutative() const; | 
| 231   void dump(const Cfg *Func) const override; | 231   void dump(const Cfg *Func) const override; | 
| 232   static bool classof(const Inst *Inst) { | 232   static bool classof(const Inst *Inst) { | 
| 233     return Inst->getKind() == Arithmetic; | 233     return Inst->getKind() == Arithmetic; | 
| 234   } | 234   } | 
| 235 | 235 | 
| 236 private: | 236 private: | 
| 237   InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1, | 237   InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1, | 
| 238                  Operand *Source2); | 238                  Operand *Source2); | 
| 239   InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION; | 239   InstArithmetic(const InstArithmetic &) = delete; | 
| 240   InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION; | 240   InstArithmetic &operator=(const InstArithmetic &) = delete; | 
| 241   ~InstArithmetic() override {} | 241   ~InstArithmetic() override {} | 
| 242 | 242 | 
| 243   const OpKind Op; | 243   const OpKind Op; | 
| 244 }; | 244 }; | 
| 245 | 245 | 
| 246 // Assignment instruction.  The source operand is captured in | 246 // Assignment instruction.  The source operand is captured in | 
| 247 // getSrc(0).  This is not part of the LLVM bitcode, but is a useful | 247 // getSrc(0).  This is not part of the LLVM bitcode, but is a useful | 
| 248 // abstraction for some of the lowering.  E.g., if Phi instruction | 248 // abstraction for some of the lowering.  E.g., if Phi instruction | 
| 249 // lowering happens before target lowering, or for representing an | 249 // lowering happens before target lowering, or for representing an | 
| 250 // Inttoptr instruction, or as an intermediate step for lowering a | 250 // Inttoptr instruction, or as an intermediate step for lowering a | 
| 251 // Load instruction. | 251 // Load instruction. | 
| 252 class InstAssign : public InstHighLevel { | 252 class InstAssign : public InstHighLevel { | 
| 253 public: | 253 public: | 
| 254   static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { | 254   static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { | 
| 255     return new (Func->allocateInst<InstAssign>()) | 255     return new (Func->allocateInst<InstAssign>()) | 
| 256         InstAssign(Func, Dest, Source); | 256         InstAssign(Func, Dest, Source); | 
| 257   } | 257   } | 
| 258   bool isSimpleAssign() const override { return true; } | 258   bool isSimpleAssign() const override { return true; } | 
| 259   void dump(const Cfg *Func) const override; | 259   void dump(const Cfg *Func) const override; | 
| 260   static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } | 260   static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } | 
| 261 | 261 | 
| 262 private: | 262 private: | 
| 263   InstAssign(Cfg *Func, Variable *Dest, Operand *Source); | 263   InstAssign(Cfg *Func, Variable *Dest, Operand *Source); | 
| 264   InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION; | 264   InstAssign(const InstAssign &) = delete; | 
| 265   InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION; | 265   InstAssign &operator=(const InstAssign &) = delete; | 
| 266   ~InstAssign() override {} | 266   ~InstAssign() override {} | 
| 267 }; | 267 }; | 
| 268 | 268 | 
| 269 // Branch instruction.  This represents both conditional and | 269 // Branch instruction.  This represents both conditional and | 
| 270 // unconditional branches. | 270 // unconditional branches. | 
| 271 class InstBr : public InstHighLevel { | 271 class InstBr : public InstHighLevel { | 
| 272 public: | 272 public: | 
| 273   // Create a conditional branch.  If TargetTrue==TargetFalse, it is | 273   // Create a conditional branch.  If TargetTrue==TargetFalse, it is | 
| 274   // optimized to an unconditional branch. | 274   // optimized to an unconditional branch. | 
| 275   static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, | 275   static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 294   } | 294   } | 
| 295   NodeList getTerminatorEdges() const override; | 295   NodeList getTerminatorEdges() const override; | 
| 296   void dump(const Cfg *Func) const override; | 296   void dump(const Cfg *Func) const override; | 
| 297   static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } | 297   static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } | 
| 298 | 298 | 
| 299 private: | 299 private: | 
| 300   // Conditional branch | 300   // Conditional branch | 
| 301   InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); | 301   InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); | 
| 302   // Unconditional branch | 302   // Unconditional branch | 
| 303   InstBr(Cfg *Func, CfgNode *Target); | 303   InstBr(Cfg *Func, CfgNode *Target); | 
| 304   InstBr(const InstBr &) LLVM_DELETED_FUNCTION; | 304   InstBr(const InstBr &) = delete; | 
| 305   InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION; | 305   InstBr &operator=(const InstBr &) = delete; | 
| 306   ~InstBr() override {} | 306   ~InstBr() override {} | 
| 307 | 307 | 
| 308   CfgNode *const TargetFalse; // Doubles as unconditional branch target | 308   CfgNode *const TargetFalse; // Doubles as unconditional branch target | 
| 309   CfgNode *const TargetTrue;  // NULL if unconditional branch | 309   CfgNode *const TargetTrue;  // NULL if unconditional branch | 
| 310 }; | 310 }; | 
| 311 | 311 | 
| 312 // Call instruction.  The call target is captured as getSrc(0), and | 312 // Call instruction.  The call target is captured as getSrc(0), and | 
| 313 // arg I is captured as getSrc(I+1). | 313 // arg I is captured as getSrc(I+1). | 
| 314 class InstCall : public InstHighLevel { | 314 class InstCall : public InstHighLevel { | 
| 315 public: | 315 public: | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 336   InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, | 336   InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, | 
| 337            bool HasTailCall, bool HasSideEff, InstKind Kind) | 337            bool HasTailCall, bool HasSideEff, InstKind Kind) | 
| 338       : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) { | 338       : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) { | 
| 339     HasSideEffects = HasSideEff; | 339     HasSideEffects = HasSideEff; | 
| 340     addSource(CallTarget); | 340     addSource(CallTarget); | 
| 341   } | 341   } | 
| 342   ~InstCall() override {} | 342   ~InstCall() override {} | 
| 343 | 343 | 
| 344 private: | 344 private: | 
| 345   bool HasTailCall; | 345   bool HasTailCall; | 
| 346   InstCall(const InstCall &) LLVM_DELETED_FUNCTION; | 346   InstCall(const InstCall &) = delete; | 
| 347   InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION; | 347   InstCall &operator=(const InstCall &) = delete; | 
| 348 }; | 348 }; | 
| 349 | 349 | 
| 350 // Cast instruction (a.k.a. conversion operation). | 350 // Cast instruction (a.k.a. conversion operation). | 
| 351 class InstCast : public InstHighLevel { | 351 class InstCast : public InstHighLevel { | 
| 352 public: | 352 public: | 
| 353   enum OpKind { | 353   enum OpKind { | 
| 354 #define X(tag, str) tag, | 354 #define X(tag, str) tag, | 
| 355     ICEINSTCAST_TABLE | 355     ICEINSTCAST_TABLE | 
| 356 #undef X | 356 #undef X | 
| 357         _num | 357         _num | 
| 358   }; | 358   }; | 
| 359 | 359 | 
| 360   static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, | 360   static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, | 
| 361                           Operand *Source) { | 361                           Operand *Source) { | 
| 362     return new (Func->allocateInst<InstCast>()) | 362     return new (Func->allocateInst<InstCast>()) | 
| 363         InstCast(Func, CastKind, Dest, Source); | 363         InstCast(Func, CastKind, Dest, Source); | 
| 364   } | 364   } | 
| 365   OpKind getCastKind() const { return CastKind; } | 365   OpKind getCastKind() const { return CastKind; } | 
| 366   void dump(const Cfg *Func) const override; | 366   void dump(const Cfg *Func) const override; | 
| 367   static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } | 367   static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } | 
| 368 | 368 | 
| 369 private: | 369 private: | 
| 370   InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); | 370   InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); | 
| 371   InstCast(const InstCast &) LLVM_DELETED_FUNCTION; | 371   InstCast(const InstCast &) = delete; | 
| 372   InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION; | 372   InstCast &operator=(const InstCast &) = delete; | 
| 373   ~InstCast() override {} | 373   ~InstCast() override {} | 
| 374   const OpKind CastKind; | 374   const OpKind CastKind; | 
| 375 }; | 375 }; | 
| 376 | 376 | 
| 377 // ExtractElement instruction. | 377 // ExtractElement instruction. | 
| 378 class InstExtractElement : public InstHighLevel { | 378 class InstExtractElement : public InstHighLevel { | 
| 379 public: | 379 public: | 
| 380   static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 380   static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 
| 381                                     Operand *Source2) { | 381                                     Operand *Source2) { | 
| 382     return new (Func->allocateInst<InstExtractElement>()) | 382     return new (Func->allocateInst<InstExtractElement>()) | 
| 383         InstExtractElement(Func, Dest, Source1, Source2); | 383         InstExtractElement(Func, Dest, Source1, Source2); | 
| 384   } | 384   } | 
| 385 | 385 | 
| 386   void dump(const Cfg *Func) const override; | 386   void dump(const Cfg *Func) const override; | 
| 387   static bool classof(const Inst *Inst) { | 387   static bool classof(const Inst *Inst) { | 
| 388     return Inst->getKind() == ExtractElement; | 388     return Inst->getKind() == ExtractElement; | 
| 389   } | 389   } | 
| 390 | 390 | 
| 391 private: | 391 private: | 
| 392   InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, | 392   InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, | 
| 393                      Operand *Source2); | 393                      Operand *Source2); | 
| 394   InstExtractElement(const InstExtractElement &) LLVM_DELETED_FUNCTION; | 394   InstExtractElement(const InstExtractElement &) = delete; | 
| 395   InstExtractElement & | 395   InstExtractElement &operator=(const InstExtractElement &) = delete; | 
| 396   operator=(const InstExtractElement &) LLVM_DELETED_FUNCTION; |  | 
| 397   ~InstExtractElement() override {} | 396   ~InstExtractElement() override {} | 
| 398 }; | 397 }; | 
| 399 | 398 | 
| 400 // Floating-point comparison instruction.  The source operands are | 399 // Floating-point comparison instruction.  The source operands are | 
| 401 // captured in getSrc(0) and getSrc(1). | 400 // captured in getSrc(0) and getSrc(1). | 
| 402 class InstFcmp : public InstHighLevel { | 401 class InstFcmp : public InstHighLevel { | 
| 403 public: | 402 public: | 
| 404   enum FCond { | 403   enum FCond { | 
| 405 #define X(tag, str) tag, | 404 #define X(tag, str) tag, | 
| 406     ICEINSTFCMP_TABLE | 405     ICEINSTFCMP_TABLE | 
| 407 #undef X | 406 #undef X | 
| 408         _num | 407         _num | 
| 409   }; | 408   }; | 
| 410 | 409 | 
| 411   static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, | 410   static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, | 
| 412                           Operand *Source1, Operand *Source2) { | 411                           Operand *Source1, Operand *Source2) { | 
| 413     return new (Func->allocateInst<InstFcmp>()) | 412     return new (Func->allocateInst<InstFcmp>()) | 
| 414         InstFcmp(Func, Condition, Dest, Source1, Source2); | 413         InstFcmp(Func, Condition, Dest, Source1, Source2); | 
| 415   } | 414   } | 
| 416   FCond getCondition() const { return Condition; } | 415   FCond getCondition() const { return Condition; } | 
| 417   void dump(const Cfg *Func) const override; | 416   void dump(const Cfg *Func) const override; | 
| 418   static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } | 417   static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } | 
| 419 | 418 | 
| 420 private: | 419 private: | 
| 421   InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, | 420   InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, | 
| 422            Operand *Source2); | 421            Operand *Source2); | 
| 423   InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION; | 422   InstFcmp(const InstFcmp &) = delete; | 
| 424   InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION; | 423   InstFcmp &operator=(const InstFcmp &) = delete; | 
| 425   ~InstFcmp() override {} | 424   ~InstFcmp() override {} | 
| 426   const FCond Condition; | 425   const FCond Condition; | 
| 427 }; | 426 }; | 
| 428 | 427 | 
| 429 // Integer comparison instruction.  The source operands are captured | 428 // Integer comparison instruction.  The source operands are captured | 
| 430 // in getSrc(0) and getSrc(1). | 429 // in getSrc(0) and getSrc(1). | 
| 431 class InstIcmp : public InstHighLevel { | 430 class InstIcmp : public InstHighLevel { | 
| 432 public: | 431 public: | 
| 433   enum ICond { | 432   enum ICond { | 
| 434 #define X(tag, str) tag, | 433 #define X(tag, str) tag, | 
| 435     ICEINSTICMP_TABLE | 434     ICEINSTICMP_TABLE | 
| 436 #undef X | 435 #undef X | 
| 437         _num | 436         _num | 
| 438   }; | 437   }; | 
| 439 | 438 | 
| 440   static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, | 439   static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, | 
| 441                           Operand *Source1, Operand *Source2) { | 440                           Operand *Source1, Operand *Source2) { | 
| 442     return new (Func->allocateInst<InstIcmp>()) | 441     return new (Func->allocateInst<InstIcmp>()) | 
| 443         InstIcmp(Func, Condition, Dest, Source1, Source2); | 442         InstIcmp(Func, Condition, Dest, Source1, Source2); | 
| 444   } | 443   } | 
| 445   ICond getCondition() const { return Condition; } | 444   ICond getCondition() const { return Condition; } | 
| 446   void dump(const Cfg *Func) const override; | 445   void dump(const Cfg *Func) const override; | 
| 447   static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } | 446   static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } | 
| 448 | 447 | 
| 449 private: | 448 private: | 
| 450   InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 449   InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 
| 451            Operand *Source2); | 450            Operand *Source2); | 
| 452   InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION; | 451   InstIcmp(const InstIcmp &) = delete; | 
| 453   InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION; | 452   InstIcmp &operator=(const InstIcmp &) = delete; | 
| 454   ~InstIcmp() override {} | 453   ~InstIcmp() override {} | 
| 455   const ICond Condition; | 454   const ICond Condition; | 
| 456 }; | 455 }; | 
| 457 | 456 | 
| 458 // InsertElement instruction. | 457 // InsertElement instruction. | 
| 459 class InstInsertElement : public InstHighLevel { | 458 class InstInsertElement : public InstHighLevel { | 
| 460 public: | 459 public: | 
| 461   static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 460   static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 
| 462                                    Operand *Source2, Operand *Source3) { | 461                                    Operand *Source2, Operand *Source3) { | 
| 463     return new (Func->allocateInst<InstInsertElement>()) | 462     return new (Func->allocateInst<InstInsertElement>()) | 
| 464         InstInsertElement(Func, Dest, Source1, Source2, Source3); | 463         InstInsertElement(Func, Dest, Source1, Source2, Source3); | 
| 465   } | 464   } | 
| 466 | 465 | 
| 467   void dump(const Cfg *Func) const override; | 466   void dump(const Cfg *Func) const override; | 
| 468   static bool classof(const Inst *Inst) { | 467   static bool classof(const Inst *Inst) { | 
| 469     return Inst->getKind() == InsertElement; | 468     return Inst->getKind() == InsertElement; | 
| 470   } | 469   } | 
| 471 | 470 | 
| 472 private: | 471 private: | 
| 473   InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, | 472   InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, | 
| 474                     Operand *Source2, Operand *Source3); | 473                     Operand *Source2, Operand *Source3); | 
| 475   InstInsertElement(const InstInsertElement &) LLVM_DELETED_FUNCTION; | 474   InstInsertElement(const InstInsertElement &) = delete; | 
| 476   InstInsertElement &operator=(const InstInsertElement &) LLVM_DELETED_FUNCTION; | 475   InstInsertElement &operator=(const InstInsertElement &) = delete; | 
| 477   ~InstInsertElement() override {} | 476   ~InstInsertElement() override {} | 
| 478 }; | 477 }; | 
| 479 | 478 | 
| 480 // Call to an intrinsic function.  The call target is captured as getSrc(0), | 479 // Call to an intrinsic function.  The call target is captured as getSrc(0), | 
| 481 // and arg I is captured as getSrc(I+1). | 480 // and arg I is captured as getSrc(I+1). | 
| 482 class InstIntrinsicCall : public InstCall { | 481 class InstIntrinsicCall : public InstCall { | 
| 483 public: | 482 public: | 
| 484   static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | 483   static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | 
| 485                                    Operand *CallTarget, | 484                                    Operand *CallTarget, | 
| 486                                    const Intrinsics::IntrinsicInfo &Info) { | 485                                    const Intrinsics::IntrinsicInfo &Info) { | 
| 487     return new (Func->allocateInst<InstIntrinsicCall>()) | 486     return new (Func->allocateInst<InstIntrinsicCall>()) | 
| 488         InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); | 487         InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); | 
| 489   } | 488   } | 
| 490   static bool classof(const Inst *Inst) { | 489   static bool classof(const Inst *Inst) { | 
| 491     return Inst->getKind() == IntrinsicCall; | 490     return Inst->getKind() == IntrinsicCall; | 
| 492   } | 491   } | 
| 493 | 492 | 
| 494   Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } | 493   Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } | 
| 495 | 494 | 
| 496 private: | 495 private: | 
| 497   InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, | 496   InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, | 
| 498                     Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) | 497                     Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) | 
| 499       : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, | 498       : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, | 
| 500                  Inst::IntrinsicCall), | 499                  Inst::IntrinsicCall), | 
| 501         Info(Info) {} | 500         Info(Info) {} | 
| 502   InstIntrinsicCall(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; | 501   InstIntrinsicCall(const InstIntrinsicCall &) = delete; | 
| 503   InstIntrinsicCall &operator=(const InstIntrinsicCall &) LLVM_DELETED_FUNCTION; | 502   InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete; | 
| 504   ~InstIntrinsicCall() override {} | 503   ~InstIntrinsicCall() override {} | 
| 505   const Intrinsics::IntrinsicInfo Info; | 504   const Intrinsics::IntrinsicInfo Info; | 
| 506 }; | 505 }; | 
| 507 | 506 | 
| 508 // Load instruction.  The source address is captured in getSrc(0). | 507 // Load instruction.  The source address is captured in getSrc(0). | 
| 509 class InstLoad : public InstHighLevel { | 508 class InstLoad : public InstHighLevel { | 
| 510 public: | 509 public: | 
| 511   static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, | 510   static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, | 
| 512                           uint32_t Align = 1) { | 511                           uint32_t Align = 1) { | 
| 513     // TODO(kschimpf) Stop ignoring alignment specification. | 512     // TODO(kschimpf) Stop ignoring alignment specification. | 
| 514     (void)Align; | 513     (void)Align; | 
| 515     return new (Func->allocateInst<InstLoad>()) | 514     return new (Func->allocateInst<InstLoad>()) | 
| 516         InstLoad(Func, Dest, SourceAddr); | 515         InstLoad(Func, Dest, SourceAddr); | 
| 517   } | 516   } | 
| 518   Operand *getSourceAddress() const { return getSrc(0); } | 517   Operand *getSourceAddress() const { return getSrc(0); } | 
| 519   void dump(const Cfg *Func) const override; | 518   void dump(const Cfg *Func) const override; | 
| 520   static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | 519   static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | 
| 521 | 520 | 
| 522 private: | 521 private: | 
| 523   InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); | 522   InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); | 
| 524   InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION; | 523   InstLoad(const InstLoad &) = delete; | 
| 525   InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION; | 524   InstLoad &operator=(const InstLoad &) = delete; | 
| 526   ~InstLoad() override {} | 525   ~InstLoad() override {} | 
| 527 }; | 526 }; | 
| 528 | 527 | 
| 529 // Phi instruction.  For incoming edge I, the node is Labels[I] and | 528 // Phi instruction.  For incoming edge I, the node is Labels[I] and | 
| 530 // the Phi source operand is getSrc(I). | 529 // the Phi source operand is getSrc(I). | 
| 531 class InstPhi : public InstHighLevel { | 530 class InstPhi : public InstHighLevel { | 
| 532 public: | 531 public: | 
| 533   static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { | 532   static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { | 
| 534     return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); | 533     return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); | 
| 535   } | 534   } | 
| 536   void addArgument(Operand *Source, CfgNode *Label); | 535   void addArgument(Operand *Source, CfgNode *Label); | 
| 537   Operand *getOperandForTarget(CfgNode *Target) const; | 536   Operand *getOperandForTarget(CfgNode *Target) const; | 
| 538   void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target, | 537   void livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target, | 
| 539                           Liveness *Liveness); | 538                           Liveness *Liveness); | 
| 540   Inst *lower(Cfg *Func); | 539   Inst *lower(Cfg *Func); | 
| 541   void dump(const Cfg *Func) const override; | 540   void dump(const Cfg *Func) const override; | 
| 542   static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } | 541   static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } | 
| 543 | 542 | 
| 544 private: | 543 private: | 
| 545   InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); | 544   InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); | 
| 546   InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION; | 545   InstPhi(const InstPhi &) = delete; | 
| 547   InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION; | 546   InstPhi &operator=(const InstPhi &) = delete; | 
| 548   void destroy(Cfg *Func) override { | 547   void destroy(Cfg *Func) override { | 
| 549     Func->deallocateArrayOf<CfgNode *>(Labels); | 548     Func->deallocateArrayOf<CfgNode *>(Labels); | 
| 550     Inst::destroy(Func); | 549     Inst::destroy(Func); | 
| 551   } | 550   } | 
| 552   ~InstPhi() override {} | 551   ~InstPhi() override {} | 
| 553 | 552 | 
| 554   // Labels[] duplicates the InEdges[] information in the enclosing | 553   // Labels[] duplicates the InEdges[] information in the enclosing | 
| 555   // CfgNode, but the Phi instruction is created before InEdges[] | 554   // CfgNode, but the Phi instruction is created before InEdges[] | 
| 556   // is available, so it's more complicated to share the list. | 555   // is available, so it's more complicated to share the list. | 
| 557   CfgNode **Labels; | 556   CfgNode **Labels; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 569   Operand *getRetValue() const { | 568   Operand *getRetValue() const { | 
| 570     assert(hasRetValue()); | 569     assert(hasRetValue()); | 
| 571     return getSrc(0); | 570     return getSrc(0); | 
| 572   } | 571   } | 
| 573   NodeList getTerminatorEdges() const override { return NodeList(); } | 572   NodeList getTerminatorEdges() const override { return NodeList(); } | 
| 574   void dump(const Cfg *Func) const override; | 573   void dump(const Cfg *Func) const override; | 
| 575   static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } | 574   static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } | 
| 576 | 575 | 
| 577 private: | 576 private: | 
| 578   InstRet(Cfg *Func, Operand *RetValue); | 577   InstRet(Cfg *Func, Operand *RetValue); | 
| 579   InstRet(const InstRet &) LLVM_DELETED_FUNCTION; | 578   InstRet(const InstRet &) = delete; | 
| 580   InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION; | 579   InstRet &operator=(const InstRet &) = delete; | 
| 581   ~InstRet() override {} | 580   ~InstRet() override {} | 
| 582 }; | 581 }; | 
| 583 | 582 | 
| 584 // Select instruction.  The condition, true, and false operands are captured. | 583 // Select instruction.  The condition, true, and false operands are captured. | 
| 585 class InstSelect : public InstHighLevel { | 584 class InstSelect : public InstHighLevel { | 
| 586 public: | 585 public: | 
| 587   static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, | 586   static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, | 
| 588                             Operand *SourceTrue, Operand *SourceFalse) { | 587                             Operand *SourceTrue, Operand *SourceFalse) { | 
| 589     return new (Func->allocateInst<InstSelect>()) | 588     return new (Func->allocateInst<InstSelect>()) | 
| 590         InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); | 589         InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); | 
| 591   } | 590   } | 
| 592   Operand *getCondition() const { return getSrc(0); } | 591   Operand *getCondition() const { return getSrc(0); } | 
| 593   Operand *getTrueOperand() const { return getSrc(1); } | 592   Operand *getTrueOperand() const { return getSrc(1); } | 
| 594   Operand *getFalseOperand() const { return getSrc(2); } | 593   Operand *getFalseOperand() const { return getSrc(2); } | 
| 595   void dump(const Cfg *Func) const override; | 594   void dump(const Cfg *Func) const override; | 
| 596   static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } | 595   static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } | 
| 597 | 596 | 
| 598 private: | 597 private: | 
| 599   InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, | 598   InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, | 
| 600              Operand *Source2); | 599              Operand *Source2); | 
| 601   InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION; | 600   InstSelect(const InstSelect &) = delete; | 
| 602   InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION; | 601   InstSelect &operator=(const InstSelect &) = delete; | 
| 603   ~InstSelect() override {} | 602   ~InstSelect() override {} | 
| 604 }; | 603 }; | 
| 605 | 604 | 
| 606 // Store instruction.  The address operand is captured, along with the | 605 // Store instruction.  The address operand is captured, along with the | 
| 607 // data operand to be stored into the address. | 606 // data operand to be stored into the address. | 
| 608 class InstStore : public InstHighLevel { | 607 class InstStore : public InstHighLevel { | 
| 609 public: | 608 public: | 
| 610   static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, | 609   static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, | 
| 611                            uint32_t align = 1) { | 610                            uint32_t align = 1) { | 
| 612     // TODO(kschimpf) Stop ignoring alignment specification. | 611     // TODO(kschimpf) Stop ignoring alignment specification. | 
| 613     (void)align; | 612     (void)align; | 
| 614     return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr); | 613     return new (Func->allocateInst<InstStore>()) InstStore(Func, Data, Addr); | 
| 615   } | 614   } | 
| 616   Operand *getAddr() const { return getSrc(1); } | 615   Operand *getAddr() const { return getSrc(1); } | 
| 617   Operand *getData() const { return getSrc(0); } | 616   Operand *getData() const { return getSrc(0); } | 
| 618   void dump(const Cfg *Func) const override; | 617   void dump(const Cfg *Func) const override; | 
| 619   static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } | 618   static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } | 
| 620 | 619 | 
| 621 private: | 620 private: | 
| 622   InstStore(Cfg *Func, Operand *Data, Operand *Addr); | 621   InstStore(Cfg *Func, Operand *Data, Operand *Addr); | 
| 623   InstStore(const InstStore &) LLVM_DELETED_FUNCTION; | 622   InstStore(const InstStore &) = delete; | 
| 624   InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION; | 623   InstStore &operator=(const InstStore &) = delete; | 
| 625   ~InstStore() override {} | 624   ~InstStore() override {} | 
| 626 }; | 625 }; | 
| 627 | 626 | 
| 628 // Switch instruction.  The single source operand is captured as | 627 // Switch instruction.  The single source operand is captured as | 
| 629 // getSrc(0). | 628 // getSrc(0). | 
| 630 class InstSwitch : public InstHighLevel { | 629 class InstSwitch : public InstHighLevel { | 
| 631 public: | 630 public: | 
| 632   static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, | 631   static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, | 
| 633                             CfgNode *LabelDefault) { | 632                             CfgNode *LabelDefault) { | 
| 634     return new (Func->allocateInst<InstSwitch>()) | 633     return new (Func->allocateInst<InstSwitch>()) | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 645     assert(I < NumCases); | 644     assert(I < NumCases); | 
| 646     return Labels[I]; | 645     return Labels[I]; | 
| 647   } | 646   } | 
| 648   void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label); | 647   void addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label); | 
| 649   NodeList getTerminatorEdges() const override; | 648   NodeList getTerminatorEdges() const override; | 
| 650   void dump(const Cfg *Func) const override; | 649   void dump(const Cfg *Func) const override; | 
| 651   static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } | 650   static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } | 
| 652 | 651 | 
| 653 private: | 652 private: | 
| 654   InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); | 653   InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); | 
| 655   InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION; | 654   InstSwitch(const InstSwitch &) = delete; | 
| 656   InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION; | 655   InstSwitch &operator=(const InstSwitch &) = delete; | 
| 657   void destroy(Cfg *Func) override { | 656   void destroy(Cfg *Func) override { | 
| 658     Func->deallocateArrayOf<uint64_t>(Values); | 657     Func->deallocateArrayOf<uint64_t>(Values); | 
| 659     Func->deallocateArrayOf<CfgNode *>(Labels); | 658     Func->deallocateArrayOf<CfgNode *>(Labels); | 
| 660     Inst::destroy(Func); | 659     Inst::destroy(Func); | 
| 661   } | 660   } | 
| 662   ~InstSwitch() override {} | 661   ~InstSwitch() override {} | 
| 663 | 662 | 
| 664   CfgNode *LabelDefault; | 663   CfgNode *LabelDefault; | 
| 665   SizeT NumCases;   // not including the default case | 664   SizeT NumCases;   // not including the default case | 
| 666   uint64_t *Values; // size is NumCases | 665   uint64_t *Values; // size is NumCases | 
| 667   CfgNode **Labels; // size is NumCases | 666   CfgNode **Labels; // size is NumCases | 
| 668 }; | 667 }; | 
| 669 | 668 | 
| 670 // Unreachable instruction.  This is a terminator instruction with no | 669 // Unreachable instruction.  This is a terminator instruction with no | 
| 671 // operands. | 670 // operands. | 
| 672 class InstUnreachable : public InstHighLevel { | 671 class InstUnreachable : public InstHighLevel { | 
| 673 public: | 672 public: | 
| 674   static InstUnreachable *create(Cfg *Func) { | 673   static InstUnreachable *create(Cfg *Func) { | 
| 675     return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func); | 674     return new (Func->allocateInst<InstUnreachable>()) InstUnreachable(Func); | 
| 676   } | 675   } | 
| 677   NodeList getTerminatorEdges() const override { return NodeList(); } | 676   NodeList getTerminatorEdges() const override { return NodeList(); } | 
| 678   void dump(const Cfg *Func) const override; | 677   void dump(const Cfg *Func) const override; | 
| 679   static bool classof(const Inst *Inst) { | 678   static bool classof(const Inst *Inst) { | 
| 680     return Inst->getKind() == Unreachable; | 679     return Inst->getKind() == Unreachable; | 
| 681   } | 680   } | 
| 682 | 681 | 
| 683 private: | 682 private: | 
| 684   InstUnreachable(Cfg *Func); | 683   InstUnreachable(Cfg *Func); | 
| 685   InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION; | 684   InstUnreachable(const InstUnreachable &) = delete; | 
| 686   InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION; | 685   InstUnreachable &operator=(const InstUnreachable &) = delete; | 
| 687   ~InstUnreachable() override {} | 686   ~InstUnreachable() override {} | 
| 688 }; | 687 }; | 
| 689 | 688 | 
| 690 // FakeDef instruction.  This creates a fake definition of a variable, | 689 // FakeDef instruction.  This creates a fake definition of a variable, | 
| 691 // which is how we represent the case when an instruction produces | 690 // which is how we represent the case when an instruction produces | 
| 692 // multiple results.  This doesn't happen with high-level ICE | 691 // multiple results.  This doesn't happen with high-level ICE | 
| 693 // instructions, but might with lowered instructions.  For example, | 692 // instructions, but might with lowered instructions.  For example, | 
| 694 // this would be a way to represent condition flags being modified by | 693 // this would be a way to represent condition flags being modified by | 
| 695 // an instruction. | 694 // an instruction. | 
| 696 // | 695 // | 
| 697 // It's generally useful to set the optional source operand to be the | 696 // It's generally useful to set the optional source operand to be the | 
| 698 // dest variable of the instruction that actually produces the FakeDef | 697 // dest variable of the instruction that actually produces the FakeDef | 
| 699 // dest.  Otherwise, the original instruction could be dead-code | 698 // dest.  Otherwise, the original instruction could be dead-code | 
| 700 // eliminated if its dest operand is unused, and therefore the FakeDef | 699 // eliminated if its dest operand is unused, and therefore the FakeDef | 
| 701 // dest wouldn't be properly initialized. | 700 // dest wouldn't be properly initialized. | 
| 702 class InstFakeDef : public InstHighLevel { | 701 class InstFakeDef : public InstHighLevel { | 
| 703 public: | 702 public: | 
| 704   static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) { | 703   static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) { | 
| 705     return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src); | 704     return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src); | 
| 706   } | 705   } | 
| 707   void emit(const Cfg *Func) const override; | 706   void emit(const Cfg *Func) const override; | 
| 708   void emitIAS(const Cfg *Func) const override { emit(Func); } | 707   void emitIAS(const Cfg *Func) const override { emit(Func); } | 
| 709   void dump(const Cfg *Func) const override; | 708   void dump(const Cfg *Func) const override; | 
| 710   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } | 709   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } | 
| 711 | 710 | 
| 712 private: | 711 private: | 
| 713   InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); | 712   InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); | 
| 714   InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION; | 713   InstFakeDef(const InstFakeDef &) = delete; | 
| 715   InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION; | 714   InstFakeDef &operator=(const InstFakeDef &) = delete; | 
| 716   ~InstFakeDef() override {} | 715   ~InstFakeDef() override {} | 
| 717 }; | 716 }; | 
| 718 | 717 | 
| 719 // FakeUse instruction.  This creates a fake use of a variable, to | 718 // FakeUse instruction.  This creates a fake use of a variable, to | 
| 720 // keep the instruction that produces that variable from being | 719 // keep the instruction that produces that variable from being | 
| 721 // dead-code eliminated.  This is useful in a variety of lowering | 720 // dead-code eliminated.  This is useful in a variety of lowering | 
| 722 // situations.  The FakeUse instruction has no dest, so it can itself | 721 // situations.  The FakeUse instruction has no dest, so it can itself | 
| 723 // never be dead-code eliminated. | 722 // never be dead-code eliminated. | 
| 724 class InstFakeUse : public InstHighLevel { | 723 class InstFakeUse : public InstHighLevel { | 
| 725 public: | 724 public: | 
| 726   static InstFakeUse *create(Cfg *Func, Variable *Src) { | 725   static InstFakeUse *create(Cfg *Func, Variable *Src) { | 
| 727     return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src); | 726     return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src); | 
| 728   } | 727   } | 
| 729   void emit(const Cfg *Func) const override; | 728   void emit(const Cfg *Func) const override; | 
| 730   void emitIAS(const Cfg *Func) const override { emit(Func); } | 729   void emitIAS(const Cfg *Func) const override { emit(Func); } | 
| 731   void dump(const Cfg *Func) const override; | 730   void dump(const Cfg *Func) const override; | 
| 732   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } | 731   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } | 
| 733 | 732 | 
| 734 private: | 733 private: | 
| 735   InstFakeUse(Cfg *Func, Variable *Src); | 734   InstFakeUse(Cfg *Func, Variable *Src); | 
| 736   InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION; | 735   InstFakeUse(const InstFakeUse &) = delete; | 
| 737   InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION; | 736   InstFakeUse &operator=(const InstFakeUse &) = delete; | 
| 738   ~InstFakeUse() override {} | 737   ~InstFakeUse() override {} | 
| 739 }; | 738 }; | 
| 740 | 739 | 
| 741 // FakeKill instruction.  This "kills" a set of variables by adding a | 740 // FakeKill instruction.  This "kills" a set of variables by adding a | 
| 742 // trivial live range at this instruction to each variable.  The | 741 // trivial live range at this instruction to each variable.  The | 
| 743 // primary use is to indicate that scratch registers are killed after | 742 // primary use is to indicate that scratch registers are killed after | 
| 744 // a call, so that the register allocator won't assign a scratch | 743 // a call, so that the register allocator won't assign a scratch | 
| 745 // register to a variable whose live range spans a call. | 744 // register to a variable whose live range spans a call. | 
| 746 // | 745 // | 
| 747 // The FakeKill instruction also holds a pointer to the instruction | 746 // The FakeKill instruction also holds a pointer to the instruction | 
| 748 // that kills the set of variables, so that if that linked instruction | 747 // that kills the set of variables, so that if that linked instruction | 
| 749 // gets dead-code eliminated, the FakeKill instruction will as well. | 748 // gets dead-code eliminated, the FakeKill instruction will as well. | 
| 750 class InstFakeKill : public InstHighLevel { | 749 class InstFakeKill : public InstHighLevel { | 
| 751 public: | 750 public: | 
| 752   static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs, | 751   static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs, | 
| 753                               const Inst *Linked) { | 752                               const Inst *Linked) { | 
| 754     return new (Func->allocateInst<InstFakeKill>()) | 753     return new (Func->allocateInst<InstFakeKill>()) | 
| 755         InstFakeKill(Func, KilledRegs, Linked); | 754         InstFakeKill(Func, KilledRegs, Linked); | 
| 756   } | 755   } | 
| 757   const Inst *getLinked() const { return Linked; } | 756   const Inst *getLinked() const { return Linked; } | 
| 758   void emit(const Cfg *Func) const override; | 757   void emit(const Cfg *Func) const override; | 
| 759   void emitIAS(const Cfg *Func) const override { emit(Func); } | 758   void emitIAS(const Cfg *Func) const override { emit(Func); } | 
| 760   void dump(const Cfg *Func) const override; | 759   void dump(const Cfg *Func) const override; | 
| 761   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } | 760   static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } | 
| 762 | 761 | 
| 763 private: | 762 private: | 
| 764   InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked); | 763   InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked); | 
| 765   InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION; | 764   InstFakeKill(const InstFakeKill &) = delete; | 
| 766   InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION; | 765   InstFakeKill &operator=(const InstFakeKill &) = delete; | 
| 767   ~InstFakeKill() override {} | 766   ~InstFakeKill() override {} | 
| 768 | 767 | 
| 769   // This instruction is ignored if Linked->isDeleted() is true. | 768   // This instruction is ignored if Linked->isDeleted() is true. | 
| 770   const Inst *Linked; | 769   const Inst *Linked; | 
| 771 }; | 770 }; | 
| 772 | 771 | 
| 773 // The Target instruction is the base class for all target-specific | 772 // The Target instruction is the base class for all target-specific | 
| 774 // instructions. | 773 // instructions. | 
| 775 class InstTarget : public Inst { | 774 class InstTarget : public Inst { | 
| 776   InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; | 775   InstTarget(const InstTarget &) = delete; | 
| 777   InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; | 776   InstTarget &operator=(const InstTarget &) = delete; | 
| 778 | 777 | 
| 779 public: | 778 public: | 
| 780   uint32_t getEmitInstCount() const override { return 1; } | 779   uint32_t getEmitInstCount() const override { return 1; } | 
| 781   void dump(const Cfg *Func) const override; | 780   void dump(const Cfg *Func) const override; | 
| 782   static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } | 781   static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } | 
| 783 | 782 | 
| 784 protected: | 783 protected: | 
| 785   InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 784   InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 
| 786       : Inst(Func, Kind, MaxSrcs, Dest) { | 785       : Inst(Func, Kind, MaxSrcs, Dest) { | 
| 787     assert(Kind >= Target); | 786     assert(Kind >= Target); | 
| 788   } | 787   } | 
| 789   void emitIAS(const Cfg *Func) const override { emit(Func); } | 788   void emitIAS(const Cfg *Func) const override { emit(Func); } | 
| 790   ~InstTarget() override {} | 789   ~InstTarget() override {} | 
| 791 }; | 790 }; | 
| 792 | 791 | 
| 793 } // end of namespace Ice | 792 } // end of namespace Ice | 
| 794 | 793 | 
| 795 #endif // SUBZERO_SRC_ICEINST_H | 794 #endif // SUBZERO_SRC_ICEINST_H | 
| OLD | NEW | 
|---|