ScheduleDAG.h revision 4c8c83022b501759d8559e224c84ae2a9921ba41
1a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
2a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//
3a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//                     The LLVM Compiler Infrastructure
4a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//
8a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//===----------------------------------------------------------------------===//
9a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//
10a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng// This file implements the ScheduleDAG class, which is used as the common
11a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng// base class for SelectionDAG-based instruction scheduler.
12a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//
13a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng//===----------------------------------------------------------------------===//
14a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
15a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
16a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng#define LLVM_CODEGEN_SCHEDULEDAG_H
17a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
189e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng#include "llvm/CodeGen/MachineBasicBlock.h"
19a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng#include "llvm/CodeGen/SelectionDAG.h"
209e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng#include "llvm/ADT/BitVector.h"
212ba528b3a75955c960347e5b5b28ae74d5a81909Chris Lattner#include "llvm/ADT/DenseMap.h"
223e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman#include "llvm/ADT/GraphTraits.h"
2394c002a190cd2e3a52b1510bc997e53d63af0b3bChris Lattner#include "llvm/ADT/SmallSet.h"
24e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
25a9c2091cd38e401c846391c9951ff416e709b65eEvan Chengnamespace llvm {
26ca5ca41a635d361604a74ea8f6dd447093a0b681Jeff Cohen  struct InstrStage;
27713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  struct SUnit;
28a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class MachineConstantPool;
296b2cf285bd43fdc98ca68df477570ef6938d4fb2Evan Cheng  class MachineFunction;
3044c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey  class MachineModuleInfo;
3184bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner  class MachineRegisterInfo;
32a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class MachineInstr;
336f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  class TargetRegisterInfo;
34a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class SelectionDAG;
359ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  class SelectionDAGISel;
36a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class TargetInstrInfo;
37749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  class TargetInstrDesc;
388a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng  class TargetLowering;
39a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class TargetMachine;
408ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng  class TargetRegisterClass;
41a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
4237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// HazardRecognizer - This determines whether or not an instruction can be
4337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// issued this cycle, and whether or not a noop needs to be inserted to handle
4437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// the hazard.
4537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  class HazardRecognizer {
4637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  public:
4737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    virtual ~HazardRecognizer();
4837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
4937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    enum HazardType {
5037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      NoHazard,      // This instruction can be emitted at this cycle.
5137e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      Hazard,        // This instruction can't be emitted at this cycle.
52d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner      NoopHazard     // This instruction can't be emitted, and needs noops.
5337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    };
5437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
5537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// getHazardType - Return the hazard type of emitting this node.  There are
5637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// three possible results.  Either:
5737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * NoHazard: it is legal to issue this instruction on this cycle.
5837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * Hazard: issuing this instruction would stall the machine.  If some
5937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///     other instruction is available, issue it first.
6037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * NoopHazard: issuing this instruction would break the program.  If
6137e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///     some other instruction can be issued, do so, otherwise issue a noop.
6213d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual HazardType getHazardType(SDNode *) {
6337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      return NoHazard;
6437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    }
6537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
6637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// EmitInstruction - This callback is invoked when an instruction is
6737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// emitted, to advance the hazard state.
6813d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void EmitInstruction(SDNode *) {}
6937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
7037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// AdvanceCycle - This callback is invoked when no instructions can be
7137e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// issued on this cycle without a hazard.  This should increment the
7237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// internal state of the hazard recognizer so that previously "Hazard"
7337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// instructions will now not be hazards.
7413d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void AdvanceCycle() {}
7537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
7637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// EmitNoop - This callback is invoked when a noop was added to the
7737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// instruction stream.
7813d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void EmitNoop() {}
794ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng  };
80713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
81713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  /// SDep - Scheduling dependency. It keeps track of dependent nodes,
82713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  /// cost of the depdenency, etc.
83713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  struct SDep {
84a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SUnit    *Dep;           // Dependent - either a predecessor or a successor.
85a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned  Reg;           // If non-zero, this dep is a phy register dependency.
86a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    int       Cost;          // Cost of the dependency.
87a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool      isCtrl    : 1; // True iff it's a control dependency.
88a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool      isSpecial : 1; // True iff it's a special ctrl dep added during sched.
89a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SDep(SUnit *d, unsigned r, int t, bool c, bool s)
90a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {}
91713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  };
92713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
93e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
94e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// a group of nodes flagged together.
95e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  struct SUnit {
96e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SDNode *Node;                       // Representative node.
979522ee3d93cb15ebcfd80200fea42378cc510d21Chris Lattner    SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
984c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    SUnit *OrigNode;                    // If not this, the node from which
994c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman                                        // this node was cloned.
100e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
101e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    // Preds/Succs - The SUnits before/after us in the graph.  The boolean value
102e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    // is true if the edge is a token chain edge, false if it is a value edge.
103713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
104713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    SmallVector<SDep, 4> Succs;  // All sunit successors.
105713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
106713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::iterator pred_iterator;
107713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::iterator succ_iterator;
108713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
109713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
110228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
111a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned NodeNum;                   // Entry # of node in the node vector.
112a0201d52049be8dcefffe4304a49690a831bcb34Roman Levenstein    unsigned NodeQueueId;               // Queue id of node.
113a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned short Latency;             // Node latency.
114e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumPreds;                     // # of preds.
115e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumSuccs;                     // # of sucss.
116e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumPredsLeft;                 // # of preds not scheduled.
117e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumSuccsLeft;                 // # of succs not scheduled.
118e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isTwoAddress     : 1;          // Is a two-address instruction.
11913d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng    bool isCommutable     : 1;          // Is a commutable instruction.
120f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
121e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isPending        : 1;          // True once pending.
122e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isAvailable      : 1;          // True once available.
123e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isScheduled      : 1;          // True once scheduled.
124e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
125e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Cycle;                     // Once scheduled, the cycle of the op.
126e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Depth;                     // Node depth;
127e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Height;                    // Node height;
1288ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
1298ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    const TargetRegisterClass *CopySrcRC;
130e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
131e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SUnit(SDNode *node, unsigned nodenum)
1324c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman      : Node(node), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), Latency(0),
133a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
13422a529990bb4bb86bdb2ae1cfce7340320a6ca7fEvan Cheng        isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
135e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng        isPending(false), isAvailable(false), isScheduled(false),
1368ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng        CycleBound(0), Cycle(0), Depth(0), Height(0),
1378ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng        CopyDstRC(NULL), CopySrcRC(NULL) {}
138a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
139228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    /// addPred - This adds the specified node as a pred of the current node if
140228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    /// not already.  This returns true if this is a new pred.
141a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool addPred(SUnit *N, bool isCtrl, bool isSpecial,
142a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                 unsigned PhyReg = 0, int Cost = 1) {
14334cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
144a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Preds[i].Dep == N &&
145a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial)
146228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner          return false;
147a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial));
148a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial));
14974d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!isCtrl) {
150a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        ++NumPreds;
151a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        ++N->NumSuccs;
152a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      }
15374d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!N->isScheduled)
15474d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng        ++NumPredsLeft;
15574d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!isScheduled)
15674d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng        ++N->NumSuccsLeft;
157228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner      return true;
158228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    }
159228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
160a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool removePred(SUnit *N, bool isCtrl, bool isSpecial) {
161a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      for (SmallVector<SDep, 4>::iterator I = Preds.begin(), E = Preds.end();
162a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng           I != E; ++I)
163a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) {
164a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          bool FoundSucc = false;
165a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          for (SmallVector<SDep, 4>::iterator II = N->Succs.begin(),
166a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                 EE = N->Succs.end(); II != EE; ++II)
167a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            if (II->Dep == this &&
168a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                II->isCtrl == isCtrl && II->isSpecial == isSpecial) {
169a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              FoundSucc = true;
170a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              N->Succs.erase(II);
171a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              break;
172a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            }
173a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          assert(FoundSucc && "Mismatching preds / succs lists!");
174a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          Preds.erase(I);
17574d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!isCtrl) {
176a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            --NumPreds;
177a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            --N->NumSuccs;
178a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          }
17974d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!N->isScheduled)
18074d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng            --NumPredsLeft;
18174d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!isScheduled)
18274d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng            --N->NumSuccsLeft;
183a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
184a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        }
185a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
186a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    }
187a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
188a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool isPred(SUnit *N) {
18934cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
190a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Preds[i].Dep == N)
191a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
192a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
193a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    }
194a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
195a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool isSucc(SUnit *N) {
19634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
197a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Succs[i].Dep == N)
198a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
199a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
200228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    }
201228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
202e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void dump(const SelectionDAG *G) const;
203e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void dumpAll(const SelectionDAG *G) const;
204e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  };
205e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
206e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  //===--------------------------------------------------------------------===//
207e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// SchedulingPriorityQueue - This interface is used to plug different
208e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// priorities computation algorithms into the list scheduler. It implements
209e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// the interface of a standard priority queue, where nodes are inserted in
210e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// arbitrary order and returned in priority order.  The computation of the
211e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// priority and the representation of the queue are totally up to the
212e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// implementation to decide.
213e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  ///
214e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  class SchedulingPriorityQueue {
215e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  public:
216e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual ~SchedulingPriorityQueue() {}
217e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
2184c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
219fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng                           std::vector<SUnit> &SUnits) = 0;
220a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void addNode(const SUnit *SU) = 0;
221a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void updateNode(const SUnit *SU) = 0;
222e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void releaseState() = 0;
223a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
224a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual unsigned size() const = 0;
225e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual bool empty() const = 0;
226e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void push(SUnit *U) = 0;
227e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
228e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
229e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual SUnit *pop() = 0;
230e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
231a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void remove(SUnit *SU) = 0;
232a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
233e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// ScheduledNode - As each node is scheduled, this method is invoked.  This
234e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// allows the priority function to adjust the priority of node that have
235e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// already been emitted.
23613d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void ScheduledNode(SUnit *) {}
237a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
23813d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void UnscheduledNode(SUnit *) {}
239e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  };
240e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
241a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class ScheduleDAG {
242a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  public:
243a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    SelectionDAG &DAG;                    // DAG of the current basic block
244a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineBasicBlock *BB;                // Current basic block
245a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    const TargetMachine &TM;              // Target processor
246a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    const TargetInstrInfo *TII;           // Target instruction information
2476f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman    const TargetRegisterInfo *TRI;        // Target processor register info
2488a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    TargetLowering *TLI;                  // Target lowering info
2496b2cf285bd43fdc98ca68df477570ef6938d4fb2Evan Cheng    MachineFunction *MF;                  // Machine function
2509e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    MachineRegisterInfo &MRI;             // Virtual/real register map
251a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineConstantPool *ConstPool;       // Target constant pool
25213d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng    std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
25313d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng                                          // represent noop instructions.
2544c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    DenseMap<SDNode*, SUnit*> SUnitMap;   // SDNode to SUnit mapping (n -> n).
255e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    std::vector<SUnit> SUnits;            // The scheduling units.
256b1e07ec6a43383ce0baa42e2f139550cc540f631Dan Gohman    SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
257a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2582f5806c2b37a4e59cb12a6d49f0e3423c2082a64Chris Lattner    ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
25984bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner                const TargetMachine &tm);
260cccf1232a69e2d78516c61a97e7bfa26acefb714Evan Cheng
26137cb415eec53e20ed77c1c90f86310de217f3e6cChris Lattner    virtual ~ScheduleDAG() {}
262a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2633e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
2643e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    /// using 'dot'.
2653e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    ///
2663e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    void viewGraph();
2673e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
268a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    /// Run - perform scheduling.
269a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    ///
270a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineBasicBlock *Run();
271a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2724ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    /// isPassiveNode - Return true if the node is a non-scheduled leaf.
2734ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    ///
2740993f1d8338ccf8552a1dbc3fb19461a5e6165d9Evan Cheng    static bool isPassiveNode(SDNode *Node) {
2754ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ConstantSDNode>(Node))       return true;
276e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman      if (isa<ConstantFPSDNode>(Node))     return true;
2774ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<RegisterSDNode>(Node))       return true;
2784ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<GlobalAddressSDNode>(Node))  return true;
2794ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<BasicBlockSDNode>(Node))     return true;
2804ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<FrameIndexSDNode>(Node))     return true;
2814ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ConstantPoolSDNode>(Node))   return true;
28237efe6764568a3829fee26aba532283131d1a104Nate Begeman      if (isa<JumpTableSDNode>(Node))      return true;
2834ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ExternalSymbolSDNode>(Node)) return true;
28469de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman      if (isa<MemOperandSDNode>(Node))     return true;
28580792f3ddec43aff7f0758c9096f8cb53dcc1e40Dan Gohman      if (Node->getOpcode() == ISD::EntryToken) return true;
2864ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      return false;
2874ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    }
2884ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng
289e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// NewSUnit - Creates a new SUnit and return a ptr to it.
290e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    ///
291e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SUnit *NewSUnit(SDNode *N) {
29234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
2934c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman      SUnits.back().OrigNode = &SUnits.back();
294e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng      return &SUnits.back();
295e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    }
296e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
297a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    /// Clone - Creates a clone of the specified SUnit. It does not copy the
298a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    /// predecessors / successors info nor the temporary scheduling states.
299a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SUnit *Clone(SUnit *N);
300a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
301e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
302e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// This SUnit graph is similar to the SelectionDAG, but represents flagged
303e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// together nodes with a single SUnit.
304e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void BuildSchedUnits();
305e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
306f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    /// ComputeLatency - Compute node latency.
307f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    ///
308f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    void ComputeLatency(SUnit *SU);
309f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng
310e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
311e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    ///
312e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void CalculateDepths();
313e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void CalculateHeights();
314e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
315fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// CountResults - The results of target nodes have register or immediate
316fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// operands first, then an optional chain, and optional flag operands
317fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// (which do not go into the machine instrs.)
318fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    static unsigned CountResults(SDNode *Node);
319fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng
32069de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman    /// CountOperands - The inputs to target nodes have any actual inputs first,
32142a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// followed by special operands that describe memory references, then an
32242a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// optional chain operand, then flag operands.  Compute the number of
32342a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// actual operands that will go into the resulting MachineInstr.
324fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    static unsigned CountOperands(SDNode *Node);
325fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng
32642a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// ComputeMemOperandsEnd - Find the index one past the last
32742a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// MemOperandSDNode operand
32842a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    static unsigned ComputeMemOperandsEnd(SDNode *Node);
32969de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman
3304ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    /// EmitNode - Generate machine code for an node and needed dependencies.
3317593639df672018d90331774f45b5ef06da2f385Chris Lattner    /// VRBaseMap contains, for each already emitted node, the first virtual
3327593639df672018d90331774f45b5ef06da2f385Chris Lattner    /// register number for the results of the node.
3334ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    ///
3344c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    void EmitNode(SDNode *Node, bool IsClone,
3359cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                  DenseMap<SDOperand, unsigned> &VRBaseMap);
336202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner
337202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    /// EmitNoop - Emit a noop instruction.
338202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    ///
339202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    void EmitNoop();
3408409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng
3418a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void EmitSchedule();
3428a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3438a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void dumpSchedule() const;
3448a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3458a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// Schedule - Order nodes according to selected style.
3468a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    ///
3478a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    virtual void Schedule() {}
3488a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3498a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng  private:
3508a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// EmitSubregNode - Generate machine code for subreg nodes.
3518a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    ///
3528a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void EmitSubregNode(SDNode *Node,
3539cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                        DenseMap<SDOperand, unsigned> &VRBaseMap);
3548a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3558a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// getVR - Return the virtual register corresponding to the specified result
3568a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// of the specified node.
3579cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein    unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap);
3588a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3598a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// getDstOfCopyToRegUse - If the only use of the specified result number of
3608a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// node is a CopyToReg, return its destination register. Return 0 otherwise.
3618a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
3628a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3638a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
3648a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng                    const TargetInstrDesc *II,
3659cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                    DenseMap<SDOperand, unsigned> &VRBaseMap);
3668a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
36736b5c1338a03453ba1c110b120269ca972fb65a3Dan Gohman    void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
3688a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3698ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
3708ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng
3718409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
3728409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    /// implicit physical register output.
3734c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
374a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                         unsigned SrcReg,
3759cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                         DenseMap<SDOperand, unsigned> &VRBaseMap);
376202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner
3778409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
378749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner                                const TargetInstrDesc &II,
3799cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                                DenseMap<SDOperand, unsigned> &VRBaseMap);
3808409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng
3819e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
3829e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// physical register has only a single copy use, then coalesced the copy
3831090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng    /// if possible.
3841090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng    void EmitLiveInCopy(MachineBasicBlock *MBB,
3851090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        MachineBasicBlock::iterator &InsertPos,
3861090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        unsigned VirtReg, unsigned PhysReg,
3871090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        const TargetRegisterClass *RC,
3881090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        DenseMap<MachineInstr*, unsigned> &CopyRegMap);
3899e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng
3909e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// EmitLiveInCopies - If this is the first basic block in the function,
3919e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// and if it has live ins that need to be copied into vregs, emit the
3929e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// copies into the top of the block.
3939e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    void EmitLiveInCopies(MachineBasicBlock *MBB);
394a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  };
395a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
396f0f9c90204c650b9f3c3feb02ccfcb1e40c6acddEvan Cheng  /// createBURRListDAGScheduler - This creates a bottom up register usage
397f0f9c90204c650b9f3c3feb02ccfcb1e40c6acddEvan Cheng  /// reduction list scheduler.
3989ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
3999ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey                                          SelectionDAG *DAG,
400f0f9c90204c650b9f3c3feb02ccfcb1e40c6acddEvan Cheng                                          MachineBasicBlock *BB);
40120614b956257d8702736ede13762385972cf4e43Chris Lattner
402e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// createTDRRListDAGScheduler - This creates a top down register usage
403e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// reduction list scheduler.
4049ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
4059ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey                                          SelectionDAG *DAG,
406e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng                                          MachineBasicBlock *BB);
407e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
40837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// createTDListDAGScheduler - This creates a top-down list scheduler with
40913ec702c430b91ee49b9e6d9581cd95412f216c8Jim Laskey  /// a hazard recognizer.
4109ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
4119ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey                                        SelectionDAG *DAG,
41213ec702c430b91ee49b9e6d9581cd95412f216c8Jim Laskey                                        MachineBasicBlock *BB);
41313ec702c430b91ee49b9e6d9581cd95412f216c8Jim Laskey
4149373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  /// createDefaultScheduler - This creates an instruction scheduler appropriate
4159373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  /// for the target.
4169373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
4179373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey                                      SelectionDAG *DAG,
4189373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey                                      MachineBasicBlock *BB);
4193e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4203e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
4213e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnit *Node;
4223e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    unsigned Operand;
4233e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4243e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
4253e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  public:
4263e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    bool operator==(const SUnitIterator& x) const {
4273e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return Operand == x.Operand;
4283e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4293e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
4303e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4313e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    const SUnitIterator &operator=(const SUnitIterator &I) {
4323e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
4333e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      Operand = I.Operand;
4343e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return *this;
4353e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4363e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4373e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    pointer operator*() const {
438713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng      return Node->Preds[Operand].Dep;
4393e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4403e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    pointer operator->() const { return operator*(); }
4413e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4423e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator& operator++() {                // Preincrement
4433e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      ++Operand;
4443e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return *this;
4453e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4463e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator operator++(int) { // Postincrement
4473e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      SUnitIterator tmp = *this; ++*this; return tmp;
4483e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4493e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4503e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
4513e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static SUnitIterator end  (SUnit *N) {
45234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      return SUnitIterator(N, (unsigned)N->Preds.size());
4533e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4543e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4553e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    unsigned getOperand() const { return Operand; }
4563e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    const SUnit *getNode() const { return Node; }
457713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; }
45889bf0a6b05c8c353890c88ed1c10dec96a9a7bd8Dan Gohman    bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; }
4593e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
4603e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4613e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  template <> struct GraphTraits<SUnit*> {
4623e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef SUnit NodeType;
4633e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef SUnitIterator ChildIteratorType;
4643e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline NodeType *getEntryNode(SUnit *N) { return N; }
4653e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline ChildIteratorType child_begin(NodeType *N) {
4663e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return SUnitIterator::begin(N);
4673e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4683e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline ChildIteratorType child_end(NodeType *N) {
4693e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return SUnitIterator::end(N);
4703e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4713e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
4723e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4733e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
4743e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef std::vector<SUnit>::iterator nodes_iterator;
4753e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static nodes_iterator nodes_begin(ScheduleDAG *G) {
4763e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return G->SUnits.begin();
4773e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4783e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static nodes_iterator nodes_end(ScheduleDAG *G) {
4793e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return G->SUnits.end();
4803e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4813e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
482a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng}
483a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
484a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng#endif
485