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

Side by Side Diff: src/IceInst.h

Issue 1181013016: Subzero. Fixes memory leaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: clang-format: for f in $(git diff --name-only HEAD~7); do if [[ ${f} == *h || ${f} == *cpp ]]; then… Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares the Inst class and its target-independent 10 // This file declares the Inst class and its target-independent
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 154 }
155 virtual void emitIAS(const Cfg *Func) const { emit(Func); } 155 virtual void emitIAS(const Cfg *Func) const { emit(Func); }
156 virtual void dump(const Cfg *Func) const; 156 virtual void dump(const Cfg *Func) const;
157 virtual void dumpExtras(const Cfg *Func) const; 157 virtual void dumpExtras(const Cfg *Func) const;
158 void dumpDecorated(const Cfg *Func) const; 158 void dumpDecorated(const Cfg *Func) const;
159 void emitSources(const Cfg *Func) const; 159 void emitSources(const Cfg *Func) const;
160 void dumpSources(const Cfg *Func) const; 160 void dumpSources(const Cfg *Func) const;
161 void dumpDest(const Cfg *Func) const; 161 void dumpDest(const Cfg *Func) const;
162 virtual bool isRedundantAssign() const { return false; } 162 virtual bool isRedundantAssign() const { return false; }
163 163
164 virtual ~Inst() {}
165
166 protected: 164 protected:
167 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest); 165 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
168 void addSource(Operand *Src) { 166 void addSource(Operand *Src) {
169 assert(Src); 167 assert(Src);
170 assert(NumSrcs < MaxSrcs); 168 assert(NumSrcs < MaxSrcs);
171 Srcs[NumSrcs++] = Src; 169 Srcs[NumSrcs++] = Src;
172 } 170 }
173 void setLastUse(SizeT VarIndex) { 171 void setLastUse(SizeT VarIndex) {
174 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded)) 172 if (VarIndex < CHAR_BIT * sizeof(LiveRangesEnded))
175 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex); 173 LiveRangesEnded |= (((LREndedBits)1u) << VarIndex);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 220
223 protected: 221 protected:
224 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 222 InstHighLevel(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
225 : Inst(Func, Kind, MaxSrcs, Dest) {} 223 : Inst(Func, Kind, MaxSrcs, Dest) {}
226 void emit(const Cfg * /*Func*/) const override { 224 void emit(const Cfg * /*Func*/) const override {
227 llvm_unreachable("emit() called on a non-lowered instruction"); 225 llvm_unreachable("emit() called on a non-lowered instruction");
228 } 226 }
229 void emitIAS(const Cfg * /*Func*/) const override { 227 void emitIAS(const Cfg * /*Func*/) const override {
230 llvm_unreachable("emitIAS() called on a non-lowered instruction"); 228 llvm_unreachable("emitIAS() called on a non-lowered instruction");
231 } 229 }
232 ~InstHighLevel() override {}
233 }; 230 };
234 231
235 // Alloca instruction. This captures the size in bytes as getSrc(0), 232 // Alloca instruction. This captures the size in bytes as getSrc(0),
236 // and the required alignment in bytes. The alignment must be either 233 // and the required alignment in bytes. The alignment must be either
237 // 0 (no alignment required) or a power of 2. 234 // 0 (no alignment required) or a power of 2.
238 class InstAlloca : public InstHighLevel { 235 class InstAlloca : public InstHighLevel {
239 InstAlloca() = delete; 236 InstAlloca() = delete;
240 InstAlloca(const InstAlloca &) = delete; 237 InstAlloca(const InstAlloca &) = delete;
241 InstAlloca &operator=(const InstAlloca &) = delete; 238 InstAlloca &operator=(const InstAlloca &) = delete;
242 239
243 public: 240 public:
244 static InstAlloca *create(Cfg *Func, Operand *ByteCount, 241 static InstAlloca *create(Cfg *Func, Operand *ByteCount,
245 uint32_t AlignInBytes, Variable *Dest) { 242 uint32_t AlignInBytes, Variable *Dest) {
246 return new (Func->allocate<InstAlloca>()) 243 return new (Func->allocate<InstAlloca>())
247 InstAlloca(Func, ByteCount, AlignInBytes, Dest); 244 InstAlloca(Func, ByteCount, AlignInBytes, Dest);
248 } 245 }
249 uint32_t getAlignInBytes() const { return AlignInBytes; } 246 uint32_t getAlignInBytes() const { return AlignInBytes; }
250 Operand *getSizeInBytes() const { return getSrc(0); } 247 Operand *getSizeInBytes() const { return getSrc(0); }
251 void dump(const Cfg *Func) const override; 248 void dump(const Cfg *Func) const override;
252 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; } 249 static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
253 250
254 private: 251 private:
255 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes, 252 InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
256 Variable *Dest); 253 Variable *Dest);
257 ~InstAlloca() override {} 254
258 const uint32_t AlignInBytes; 255 const uint32_t AlignInBytes;
259 }; 256 };
260 257
261 // Binary arithmetic instruction. The source operands are captured in 258 // Binary arithmetic instruction. The source operands are captured in
262 // getSrc(0) and getSrc(1). 259 // getSrc(0) and getSrc(1).
263 class InstArithmetic : public InstHighLevel { 260 class InstArithmetic : public InstHighLevel {
264 InstArithmetic() = delete; 261 InstArithmetic() = delete;
265 InstArithmetic(const InstArithmetic &) = delete; 262 InstArithmetic(const InstArithmetic &) = delete;
266 InstArithmetic &operator=(const InstArithmetic &) = delete; 263 InstArithmetic &operator=(const InstArithmetic &) = delete;
267 264
(...skipping 14 matching lines...) Expand all
282 static const char *getOpName(OpKind Op); 279 static const char *getOpName(OpKind Op);
283 bool isCommutative() const; 280 bool isCommutative() const;
284 void dump(const Cfg *Func) const override; 281 void dump(const Cfg *Func) const override;
285 static bool classof(const Inst *Inst) { 282 static bool classof(const Inst *Inst) {
286 return Inst->getKind() == Arithmetic; 283 return Inst->getKind() == Arithmetic;
287 } 284 }
288 285
289 private: 286 private:
290 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1, 287 InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest, Operand *Source1,
291 Operand *Source2); 288 Operand *Source2);
292 ~InstArithmetic() override {}
293 289
294 const OpKind Op; 290 const OpKind Op;
295 }; 291 };
296 292
297 // Assignment instruction. The source operand is captured in 293 // Assignment instruction. The source operand is captured in
298 // getSrc(0). This is not part of the LLVM bitcode, but is a useful 294 // getSrc(0). This is not part of the LLVM bitcode, but is a useful
299 // abstraction for some of the lowering. E.g., if Phi instruction 295 // abstraction for some of the lowering. E.g., if Phi instruction
300 // lowering happens before target lowering, or for representing an 296 // lowering happens before target lowering, or for representing an
301 // Inttoptr instruction, or as an intermediate step for lowering a 297 // Inttoptr instruction, or as an intermediate step for lowering a
302 // Load instruction. 298 // Load instruction.
303 class InstAssign : public InstHighLevel { 299 class InstAssign : public InstHighLevel {
304 InstAssign() = delete; 300 InstAssign() = delete;
305 InstAssign(const InstAssign &) = delete; 301 InstAssign(const InstAssign &) = delete;
306 InstAssign &operator=(const InstAssign &) = delete; 302 InstAssign &operator=(const InstAssign &) = delete;
307 303
308 public: 304 public:
309 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) { 305 static InstAssign *create(Cfg *Func, Variable *Dest, Operand *Source) {
310 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source); 306 return new (Func->allocate<InstAssign>()) InstAssign(Func, Dest, Source);
311 } 307 }
312 bool isSimpleAssign() const override { return true; } 308 bool isSimpleAssign() const override { return true; }
313 void dump(const Cfg *Func) const override; 309 void dump(const Cfg *Func) const override;
314 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; } 310 static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
315 311
316 private: 312 private:
317 InstAssign(Cfg *Func, Variable *Dest, Operand *Source); 313 InstAssign(Cfg *Func, Variable *Dest, Operand *Source);
318 ~InstAssign() override {}
319 }; 314 };
320 315
321 // Branch instruction. This represents both conditional and 316 // Branch instruction. This represents both conditional and
322 // unconditional branches. 317 // unconditional branches.
323 class InstBr : public InstHighLevel { 318 class InstBr : public InstHighLevel {
324 InstBr() = delete; 319 InstBr() = delete;
325 InstBr(const InstBr &) = delete; 320 InstBr(const InstBr &) = delete;
326 InstBr &operator=(const InstBr &) = delete; 321 InstBr &operator=(const InstBr &) = delete;
327 322
328 public: 323 public:
(...skipping 23 matching lines...) Expand all
352 bool isUnconditionalBranch() const override { return isUnconditional(); } 347 bool isUnconditionalBranch() const override { return isUnconditional(); }
353 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; 348 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
354 void dump(const Cfg *Func) const override; 349 void dump(const Cfg *Func) const override;
355 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; } 350 static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
356 351
357 private: 352 private:
358 // Conditional branch 353 // Conditional branch
359 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse); 354 InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue, CfgNode *TargetFalse);
360 // Unconditional branch 355 // Unconditional branch
361 InstBr(Cfg *Func, CfgNode *Target); 356 InstBr(Cfg *Func, CfgNode *Target);
362 ~InstBr() override {}
363 357
364 CfgNode *TargetFalse; // Doubles as unconditional branch target 358 CfgNode *TargetFalse; // Doubles as unconditional branch target
365 CfgNode *TargetTrue; // nullptr if unconditional branch 359 CfgNode *TargetTrue; // nullptr if unconditional branch
366 }; 360 };
367 361
368 // Call instruction. The call target is captured as getSrc(0), and 362 // Call instruction. The call target is captured as getSrc(0), and
369 // arg I is captured as getSrc(I+1). 363 // arg I is captured as getSrc(I+1).
370 class InstCall : public InstHighLevel { 364 class InstCall : public InstHighLevel {
371 InstCall() = delete; 365 InstCall() = delete;
372 InstCall(const InstCall &) = delete; 366 InstCall(const InstCall &) = delete;
(...skipping 19 matching lines...) Expand all
392 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; } 386 static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
393 Type getReturnType() const; 387 Type getReturnType() const;
394 388
395 protected: 389 protected:
396 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget, 390 InstCall(Cfg *Func, SizeT NumArgs, Variable *Dest, Operand *CallTarget,
397 bool HasTailCall, bool HasSideEff, InstKind Kind) 391 bool HasTailCall, bool HasSideEff, InstKind Kind)
398 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) { 392 : InstHighLevel(Func, Kind, NumArgs + 1, Dest), HasTailCall(HasTailCall) {
399 HasSideEffects = HasSideEff; 393 HasSideEffects = HasSideEff;
400 addSource(CallTarget); 394 addSource(CallTarget);
401 } 395 }
402 ~InstCall() override {}
403 396
404 private: 397 private:
405 bool HasTailCall; 398 bool HasTailCall;
406 }; 399 };
407 400
408 // Cast instruction (a.k.a. conversion operation). 401 // Cast instruction (a.k.a. conversion operation).
409 class InstCast : public InstHighLevel { 402 class InstCast : public InstHighLevel {
410 InstCast() = delete; 403 InstCast() = delete;
411 InstCast(const InstCast &) = delete; 404 InstCast(const InstCast &) = delete;
412 InstCast &operator=(const InstCast &) = delete; 405 InstCast &operator=(const InstCast &) = delete;
(...skipping 12 matching lines...) Expand all
425 Operand *Source) { 418 Operand *Source) {
426 return new (Func->allocate<InstCast>()) 419 return new (Func->allocate<InstCast>())
427 InstCast(Func, CastKind, Dest, Source); 420 InstCast(Func, CastKind, Dest, Source);
428 } 421 }
429 OpKind getCastKind() const { return CastKind; } 422 OpKind getCastKind() const { return CastKind; }
430 void dump(const Cfg *Func) const override; 423 void dump(const Cfg *Func) const override;
431 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } 424 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
432 425
433 private: 426 private:
434 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); 427 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
435 ~InstCast() override {} 428
436 const OpKind CastKind; 429 const OpKind CastKind;
437 }; 430 };
438 431
439 // ExtractElement instruction. 432 // ExtractElement instruction.
440 class InstExtractElement : public InstHighLevel { 433 class InstExtractElement : public InstHighLevel {
441 InstExtractElement() = delete; 434 InstExtractElement() = delete;
442 InstExtractElement(const InstExtractElement &) = delete; 435 InstExtractElement(const InstExtractElement &) = delete;
443 InstExtractElement &operator=(const InstExtractElement &) = delete; 436 InstExtractElement &operator=(const InstExtractElement &) = delete;
444 437
445 public: 438 public:
446 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 439 static InstExtractElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
447 Operand *Source2) { 440 Operand *Source2) {
448 return new (Func->allocate<InstExtractElement>()) 441 return new (Func->allocate<InstExtractElement>())
449 InstExtractElement(Func, Dest, Source1, Source2); 442 InstExtractElement(Func, Dest, Source1, Source2);
450 } 443 }
451 444
452 void dump(const Cfg *Func) const override; 445 void dump(const Cfg *Func) const override;
453 static bool classof(const Inst *Inst) { 446 static bool classof(const Inst *Inst) {
454 return Inst->getKind() == ExtractElement; 447 return Inst->getKind() == ExtractElement;
455 } 448 }
456 449
457 private: 450 private:
458 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1, 451 InstExtractElement(Cfg *Func, Variable *Dest, Operand *Source1,
459 Operand *Source2); 452 Operand *Source2);
460 ~InstExtractElement() override {}
461 }; 453 };
462 454
463 // Floating-point comparison instruction. The source operands are 455 // Floating-point comparison instruction. The source operands are
464 // captured in getSrc(0) and getSrc(1). 456 // captured in getSrc(0) and getSrc(1).
465 class InstFcmp : public InstHighLevel { 457 class InstFcmp : public InstHighLevel {
466 InstFcmp() = delete; 458 InstFcmp() = delete;
467 InstFcmp(const InstFcmp &) = delete; 459 InstFcmp(const InstFcmp &) = delete;
468 InstFcmp &operator=(const InstFcmp &) = delete; 460 InstFcmp &operator=(const InstFcmp &) = delete;
469 461
470 public: 462 public:
471 enum FCond { 463 enum FCond {
472 #define X(tag, str) tag, 464 #define X(tag, str) tag,
473 ICEINSTFCMP_TABLE 465 ICEINSTFCMP_TABLE
474 #undef X 466 #undef X
475 _num 467 _num
476 }; 468 };
477 469
478 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, 470 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
479 Operand *Source1, Operand *Source2) { 471 Operand *Source1, Operand *Source2) {
480 return new (Func->allocate<InstFcmp>()) 472 return new (Func->allocate<InstFcmp>())
481 InstFcmp(Func, Condition, Dest, Source1, Source2); 473 InstFcmp(Func, Condition, Dest, Source1, Source2);
482 } 474 }
483 FCond getCondition() const { return Condition; } 475 FCond getCondition() const { return Condition; }
484 void dump(const Cfg *Func) const override; 476 void dump(const Cfg *Func) const override;
485 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } 477 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
486 478
487 private: 479 private:
488 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, 480 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
489 Operand *Source2); 481 Operand *Source2);
490 ~InstFcmp() override {} 482
491 const FCond Condition; 483 const FCond Condition;
492 }; 484 };
493 485
494 // Integer comparison instruction. The source operands are captured 486 // Integer comparison instruction. The source operands are captured
495 // in getSrc(0) and getSrc(1). 487 // in getSrc(0) and getSrc(1).
496 class InstIcmp : public InstHighLevel { 488 class InstIcmp : public InstHighLevel {
497 InstIcmp() = delete; 489 InstIcmp() = delete;
498 InstIcmp(const InstIcmp &) = delete; 490 InstIcmp(const InstIcmp &) = delete;
499 InstIcmp &operator=(const InstIcmp &) = delete; 491 InstIcmp &operator=(const InstIcmp &) = delete;
500 492
(...skipping 10 matching lines...) Expand all
511 return new (Func->allocate<InstIcmp>()) 503 return new (Func->allocate<InstIcmp>())
512 InstIcmp(Func, Condition, Dest, Source1, Source2); 504 InstIcmp(Func, Condition, Dest, Source1, Source2);
513 } 505 }
514 ICond getCondition() const { return Condition; } 506 ICond getCondition() const { return Condition; }
515 void dump(const Cfg *Func) const override; 507 void dump(const Cfg *Func) const override;
516 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } 508 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
517 509
518 private: 510 private:
519 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1, 511 InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
520 Operand *Source2); 512 Operand *Source2);
521 ~InstIcmp() override {} 513
522 const ICond Condition; 514 const ICond Condition;
523 }; 515 };
524 516
525 // InsertElement instruction. 517 // InsertElement instruction.
526 class InstInsertElement : public InstHighLevel { 518 class InstInsertElement : public InstHighLevel {
527 InstInsertElement() = delete; 519 InstInsertElement() = delete;
528 InstInsertElement(const InstInsertElement &) = delete; 520 InstInsertElement(const InstInsertElement &) = delete;
529 InstInsertElement &operator=(const InstInsertElement &) = delete; 521 InstInsertElement &operator=(const InstInsertElement &) = delete;
530 522
531 public: 523 public:
532 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1, 524 static InstInsertElement *create(Cfg *Func, Variable *Dest, Operand *Source1,
533 Operand *Source2, Operand *Source3) { 525 Operand *Source2, Operand *Source3) {
534 return new (Func->allocate<InstInsertElement>()) 526 return new (Func->allocate<InstInsertElement>())
535 InstInsertElement(Func, Dest, Source1, Source2, Source3); 527 InstInsertElement(Func, Dest, Source1, Source2, Source3);
536 } 528 }
537 529
538 void dump(const Cfg *Func) const override; 530 void dump(const Cfg *Func) const override;
539 static bool classof(const Inst *Inst) { 531 static bool classof(const Inst *Inst) {
540 return Inst->getKind() == InsertElement; 532 return Inst->getKind() == InsertElement;
541 } 533 }
542 534
543 private: 535 private:
544 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1, 536 InstInsertElement(Cfg *Func, Variable *Dest, Operand *Source1,
545 Operand *Source2, Operand *Source3); 537 Operand *Source2, Operand *Source3);
546 ~InstInsertElement() override {}
547 }; 538 };
548 539
549 // Call to an intrinsic function. The call target is captured as getSrc(0), 540 // Call to an intrinsic function. The call target is captured as getSrc(0),
550 // and arg I is captured as getSrc(I+1). 541 // and arg I is captured as getSrc(I+1).
551 class InstIntrinsicCall : public InstCall { 542 class InstIntrinsicCall : public InstCall {
552 InstIntrinsicCall() = delete; 543 InstIntrinsicCall() = delete;
553 InstIntrinsicCall(const InstIntrinsicCall &) = delete; 544 InstIntrinsicCall(const InstIntrinsicCall &) = delete;
554 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete; 545 InstIntrinsicCall &operator=(const InstIntrinsicCall &) = delete;
555 546
556 public: 547 public:
557 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest, 548 static InstIntrinsicCall *create(Cfg *Func, SizeT NumArgs, Variable *Dest,
558 Operand *CallTarget, 549 Operand *CallTarget,
559 const Intrinsics::IntrinsicInfo &Info) { 550 const Intrinsics::IntrinsicInfo &Info) {
560 return new (Func->allocate<InstIntrinsicCall>()) 551 return new (Func->allocate<InstIntrinsicCall>())
561 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info); 552 InstIntrinsicCall(Func, NumArgs, Dest, CallTarget, Info);
562 } 553 }
563 static bool classof(const Inst *Inst) { 554 static bool classof(const Inst *Inst) {
564 return Inst->getKind() == IntrinsicCall; 555 return Inst->getKind() == IntrinsicCall;
565 } 556 }
566 557
567 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; } 558 Intrinsics::IntrinsicInfo getIntrinsicInfo() const { return Info; }
568 559
569 private: 560 private:
570 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest, 561 InstIntrinsicCall(Cfg *Func, SizeT NumArgs, Variable *Dest,
571 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info) 562 Operand *CallTarget, const Intrinsics::IntrinsicInfo &Info)
572 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects, 563 : InstCall(Func, NumArgs, Dest, CallTarget, false, Info.HasSideEffects,
573 Inst::IntrinsicCall), 564 Inst::IntrinsicCall),
574 Info(Info) {} 565 Info(Info) {}
575 ~InstIntrinsicCall() override {} 566
576 const Intrinsics::IntrinsicInfo Info; 567 const Intrinsics::IntrinsicInfo Info;
577 }; 568 };
578 569
579 // Load instruction. The source address is captured in getSrc(0). 570 // Load instruction. The source address is captured in getSrc(0).
580 class InstLoad : public InstHighLevel { 571 class InstLoad : public InstHighLevel {
581 InstLoad() = delete; 572 InstLoad() = delete;
582 InstLoad(const InstLoad &) = delete; 573 InstLoad(const InstLoad &) = delete;
583 InstLoad &operator=(const InstLoad &) = delete; 574 InstLoad &operator=(const InstLoad &) = delete;
584 575
585 public: 576 public:
586 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr, 577 static InstLoad *create(Cfg *Func, Variable *Dest, Operand *SourceAddr,
587 uint32_t Align = 1) { 578 uint32_t Align = 1) {
588 // TODO(kschimpf) Stop ignoring alignment specification. 579 // TODO(kschimpf) Stop ignoring alignment specification.
589 (void)Align; 580 (void)Align;
590 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr); 581 return new (Func->allocate<InstLoad>()) InstLoad(Func, Dest, SourceAddr);
591 } 582 }
592 Operand *getSourceAddress() const { return getSrc(0); } 583 Operand *getSourceAddress() const { return getSrc(0); }
593 void dump(const Cfg *Func) const override; 584 void dump(const Cfg *Func) const override;
594 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; } 585 static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
595 586
596 private: 587 private:
597 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr); 588 InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr);
598 ~InstLoad() override {}
599 }; 589 };
600 590
601 // Phi instruction. For incoming edge I, the node is Labels[I] and 591 // Phi instruction. For incoming edge I, the node is Labels[I] and
602 // the Phi source operand is getSrc(I). 592 // the Phi source operand is getSrc(I).
603 class InstPhi : public InstHighLevel { 593 class InstPhi : public InstHighLevel {
604 InstPhi() = delete; 594 InstPhi() = delete;
605 InstPhi(const InstPhi &) = delete; 595 InstPhi(const InstPhi &) = delete;
606 InstPhi &operator=(const InstPhi &) = delete; 596 InstPhi &operator=(const InstPhi &) = delete;
607 597
608 public: 598 public:
609 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { 599 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
610 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); 600 return new (Func->allocate<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
611 } 601 }
612 void addArgument(Operand *Source, CfgNode *Label); 602 void addArgument(Operand *Source, CfgNode *Label);
613 Operand *getOperandForTarget(CfgNode *Target) const; 603 Operand *getOperandForTarget(CfgNode *Target) const;
614 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; } 604 CfgNode *getLabel(SizeT Index) const { return Labels[Index]; }
615 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target, 605 void livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
616 Liveness *Liveness); 606 Liveness *Liveness);
617 Inst *lower(Cfg *Func); 607 Inst *lower(Cfg *Func);
618 void dump(const Cfg *Func) const override; 608 void dump(const Cfg *Func) const override;
619 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } 609 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
620 610
621 private: 611 private:
622 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); 612 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
623 void destroy(Cfg *Func) override { 613 void destroy(Cfg *Func) override {
624 Func->deallocateArrayOf<CfgNode *>(Labels); 614 Func->deallocateArrayOf<CfgNode *>(Labels);
625 Inst::destroy(Func); 615 Inst::destroy(Func);
626 } 616 }
627 ~InstPhi() override {}
628 617
629 // Labels[] duplicates the InEdges[] information in the enclosing 618 // Labels[] duplicates the InEdges[] information in the enclosing
630 // CfgNode, but the Phi instruction is created before InEdges[] 619 // CfgNode, but the Phi instruction is created before InEdges[]
631 // is available, so it's more complicated to share the list. 620 // is available, so it's more complicated to share the list.
632 CfgNode **Labels; 621 CfgNode **Labels;
633 }; 622 };
634 623
635 // Ret instruction. The return value is captured in getSrc(0), but if 624 // Ret instruction. The return value is captured in getSrc(0), but if
636 // there is no return value (void-type function), then 625 // there is no return value (void-type function), then
637 // getSrcSize()==0 and hasRetValue()==false. 626 // getSrcSize()==0 and hasRetValue()==false.
(...skipping 10 matching lines...) Expand all
648 Operand *getRetValue() const { 637 Operand *getRetValue() const {
649 assert(hasRetValue()); 638 assert(hasRetValue());
650 return getSrc(0); 639 return getSrc(0);
651 } 640 }
652 NodeList getTerminatorEdges() const override { return NodeList(); } 641 NodeList getTerminatorEdges() const override { return NodeList(); }
653 void dump(const Cfg *Func) const override; 642 void dump(const Cfg *Func) const override;
654 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; } 643 static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
655 644
656 private: 645 private:
657 InstRet(Cfg *Func, Operand *RetValue); 646 InstRet(Cfg *Func, Operand *RetValue);
658 ~InstRet() override {}
659 }; 647 };
660 648
661 // Select instruction. The condition, true, and false operands are captured. 649 // Select instruction. The condition, true, and false operands are captured.
662 class InstSelect : public InstHighLevel { 650 class InstSelect : public InstHighLevel {
663 InstSelect() = delete; 651 InstSelect() = delete;
664 InstSelect(const InstSelect &) = delete; 652 InstSelect(const InstSelect &) = delete;
665 InstSelect &operator=(const InstSelect &) = delete; 653 InstSelect &operator=(const InstSelect &) = delete;
666 654
667 public: 655 public:
668 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition, 656 static InstSelect *create(Cfg *Func, Variable *Dest, Operand *Condition,
669 Operand *SourceTrue, Operand *SourceFalse) { 657 Operand *SourceTrue, Operand *SourceFalse) {
670 return new (Func->allocate<InstSelect>()) 658 return new (Func->allocate<InstSelect>())
671 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse); 659 InstSelect(Func, Dest, Condition, SourceTrue, SourceFalse);
672 } 660 }
673 Operand *getCondition() const { return getSrc(0); } 661 Operand *getCondition() const { return getSrc(0); }
674 Operand *getTrueOperand() const { return getSrc(1); } 662 Operand *getTrueOperand() const { return getSrc(1); }
675 Operand *getFalseOperand() const { return getSrc(2); } 663 Operand *getFalseOperand() const { return getSrc(2); }
676 void dump(const Cfg *Func) const override; 664 void dump(const Cfg *Func) const override;
677 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; } 665 static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
678 666
679 private: 667 private:
680 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1, 668 InstSelect(Cfg *Func, Variable *Dest, Operand *Condition, Operand *Source1,
681 Operand *Source2); 669 Operand *Source2);
682 ~InstSelect() override {}
683 }; 670 };
684 671
685 // Store instruction. The address operand is captured, along with the 672 // Store instruction. The address operand is captured, along with the
686 // data operand to be stored into the address. 673 // data operand to be stored into the address.
687 class InstStore : public InstHighLevel { 674 class InstStore : public InstHighLevel {
688 InstStore() = delete; 675 InstStore() = delete;
689 InstStore(const InstStore &) = delete; 676 InstStore(const InstStore &) = delete;
690 InstStore &operator=(const InstStore &) = delete; 677 InstStore &operator=(const InstStore &) = delete;
691 678
692 public: 679 public:
693 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr, 680 static InstStore *create(Cfg *Func, Operand *Data, Operand *Addr,
694 uint32_t Align = 1) { 681 uint32_t Align = 1) {
695 // TODO(kschimpf) Stop ignoring alignment specification. 682 // TODO(kschimpf) Stop ignoring alignment specification.
696 (void)Align; 683 (void)Align;
697 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr); 684 return new (Func->allocate<InstStore>()) InstStore(Func, Data, Addr);
698 } 685 }
699 Operand *getAddr() const { return getSrc(1); } 686 Operand *getAddr() const { return getSrc(1); }
700 Operand *getData() const { return getSrc(0); } 687 Operand *getData() const { return getSrc(0); }
701 Variable *getRmwBeacon() const { return llvm::dyn_cast<Variable>(getSrc(2)); } 688 Variable *getRmwBeacon() const { return llvm::dyn_cast<Variable>(getSrc(2)); }
702 void setRmwBeacon(Variable *Beacon); 689 void setRmwBeacon(Variable *Beacon);
703 void dump(const Cfg *Func) const override; 690 void dump(const Cfg *Func) const override;
704 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; } 691 static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
705 692
706 private: 693 private:
707 InstStore(Cfg *Func, Operand *Data, Operand *Addr); 694 InstStore(Cfg *Func, Operand *Data, Operand *Addr);
708 ~InstStore() override {}
709 }; 695 };
710 696
711 // Switch instruction. The single source operand is captured as 697 // Switch instruction. The single source operand is captured as
712 // getSrc(0). 698 // getSrc(0).
713 class InstSwitch : public InstHighLevel { 699 class InstSwitch : public InstHighLevel {
714 InstSwitch() = delete; 700 InstSwitch() = delete;
715 InstSwitch(const InstSwitch &) = delete; 701 InstSwitch(const InstSwitch &) = delete;
716 InstSwitch &operator=(const InstSwitch &) = delete; 702 InstSwitch &operator=(const InstSwitch &) = delete;
717 703
718 public: 704 public:
(...skipping 19 matching lines...) Expand all
738 void dump(const Cfg *Func) const override; 724 void dump(const Cfg *Func) const override;
739 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; } 725 static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
740 726
741 private: 727 private:
742 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault); 728 InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source, CfgNode *LabelDefault);
743 void destroy(Cfg *Func) override { 729 void destroy(Cfg *Func) override {
744 Func->deallocateArrayOf<uint64_t>(Values); 730 Func->deallocateArrayOf<uint64_t>(Values);
745 Func->deallocateArrayOf<CfgNode *>(Labels); 731 Func->deallocateArrayOf<CfgNode *>(Labels);
746 Inst::destroy(Func); 732 Inst::destroy(Func);
747 } 733 }
748 ~InstSwitch() override {}
749 734
750 CfgNode *LabelDefault; 735 CfgNode *LabelDefault;
751 SizeT NumCases; // not including the default case 736 SizeT NumCases; // not including the default case
752 uint64_t *Values; // size is NumCases 737 uint64_t *Values; // size is NumCases
753 CfgNode **Labels; // size is NumCases 738 CfgNode **Labels; // size is NumCases
754 }; 739 };
755 740
756 // Unreachable instruction. This is a terminator instruction with no 741 // Unreachable instruction. This is a terminator instruction with no
757 // operands. 742 // operands.
758 class InstUnreachable : public InstHighLevel { 743 class InstUnreachable : public InstHighLevel {
759 InstUnreachable() = delete; 744 InstUnreachable() = delete;
760 InstUnreachable(const InstUnreachable &) = delete; 745 InstUnreachable(const InstUnreachable &) = delete;
761 InstUnreachable &operator=(const InstUnreachable &) = delete; 746 InstUnreachable &operator=(const InstUnreachable &) = delete;
762 747
763 public: 748 public:
764 static InstUnreachable *create(Cfg *Func) { 749 static InstUnreachable *create(Cfg *Func) {
765 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func); 750 return new (Func->allocate<InstUnreachable>()) InstUnreachable(Func);
766 } 751 }
767 NodeList getTerminatorEdges() const override { return NodeList(); } 752 NodeList getTerminatorEdges() const override { return NodeList(); }
768 void dump(const Cfg *Func) const override; 753 void dump(const Cfg *Func) const override;
769 static bool classof(const Inst *Inst) { 754 static bool classof(const Inst *Inst) {
770 return Inst->getKind() == Unreachable; 755 return Inst->getKind() == Unreachable;
771 } 756 }
772 757
773 private: 758 private:
774 explicit InstUnreachable(Cfg *Func); 759 explicit InstUnreachable(Cfg *Func);
775 ~InstUnreachable() override {}
776 }; 760 };
777 761
778 // BundleLock instruction. There are no operands. Contains an option 762 // BundleLock instruction. There are no operands. Contains an option
779 // indicating whether align_to_end is specified. 763 // indicating whether align_to_end is specified.
780 class InstBundleLock : public InstHighLevel { 764 class InstBundleLock : public InstHighLevel {
781 InstBundleLock() = delete; 765 InstBundleLock() = delete;
782 InstBundleLock(const InstBundleLock &) = delete; 766 InstBundleLock(const InstBundleLock &) = delete;
783 InstBundleLock &operator=(const InstBundleLock &) = delete; 767 InstBundleLock &operator=(const InstBundleLock &) = delete;
784 768
785 public: 769 public:
786 enum Option { Opt_None, Opt_AlignToEnd }; 770 enum Option { Opt_None, Opt_AlignToEnd };
787 static InstBundleLock *create(Cfg *Func, Option BundleOption) { 771 static InstBundleLock *create(Cfg *Func, Option BundleOption) {
788 return new (Func->allocate<InstBundleLock>()) 772 return new (Func->allocate<InstBundleLock>())
789 InstBundleLock(Func, BundleOption); 773 InstBundleLock(Func, BundleOption);
790 } 774 }
791 void emit(const Cfg *Func) const override; 775 void emit(const Cfg *Func) const override;
792 void emitIAS(const Cfg * /* Func */) const override {} 776 void emitIAS(const Cfg * /* Func */) const override {}
793 void dump(const Cfg *Func) const override; 777 void dump(const Cfg *Func) const override;
794 Option getOption() const { return BundleOption; } 778 Option getOption() const { return BundleOption; }
795 static bool classof(const Inst *Inst) { 779 static bool classof(const Inst *Inst) {
796 return Inst->getKind() == BundleLock; 780 return Inst->getKind() == BundleLock;
797 } 781 }
798 782
799 private: 783 private:
800 Option BundleOption; 784 Option BundleOption;
801 InstBundleLock(Cfg *Func, Option BundleOption); 785 InstBundleLock(Cfg *Func, Option BundleOption);
802 ~InstBundleLock() override {}
803 }; 786 };
804 787
805 // BundleUnlock instruction. There are no operands. 788 // BundleUnlock instruction. There are no operands.
806 class InstBundleUnlock : public InstHighLevel { 789 class InstBundleUnlock : public InstHighLevel {
807 InstBundleUnlock() = delete; 790 InstBundleUnlock() = delete;
808 InstBundleUnlock(const InstBundleUnlock &) = delete; 791 InstBundleUnlock(const InstBundleUnlock &) = delete;
809 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete; 792 InstBundleUnlock &operator=(const InstBundleUnlock &) = delete;
810 793
811 public: 794 public:
812 static InstBundleUnlock *create(Cfg *Func) { 795 static InstBundleUnlock *create(Cfg *Func) {
813 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func); 796 return new (Func->allocate<InstBundleUnlock>()) InstBundleUnlock(Func);
814 } 797 }
815 void emit(const Cfg *Func) const override; 798 void emit(const Cfg *Func) const override;
816 void emitIAS(const Cfg * /* Func */) const override {} 799 void emitIAS(const Cfg * /* Func */) const override {}
817 void dump(const Cfg *Func) const override; 800 void dump(const Cfg *Func) const override;
818 static bool classof(const Inst *Inst) { 801 static bool classof(const Inst *Inst) {
819 return Inst->getKind() == BundleUnlock; 802 return Inst->getKind() == BundleUnlock;
820 } 803 }
821 804
822 private: 805 private:
823 explicit InstBundleUnlock(Cfg *Func); 806 explicit InstBundleUnlock(Cfg *Func);
824 ~InstBundleUnlock() override {}
825 }; 807 };
826 808
827 // FakeDef instruction. This creates a fake definition of a variable, 809 // FakeDef instruction. This creates a fake definition of a variable,
828 // which is how we represent the case when an instruction produces 810 // which is how we represent the case when an instruction produces
829 // multiple results. This doesn't happen with high-level ICE 811 // multiple results. This doesn't happen with high-level ICE
830 // instructions, but might with lowered instructions. For example, 812 // instructions, but might with lowered instructions. For example,
831 // this would be a way to represent condition flags being modified by 813 // this would be a way to represent condition flags being modified by
832 // an instruction. 814 // an instruction.
833 // 815 //
834 // It's generally useful to set the optional source operand to be the 816 // It's generally useful to set the optional source operand to be the
(...skipping 11 matching lines...) Expand all
846 Variable *Src = nullptr) { 828 Variable *Src = nullptr) {
847 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src); 829 return new (Func->allocate<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
848 } 830 }
849 void emit(const Cfg *Func) const override; 831 void emit(const Cfg *Func) const override;
850 void emitIAS(const Cfg * /* Func */) const override {} 832 void emitIAS(const Cfg * /* Func */) const override {}
851 void dump(const Cfg *Func) const override; 833 void dump(const Cfg *Func) const override;
852 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } 834 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
853 835
854 private: 836 private:
855 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); 837 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
856 ~InstFakeDef() override {}
857 }; 838 };
858 839
859 // FakeUse instruction. This creates a fake use of a variable, to 840 // FakeUse instruction. This creates a fake use of a variable, to
860 // keep the instruction that produces that variable from being 841 // keep the instruction that produces that variable from being
861 // dead-code eliminated. This is useful in a variety of lowering 842 // dead-code eliminated. This is useful in a variety of lowering
862 // situations. The FakeUse instruction has no dest, so it can itself 843 // situations. The FakeUse instruction has no dest, so it can itself
863 // never be dead-code eliminated. 844 // never be dead-code eliminated.
864 class InstFakeUse : public InstHighLevel { 845 class InstFakeUse : public InstHighLevel {
865 InstFakeUse() = delete; 846 InstFakeUse() = delete;
866 InstFakeUse(const InstFakeUse &) = delete; 847 InstFakeUse(const InstFakeUse &) = delete;
867 InstFakeUse &operator=(const InstFakeUse &) = delete; 848 InstFakeUse &operator=(const InstFakeUse &) = delete;
868 849
869 public: 850 public:
870 static InstFakeUse *create(Cfg *Func, Variable *Src) { 851 static InstFakeUse *create(Cfg *Func, Variable *Src) {
871 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src); 852 return new (Func->allocate<InstFakeUse>()) InstFakeUse(Func, Src);
872 } 853 }
873 void emit(const Cfg *Func) const override; 854 void emit(const Cfg *Func) const override;
874 void emitIAS(const Cfg * /* Func */) const override {} 855 void emitIAS(const Cfg * /* Func */) const override {}
875 void dump(const Cfg *Func) const override; 856 void dump(const Cfg *Func) const override;
876 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } 857 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
877 858
878 private: 859 private:
879 InstFakeUse(Cfg *Func, Variable *Src); 860 InstFakeUse(Cfg *Func, Variable *Src);
880 ~InstFakeUse() override {}
881 }; 861 };
882 862
883 // FakeKill instruction. This "kills" a set of variables by modeling 863 // FakeKill instruction. This "kills" a set of variables by modeling
884 // a trivial live range at this instruction for each (implicit) 864 // a trivial live range at this instruction for each (implicit)
885 // variable. The primary use is to indicate that scratch registers 865 // variable. The primary use is to indicate that scratch registers
886 // are killed after a call, so that the register allocator won't 866 // are killed after a call, so that the register allocator won't
887 // assign a scratch register to a variable whose live range spans a 867 // assign a scratch register to a variable whose live range spans a
888 // call. 868 // call.
889 // 869 //
890 // The FakeKill instruction also holds a pointer to the instruction 870 // The FakeKill instruction also holds a pointer to the instruction
891 // that kills the set of variables, so that if that linked instruction 871 // that kills the set of variables, so that if that linked instruction
892 // gets dead-code eliminated, the FakeKill instruction will as well. 872 // gets dead-code eliminated, the FakeKill instruction will as well.
893 class InstFakeKill : public InstHighLevel { 873 class InstFakeKill : public InstHighLevel {
894 InstFakeKill() = delete; 874 InstFakeKill() = delete;
895 InstFakeKill(const InstFakeKill &) = delete; 875 InstFakeKill(const InstFakeKill &) = delete;
896 InstFakeKill &operator=(const InstFakeKill &) = delete; 876 InstFakeKill &operator=(const InstFakeKill &) = delete;
897 877
898 public: 878 public:
899 static InstFakeKill *create(Cfg *Func, const Inst *Linked) { 879 static InstFakeKill *create(Cfg *Func, const Inst *Linked) {
900 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked); 880 return new (Func->allocate<InstFakeKill>()) InstFakeKill(Func, Linked);
901 } 881 }
902 const Inst *getLinked() const { return Linked; } 882 const Inst *getLinked() const { return Linked; }
903 void emit(const Cfg *Func) const override; 883 void emit(const Cfg *Func) const override;
904 void emitIAS(const Cfg * /* Func */) const override {} 884 void emitIAS(const Cfg * /* Func */) const override {}
905 void dump(const Cfg *Func) const override; 885 void dump(const Cfg *Func) const override;
906 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } 886 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
907 887
908 private: 888 private:
909 InstFakeKill(Cfg *Func, const Inst *Linked); 889 InstFakeKill(Cfg *Func, const Inst *Linked);
910 ~InstFakeKill() override {}
911 890
912 // This instruction is ignored if Linked->isDeleted() is true. 891 // This instruction is ignored if Linked->isDeleted() is true.
913 const Inst *Linked; 892 const Inst *Linked;
914 }; 893 };
915 894
916 // The Target instruction is the base class for all target-specific 895 // The Target instruction is the base class for all target-specific
917 // instructions. 896 // instructions.
918 class InstTarget : public Inst { 897 class InstTarget : public Inst {
919 InstTarget() = delete; 898 InstTarget() = delete;
920 InstTarget(const InstTarget &) = delete; 899 InstTarget(const InstTarget &) = delete;
921 InstTarget &operator=(const InstTarget &) = delete; 900 InstTarget &operator=(const InstTarget &) = delete;
922 901
923 public: 902 public:
924 uint32_t getEmitInstCount() const override { return 1; } 903 uint32_t getEmitInstCount() const override { return 1; }
925 void dump(const Cfg *Func) const override; 904 void dump(const Cfg *Func) const override;
926 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } 905 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
927 906
928 protected: 907 protected:
929 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) 908 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
930 : Inst(Func, Kind, MaxSrcs, Dest) { 909 : Inst(Func, Kind, MaxSrcs, Dest) {
931 assert(Kind >= Target); 910 assert(Kind >= Target);
932 } 911 }
933 ~InstTarget() override {}
934 }; 912 };
935 913
936 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source); 914 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source);
937 915
938 } // end of namespace Ice 916 } // end of namespace Ice
939 917
940 namespace llvm { 918 namespace llvm {
941 919
942 // Override the default ilist traits so that Inst's private ctor and 920 // Override the default ilist traits so that Inst's private ctor and
943 // deleted dtor aren't invoked. 921 // deleted dtor aren't invoked.
944 template <> 922 template <>
945 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> { 923 struct ilist_traits<Ice::Inst> : public ilist_default_traits<Ice::Inst> {
946 Ice::Inst *createSentinel() const { 924 Ice::Inst *createSentinel() const {
947 return static_cast<Ice::Inst *>(&Sentinel); 925 return static_cast<Ice::Inst *>(&Sentinel);
948 } 926 }
949 static void destroySentinel(Ice::Inst *) {} 927 static void destroySentinel(Ice::Inst *) {}
950 Ice::Inst *provideInitialHead() const { return createSentinel(); } 928 Ice::Inst *provideInitialHead() const { return createSentinel(); }
951 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); } 929 Ice::Inst *ensureHead(Ice::Inst *) const { return createSentinel(); }
952 static void noteHead(Ice::Inst *, Ice::Inst *) {} 930 static void noteHead(Ice::Inst *, Ice::Inst *) {}
953 void deleteNode(Ice::Inst *) {} 931 void deleteNode(Ice::Inst *) {}
954 932
955 private: 933 private:
956 mutable ilist_half_node<Ice::Inst> Sentinel; 934 mutable ilist_half_node<Ice::Inst> Sentinel;
957 }; 935 };
958 936
959 } // end of namespace llvm 937 } // end of namespace llvm
960 938
961 #endif // SUBZERO_SRC_ICEINST_H 939 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW
« src/IceGlobalInits.h ('K') | « src/IceGlobalInits.cpp ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698