ScheduleDAG.h revision 4576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5
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"
202ba528b3a75955c960347e5b5b28ae74d5a81909Chris Lattner#include "llvm/ADT/DenseMap.h"
213e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman#include "llvm/ADT/GraphTraits.h"
2294c002a190cd2e3a52b1510bc997e53d63af0b3bChris Lattner#include "llvm/ADT/SmallSet.h"
23e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
24a9c2091cd38e401c846391c9951ff416e709b65eEvan Chengnamespace llvm {
25ca5ca41a635d361604a74ea8f6dd447093a0b681Jeff Cohen  struct InstrStage;
26713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  struct SUnit;
27a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class MachineConstantPool;
286b2cf285bd43fdc98ca68df477570ef6938d4fb2Evan Cheng  class MachineFunction;
2944c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey  class MachineModuleInfo;
3084bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner  class MachineRegisterInfo;
31a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class MachineInstr;
326f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  class TargetRegisterInfo;
33a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class SelectionDAG;
349ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  class SelectionDAGISel;
35a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class TargetInstrInfo;
36749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner  class TargetInstrDesc;
378a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng  class TargetLowering;
38a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class TargetMachine;
398ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng  class TargetRegisterClass;
40a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
4137e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// HazardRecognizer - This determines whether or not an instruction can be
4237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// issued this cycle, and whether or not a noop needs to be inserted to handle
4337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// the hazard.
4437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  class HazardRecognizer {
4537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  public:
4637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    virtual ~HazardRecognizer();
4737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
4837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    enum HazardType {
4937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      NoHazard,      // This instruction can be emitted at this cycle.
5037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      Hazard,        // This instruction can't be emitted at this cycle.
51d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner      NoopHazard     // This instruction can't be emitted, and needs noops.
5237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    };
5337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
5437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// getHazardType - Return the hazard type of emitting this node.  There are
5537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// three possible results.  Either:
5637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * NoHazard: it is legal to issue this instruction on this cycle.
5737e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * Hazard: issuing this instruction would stall the machine.  If some
5837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///     other instruction is available, issue it first.
5937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///  * NoopHazard: issuing this instruction would break the program.  If
6037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    ///     some other instruction can be issued, do so, otherwise issue a noop.
6113d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual HazardType getHazardType(SDNode *) {
6237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner      return NoHazard;
6337e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    }
6437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
6537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// EmitInstruction - This callback is invoked when an instruction is
6637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// emitted, to advance the hazard state.
6713d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void EmitInstruction(SDNode *) {}
6837e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
6937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// AdvanceCycle - This callback is invoked when no instructions can be
7037e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// issued on this cycle without a hazard.  This should increment the
7137e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// internal state of the hazard recognizer so that previously "Hazard"
7237e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// instructions will now not be hazards.
7313d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void AdvanceCycle() {}
7437e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner
7537e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// EmitNoop - This callback is invoked when a noop was added to the
7637e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner    /// instruction stream.
7713d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void EmitNoop() {}
784ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng  };
79713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
80713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  /// SDep - Scheduling dependency. It keeps track of dependent nodes,
81713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  /// cost of the depdenency, etc.
82713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  struct SDep {
83a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SUnit    *Dep;           // Dependent - either a predecessor or a successor.
84a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned  Reg;           // If non-zero, this dep is a phy register dependency.
85a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    int       Cost;          // Cost of the dependency.
86a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool      isCtrl    : 1; // True iff it's a control dependency.
87a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool      isSpecial : 1; // True iff it's a special ctrl dep added during sched.
88a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SDep(SUnit *d, unsigned r, int t, bool c, bool s)
89a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      : Dep(d), Reg(r), Cost(t), isCtrl(c), isSpecial(s) {}
90713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng  };
91713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
92e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
93e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// a group of nodes flagged together.
94e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  struct SUnit {
95e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SDNode *Node;                       // Representative node.
969522ee3d93cb15ebcfd80200fea42378cc510d21Chris Lattner    SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
974c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    SUnit *OrigNode;                    // If not this, the node from which
984c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman                                        // this node was cloned.
99e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
100e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    // Preds/Succs - The SUnits before/after us in the graph.  The boolean value
101e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    // is true if the edge is a token chain edge, false if it is a value edge.
102713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    SmallVector<SDep, 4> Preds;  // All sunit predecessors.
103713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    SmallVector<SDep, 4> Succs;  // All sunit successors.
104713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng
105713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::iterator pred_iterator;
106713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::iterator succ_iterator;
107713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
108713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
109228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
110a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned NodeNum;                   // Entry # of node in the node vector.
111a0201d52049be8dcefffe4304a49690a831bcb34Roman Levenstein    unsigned NodeQueueId;               // Queue id of node.
112a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    unsigned short Latency;             // Node latency.
113e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumPreds;                     // # of preds.
114e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumSuccs;                     // # of sucss.
115e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumPredsLeft;                 // # of preds not scheduled.
116e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    short NumSuccsLeft;                 // # of succs not scheduled.
117e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isTwoAddress     : 1;          // Is a two-address instruction.
11813d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng    bool isCommutable     : 1;          // Is a commutable instruction.
119f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    bool hasPhysRegDefs   : 1;          // Has physreg defs that are being used.
120e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isPending        : 1;          // True once pending.
121e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isAvailable      : 1;          // True once available.
122e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    bool isScheduled      : 1;          // True once scheduled.
123e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned CycleBound;                // Upper/lower cycle to be scheduled at.
124e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Cycle;                     // Once scheduled, the cycle of the op.
125e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Depth;                     // Node depth;
126e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    unsigned Height;                    // Node height;
1278ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
1288ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    const TargetRegisterClass *CopySrcRC;
129e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
130e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SUnit(SDNode *node, unsigned nodenum)
1314c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman      : Node(node), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), Latency(0),
132a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
13322a529990bb4bb86bdb2ae1cfce7340320a6ca7fEvan Cheng        isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
134e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng        isPending(false), isAvailable(false), isScheduled(false),
1358ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng        CycleBound(0), Cycle(0), Depth(0), Height(0),
1368ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng        CopyDstRC(NULL), CopySrcRC(NULL) {}
137a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
138228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    /// addPred - This adds the specified node as a pred of the current node if
139228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    /// not already.  This returns true if this is a new pred.
140a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool addPred(SUnit *N, bool isCtrl, bool isSpecial,
141a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                 unsigned PhyReg = 0, int Cost = 1) {
14234cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
143a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Preds[i].Dep == N &&
144a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            Preds[i].isCtrl == isCtrl && Preds[i].isSpecial == isSpecial)
145228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner          return false;
146a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      Preds.push_back(SDep(N, PhyReg, Cost, isCtrl, isSpecial));
147a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      N->Succs.push_back(SDep(this, PhyReg, Cost, isCtrl, isSpecial));
14874d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!isCtrl) {
149a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        ++NumPreds;
150a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        ++N->NumSuccs;
151a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      }
15274d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!N->isScheduled)
15374d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng        ++NumPredsLeft;
15474d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng      if (!isScheduled)
15574d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng        ++N->NumSuccsLeft;
156228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner      return true;
157228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    }
158228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
159a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool removePred(SUnit *N, bool isCtrl, bool isSpecial) {
160a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      for (SmallVector<SDep, 4>::iterator I = Preds.begin(), E = Preds.end();
161a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng           I != E; ++I)
162a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (I->Dep == N && I->isCtrl == isCtrl && I->isSpecial == isSpecial) {
163a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          bool FoundSucc = false;
164a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          for (SmallVector<SDep, 4>::iterator II = N->Succs.begin(),
165a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                 EE = N->Succs.end(); II != EE; ++II)
166a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            if (II->Dep == this &&
167a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                II->isCtrl == isCtrl && II->isSpecial == isSpecial) {
168a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              FoundSucc = true;
169a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              N->Succs.erase(II);
170a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng              break;
171a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            }
172a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          assert(FoundSucc && "Mismatching preds / succs lists!");
173a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          Preds.erase(I);
17474d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!isCtrl) {
175a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            --NumPreds;
176a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng            --N->NumSuccs;
177a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          }
17874d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!N->isScheduled)
17974d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng            --NumPredsLeft;
18074d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng          if (!isScheduled)
18174d2fd8dd847e0ebccef30e2c5907ff09495d518Evan Cheng            --N->NumSuccsLeft;
182a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
183a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        }
184a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
185a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    }
186a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
187a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool isPred(SUnit *N) {
18834cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
189a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Preds[i].Dep == N)
190a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
191a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
192a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    }
193a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
194a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    bool isSucc(SUnit *N) {
19534cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
196a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng        if (Succs[i].Dep == N)
197a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng          return true;
198a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng      return false;
199228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner    }
200228a18e0f220fb85ee06fd5bfa29304e57047ff1Chris Lattner
201e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void dump(const SelectionDAG *G) const;
202e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void dumpAll(const SelectionDAG *G) const;
203e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  };
204e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
205e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  //===--------------------------------------------------------------------===//
206e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// SchedulingPriorityQueue - This interface is used to plug different
207e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// priorities computation algorithms into the list scheduler. It implements
208e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// the interface of a standard priority queue, where nodes are inserted in
209e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// arbitrary order and returned in priority order.  The computation of the
210e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// priority and the representation of the queue are totally up to the
211e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  /// implementation to decide.
212e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  ///
213e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  class SchedulingPriorityQueue {
214e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  public:
215e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual ~SchedulingPriorityQueue() {}
216e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
21794d7a5f8156e62532870fbaf197377b34e52ff2aDan Gohman    virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
218a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void addNode(const SUnit *SU) = 0;
219a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void updateNode(const SUnit *SU) = 0;
220e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void releaseState() = 0;
221a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
222a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual unsigned size() const = 0;
223e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual bool empty() const = 0;
224e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void push(SUnit *U) = 0;
225e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
226e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
227e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    virtual SUnit *pop() = 0;
228e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
229a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    virtual void remove(SUnit *SU) = 0;
230a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
231e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// ScheduledNode - As each node is scheduled, this method is invoked.  This
232a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    /// allows the priority function to adjust the priority of related
233a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    /// unscheduled nodes, for example.
234a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    ///
23513d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void ScheduledNode(SUnit *) {}
236a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
23713d57320bd212483463d4f8992d5787b29eda5dfBill Wendling    virtual void UnscheduledNode(SUnit *) {}
238e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng  };
239e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
240a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  class ScheduleDAG {
241a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  public:
242a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    SelectionDAG &DAG;                    // DAG of the current basic block
243a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineBasicBlock *BB;                // Current basic block
244a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    const TargetMachine &TM;              // Target processor
245a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    const TargetInstrInfo *TII;           // Target instruction information
2466f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman    const TargetRegisterInfo *TRI;        // Target processor register info
2478a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    TargetLowering *TLI;                  // Target lowering info
2486b2cf285bd43fdc98ca68df477570ef6938d4fb2Evan Cheng    MachineFunction *MF;                  // Machine function
2499e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    MachineRegisterInfo &MRI;             // Virtual/real register map
250a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineConstantPool *ConstPool;       // Target constant pool
25113d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng    std::vector<SUnit*> Sequence;         // The schedule. Null SUnit*'s
25213d41b9d721f98372b97d2ec119e6c91932ab0aeEvan Cheng                                          // represent noop instructions.
253e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    std::vector<SUnit> SUnits;            // The scheduling units.
254b1e07ec6a43383ce0baa42e2f139550cc540f631Dan Gohman    SmallSet<SDNode*, 16> CommuteSet;     // Nodes that should be commuted.
255a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2562f5806c2b37a4e59cb12a6d49f0e3423c2082a64Chris Lattner    ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
25784bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner                const TargetMachine &tm);
258cccf1232a69e2d78516c61a97e7bfa26acefb714Evan Cheng
25937cb415eec53e20ed77c1c90f86310de217f3e6cChris Lattner    virtual ~ScheduleDAG() {}
260a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2613e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
2623e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    /// using 'dot'.
2633e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    ///
2643e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    void viewGraph();
2653e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
266a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    /// Run - perform scheduling.
267a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    ///
268a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng    MachineBasicBlock *Run();
269a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
2704ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    /// isPassiveNode - Return true if the node is a non-scheduled leaf.
2714ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    ///
2720993f1d8338ccf8552a1dbc3fb19461a5e6165d9Evan Cheng    static bool isPassiveNode(SDNode *Node) {
2734ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ConstantSDNode>(Node))       return true;
274e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman      if (isa<ConstantFPSDNode>(Node))     return true;
2754ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<RegisterSDNode>(Node))       return true;
2764ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<GlobalAddressSDNode>(Node))  return true;
2774ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<BasicBlockSDNode>(Node))     return true;
2784ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<FrameIndexSDNode>(Node))     return true;
2794ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ConstantPoolSDNode>(Node))   return true;
28037efe6764568a3829fee26aba532283131d1a104Nate Begeman      if (isa<JumpTableSDNode>(Node))      return true;
2814ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      if (isa<ExternalSymbolSDNode>(Node)) return true;
28269de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman      if (isa<MemOperandSDNode>(Node))     return true;
28380792f3ddec43aff7f0758c9096f8cb53dcc1e40Dan Gohman      if (Node->getOpcode() == ISD::EntryToken) return true;
2844ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng      return false;
2854ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    }
2864ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng
287e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// NewSUnit - Creates a new SUnit and return a ptr to it.
288e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    ///
289e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    SUnit *NewSUnit(SDNode *N) {
29034cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
2914c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman      SUnits.back().OrigNode = &SUnits.back();
292e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng      return &SUnits.back();
293e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    }
294e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
295a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    /// Clone - Creates a clone of the specified SUnit. It does not copy the
296a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    /// predecessors / successors info nor the temporary scheduling states.
297a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng    SUnit *Clone(SUnit *N);
298a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng
299e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
300e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// This SUnit graph is similar to the SelectionDAG, but represents flagged
301e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// together nodes with a single SUnit.
302e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void BuildSchedUnits();
303e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
304f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    /// ComputeLatency - Compute node latency.
305f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    ///
306f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng    void ComputeLatency(SUnit *SU);
307f10c973797cf79da802f9b0118543cbd50954c9cEvan Cheng
308e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    /// CalculateDepths, CalculateHeights - Calculate node depth / height.
309e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    ///
310e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void CalculateDepths();
311e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng    void CalculateHeights();
312e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
313fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// CountResults - The results of target nodes have register or immediate
314fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// operands first, then an optional chain, and optional flag operands
315fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    /// (which do not go into the machine instrs.)
316fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    static unsigned CountResults(SDNode *Node);
317fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng
31869de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman    /// CountOperands - The inputs to target nodes have any actual inputs first,
31942a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// followed by special operands that describe memory references, then an
32042a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// optional chain operand, then flag operands.  Compute the number of
32142a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// actual operands that will go into the resulting MachineInstr.
322fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng    static unsigned CountOperands(SDNode *Node);
323fe0b81759d207072ae468f5154f6a513c3a1be72Evan Cheng
32442a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// ComputeMemOperandsEnd - Find the index one past the last
32542a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    /// MemOperandSDNode operand
32642a77880a83b76112a1f42ce16b46dbde01cd0a8Dan Gohman    static unsigned ComputeMemOperandsEnd(SDNode *Node);
32769de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman
3284ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    /// EmitNode - Generate machine code for an node and needed dependencies.
3297593639df672018d90331774f45b5ef06da2f385Chris Lattner    /// VRBaseMap contains, for each already emitted node, the first virtual
3307593639df672018d90331774f45b5ef06da2f385Chris Lattner    /// register number for the results of the node.
3314ef10867499aa146cd819c78d8d37a8353d4f0ffEvan Cheng    ///
3324c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    void EmitNode(SDNode *Node, bool IsClone,
3339cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                  DenseMap<SDOperand, unsigned> &VRBaseMap);
334202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner
335202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    /// EmitNoop - Emit a noop instruction.
336202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    ///
337202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner    void EmitNoop();
3388409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng
3398a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void EmitSchedule();
3408a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3418a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void dumpSchedule() const;
3428a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
343a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    /// Schedule - Order nodes according to selected style, filling
344a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    /// in the Sequence member.
3458a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    ///
346a0b50d7f0dd965b4269cce198cab395e2c2be900Dan Gohman    virtual void Schedule() = 0;
3478a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3488a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng  private:
3498a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// EmitSubregNode - Generate machine code for subreg nodes.
3508a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    ///
3518a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void EmitSubregNode(SDNode *Node,
3529cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                        DenseMap<SDOperand, unsigned> &VRBaseMap);
3538a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3548a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// getVR - Return the virtual register corresponding to the specified result
3558a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// of the specified node.
3569cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein    unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap);
3578a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3588a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// getDstOfCopyToRegUse - If the only use of the specified result number of
3598a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    /// node is a CopyToReg, return its destination register. Return 0 otherwise.
3608a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    unsigned getDstOfOnlyCopyToRegUse(SDNode *Node, unsigned ResNo) const;
3618a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3628a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng    void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
3638a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng                    const TargetInstrDesc *II,
3649cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                    DenseMap<SDOperand, unsigned> &VRBaseMap);
3658a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
36636b5c1338a03453ba1c110b120269ca972fb65a3Dan Gohman    void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO);
3678a50f1fcf0147d4ba959dc48066ddf281d5bc7e6Evan Cheng
3688ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng    void EmitCrossRCCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
3698ed3ffee53105275ca03f06ba0195bc6008477faEvan Cheng
3708409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
3718409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    /// implicit physical register output.
3724c8c83022b501759d8559e224c84ae2a9921ba41Dan Gohman    void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
373a6fb1b6743ee1411accf2d6e636f73f2ee0a7f5bEvan Cheng                         unsigned SrcReg,
3749cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                         DenseMap<SDOperand, unsigned> &VRBaseMap);
375202bc85a9508de5b5f24cfbac060e17ea2f5f8dcChris Lattner
3768409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng    void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
377749c6f6b5ed301c84aac562e414486549d7b98ebChris Lattner                                const TargetInstrDesc &II,
3789cac5259fe237120a0c347d6d14e549005148f1bRoman Levenstein                                DenseMap<SDOperand, unsigned> &VRBaseMap);
3798409747efadda025aa3cce626b1a2c33429fd5e5Evan Cheng
3809e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
3819e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// physical register has only a single copy use, then coalesced the copy
3821090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng    /// if possible.
3831090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng    void EmitLiveInCopy(MachineBasicBlock *MBB,
3841090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        MachineBasicBlock::iterator &InsertPos,
3851090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        unsigned VirtReg, unsigned PhysReg,
3861090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        const TargetRegisterClass *RC,
3871090fc99cd63b78f5d672cf0914287656f746f98Evan Cheng                        DenseMap<MachineInstr*, unsigned> &CopyRegMap);
3889e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng
3899e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// EmitLiveInCopies - If this is the first basic block in the function,
3909e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// and if it has live ins that need to be copied into vregs, emit the
3919e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    /// copies into the top of the block.
3929e23336d0c99fc5cae04037ead6d8f2b677e8764Evan Cheng    void EmitLiveInCopies(MachineBasicBlock *MBB);
393a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng  };
394a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
395f0f9c90204c650b9f3c3feb02ccfcb1e40c6acddEvan Cheng  /// createBURRListDAGScheduler - This creates a bottom up register usage
396f0f9c90204c650b9f3c3feb02ccfcb1e40c6acddEvan Cheng  /// reduction list scheduler.
3979ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
3989ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey                                          SelectionDAG *DAG,
3994576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                          MachineBasicBlock *BB,
4004576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                          bool Fast);
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,
4064576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                          MachineBasicBlock *BB,
4074576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                          bool Fast);
408e165a78551a91d8420cd8f074d97701e8788f8b5Evan Cheng
40937e30cf736f9975704f4994d4181fe65ebb7b76cChris Lattner  /// createTDListDAGScheduler - This creates a top-down list scheduler with
41013ec702c430b91ee49b9e6d9581cd95412f216c8Jim Laskey  /// a hazard recognizer.
4119ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey  ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
4129ff542f2cce5bf7bf3cf9f692cf3ec0690ad2b3bJim Laskey                                        SelectionDAG *DAG,
4134576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                        MachineBasicBlock *BB,
4144576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                        bool Fast);
41513ec702c430b91ee49b9e6d9581cd95412f216c8Jim Laskey
4169373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  /// createDefaultScheduler - This creates an instruction scheduler appropriate
4179373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  /// for the target.
4189373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
4199373beba6010dd34316a801c3a9b37ab9e048031Jim Laskey                                      SelectionDAG *DAG,
4204576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                      MachineBasicBlock *BB,
4214576f6d7a9c0f2c6a3b6c5d4d8a3063bbf763ae5Evan Cheng                                      bool Fast);
4223e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4233e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
4243e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnit *Node;
4253e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    unsigned Operand;
4263e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4273e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
4283e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  public:
4293e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    bool operator==(const SUnitIterator& x) const {
4303e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return Operand == x.Operand;
4313e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4323e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
4333e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4343e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    const SUnitIterator &operator=(const SUnitIterator &I) {
4353e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
4363e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      Operand = I.Operand;
4373e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return *this;
4383e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4393e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4403e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    pointer operator*() const {
441713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng      return Node->Preds[Operand].Dep;
4423e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4433e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    pointer operator->() const { return operator*(); }
4443e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4453e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator& operator++() {                // Preincrement
4463e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      ++Operand;
4473e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return *this;
4483e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4493e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    SUnitIterator operator++(int) { // Postincrement
4503e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      SUnitIterator tmp = *this; ++*this; return tmp;
4513e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4523e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4533e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
4543e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static SUnitIterator end  (SUnit *N) {
45534cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng      return SUnitIterator(N, (unsigned)N->Preds.size());
4563e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4573e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4583e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    unsigned getOperand() const { return Operand; }
4593e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    const SUnit *getNode() const { return Node; }
460713a98dee8ab07a3066d1707a07648d27dd0c19cEvan Cheng    bool isCtrlDep() const { return Node->Preds[Operand].isCtrl; }
46189bf0a6b05c8c353890c88ed1c10dec96a9a7bd8Dan Gohman    bool isSpecialDep() const { return Node->Preds[Operand].isSpecial; }
4623e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
4633e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4643e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  template <> struct GraphTraits<SUnit*> {
4653e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef SUnit NodeType;
4663e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef SUnitIterator ChildIteratorType;
4673e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline NodeType *getEntryNode(SUnit *N) { return N; }
4683e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline ChildIteratorType child_begin(NodeType *N) {
4693e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return SUnitIterator::begin(N);
4703e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4713e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static inline ChildIteratorType child_end(NodeType *N) {
4723e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return SUnitIterator::end(N);
4733e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4743e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
4753e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman
4763e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
4773e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    typedef std::vector<SUnit>::iterator nodes_iterator;
4783e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static nodes_iterator nodes_begin(ScheduleDAG *G) {
4793e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return G->SUnits.begin();
4803e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4813e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    static nodes_iterator nodes_end(ScheduleDAG *G) {
4823e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman      return G->SUnits.end();
4833e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman    }
4843e1a7aef17575d9c7058a035449d57e3c7295ed0Dan Gohman  };
485a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng}
486a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng
487a9c2091cd38e401c846391c9951ff416e709b65eEvan Cheng#endif
488