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 17 matching lines...) Expand all Loading... |
28 // We need a list of everything that should be validated, and tests | 28 // We need a list of everything that should be validated, and tests |
29 // for each. | 29 // for each. |
30 | 30 |
31 namespace Ice { | 31 namespace Ice { |
32 | 32 |
33 // Base instruction class for ICE. Inst has two subclasses: | 33 // Base instruction class for ICE. Inst has two subclasses: |
34 // InstHighLevel and InstTarget. High-level ICE instructions inherit | 34 // InstHighLevel and InstTarget. High-level ICE instructions inherit |
35 // from InstHighLevel, and low-level (target-specific) ICE | 35 // from InstHighLevel, and low-level (target-specific) ICE |
36 // instructions inherit from InstTarget. | 36 // instructions inherit from InstTarget. |
37 class Inst : public llvm::ilist_node<Inst> { | 37 class Inst : public llvm::ilist_node<Inst> { |
| 38 Inst() = delete; |
38 Inst(const Inst &) = delete; | 39 Inst(const Inst &) = delete; |
39 Inst &operator=(const Inst &) = delete; | 40 Inst &operator=(const Inst &) = delete; |
40 | 41 |
41 public: | 42 public: |
42 enum InstKind { | 43 enum InstKind { |
43 // Arbitrary (alphabetical) order, except put Unreachable first. | 44 // Arbitrary (alphabetical) order, except put Unreachable first. |
44 Unreachable, | 45 Unreachable, |
45 Alloca, | 46 Alloca, |
46 Arithmetic, | 47 Arithmetic, |
47 Assign, // not part of LLVM/PNaCl bitcode | |
48 Br, | 48 Br, |
49 Call, | 49 Call, |
50 Cast, | 50 Cast, |
51 ExtractElement, | 51 ExtractElement, |
52 Fcmp, | 52 Fcmp, |
53 Icmp, | 53 Icmp, |
54 IntrinsicCall, | 54 IntrinsicCall, |
55 InsertElement, | 55 InsertElement, |
56 Load, | 56 Load, |
57 Phi, | 57 Phi, |
58 Ret, | 58 Ret, |
59 Select, | 59 Select, |
60 Store, | 60 Store, |
61 Switch, | 61 Switch, |
| 62 Assign, // not part of LLVM/PNaCl bitcode |
62 BundleLock, // not part of LLVM/PNaCl bitcode | 63 BundleLock, // not part of LLVM/PNaCl bitcode |
63 BundleUnlock, // not part of LLVM/PNaCl bitcode | 64 BundleUnlock, // not part of LLVM/PNaCl bitcode |
64 FakeDef, // not part of LLVM/PNaCl bitcode | 65 FakeDef, // not part of LLVM/PNaCl bitcode |
65 FakeUse, // not part of LLVM/PNaCl bitcode | 66 FakeUse, // not part of LLVM/PNaCl bitcode |
66 FakeKill, // not part of LLVM/PNaCl bitcode | 67 FakeKill, // not part of LLVM/PNaCl bitcode |
67 Target // target-specific low-level ICE | 68 Target // target-specific low-level ICE |
68 // Anything >= Target is an InstTarget subclass. | 69 // Anything >= Target is an InstTarget subclass. |
69 }; | 70 }; |
70 InstKind getKind() const { return Kind; } | 71 InstKind getKind() const { return Kind; } |
71 | 72 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // could contain more than 1 Variable). All the variables in an | 201 // could contain more than 1 Variable). All the variables in an |
201 // instruction are conceptually flattened and each variable is | 202 // instruction are conceptually flattened and each variable is |
202 // mapped to one bit position of the LiveRangesEnded bit vector. | 203 // mapped to one bit position of the LiveRangesEnded bit vector. |
203 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are | 204 // Only the first CHAR_BIT * sizeof(LREndedBits) variables are |
204 // tracked this way. | 205 // tracked this way. |
205 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry | 206 typedef uint32_t LREndedBits; // only first 32 src operands tracked, sorry |
206 LREndedBits LiveRangesEnded; | 207 LREndedBits LiveRangesEnded; |
207 }; | 208 }; |
208 | 209 |
209 class InstHighLevel : public Inst { | 210 class InstHighLevel : public Inst { |
| 211 InstHighLevel() = delete; |
210 InstHighLevel(const InstHighLevel &) = delete; | 212 InstHighLevel(const InstHighLevel &) = delete; |
211 InstHighLevel &operator=(const InstHighLevel &) = delete; | 213 InstHighLevel &operator=(const InstHighLevel &) = delete; |
212 | 214 |
213 protected: | 215 protected: |
214 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 216 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) |
215 : Inst(Func, Kind, MaxSrcs, Dest) {} | 217 : Inst(Func, Kind, MaxSrcs, Dest) {} |
216 void emit(const Cfg * /*Func*/) const override { | 218 void emit(const Cfg * /*Func*/) const override { |
217 llvm_unreachable("emit() called on a non-lowered instruction"); | 219 llvm_unreachable("emit() called on a non-lowered instruction"); |
218 } | 220 } |
219 void emitIAS(const Cfg * /*Func*/) const override { | 221 void emitIAS(const Cfg * /*Func*/) const override { |
220 llvm_unreachable("emitIAS() called on a non-lowered instruction"); | 222 llvm_unreachable("emitIAS() called on a non-lowered instruction"); |
221 } | 223 } |
222 ~InstHighLevel() override {} | 224 ~InstHighLevel() override {} |
223 }; | 225 }; |
224 | 226 |
225 // Alloca instruction. This captures the size in bytes as getSrc(0), | 227 // Alloca instruction. This captures the size in bytes as getSrc(0), |
226 // and the required alignment in bytes. The alignment must be either | 228 // and the required alignment in bytes. The alignment must be either |
227 // 0 (no alignment required) or a power of 2. | 229 // 0 (no alignment required) or a power of 2. |
228 class InstAlloca : public InstHighLevel { | 230 class InstAlloca : public InstHighLevel { |
| 231 InstAlloca() = delete; |
229 InstAlloca(const InstAlloca &) = delete; | 232 InstAlloca(const InstAlloca &) = delete; |
230 InstAlloca &operator=(const InstAlloca &) = delete; | 233 InstAlloca &operator=(const InstAlloca &) = delete; |
231 | 234 |
232 public: | 235 public: |
233 static InstAlloca *create(Cfg *Func, Operand *ByteCount, | 236 static InstAlloca *create(Cfg *Func, Operand *ByteCount, |
234 uint32_t AlignInBytes, Variable *Dest) { | 237 uint32_t AlignInBytes, Variable *Dest) { |
235 return new (Func->allocate<InstAlloca>()) | 238 return new (Func->allocate<InstAlloca>()) |
236 InstAlloca(Func, ByteCount, AlignInBytes, Dest); | 239 InstAlloca(Func, ByteCount, AlignInBytes, Dest); |
237 } | 240 } |
238 uint32_t getAlignInBytes() const { return AlignInBytes; } | 241 uint32_t getAlignInBytes() const { return AlignInBytes; } |
239 Operand *getSizeInBytes() const { return getSrc(0); } | 242 Operand *getSizeInBytes() const { return getSrc(0); } |
240 void dump(const Cfg *Func) const override; | 243 void dump(const Cfg *Func) const override; |
241 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } | 244 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } |
242 | 245 |
243 private: | 246 private: |
244 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, | 247 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, |
245 Variable *Dest); | 248 Variable *Dest); |
246 ~InstAlloca() override {} | 249 ~InstAlloca() override {} |
247 const uint32_t AlignInBytes; | 250 const uint32_t AlignInBytes; |
248 }; | 251 }; |
249 | 252 |
250 // Binary arithmetic instruction. The source operands are captured in | 253 // Binary arithmetic instruction. The source operands are captured in |
251 // getSrc(0) and getSrc(1). | 254 // getSrc(0) and getSrc(1). |
252 class InstArithmetic : public InstHighLevel { | 255 class InstArithmetic : public InstHighLevel { |
| 256 InstArithmetic() = delete; |
253 InstArithmetic(const InstArithmetic &) = delete; | 257 InstArithmetic(const InstArithmetic &) = delete; |
254 InstArithmetic &operator=(const InstArithmetic &) = delete; | 258 InstArithmetic &operator=(const InstArithmetic &) = delete; |
255 | 259 |
256 public: | 260 public: |
257 enum OpKind { | 261 enum OpKind { |
258 #define X(tag, str, commutative) tag, | 262 #define X(tag, str, commutative) tag, |
259 ICEINSTARITHMETIC_TABLE | 263 ICEINSTARITHMETIC_TABLE |
260 #undef X | 264 #undef X |
261 _num | 265 _num |
262 }; | 266 }; |
(...skipping 19 matching lines...) Expand all Loading... |
282 const OpKind Op; | 286 const OpKind Op; |
283 }; | 287 }; |
284 | 288 |
285 // Assignment instruction. The source operand is captured in | 289 // Assignment instruction. The source operand is captured in |
286 // getSrc(0). This is not part of the LLVM bitcode, but is a useful | 290 // getSrc(0). This is not part of the LLVM bitcode, but is a useful |
287 // abstraction for some of the lowering. E.g., if Phi instruction | 291 // abstraction for some of the lowering. E.g., if Phi instruction |
288 // lowering happens before target lowering, or for representing an | 292 // lowering happens before target lowering, or for representing an |
289 // Inttoptr instruction, or as an intermediate step for lowering a | 293 // Inttoptr instruction, or as an intermediate step for lowering a |
290 // Load instruction. | 294 // Load instruction. |
291 class InstAssign : public InstHighLevel { | 295 class InstAssign : public InstHighLevel { |
| 296 InstAssign() = delete; |
292 InstAssign(const InstAssign &) = delete; | 297 InstAssign(const InstAssign &) = delete; |
293 InstAssign &operator=(const InstAssign &) = delete; | 298 InstAssign &operator=(const InstAssign &) = delete; |
294 | 299 |
295 public: | 300 public: |
296 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { | 301 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { |
297 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source); | 302 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source); |
298 } | 303 } |
299 bool isSimpleAssign() const override { return true; } | 304 bool isSimpleAssign() const override { return true; } |
300 void dump(const Cfg *Func) const override; | 305 void dump(const Cfg *Func) const override; |
301 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } | 306 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } |
302 | 307 |
303 private: | 308 private: |
304 InstAssign(Cfg *Func, Variable *Dest, Operand *Source); | 309 InstAssign(Cfg *Func, Variable *Dest, Operand *Source); |
305 ~InstAssign() override {} | 310 ~InstAssign() override {} |
306 }; | 311 }; |
307 | 312 |
308 // Branch instruction. This represents both conditional and | 313 // Branch instruction. This represents both conditional and |
309 // unconditional branches. | 314 // unconditional branches. |
310 class InstBr : public InstHighLevel { | 315 class InstBr : public InstHighLevel { |
| 316 InstBr() = delete; |
311 InstBr(const InstBr &) = delete; | 317 InstBr(const InstBr &) = delete; |
312 InstBr &operator=(const InstBr &) = delete; | 318 InstBr &operator=(const InstBr &) = delete; |
313 | 319 |
314 public: | 320 public: |
315 // Create a conditional branch. If TargetTrue==TargetFalse, it is | 321 // Create a conditional branch. If TargetTrue==TargetFalse, it is |
316 // optimized to an unconditional branch. | 322 // optimized to an unconditional branch. |
317 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, | 323 static InstBr *create(Cfg *Func, Operand *Source, CfgNode *TargetTrue, |
318 CfgNode *TargetFalse) { | 324 CfgNode *TargetFalse) { |
319 return new (Func->allocate<InstBr>()) | 325 return new (Func->allocate<InstBr>()) |
320 InstBr(Func, Source, TargetTrue, TargetFalse); | 326 InstBr(Func, Source, TargetTrue, TargetFalse); |
(...skipping 26 matching lines...) Expand all Loading... |
347 InstBr(Cfg *Func, CfgNode *Target); | 353 InstBr(Cfg *Func, CfgNode *Target); |
348 ~InstBr() override {} | 354 ~InstBr() override {} |
349 | 355 |
350 CfgNode *TargetFalse; // Doubles as unconditional branch target | 356 CfgNode *TargetFalse; // Doubles as unconditional branch target |
351 CfgNode *TargetTrue; // nullptr if unconditional branch | 357 CfgNode *TargetTrue; // nullptr if unconditional branch |
352 }; | 358 }; |
353 | 359 |
354 // Call instruction. The call target is captured as getSrc(0), and | 360 // Call instruction. The call target is captured as getSrc(0), and |
355 // arg I is captured as getSrc(I+1). | 361 // arg I is captured as getSrc(I+1). |
356 class InstCall : public InstHighLevel { | 362 class InstCall : public InstHighLevel { |
| 363 InstCall() = delete; |
357 InstCall(const InstCall &) = delete; | 364 InstCall(const InstCall &) = delete; |
358 InstCall &operator=(const InstCall &) = delete; | 365 InstCall &operator=(const InstCall &) = delete; |
359 | 366 |
360 public: | 367 public: |
361 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | 368 static InstCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, |
362 Operand *CallTarget, bool HasTailCall) { | 369 Operand *CallTarget, bool HasTailCall) { |
363 // Set HasSideEffects to true so that the call instruction can't be | 370 // Set HasSideEffects to true so that the call instruction can't be |
364 // dead-code eliminated. IntrinsicCalls can override this if the | 371 // dead-code eliminated. IntrinsicCalls can override this if the |
365 // particular intrinsic is deletable and has no side-effects. | 372 // particular intrinsic is deletable and has no side-effects. |
366 const bool HasSideEffects = true; | 373 const bool HasSideEffects = true; |
(...skipping 18 matching lines...) Expand all Loading... |
385 addSource(CallTarget); | 392 addSource(CallTarget); |
386 } | 393 } |
387 ~InstCall() override {} | 394 ~InstCall() override {} |
388 | 395 |
389 private: | 396 private: |
390 bool HasTailCall; | 397 bool HasTailCall; |
391 }; | 398 }; |
392 | 399 |
393 // Cast instruction (a.k.a. conversion operation). | 400 // Cast instruction (a.k.a. conversion operation). |
394 class InstCast : public InstHighLevel { | 401 class InstCast : public InstHighLevel { |
| 402 InstCast() = delete; |
395 InstCast(const InstCast &) = delete; | 403 InstCast(const InstCast &) = delete; |
396 InstCast &operator=(const InstCast &) = delete; | 404 InstCast &operator=(const InstCast &) = delete; |
397 | 405 |
398 public: | 406 public: |
399 enum OpKind { | 407 enum OpKind { |
400 #define X(tag, str) tag, | 408 #define X(tag, str) tag, |
401 ICEINSTCAST_TABLE | 409 ICEINSTCAST_TABLE |
402 #undef X | 410 #undef X |
403 _num | 411 _num |
404 }; | 412 }; |
(...skipping 10 matching lines...) Expand all Loading... |
415 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } | 423 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } |
416 | 424 |
417 private: | 425 private: |
418 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); | 426 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); |
419 ~InstCast() override {} | 427 ~InstCast() override {} |
420 const OpKind CastKind; | 428 const OpKind CastKind; |
421 }; | 429 }; |
422 | 430 |
423 // ExtractElement instruction. | 431 // ExtractElement instruction. |
424 class InstExtractElement : public InstHighLevel { | 432 class InstExtractElement : public InstHighLevel { |
| 433 InstExtractElement() = delete; |
425 InstExtractElement(const InstExtractElement &) = delete; | 434 InstExtractElement(const InstExtractElement &) = delete; |
426 InstExtractElement &operator=(const InstExtractElement &) = delete; | 435 InstExtractElement &operator=(const InstExtractElement &) = delete; |
427 | 436 |
428 public: | 437 public: |
429 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 438 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, |
430 Operand *Source2) { | 439 Operand *Source2) { |
431 return new (Func->allocate<InstExtractElement>()) | 440 return new (Func->allocate<InstExtractElement>()) |
432 InstExtractElement(Func, Dest, Source1, Source2); | 441 InstExtractElement(Func, Dest, Source1, Source2); |
433 } | 442 } |
434 | 443 |
435 void dump(const Cfg *Func) const override; | 444 void dump(const Cfg *Func) const override; |
436 static bool classof(const Inst *Inst) { | 445 static bool classof(const Inst *Inst) { |
437 return Inst->getKind() == ExtractElement; | 446 return Inst->getKind() == ExtractElement; |
438 } | 447 } |
439 | 448 |
440 private: | 449 private: |
441 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, | 450 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, |
442 Operand *Source2); | 451 Operand *Source2); |
443 ~InstExtractElement() override {} | 452 ~InstExtractElement() override {} |
444 }; | 453 }; |
445 | 454 |
446 // Floating-point comparison instruction. The source operands are | 455 // Floating-point comparison instruction. The source operands are |
447 // captured in getSrc(0) and getSrc(1). | 456 // captured in getSrc(0) and getSrc(1). |
448 class InstFcmp : public InstHighLevel { | 457 class InstFcmp : public InstHighLevel { |
| 458 InstFcmp() = delete; |
449 InstFcmp(const InstFcmp &) = delete; | 459 InstFcmp(const InstFcmp &) = delete; |
450 InstFcmp &operator=(const InstFcmp &) = delete; | 460 InstFcmp &operator=(const InstFcmp &) = delete; |
451 | 461 |
452 public: | 462 public: |
453 enum FCond { | 463 enum FCond { |
454 #define X(tag, str) tag, | 464 #define X(tag, str) tag, |
455 ICEINSTFCMP_TABLE | 465 ICEINSTFCMP_TABLE |
456 #undef X | 466 #undef X |
457 _num | 467 _num |
458 }; | 468 }; |
(...skipping 10 matching lines...) Expand all Loading... |
469 private: | 479 private: |
470 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, | 480 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, |
471 Operand *Source2); | 481 Operand *Source2); |
472 ~InstFcmp() override {} | 482 ~InstFcmp() override {} |
473 const FCond Condition; | 483 const FCond Condition; |
474 }; | 484 }; |
475 | 485 |
476 // Integer comparison instruction. The source operands are captured | 486 // Integer comparison instruction. The source operands are captured |
477 // in getSrc(0) and getSrc(1). | 487 // in getSrc(0) and getSrc(1). |
478 class InstIcmp : public InstHighLevel { | 488 class InstIcmp : public InstHighLevel { |
| 489 InstIcmp() = delete; |
479 InstIcmp(const InstIcmp &) = delete; | 490 InstIcmp(const InstIcmp &) = delete; |
480 InstIcmp &operator=(const InstIcmp &) = delete; | 491 InstIcmp &operator=(const InstIcmp &) = delete; |
481 | 492 |
482 public: | 493 public: |
483 enum ICond { | 494 enum ICond { |
484 #define X(tag, str) tag, | 495 #define X(tag, str) tag, |
485 ICEINSTICMP_TABLE | 496 ICEINSTICMP_TABLE |
486 #undef X | 497 #undef X |
487 _num | 498 _num |
488 }; | 499 }; |
489 | 500 |
490 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, | 501 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, |
491 Operand *Source1, Operand *Source2) { | 502 Operand *Source1, Operand *Source2) { |
492 return new (Func->allocate<InstIcmp>()) | 503 return new (Func->allocate<InstIcmp>()) |
493 InstIcmp(Func, Condition, Dest, Source1, Source2); | 504 InstIcmp(Func, Condition, Dest, Source1, Source2); |
494 } | 505 } |
495 ICond getCondition() const { return Condition; } | 506 ICond getCondition() const { return Condition; } |
496 void dump(const Cfg *Func) const override; | 507 void dump(const Cfg *Func) const override; |
497 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } | 508 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } |
498 | 509 |
499 private: | 510 private: |
500 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, | 511 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, |
501 Operand *Source2); | 512 Operand *Source2); |
502 ~InstIcmp() override {} | 513 ~InstIcmp() override {} |
503 const ICond Condition; | 514 const ICond Condition; |
504 }; | 515 }; |
505 | 516 |
506 // InsertElement instruction. | 517 // InsertElement instruction. |
507 class InstInsertElement : public InstHighLevel { | 518 class InstInsertElement : public InstHighLevel { |
| 519 InstInsertElement() = delete; |
508 InstInsertElement(const InstInsertElement &) = delete; | 520 InstInsertElement(const InstInsertElement &) = delete; |
509 InstInsertElement &operator=(const InstInsertElement &) = delete; | 521 InstInsertElement &operator=(const InstInsertElement &) = delete; |
510 | 522 |
511 public: | 523 public: |
512 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, | 524 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, |
513 Operand *Source2, Operand *Source3) { | 525 Operand *Source2, Operand *Source3) { |
514 return new (Func->allocate<InstInsertElement>()) | 526 return new (Func->allocate<InstInsertElement>()) |
515 InstInsertElement(Func, Dest, Source1, Source2, Source3); | 527 InstInsertElement(Func, Dest, Source1, Source2, Source3); |
516 } | 528 } |
517 | 529 |
518 void dump(const Cfg *Func) const override; | 530 void dump(const Cfg *Func) const override; |
519 static bool classof(const Inst *Inst) { | 531 static bool classof(const Inst *Inst) { |
520 return Inst->getKind() == InsertElement; | 532 return Inst->getKind() == InsertElement; |
521 } | 533 } |
522 | 534 |
523 private: | 535 private: |
524 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, | 536 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, |
525 Operand *Source2, Operand *Source3); | 537 Operand *Source2, Operand *Source3); |
526 ~InstInsertElement() override {} | 538 ~InstInsertElement() override {} |
527 }; | 539 }; |
528 | 540 |
529 // Call to an intrinsic function. The call target is captured as getSrc(0), | 541 // Call to an intrinsic function. The call target is captured as getSrc(0), |
530 // and arg I is captured as getSrc(I+1). | 542 // and arg I is captured as getSrc(I+1). |
531 class InstIntrinsicCall : public InstCall { | 543 class InstIntrinsicCall : public InstCall { |
| 544 InstIntrinsicCall() = delete; |
532 InstIntrinsicCall(const InstIntrinsicCall &) = delete; | 545 InstIntrinsicCall(const InstIntrinsicCall &) = delete; |
533 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete; | 546 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete; |
534 | 547 |
535 public: | 548 public: |
536 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, | 549 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, |
537 Operand *CallTarget, | 550 Operand *CallTarget, |
538 const Intrinsics::IntrinsicInfo &Info) { | 551 const Intrinsics::IntrinsicInfo &Info) { |
539 return new (Func->allocate<InstIntrinsicCall>()) | 552 return new (Func->allocate<InstIntrinsicCall>()) |
540 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); | 553 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); |
541 } | 554 } |
542 static bool classof(const Inst *Inst) { | 555 static bool classof(const Inst *Inst) { |
543 return Inst->getKind() == IntrinsicCall; | 556 return Inst->getKind() == IntrinsicCall; |
544 } | 557 } |
545 | 558 |
546 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } | 559 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } |
547 | 560 |
548 private: | 561 private: |
549 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, | 562 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, |
550 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) | 563 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) |
551 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, | 564 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, |
552 Inst::IntrinsicCall), | 565 Inst::IntrinsicCall), |
553 Info(Info) {} | 566 Info(Info) {} |
554 ~InstIntrinsicCall() override {} | 567 ~InstIntrinsicCall() override {} |
555 const Intrinsics::IntrinsicInfo Info; | 568 const Intrinsics::IntrinsicInfo Info; |
556 }; | 569 }; |
557 | 570 |
558 // Load instruction. The source address is captured in getSrc(0). | 571 // Load instruction. The source address is captured in getSrc(0). |
559 class InstLoad : public InstHighLevel { | 572 class InstLoad : public InstHighLevel { |
| 573 InstLoad() = delete; |
560 InstLoad(const InstLoad &) = delete; | 574 InstLoad(const InstLoad &) = delete; |
561 InstLoad &operator=(const InstLoad &) = delete; | 575 InstLoad &operator=(const InstLoad &) = delete; |
562 | 576 |
563 public: | 577 public: |
564 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, | 578 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, |
565 uint32_t Align = 1) { | 579 uint32_t Align = 1) { |
566 // TODO(kschimpf) Stop ignoring alignment specification. | 580 // TODO(kschimpf) Stop ignoring alignment specification. |
567 (void)Align; | 581 (void)Align; |
568 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr); | 582 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr); |
569 } | 583 } |
570 Operand *getSourceAddress() const { return getSrc(0); } | 584 Operand *getSourceAddress() const { return getSrc(0); } |
571 void dump(const Cfg *Func) const override; | 585 void dump(const Cfg *Func) const override; |
572 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } | 586 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } |
573 | 587 |
574 private: | 588 private: |
575 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); | 589 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); |
576 ~InstLoad() override {} | 590 ~InstLoad() override {} |
577 }; | 591 }; |
578 | 592 |
579 // Phi instruction. For incoming edge I, the node is Labels[I] and | 593 // Phi instruction. For incoming edge I, the node is Labels[I] and |
580 // the Phi source operand is getSrc(I). | 594 // the Phi source operand is getSrc(I). |
581 class InstPhi : public InstHighLevel { | 595 class InstPhi : public InstHighLevel { |
| 596 InstPhi() = delete; |
582 InstPhi(const InstPhi &) = delete; | 597 InstPhi(const InstPhi &) = delete; |
583 InstPhi &operator=(const InstPhi &) = delete; | 598 InstPhi &operator=(const InstPhi &) = delete; |
584 | 599 |
585 public: | 600 public: |
586 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { | 601 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { |
587 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); | 602 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); |
588 } | 603 } |
589 void addArgument(Operand *Source, CfgNode *Label); | 604 void addArgument(Operand *Source, CfgNode *Label); |
590 Operand *getOperandForTarget(CfgNode *Target) const; | 605 Operand *getOperandForTarget(CfgNode *Target) const; |
591 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; } | 606 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; } |
(...skipping 14 matching lines...) Expand all Loading... |
606 // Labels[] duplicates the InEdges[] information in the enclosing | 621 // Labels[] duplicates the InEdges[] information in the enclosing |
607 // CfgNode, but the Phi instruction is created before InEdges[] | 622 // CfgNode, but the Phi instruction is created before InEdges[] |
608 // is available, so it's more complicated to share the list. | 623 // is available, so it's more complicated to share the list. |
609 CfgNode **Labels; | 624 CfgNode **Labels; |
610 }; | 625 }; |
611 | 626 |
612 // Ret instruction. The return value is captured in getSrc(0), but if | 627 // Ret instruction. The return value is captured in getSrc(0), but if |
613 // there is no return value (void-type function), then | 628 // there is no return value (void-type function), then |
614 // getSrcSize()==0 and hasRetValue()==false. | 629 // getSrcSize()==0 and hasRetValue()==false. |
615 class InstRet : public InstHighLevel { | 630 class InstRet : public InstHighLevel { |
| 631 InstRet() = delete; |
616 InstRet(const InstRet &) = delete; | 632 InstRet(const InstRet &) = delete; |
617 InstRet &operator=(const InstRet &) = delete; | 633 InstRet &operator=(const InstRet &) = delete; |
618 | 634 |
619 public: | 635 public: |
620 static InstRet *create(Cfg *Func, Operand *RetValue = nullptr) { | 636 static InstRet *create(Cfg *Func, Operand *RetValue = nullptr) { |
621 return new (Func->allocate<InstRet>()) InstRet(Func, RetValue); | 637 return new (Func->allocate<InstRet>()) InstRet(Func, RetValue); |
622 } | 638 } |
623 bool hasRetValue() const { return getSrcSize(); } | 639 bool hasRetValue() const { return getSrcSize(); } |
624 Operand *getRetValue() const { | 640 Operand *getRetValue() const { |
625 assert(hasRetValue()); | 641 assert(hasRetValue()); |
626 return getSrc(0); | 642 return getSrc(0); |
627 } | 643 } |
628 NodeList getTerminatorEdges() const override { return NodeList(); } | 644 NodeList getTerminatorEdges() const override { return NodeList(); } |
629 void dump(const Cfg *Func) const override; | 645 void dump(const Cfg *Func) const override; |
630 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } | 646 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } |
631 | 647 |
632 private: | 648 private: |
633 InstRet(Cfg *Func, Operand *RetValue); | 649 InstRet(Cfg *Func, Operand *RetValue); |
634 ~InstRet() override {} | 650 ~InstRet() override {} |
635 }; | 651 }; |
636 | 652 |
637 // Select instruction. The condition, true, and false operands are captured. | 653 // Select instruction. The condition, true, and false operands are captured. |
638 class InstSelect : public InstHighLevel { | 654 class InstSelect : public InstHighLevel { |
| 655 InstSelect() = delete; |
639 InstSelect(const InstSelect &) = delete; | 656 InstSelect(const InstSelect &) = delete; |
640 InstSelect &operator=(const InstSelect &) = delete; | 657 InstSelect &operator=(const InstSelect &) = delete; |
641 | 658 |
642 public: | 659 public: |
643 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, | 660 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, |
644 Operand *SourceTrue, Operand *SourceFalse) { | 661 Operand *SourceTrue, Operand *SourceFalse) { |
645 return new (Func->allocate<InstSelect>()) | 662 return new (Func->allocate<InstSelect>()) |
646 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); | 663 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); |
647 } | 664 } |
648 Operand *getCondition() const { return getSrc(0); } | 665 Operand *getCondition() const { return getSrc(0); } |
649 Operand *getTrueOperand() const { return getSrc(1); } | 666 Operand *getTrueOperand() const { return getSrc(1); } |
650 Operand *getFalseOperand() const { return getSrc(2); } | 667 Operand *getFalseOperand() const { return getSrc(2); } |
651 void dump(const Cfg *Func) const override; | 668 void dump(const Cfg *Func) const override; |
652 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } | 669 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } |
653 | 670 |
654 private: | 671 private: |
655 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, | 672 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, |
656 Operand *Source2); | 673 Operand *Source2); |
657 ~InstSelect() override {} | 674 ~InstSelect() override {} |
658 }; | 675 }; |
659 | 676 |
660 // Store instruction. The address operand is captured, along with the | 677 // Store instruction. The address operand is captured, along with the |
661 // data operand to be stored into the address. | 678 // data operand to be stored into the address. |
662 class InstStore : public InstHighLevel { | 679 class InstStore : public InstHighLevel { |
| 680 InstStore() = delete; |
663 InstStore(const InstStore &) = delete; | 681 InstStore(const InstStore &) = delete; |
664 InstStore &operator=(const InstStore &) = delete; | 682 InstStore &operator=(const InstStore &) = delete; |
665 | 683 |
666 public: | 684 public: |
667 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, | 685 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, |
668 uint32_t align = 1) { | 686 uint32_t align = 1) { |
669 // TODO(kschimpf) Stop ignoring alignment specification. | 687 // TODO(kschimpf) Stop ignoring alignment specification. |
670 (void)align; | 688 (void)align; |
671 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr); | 689 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr); |
672 } | 690 } |
673 Operand *getAddr() const { return getSrc(1); } | 691 Operand *getAddr() const { return getSrc(1); } |
674 Operand *getData() const { return getSrc(0); } | 692 Operand *getData() const { return getSrc(0); } |
675 void dump(const Cfg *Func) const override; | 693 void dump(const Cfg *Func) const override; |
676 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } | 694 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } |
677 | 695 |
678 private: | 696 private: |
679 InstStore(Cfg *Func, Operand *Data, Operand *Addr); | 697 InstStore(Cfg *Func, Operand *Data, Operand *Addr); |
680 ~InstStore() override {} | 698 ~InstStore() override {} |
681 }; | 699 }; |
682 | 700 |
683 // Switch instruction. The single source operand is captured as | 701 // Switch instruction. The single source operand is captured as |
684 // getSrc(0). | 702 // getSrc(0). |
685 class InstSwitch : public InstHighLevel { | 703 class InstSwitch : public InstHighLevel { |
| 704 InstSwitch() = delete; |
686 InstSwitch(const InstSwitch &) = delete; | 705 InstSwitch(const InstSwitch &) = delete; |
687 InstSwitch &operator=(const InstSwitch &) = delete; | 706 InstSwitch &operator=(const InstSwitch &) = delete; |
688 | 707 |
689 public: | 708 public: |
690 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, | 709 static InstSwitch *create(Cfg *Func, SizeT NumCases, Operand *Source, |
691 CfgNode *LabelDefault) { | 710 CfgNode *LabelDefault) { |
692 return new (Func->allocate<InstSwitch>()) | 711 return new (Func->allocate<InstSwitch>()) |
693 InstSwitch(Func, NumCases, Source, LabelDefault); | 712 InstSwitch(Func, NumCases, Source, LabelDefault); |
694 } | 713 } |
695 Operand *getComparison() const { return getSrc(0); } | 714 Operand *getComparison() const { return getSrc(0); } |
(...skipping 24 matching lines...) Expand all Loading... |
720 | 739 |
721 CfgNode *LabelDefault; | 740 CfgNode *LabelDefault; |
722 SizeT NumCases; // not including the default case | 741 SizeT NumCases; // not including the default case |
723 uint64_t *Values; // size is NumCases | 742 uint64_t *Values; // size is NumCases |
724 CfgNode **Labels; // size is NumCases | 743 CfgNode **Labels; // size is NumCases |
725 }; | 744 }; |
726 | 745 |
727 // Unreachable instruction. This is a terminator instruction with no | 746 // Unreachable instruction. This is a terminator instruction with no |
728 // operands. | 747 // operands. |
729 class InstUnreachable : public InstHighLevel { | 748 class InstUnreachable : public InstHighLevel { |
| 749 InstUnreachable() = delete; |
730 InstUnreachable(const InstUnreachable &) = delete; | 750 InstUnreachable(const InstUnreachable &) = delete; |
731 InstUnreachable &operator=(const InstUnreachable &) = delete; | 751 InstUnreachable &operator=(const InstUnreachable &) = delete; |
732 | 752 |
733 public: | 753 public: |
734 static InstUnreachable *create(Cfg *Func) { | 754 static InstUnreachable *create(Cfg *Func) { |
735 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func); | 755 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func); |
736 } | 756 } |
737 NodeList getTerminatorEdges() const override { return NodeList(); } | 757 NodeList getTerminatorEdges() const override { return NodeList(); } |
738 void dump(const Cfg *Func) const override; | 758 void dump(const Cfg *Func) const override; |
739 static bool classof(const Inst *Inst) { | 759 static bool classof(const Inst *Inst) { |
740 return Inst->getKind() == Unreachable; | 760 return Inst->getKind() == Unreachable; |
741 } | 761 } |
742 | 762 |
743 private: | 763 private: |
744 InstUnreachable(Cfg *Func); | 764 explicit InstUnreachable(Cfg *Func); |
745 ~InstUnreachable() override {} | 765 ~InstUnreachable() override {} |
746 }; | 766 }; |
747 | 767 |
748 // BundleLock instruction. There are no operands. Contains an option | 768 // BundleLock instruction. There are no operands. Contains an option |
749 // indicating whether align_to_end is specified. | 769 // indicating whether align_to_end is specified. |
750 class InstBundleLock : public InstHighLevel { | 770 class InstBundleLock : public InstHighLevel { |
| 771 InstBundleLock() = delete; |
751 InstBundleLock(const InstBundleLock &) = delete; | 772 InstBundleLock(const InstBundleLock &) = delete; |
752 InstBundleLock &operator=(const InstBundleLock &) = delete; | 773 InstBundleLock &operator=(const InstBundleLock &) = delete; |
753 | 774 |
754 public: | 775 public: |
755 enum Option { Opt_None, Opt_AlignToEnd }; | 776 enum Option { Opt_None, Opt_AlignToEnd }; |
756 static InstBundleLock *create(Cfg *Func, Option BundleOption) { | 777 static InstBundleLock *create(Cfg *Func, Option BundleOption) { |
757 return new (Func->allocate<InstBundleLock>()) | 778 return new (Func->allocate<InstBundleLock>()) |
758 InstBundleLock(Func, BundleOption); | 779 InstBundleLock(Func, BundleOption); |
759 } | 780 } |
760 void emit(const Cfg *Func) const override; | 781 void emit(const Cfg *Func) const override; |
761 void emitIAS(const Cfg * /* Func */) const override {} | 782 void emitIAS(const Cfg * /* Func */) const override {} |
762 void dump(const Cfg *Func) const override; | 783 void dump(const Cfg *Func) const override; |
763 Option getOption() const { return BundleOption; } | 784 Option getOption() const { return BundleOption; } |
764 static bool classof(const Inst *Inst) { | 785 static bool classof(const Inst *Inst) { |
765 return Inst->getKind() == BundleLock; | 786 return Inst->getKind() == BundleLock; |
766 } | 787 } |
767 | 788 |
768 private: | 789 private: |
769 Option BundleOption; | 790 Option BundleOption; |
770 InstBundleLock(Cfg *Func, Option BundleOption); | 791 InstBundleLock(Cfg *Func, Option BundleOption); |
771 ~InstBundleLock() override {} | 792 ~InstBundleLock() override {} |
772 }; | 793 }; |
773 | 794 |
774 // BundleUnlock instruction. There are no operands. | 795 // BundleUnlock instruction. There are no operands. |
775 class InstBundleUnlock : public InstHighLevel { | 796 class InstBundleUnlock : public InstHighLevel { |
| 797 InstBundleUnlock() = delete; |
776 InstBundleUnlock(const InstBundleUnlock &) = delete; | 798 InstBundleUnlock(const InstBundleUnlock &) = delete; |
777 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete; | 799 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete; |
778 | 800 |
779 public: | 801 public: |
780 static InstBundleUnlock *create(Cfg *Func) { | 802 static InstBundleUnlock *create(Cfg *Func) { |
781 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func); | 803 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func); |
782 } | 804 } |
783 void emit(const Cfg *Func) const override; | 805 void emit(const Cfg *Func) const override; |
784 void emitIAS(const Cfg * /* Func */) const override {} | 806 void emitIAS(const Cfg * /* Func */) const override {} |
785 void dump(const Cfg *Func) const override; | 807 void dump(const Cfg *Func) const override; |
(...skipping 12 matching lines...) Expand all Loading... |
798 // instructions, but might with lowered instructions. For example, | 820 // instructions, but might with lowered instructions. For example, |
799 // this would be a way to represent condition flags being modified by | 821 // this would be a way to represent condition flags being modified by |
800 // an instruction. | 822 // an instruction. |
801 // | 823 // |
802 // It's generally useful to set the optional source operand to be the | 824 // It's generally useful to set the optional source operand to be the |
803 // dest variable of the instruction that actually produces the FakeDef | 825 // dest variable of the instruction that actually produces the FakeDef |
804 // dest. Otherwise, the original instruction could be dead-code | 826 // dest. Otherwise, the original instruction could be dead-code |
805 // eliminated if its dest operand is unused, and therefore the FakeDef | 827 // eliminated if its dest operand is unused, and therefore the FakeDef |
806 // dest wouldn't be properly initialized. | 828 // dest wouldn't be properly initialized. |
807 class InstFakeDef : public InstHighLevel { | 829 class InstFakeDef : public InstHighLevel { |
| 830 InstFakeDef() = delete; |
808 InstFakeDef(const InstFakeDef &) = delete; | 831 InstFakeDef(const InstFakeDef &) = delete; |
809 InstFakeDef &operator=(const InstFakeDef &) = delete; | 832 InstFakeDef &operator=(const InstFakeDef &) = delete; |
810 | 833 |
811 public: | 834 public: |
812 static InstFakeDef *create(Cfg *Func, Variable *Dest, | 835 static InstFakeDef *create(Cfg *Func, Variable *Dest, |
813 Variable *Src = nullptr) { | 836 Variable *Src = nullptr) { |
814 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src); | 837 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src); |
815 } | 838 } |
816 void emit(const Cfg *Func) const override; | 839 void emit(const Cfg *Func) const override; |
817 void emitIAS(const Cfg * /* Func */) const override {} | 840 void emitIAS(const Cfg * /* Func */) const override {} |
818 void dump(const Cfg *Func) const override; | 841 void dump(const Cfg *Func) const override; |
819 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } | 842 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } |
820 | 843 |
821 private: | 844 private: |
822 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); | 845 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); |
823 ~InstFakeDef() override {} | 846 ~InstFakeDef() override {} |
824 }; | 847 }; |
825 | 848 |
826 // FakeUse instruction. This creates a fake use of a variable, to | 849 // FakeUse instruction. This creates a fake use of a variable, to |
827 // keep the instruction that produces that variable from being | 850 // keep the instruction that produces that variable from being |
828 // dead-code eliminated. This is useful in a variety of lowering | 851 // dead-code eliminated. This is useful in a variety of lowering |
829 // situations. The FakeUse instruction has no dest, so it can itself | 852 // situations. The FakeUse instruction has no dest, so it can itself |
830 // never be dead-code eliminated. | 853 // never be dead-code eliminated. |
831 class InstFakeUse : public InstHighLevel { | 854 class InstFakeUse : public InstHighLevel { |
| 855 InstFakeUse() = delete; |
832 InstFakeUse(const InstFakeUse &) = delete; | 856 InstFakeUse(const InstFakeUse &) = delete; |
833 InstFakeUse &operator=(const InstFakeUse &) = delete; | 857 InstFakeUse &operator=(const InstFakeUse &) = delete; |
834 | 858 |
835 public: | 859 public: |
836 static InstFakeUse *create(Cfg *Func, Variable *Src) { | 860 static InstFakeUse *create(Cfg *Func, Variable *Src) { |
837 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src); | 861 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src); |
838 } | 862 } |
839 void emit(const Cfg *Func) const override; | 863 void emit(const Cfg *Func) const override; |
840 void emitIAS(const Cfg * /* Func */) const override {} | 864 void emitIAS(const Cfg * /* Func */) const override {} |
841 void dump(const Cfg *Func) const override; | 865 void dump(const Cfg *Func) const override; |
842 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } | 866 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } |
843 | 867 |
844 private: | 868 private: |
845 InstFakeUse(Cfg *Func, Variable *Src); | 869 InstFakeUse(Cfg *Func, Variable *Src); |
846 ~InstFakeUse() override {} | 870 ~InstFakeUse() override {} |
847 }; | 871 }; |
848 | 872 |
849 // FakeKill instruction. This "kills" a set of variables by modeling | 873 // FakeKill instruction. This "kills" a set of variables by modeling |
850 // a trivial live range at this instruction for each (implicit) | 874 // a trivial live range at this instruction for each (implicit) |
851 // variable. The primary use is to indicate that scratch registers | 875 // variable. The primary use is to indicate that scratch registers |
852 // are killed after a call, so that the register allocator won't | 876 // are killed after a call, so that the register allocator won't |
853 // assign a scratch register to a variable whose live range spans a | 877 // assign a scratch register to a variable whose live range spans a |
854 // call. | 878 // call. |
855 // | 879 // |
856 // The FakeKill instruction also holds a pointer to the instruction | 880 // The FakeKill instruction also holds a pointer to the instruction |
857 // that kills the set of variables, so that if that linked instruction | 881 // that kills the set of variables, so that if that linked instruction |
858 // gets dead-code eliminated, the FakeKill instruction will as well. | 882 // gets dead-code eliminated, the FakeKill instruction will as well. |
859 class InstFakeKill : public InstHighLevel { | 883 class InstFakeKill : public InstHighLevel { |
| 884 InstFakeKill() = delete; |
860 InstFakeKill(const InstFakeKill &) = delete; | 885 InstFakeKill(const InstFakeKill &) = delete; |
861 InstFakeKill &operator=(const InstFakeKill &) = delete; | 886 InstFakeKill &operator=(const InstFakeKill &) = delete; |
862 | 887 |
863 public: | 888 public: |
864 static InstFakeKill *create(Cfg *Func, const Inst *Linked) { | 889 static InstFakeKill *create(Cfg *Func, const Inst *Linked) { |
865 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked); | 890 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked); |
866 } | 891 } |
867 const Inst *getLinked() const { return Linked; } | 892 const Inst *getLinked() const { return Linked; } |
868 void emit(const Cfg *Func) const override; | 893 void emit(const Cfg *Func) const override; |
869 void emitIAS(const Cfg * /* Func */) const override {} | 894 void emitIAS(const Cfg * /* Func */) const override {} |
870 void dump(const Cfg *Func) const override; | 895 void dump(const Cfg *Func) const override; |
871 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } | 896 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } |
872 | 897 |
873 private: | 898 private: |
874 InstFakeKill(Cfg *Func, const Inst *Linked); | 899 InstFakeKill(Cfg *Func, const Inst *Linked); |
875 ~InstFakeKill() override {} | 900 ~InstFakeKill() override {} |
876 | 901 |
877 // This instruction is ignored if Linked->isDeleted() is true. | 902 // This instruction is ignored if Linked->isDeleted() is true. |
878 const Inst *Linked; | 903 const Inst *Linked; |
879 }; | 904 }; |
880 | 905 |
881 // The Target instruction is the base class for all target-specific | 906 // The Target instruction is the base class for all target-specific |
882 // instructions. | 907 // instructions. |
883 class InstTarget : public Inst { | 908 class InstTarget : public Inst { |
| 909 InstTarget() = delete; |
884 InstTarget(const InstTarget &) = delete; | 910 InstTarget(const InstTarget &) = delete; |
885 InstTarget &operator=(const InstTarget &) = delete; | 911 InstTarget &operator=(const InstTarget &) = delete; |
886 | 912 |
887 public: | 913 public: |
888 uint32_t getEmitInstCount() const override { return 1; } | 914 uint32_t getEmitInstCount() const override { return 1; } |
889 void dump(const Cfg *Func) const override; | 915 void dump(const Cfg *Func) const override; |
890 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } | 916 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } |
891 | 917 |
892 protected: | 918 protected: |
893 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | 919 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) |
(...skipping 20 matching lines...) Expand all Loading... |
914 static void noteHead(Ice::Inst *, Ice::Inst *) {} | 940 static void noteHead(Ice::Inst *, Ice::Inst *) {} |
915 void deleteNode(Ice::Inst *) {} | 941 void deleteNode(Ice::Inst *) {} |
916 | 942 |
917 private: | 943 private: |
918 mutable ilist_half_node<Ice::Inst> Sentinel; | 944 mutable ilist_half_node<Ice::Inst> Sentinel; |
919 }; | 945 }; |
920 | 946 |
921 } // end of namespace llvm | 947 } // end of namespace llvm |
922 | 948 |
923 #endif // SUBZERO_SRC_ICEINST_H | 949 #endif // SUBZERO_SRC_ICEINST_H |
OLD | NEW |