HexagonMachineScheduler.h revision 7ae51be2a3a56be5cf0ee4557aa13a069c96a241
13e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===-- HexagonMachineScheduler.h - Custom Hexagon MI scheduler.      ----===//
23e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//
33e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//                     The LLVM Compiler Infrastructure
43e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//
53e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin// This file is distributed under the University of Illinois Open Source
63e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin// License. See LICENSE.TXT for details.
73e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//
83e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
93e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//
103e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin// Custom Hexagon MI scheduler.
113e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//
123e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
133e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
143e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#ifndef HEXAGONASMPRINTER_H
153e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#define HEXAGONASMPRINTER_H
163e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
173e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/LiveIntervalAnalysis.h"
183e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/MachineScheduler.h"
193e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/Passes.h"
203e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/RegisterClassInfo.h"
213e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/RegisterPressure.h"
223e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/ResourcePriorityQueue.h"
233e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/ScheduleDAGInstrs.h"
243e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
253e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Analysis/AliasAnalysis.h"
263e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Target/TargetInstrInfo.h"
273e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Support/CommandLine.h"
283e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Support/Debug.h"
293e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Support/ErrorHandling.h"
303e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/Support/raw_ostream.h"
313e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/ADT/OwningPtr.h"
323e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#include "llvm/ADT/PriorityQueue.h"
333e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
343e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinusing namespace llvm;
353e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
363e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
373e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin// MachineSchedStrategy - Interface to a machine scheduling algorithm.
383e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
393e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
403e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinnamespace llvm {
413e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinclass VLIWMachineScheduler;
423e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
437ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin/// MachineSchedStrategy - Interface used by VLIWMachineScheduler to drive
447ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin/// the selected scheduling algorithm.
453e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin///
467ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin/// TODO: Move this to ScheduleDAGInstrs.h
473e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinclass MachineSchedStrategy {
483e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinpublic:
493e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual ~MachineSchedStrategy() {}
503e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
513e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Initialize the strategy after building the DAG for a new region.
523e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual void initialize(VLIWMachineScheduler *DAG) = 0;
533e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
543e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Pick the next node to schedule, or return NULL. Set IsTopNode to true to
553e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// schedule the node at the top of the unscheduled region. Otherwise it will
563e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// be scheduled at the bottom.
573e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual SUnit *pickNode(bool &IsTopNode) = 0;
583e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
597ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// Notify MachineSchedStrategy that VLIWMachineScheduler has
607ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// scheduled a node.
613e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
623e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
633e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// When all predecessor dependencies have been resolved, free this node for
643e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// top-down scheduling.
653e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual void releaseTopNode(SUnit *SU) = 0;
663e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// When all successor dependencies have been resolved, free this node for
673e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// bottom-up scheduling.
683e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual void releaseBottomNode(SUnit *SU) = 0;
693e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin};
703e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
713e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
727ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin// ConvergingVLIWScheduler - Implementation of the standard
737ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin// MachineSchedStrategy.
743e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin//===----------------------------------------------------------------------===//
753e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
763e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
773e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
783e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
793e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinclass ReadyQueue {
803e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned ID;
813e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  std::string Name;
823e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  std::vector<SUnit*> Queue;
833e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
843e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinpublic:
853e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
863e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
873e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned getID() const { return ID; }
883e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
893e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  StringRef getName() const { return Name; }
903e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
913e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  // SU is in this queue if it's NodeQueueID is a superset of this ID.
923e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
933e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
943e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  bool empty() const { return Queue.empty(); }
953e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
963e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned size() const { return Queue.size(); }
973e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
983e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  typedef std::vector<SUnit*>::iterator iterator;
993e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1003e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  iterator begin() { return Queue.begin(); }
1013e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1023e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  iterator end() { return Queue.end(); }
1033e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1043e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  iterator find(SUnit *SU) {
1053e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    return std::find(Queue.begin(), Queue.end(), SU);
1063e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1073e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1083e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void push(SUnit *SU) {
1093e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    Queue.push_back(SU);
1103e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    SU->NodeQueueId |= ID;
1113e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1123e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1133e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void remove(iterator I) {
1143e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    (*I)->NodeQueueId &= ~ID;
1153e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    *I = Queue.back();
1163e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    Queue.pop_back();
1173e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1183e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1193e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void dump() {
1203e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    dbgs() << Name << ": ";
1213e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    for (unsigned i = 0, e = Queue.size(); i < e; ++i)
1223e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin      dbgs() << Queue[i]->NodeNum << " ";
1233e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    dbgs() << "\n";
1243e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1253e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin};
1263e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1273e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinclass VLIWResourceModel {
1283e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// ResourcesModel - Represents VLIW state.
1293e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Not limited to VLIW targets per say, but assumes
1303e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// definition of DFA by a target.
1313e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  DFAPacketizer *ResourcesModel;
1323e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1333e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const InstrItineraryData *InstrItins;
1343e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1353e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Local packet/bundle model. Purely
1363e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// internal to the MI schedulre at the time.
1373e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  std::vector<SUnit*> Packet;
1383e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1393e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Total packets created.
1403e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned TotalPackets;
1413e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1423e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinpublic:
1433e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  VLIWResourceModel(MachineSchedContext *C, const InstrItineraryData *IID) :
1443e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    InstrItins(IID), TotalPackets(0) {
1453e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    const TargetMachine &TM = C->MF->getTarget();
1463e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
1473e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1487ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // This hard requirement could be relaxed,
1497ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // but for now do not let it proceed.
1507ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
1517ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
1527ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    Packet.resize(InstrItins->SchedModel->IssueWidth);
1537ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    Packet.clear();
1547ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ResourcesModel->clearResources();
1557ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  }
1567ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
1577ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  VLIWResourceModel(const TargetMachine &TM) :
1587ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    InstrItins(TM.getInstrItineraryData()), TotalPackets(0) {
1597ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
1607ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
1617ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // This hard requirement could be relaxed,
1627ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // but for now do not let it proceed.
1633e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
1643e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1653e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    Packet.resize(InstrItins->SchedModel->IssueWidth);
1663e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    Packet.clear();
1673e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    ResourcesModel->clearResources();
1683e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1693e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1703e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  ~VLIWResourceModel() {
1713e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    delete ResourcesModel;
1723e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1733e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1743e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void resetPacketState() {
1753e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    Packet.clear();
1763e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1773e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1783e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void resetDFA() {
1793e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    ResourcesModel->clearResources();
1803e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
1813e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1827ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  void reset() {
1837ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    Packet.clear();
1847ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ResourcesModel->clearResources();
1857ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  }
1867ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
1873e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  bool isResourceAvailable(SUnit *SU);
1887ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  bool reserveResources(SUnit *SU);
1893e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned getTotalPackets() const { return TotalPackets; }
1903e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin};
1913e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1923e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinclass VLIWMachineScheduler : public ScheduleDAGInstrs {
1933e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// AA - AliasAnalysis for making memory reference queries.
1943e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  AliasAnalysis *AA;
1953e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1963e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  RegisterClassInfo *RegClassInfo;
1973e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineSchedStrategy *SchedImpl;
1983e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
1993e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineBasicBlock::iterator LiveRegionEnd;
2003e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2013e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Register pressure in this region computed by buildSchedGraph.
2023e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  IntervalPressure RegPressure;
2033e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  RegPressureTracker RPTracker;
2043e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2053e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// List of pressure sets that exceed the target's pressure limit before
2063e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// scheduling, listed in increasing set ID order. Each pressure set is paired
2073e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// with its max pressure in the currently scheduled regions.
2083e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  std::vector<PressureElement> RegionCriticalPSets;
2093e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2103e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// The top of the unscheduled zone.
2113e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineBasicBlock::iterator CurrentTop;
2123e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  IntervalPressure TopPressure;
2133e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  RegPressureTracker TopRPTracker;
2143e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2153e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// The bottom of the unscheduled zone.
2163e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineBasicBlock::iterator CurrentBottom;
2173e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  IntervalPressure BotPressure;
2183e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  RegPressureTracker BotRPTracker;
2193e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2203e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#ifndef NDEBUG
2213e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// The number of instructions scheduled so far. Used to cut off the
2223e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// scheduler at the point determined by misched-cutoff.
2233e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned NumInstrsScheduled;
2243e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#endif
2253e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2263e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Total packets in the region.
2273e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned TotalPackets;
2283e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2293e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const MachineLoopInfo *MLI;
2303e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinpublic:
2313e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  VLIWMachineScheduler(MachineSchedContext *C, MachineSchedStrategy *S):
2323e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
2333e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
2343e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
2353e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    CurrentBottom(), BotRPTracker(BotPressure), MLI(C->MLI) {
2363e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#ifndef NDEBUG
2373e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    NumInstrsScheduled = 0;
2383e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#endif
2393e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    TotalPackets = 0;
2403e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
2413e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2423e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  virtual ~VLIWMachineScheduler() {
2433e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    delete SchedImpl;
2443e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
2453e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2463e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineBasicBlock::iterator top() const { return CurrentTop; }
2473e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
2483e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2493e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
2503e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// region. This covers all instructions in a block, while schedule() may only
2513e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// cover a subset.
2523e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void enterRegion(MachineBasicBlock *bb,
2533e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin                   MachineBasicBlock::iterator begin,
2543e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin                   MachineBasicBlock::iterator end,
2553e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin                   unsigned endcount);
2563e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2573e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
2583e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// time to do some work.
2593e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void schedule();
2603e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2613e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned CurCycle;
2623e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2633e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Get current register pressure for the top scheduled instructions.
2643e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const IntervalPressure &getTopPressure() const { return TopPressure; }
2653e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
2663e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2673e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Get current register pressure for the bottom scheduled instructions.
2683e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const IntervalPressure &getBotPressure() const { return BotPressure; }
2693e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
2703e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2713e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// Get register pressure for the entire scheduling region before scheduling.
2723e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const IntervalPressure &getRegPressure() const { return RegPressure; }
2733e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2743e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  const std::vector<PressureElement> &getRegionCriticalPSets() const {
2753e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    return RegionCriticalPSets;
2763e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
2773e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2783e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// getIssueWidth - Return the max instructions per scheduling group.
2793e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned getIssueWidth() const {
2803e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin    return (InstrItins && InstrItins->SchedModel)
2813e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin      ? InstrItins->SchedModel->IssueWidth : 1;
2823e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
2833e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2843e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  /// getNumMicroOps - Return the number of issue slots required for this MI.
2853e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  unsigned getNumMicroOps(MachineInstr *MI) const {
2867ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    return 1;
2877ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    //if (!InstrItins) return 1;
2887ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    //int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
2897ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    //return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
2903e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  }
2913e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2923e59040810d0e6e04269ac8f781fa44df6088458Sergei Larinprivate:
2933e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void scheduleNodeTopDown(SUnit *SU);
2943e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void listScheduleTopDown();
2953e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2963e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void initRegPressure();
2973e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
2983e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
2993e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
3003e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  bool checkSchedLimit();
3013e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
3023e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void releaseRoots();
3033e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
3043e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void releaseSucc(SUnit *SU, SDep *SuccEdge);
3053e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void releaseSuccessors(SUnit *SU);
3063e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void releasePred(SUnit *SU, SDep *PredEdge);
3073e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void releasePredecessors(SUnit *SU);
3083e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
3093e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin  void placeDebugValues();
3103e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin};
3117ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3127ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin/// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
3137ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin/// to balance the schedule.
3147ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larinclass ConvergingVLIWScheduler : public MachineSchedStrategy {
3157ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3167ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// Store the state used by ConvergingVLIWScheduler heuristics, required
3177ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  ///  for the lifetime of one invocation of pickNode().
3187ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  struct SchedCandidate {
3197ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // The best SUnit candidate.
3207ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    SUnit *SU;
3217ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3227ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // Register pressure values for the best candidate.
3237ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    RegPressureDelta RPDelta;
3247ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3257ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // Best scheduling cost.
3267ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    int SCost;
3277ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3287ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    SchedCandidate(): SU(NULL), SCost(0) {}
3297ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  };
3307ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// Represent the type of SchedCandidate found within a single queue.
3317ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  enum CandResult {
3327ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    NoCand, NodeOrder, SingleExcess, SingleCritical, SingleMax, MultiPressure,
3337ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    BestCost};
3347ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3357ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// Each Scheduling boundary is associated with ready queues. It tracks the
3367ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// current cycle in whichever direction at has moved, and maintains the state
3377ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// of "hazards" and other interlocks at the current cycle.
3387ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  struct SchedBoundary {
3397ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    VLIWMachineScheduler *DAG;
3407ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3417ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ReadyQueue Available;
3427ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ReadyQueue Pending;
3437ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    bool CheckPending;
3447ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3457ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ScheduleHazardRecognizer *HazardRec;
3467ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    VLIWResourceModel *ResourceModel;
3477ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3487ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    unsigned CurrCycle;
3497ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    unsigned IssueCount;
3507ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3517ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    /// MinReadyCycle - Cycle of the soonest available instruction.
3527ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    unsigned MinReadyCycle;
3537ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3547ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    // Remember the greatest min operand latency.
3557ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    unsigned MaxMinLatency;
3567ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3577ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    /// Pending queues extend the ready queues with the same ID and the
3587ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    /// PendingFlag set.
3597ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    SchedBoundary(unsigned ID, const Twine &Name):
3607ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      DAG(0), Available(ID, Name+".A"),
3617ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
3627ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      CheckPending(false), HazardRec(0), ResourceModel(0),
3637ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      CurrCycle(0), IssueCount(0),
3647ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
3657ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3667ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    ~SchedBoundary() {
3677ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      delete ResourceModel;
3687ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      delete HazardRec;
3697ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    }
3707ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3717ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    bool isTop() const {
3727ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin      return Available.getID() == ConvergingVLIWScheduler::TopQID;
3737ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    }
3747ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3757ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    bool checkHazard(SUnit *SU);
3767ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3777ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    void releaseNode(SUnit *SU, unsigned ReadyCycle);
3787ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3797ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    void bumpCycle();
3807ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3817ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    void bumpNode(SUnit *SU);
3827ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3837ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    void releasePending();
3847ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3857ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    void removeReady(SUnit *SU);
3867ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3877ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    SUnit *pickOnlyChoice();
3887ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  };
3897ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3907ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  VLIWMachineScheduler *DAG;
3917ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  const TargetRegisterInfo *TRI;
3927ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3937ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  // State of the top and bottom scheduled instruction boundaries.
3947ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  SchedBoundary Top;
3957ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  SchedBoundary Bot;
3967ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
3977ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larinpublic:
3987ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
3997ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  enum {
4007ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    TopQID = 1,
4017ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    BotQID = 2,
4027ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    LogMaxQID = 2
4037ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  };
4047ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4057ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  ConvergingVLIWScheduler():
4067ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin    DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
4077ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4087ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  virtual void initialize(VLIWMachineScheduler *dag);
4097ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4107ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  virtual SUnit *pickNode(bool &IsTopNode);
4117ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4127ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  virtual void schedNode(SUnit *SU, bool IsTopNode);
4137ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4147ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  virtual void releaseTopNode(SUnit *SU);
4157ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4167ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  virtual void releaseBottomNode(SUnit *SU);
4177ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4187ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larinprotected:
4197ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  SUnit *pickNodeBidrectional(bool &IsTopNode);
4207ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4217ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  int SchedulingCost(ReadyQueue &Q,
4227ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin                     SUnit *SU, SchedCandidate &Candidate,
4237ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin                     RegPressureDelta &Delta, bool verbose);
4247ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4257ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  CandResult pickNodeFromQueue(ReadyQueue &Q,
4267ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin                               const RegPressureTracker &RPTracker,
4277ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin                               SchedCandidate &Candidate);
4287ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin#ifndef NDEBUG
4297ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin  void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU,
4307ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin                      PressureElement P = PressureElement());
4317ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin#endif
4327ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin};
4337ae51be2a3a56be5cf0ee4557aa13a069c96a241Sergei Larin
4343e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin} // namespace
4353e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
4363e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin
4373e59040810d0e6e04269ac8f781fa44df6088458Sergei Larin#endif
438