| 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 |