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

Side by Side Diff: src/IceInst.h

Issue 265703002: Add Om1 lowering with no optimizations (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 7 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 29 matching lines...) Expand all
40 Br, 40 Br,
41 Call, 41 Call,
42 Cast, 42 Cast,
43 Fcmp, 43 Fcmp,
44 Icmp, 44 Icmp,
45 Load, 45 Load,
46 Phi, 46 Phi,
47 Ret, 47 Ret,
48 Select, 48 Select,
49 Store, 49 Store,
50 Switch 50 Switch,
51 FakeDef, // not part of LLVM/PNaCl bitcode
52 FakeUse, // not part of LLVM/PNaCl bitcode
53 FakeKill, // not part of LLVM/PNaCl bitcode
54 Target // target-specific low-level ICE
55 // Anything >= Target is an InstTarget subclass.
51 }; 56 };
52 InstKind getKind() const { return Kind; } 57 InstKind getKind() const { return Kind; }
53 58
54 int32_t getNumber() const { return Number; } 59 int32_t getNumber() const { return Number; }
55 60
56 bool isDeleted() const { return Deleted; } 61 bool isDeleted() const { return Deleted; }
57 void setDeleted() { Deleted = true; } 62 void setDeleted() { Deleted = true; }
58 63
59 bool hasSideEffects() const { return HasSideEffects; } 64 bool hasSideEffects() const { return HasSideEffects; }
60 65
(...skipping 15 matching lines...) Expand all
76 "getTerminatorEdges() called on a non-terminator instruction"); 81 "getTerminatorEdges() called on a non-terminator instruction");
77 return NodeList(); 82 return NodeList();
78 } 83 }
79 84
80 // Updates the status of the Variables contained within the 85 // Updates the status of the Variables contained within the
81 // instruction. In particular, it marks where the Dest variable is 86 // instruction. In particular, it marks where the Dest variable is
82 // first assigned, and it tracks whether variables are live across 87 // first assigned, and it tracks whether variables are live across
83 // basic blocks, i.e. used in a different block from their definition. 88 // basic blocks, i.e. used in a different block from their definition.
84 void updateVars(CfgNode *Node); 89 void updateVars(CfgNode *Node);
85 90
91 virtual void emit(const Cfg *Func) const;
86 virtual void dump(const Cfg *Func) const; 92 virtual void dump(const Cfg *Func) const;
87 void dumpDecorated(const Cfg *Func) const; 93 void dumpDecorated(const Cfg *Func) const;
94 void emitSources(const Cfg *Func) const;
88 void dumpSources(const Cfg *Func) const; 95 void dumpSources(const Cfg *Func) const;
89 void dumpDest(const Cfg *Func) const; 96 void dumpDest(const Cfg *Func) const;
97 virtual bool isRedundantAssign() const { return false; }
90 98
91 virtual ~Inst() {} 99 virtual ~Inst() {}
92 100
93 protected: 101 protected:
94 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest); 102 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
95 void addSource(Operand *Src) { 103 void addSource(Operand *Src) {
96 assert(Src); 104 assert(Src);
97 assert(NumSrcs < MaxSrcs); 105 assert(NumSrcs < MaxSrcs);
98 Srcs[NumSrcs++] = Src; 106 Srcs[NumSrcs++] = Src;
99 } 107 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 155
148 // Binary arithmetic instruction. The source operands are captured in 156 // Binary arithmetic instruction. The source operands are captured in
149 // getSrc(0) and getSrc(1). 157 // getSrc(0) and getSrc(1).
150 class InstArithmetic : public Inst { 158 class InstArithmetic : public Inst {
151 public: 159 public:
152 enum OpKind { 160 enum OpKind {
153 #define X(tag, str, commutative) tag, 161 #define X(tag, str, commutative) tag,
154 ICEINSTARITHMETIC_TABLE 162 ICEINSTARITHMETIC_TABLE
155 #undef X 163 #undef X
156 }; 164 };
165
157 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest, 166 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest,
158 Operand *Source1, Operand *Source2) { 167 Operand *Source1, Operand *Source2) {
159 return new (Func->allocateInst<InstArithmetic>()) 168 return new (Func->allocateInst<InstArithmetic>())
160 InstArithmetic(Func, Op, Dest, Source1, Source2); 169 InstArithmetic(Func, Op, Dest, Source1, Source2);
161 } 170 }
162 OpKind getOp() const { return Op; } 171 OpKind getOp() const { return Op; }
163 bool isCommutative() const; 172 bool isCommutative() const;
164 virtual void dump(const Cfg *Func) const; 173 virtual void dump(const Cfg *Func) const;
165 static bool classof(const Inst *Inst) { 174 static bool classof(const Inst *Inst) {
166 return Inst->getKind() == Arithmetic; 175 return Inst->getKind() == Arithmetic;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 }; 281 };
273 282
274 // Cast instruction (a.k.a. conversion operation). 283 // Cast instruction (a.k.a. conversion operation).
275 class InstCast : public Inst { 284 class InstCast : public Inst {
276 public: 285 public:
277 enum OpKind { 286 enum OpKind {
278 #define X(tag, str) tag, 287 #define X(tag, str) tag,
279 ICEINSTCAST_TABLE 288 ICEINSTCAST_TABLE
280 #undef X 289 #undef X
281 }; 290 };
291
282 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, 292 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
283 Operand *Source) { 293 Operand *Source) {
284 return new (Func->allocateInst<InstCast>()) 294 return new (Func->allocateInst<InstCast>())
285 InstCast(Func, CastKind, Dest, Source); 295 InstCast(Func, CastKind, Dest, Source);
286 } 296 }
287 OpKind getCastKind() const { return CastKind; } 297 OpKind getCastKind() const { return CastKind; }
288 virtual void dump(const Cfg *Func) const; 298 virtual void dump(const Cfg *Func) const;
289 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } 299 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
290 300
291 private: 301 private:
292 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); 302 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source);
293 InstCast(const InstCast &) LLVM_DELETED_FUNCTION; 303 InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
294 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION; 304 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
295 virtual ~InstCast() {} 305 virtual ~InstCast() {}
296 const OpKind CastKind; 306 const OpKind CastKind;
297 }; 307 };
298 308
299 // Floating-point comparison instruction. The source operands are 309 // Floating-point comparison instruction. The source operands are
300 // captured in getSrc(0) and getSrc(1). 310 // captured in getSrc(0) and getSrc(1).
301 class InstFcmp : public Inst { 311 class InstFcmp : public Inst {
302 public: 312 public:
303 enum FCond { 313 enum FCond {
304 #define X(tag, str) tag, 314 #define X(tag, str) tag,
305 ICEINSTFCMP_TABLE 315 ICEINSTFCMP_TABLE
306 #undef X 316 #undef X
307 }; 317 };
318
308 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, 319 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest,
309 Operand *Source1, Operand *Source2) { 320 Operand *Source1, Operand *Source2) {
310 return new (Func->allocateInst<InstFcmp>()) 321 return new (Func->allocateInst<InstFcmp>())
311 InstFcmp(Func, Condition, Dest, Source1, Source2); 322 InstFcmp(Func, Condition, Dest, Source1, Source2);
312 } 323 }
313 FCond getCondition() const { return Condition; } 324 FCond getCondition() const { return Condition; }
314 virtual void dump(const Cfg *Func) const; 325 virtual void dump(const Cfg *Func) const;
315 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } 326 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
316 327
317 private: 328 private:
318 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, 329 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
319 Operand *Source2); 330 Operand *Source2);
320 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION; 331 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
321 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION; 332 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
322 virtual ~InstFcmp() {} 333 virtual ~InstFcmp() {}
323 const FCond Condition; 334 const FCond Condition;
324 }; 335 };
325 336
326 // Integer comparison instruction. The source operands are captured 337 // Integer comparison instruction. The source operands are captured
327 // in getSrc(0) and getSrc(1). 338 // in getSrc(0) and getSrc(1).
328 class InstIcmp : public Inst { 339 class InstIcmp : public Inst {
329 public: 340 public:
330 enum ICond { 341 enum ICond {
331 #define X(tag, str) tag, 342 #define X(tag, str) tag,
332 ICEINSTICMP_TABLE 343 ICEINSTICMP_TABLE
333 #undef X 344 #undef X
345 None // not part of LLVM; used for unconditional branch
JF 2014/05/04 23:54:58 Isn't that True?
Jim Stichnoth 2014/05/05 07:03:55 Weird, I don't know why this was there. :) It's g
334 }; 346 };
347
335 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, 348 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest,
336 Operand *Source1, Operand *Source2) { 349 Operand *Source1, Operand *Source2) {
337 return new (Func->allocateInst<InstIcmp>()) 350 return new (Func->allocateInst<InstIcmp>())
338 InstIcmp(Func, Condition, Dest, Source1, Source2); 351 InstIcmp(Func, Condition, Dest, Source1, Source2);
339 } 352 }
340 ICond getCondition() const { return Condition; } 353 ICond getCondition() const { return Condition; }
341 virtual void dump(const Cfg *Func) const; 354 virtual void dump(const Cfg *Func) const;
342 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } 355 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
343 356
344 private: 357 private:
(...skipping 24 matching lines...) Expand all
369 }; 382 };
370 383
371 // Phi instruction. For incoming edge I, the node is Labels[I] and 384 // Phi instruction. For incoming edge I, the node is Labels[I] and
372 // the Phi source operand is getSrc(I). 385 // the Phi source operand is getSrc(I).
373 class InstPhi : public Inst { 386 class InstPhi : public Inst {
374 public: 387 public:
375 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { 388 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) {
376 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); 389 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest);
377 } 390 }
378 void addArgument(Operand *Source, CfgNode *Label); 391 void addArgument(Operand *Source, CfgNode *Label);
392 Operand *getOperandForTarget(CfgNode *Target) const;
393 Inst *lower(Cfg *Func, CfgNode *Node);
379 virtual void dump(const Cfg *Func) const; 394 virtual void dump(const Cfg *Func) const;
380 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } 395 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
381 396
382 private: 397 private:
383 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); 398 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest);
384 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION; 399 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
385 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION; 400 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
386 virtual void destroy(Cfg *Func) { 401 virtual void destroy(Cfg *Func) {
387 Func->deallocateArrayOf<CfgNode *>(Labels); 402 Func->deallocateArrayOf<CfgNode *>(Labels);
388 Inst::destroy(Func); 403 Inst::destroy(Func);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 return Inst->getKind() == Unreachable; 530 return Inst->getKind() == Unreachable;
516 } 531 }
517 532
518 private: 533 private:
519 InstUnreachable(Cfg *Func); 534 InstUnreachable(Cfg *Func);
520 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION; 535 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
521 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION; 536 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
522 virtual ~InstUnreachable() {} 537 virtual ~InstUnreachable() {}
523 }; 538 };
524 539
540 // FakeDef instruction. This creates a fake definition of a variable,
541 // which is how we represent the case when an instruction produces
542 // multiple results. This doesn't happen with high-level ICE
543 // instructions, but might with lowered instructions. For example,
544 // this would be a way to represent condition flags being modified by
545 // an instruction.
546 //
547 // It's generally useful to set the optional source operand to be the
548 // dest variable of the instruction that actually produces the FakeDef
549 // dest. Otherwise, the original instruction could be dead-code
550 // eliminated if its dest operand is unused, and therefore the FakeDef
551 // dest wouldn't be properly initialized.
552 class InstFakeDef : public Inst {
553 public:
554 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) {
555 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src);
556 }
557 virtual void emit(const Cfg *Func) const;
558 virtual void dump(const Cfg *Func) const;
559 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; }
560
561 private:
562 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src);
563 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION;
564 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION;
565 virtual ~InstFakeDef() {}
566 };
567
568 // FakeUse instruction. This creates a fake use of a variable, to
569 // keep the instruction that produces that variable from being
570 // dead-code eliminated. This is useful in a variety of lowering
571 // situations. The FakeUse instruction has no dest, so it can itself
572 // never be dead-code eliminated.
573 class InstFakeUse : public Inst {
574 public:
575 static InstFakeUse *create(Cfg *Func, Variable *Src) {
576 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src);
577 }
578 virtual void emit(const Cfg *Func) const;
579 virtual void dump(const Cfg *Func) const;
580 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; }
581
582 private:
583 InstFakeUse(Cfg *Func, Variable *Src);
584 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION;
585 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION;
586 virtual ~InstFakeUse() {}
587 };
588
589 // FakeKill instruction. This "kills" a set of variables by adding a
590 // trivial live range at this instruction to each variable. The
591 // primary use is to indicate that scratch registers are killed after
592 // a call, so that the register allocator won't assign a scratch
593 // register to a variable whose live range spans a call.
594 //
595 // The FakeKill instruction also holds a pointer to the instruction
596 // that kills the set of variables, so that if that linked instruction
597 // gets dead-code eliminated, the FakeKill instruction will as well.
598 class InstFakeKill : public Inst {
599 public:
600 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs,
601 const Inst *Linked) {
602 return new (Func->allocateInst<InstFakeKill>())
603 InstFakeKill(Func, KilledRegs, Linked);
604 }
605 const Inst *getLinked() const { return Linked; }
606 virtual void emit(const Cfg *Func) const;
607 virtual void dump(const Cfg *Func) const;
608 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; }
609
610 private:
611 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked);
612 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION;
613 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION;
614 virtual ~InstFakeKill() {}
615
616 // This instruction is ignored if Linked->isDeleted() is true.
617 const Inst *Linked;
618 };
619
620 // The Target instruction is the base class for all target-specific
621 // instructions.
622 class InstTarget : public Inst {
623 public:
624 virtual void emit(const Cfg *Func) const = 0;
625 virtual void dump(const Cfg *Func) const;
626 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; }
627
628 protected:
629 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
630 : Inst(Func, Kind, MaxSrcs, Dest) {
631 assert(Kind >= Target);
632 }
633 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION;
634 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION;
635 virtual ~InstTarget() {}
636 };
637
525 } // end of namespace Ice 638 } // end of namespace Ice
526 639
527 #endif // SUBZERO_SRC_ICEINST_H 640 #endif // SUBZERO_SRC_ICEINST_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698