[llvm-commits] [llvm] r168773 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDFS.h lib/CodeGen/MachineScheduler.cpp lib/CodeGen/ScheduleDAGInstrs.cpp test/CodeGen/X86/misched-matrix.ll

Demikhovsky, Elena elena.demikhovsky at intel.com
Thu Nov 29 04:51:37 PST 2012


Hi Andrew,



This test

llc  llvm\test\CodeGen\X86\misched-matrix.ll -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched -misched=ilpmin -verify-machineinstrs



fails with assertion on VC10. I hope you see the attached picture.



[cid:image001.png at 01CDCE41.031D4B60]



- Elena

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Andrew Trick
Sent: Wednesday, November 28, 2012 07:13
To: llvm-commits at cs.uiuc.edu
Subject: [llvm-commits] [llvm] r168773 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDFS.h lib/CodeGen/MachineScheduler.cpp lib/CodeGen/ScheduleDAGInstrs.cpp test/CodeGen/X86/misched-matrix.ll



Author: atrick

Date: Tue Nov 27 23:13:28 2012

New Revision: 168773



URL: http://llvm.org/viewvc/llvm-project?rev=168773&view=rev

Log:

misched: Analysis that partitions the DAG into subtrees.



This is a simple, cheap infrastructure for analyzing the shape of a DAG. It recognizes uniform DAGs that take the shape of bottom-up subtrees, such as the included matrix multiplication example. This is useful for heuristics that balance register pressure with ILP. Two canonical expressions of the heuristic are implemented in scheduling

modes: -misched-ilpmin and -misched-ilpmax.



Modified:

    llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h

    llvm/trunk/lib/CodeGen/MachineScheduler.cpp

    llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp

    llvm/trunk/test/CodeGen/X86/misched-matrix.ll



Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h

URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h?rev=168773&r1=168772&r2=168773&view=diff

==============================================================================

--- llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h (original)

+++ llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h Tue Nov 27 23:13:28

+++ 2012

@@ -14,38 +14,41 @@

#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H

#define LLVM_CODEGEN_SCHEDULEDAGILP_H

+#include "llvm/CodeGen/ScheduleDAG.h"

#include "llvm/Support/DataTypes.h"

#include <vector>

 namespace llvm {

 class raw_ostream;

+class IntEqClasses;

class ScheduleDAGInstrs;

class SUnit;

 /// \brief Represent the ILP of the subDAG rooted at a DAG node.

+///

+/// When computed using bottom-up DFS, this metric assumes that the DAG

+is a /// forest of trees with roots at the bottom of the schedule branching upward.

struct ILPValue {

   unsigned InstrCount;

-  unsigned Cycles;

-

-  ILPValue(): InstrCount(0), Cycles(0) {}

+  /// Length may either correspond to depth or height, depending on

+ direction,  /// and cycles or nodes depending on context.

+  unsigned Length;

-  ILPValue(unsigned count, unsigned cycles):

-    InstrCount(count), Cycles(cycles) {}

-

-  bool isValid() const { return Cycles > 0; }

+  ILPValue(unsigned count, unsigned length):

+    InstrCount(count), Length(length) {}

   // Order by the ILP metric's value.

   bool operator<(ILPValue RHS) const {

-    return (uint64_t)InstrCount * RHS.Cycles

-      < (uint64_t)Cycles * RHS.InstrCount;

+    return (uint64_t)InstrCount * RHS.Length

+      < (uint64_t)Length * RHS.InstrCount;

   }

   bool operator>(ILPValue RHS) const {

     return RHS < *this;

   }

   bool operator<=(ILPValue RHS) const {

-    return (uint64_t)InstrCount * RHS.Cycles

-      <= (uint64_t)Cycles * RHS.InstrCount;

+    return (uint64_t)InstrCount * RHS.Length

+      <= (uint64_t)Length * RHS.InstrCount;

   }

   bool operator>=(ILPValue RHS) const {

     return RHS <= *this;

@@ -58,25 +61,88 @@

#endif

};

-/// \brief Compute the values of each DAG node for an ILP metric.

+/// \brief Compute the values of each DAG node for various metrics during DFS.

///

-/// This metric assumes that the DAG is a forest of trees with roots at the -/// bottom of the schedule.

-class ScheduleDAGILP {

+/// ILPValues summarize the DAG subtree rooted at each node up to ///

+SubtreeLimit. ILPValues are also valid for interior nodes of a subtree,

+not /// just the root.

+class SchedDFSResult {

+  friend class SchedDFSImpl;

+

+  /// \brief Per-SUnit data computed during DFS for various metrics.

+  struct NodeData {

+    unsigned InstrCount;

+    unsigned SubtreeID;

+

+    NodeData(): InstrCount(0), SubtreeID(0) {}  };

+

+  /// \brief Record a connection between subtrees and the connection level.

+  struct Connection {

+    unsigned TreeID;

+    unsigned Level;

+

+    Connection(unsigned tree, unsigned level): TreeID(tree),

+ Level(level) {}  };

+

   bool IsBottomUp;

-  std::vector<ILPValue> ILPValues;

+  unsigned SubtreeLimit;

+  /// DFS results for each SUnit in this DAG.

+  std::vector<NodeData> DFSData;

+

+  // For each subtree discovered during DFS, record its connections to

+ other  // subtrees.

+  std::vector<SmallVector<Connection, 4> > SubtreeConnections;

+

+  /// Cache the current connection level of each subtree.

+  /// This mutable array is updated during scheduling.

+  std::vector<unsigned> SubtreeConnectLevels;

 public:

-  ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {}

+  SchedDFSResult(bool IsBU, unsigned lim)

+    : IsBottomUp(IsBU), SubtreeLimit(lim) {}

+

+  /// \brief Clear the results.

+  void clear() {

+    DFSData.clear();

+    SubtreeConnections.clear();

+    SubtreeConnectLevels.clear();

+  }

   /// \brief Initialize the result data with the size of the DAG.

-  void resize(unsigned NumSUnits);

+  void resize(unsigned NumSUnits) {

+    DFSData.resize(NumSUnits);

+  }

-  /// \brief Compute the ILP metric for the subDAG at this root.

-  void computeILP(const SUnit *Root);

+  /// \brief Compute various metrics for the DAG with given roots.

+  void compute(ArrayRef<SUnit *> Roots);

   /// \brief Get the ILP value for a DAG node.

-  ILPValue getILP(const SUnit *SU);

+  ///

+  /// A leaf node has an ILP of 1/1.

+  ILPValue getILP(const SUnit *SU) {

+    return ILPValue(DFSData[SU->NodeNum].InstrCount, 1 +

+ SU->getDepth());  }

+

+  /// \brief The number of subtrees detected in this DAG.

+  unsigned getNumSubtrees() const { return SubtreeConnectLevels.size();

+ }

+

+  /// \brief Get the ID of the subtree the given DAG node belongs to.

+  unsigned getSubtreeID(const SUnit *SU) {

+    return DFSData[SU->NodeNum].SubtreeID;  }

+

+  /// \brief Get the connection level of a subtree.

+  ///

+  /// For bottom-up trees, the connection level is the latency depth

+ (in cycles)  /// of the deepest connection to another subtree.

+  unsigned getSubtreeLevel(unsigned SubtreeID) {

+    return SubtreeConnectLevels[SubtreeID];  }

+

+  /// \brief Scheduler callback to update SubtreeConnectLevels when a

+ tree is  /// initially scheduled.

+  void scheduleTree(unsigned SubtreeID);

};

 raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);



Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp

URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=168773&r1=168772&r2=168773&view=diff

==============================================================================

--- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original)

+++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Tue Nov 27 23:13:28 2012

@@ -2054,58 +2054,99 @@

namespace {

/// \brief Order nodes by the ILP metric.

struct ILPOrder {

-  ScheduleDAGILP *ILP;

+  SchedDFSResult *DFSResult;

+  BitVector *ScheduledTrees;

   bool MaximizeILP;

-  ILPOrder(ScheduleDAGILP *ilp, bool MaxILP): ILP(ilp), MaximizeILP(MaxILP) {}

+  ILPOrder(SchedDFSResult *dfs, BitVector *schedtrees, bool MaxILP)

+    : DFSResult(dfs), ScheduledTrees(schedtrees), MaximizeILP(MaxILP)

+ {}

   /// \brief Apply a less-than relation on node priority.

+  ///

+  /// (Return true if A comes after B in the Q.)

   bool operator()(const SUnit *A, const SUnit *B) const {

-    // Return true if A comes after B in the Q.

+    unsigned SchedTreeA = DFSResult->getSubtreeID(A);

+    unsigned SchedTreeB = DFSResult->getSubtreeID(B);

+    if (SchedTreeA != SchedTreeB) {

+      // Unscheduled trees have lower priority.

+      if (ScheduledTrees->test(SchedTreeA) != ScheduledTrees->test(SchedTreeB))

+        return ScheduledTrees->test(SchedTreeB);

+

+      // Trees with shallower connections have have lower priority.

+      if (DFSResult->getSubtreeLevel(SchedTreeA)

+          != DFSResult->getSubtreeLevel(SchedTreeB)) {

+        return DFSResult->getSubtreeLevel(SchedTreeA)

+          < DFSResult->getSubtreeLevel(SchedTreeB);

+      }

+    }

     if (MaximizeILP)

-      return ILP->getILP(A) < ILP->getILP(B);

+      return DFSResult->getILP(A) < DFSResult->getILP(B);

     else

-      return ILP->getILP(A) > ILP->getILP(B);

+      return DFSResult->getILP(A) > DFSResult->getILP(B);

   }

};

 /// \brief Schedule based on the ILP metric.

class ILPScheduler : public MachineSchedStrategy {

-  ScheduleDAGILP ILP;

+  /// In case all subtrees are eventually connected to a common root

+ through  /// data dependence (e.g. reduction), place an upper limit on their size.

+  ///

+  /// FIXME: A subtree limit is generally good, but in the situation

+ commented  /// above, where multiple similar subtrees feed a common

+ root, we should  /// only split at a point where the resulting subtrees will be balanced.

+  /// (a motivating test case must be found).

+  static const unsigned SubtreeLimit = 16;

+

+  SchedDFSResult DFSResult;

+  BitVector ScheduledTrees;

   ILPOrder Cmp;

   std::vector<SUnit*> ReadyQ;

public:

   ILPScheduler(bool MaximizeILP)

-  : ILP(/*BottomUp=*/true), Cmp(&ILP, MaximizeILP) {}

+  : DFSResult(/*BottomUp=*/true, SubtreeLimit),

+    Cmp(&DFSResult, &ScheduledTrees, MaximizeILP) {}

   virtual void initialize(ScheduleDAGMI *DAG) {

     ReadyQ.clear();

-    ILP.resize(DAG->SUnits.size());

+    DFSResult.clear();

+    DFSResult.resize(DAG->SUnits.size());

+    ScheduledTrees.clear();

   }

   virtual void registerRoots() {

-    for (std::vector<SUnit*>::const_iterator

-           I = ReadyQ.begin(), E = ReadyQ.end(); I != E; ++I) {

-      ILP.computeILP(*I);

-    }

+    DFSResult.compute(ReadyQ);

+    ScheduledTrees.resize(DFSResult.getNumSubtrees());

   }

   /// Implement MachineSchedStrategy interface.

   /// -----------------------------------------

+  /// Callback to select the highest priority node from the ready Q.

   virtual SUnit *pickNode(bool &IsTopNode) {

     if (ReadyQ.empty()) return NULL;

     pop_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);

     SUnit *SU = ReadyQ.back();

     ReadyQ.pop_back();

     IsTopNode = false;

-    DEBUG(dbgs() << "*** Scheduling " << *SU->getInstr()

-          << " ILP: " << ILP.getILP(SU) << '\n');

+    DEBUG(dbgs() << "*** Scheduling " << "SU(" << SU->NodeNum << "): "

+          << *SU->getInstr()

+          << " ILP: " << DFSResult.getILP(SU)

+          << " Tree: " << DFSResult.getSubtreeID(SU) << " @"

+          << DFSResult.getSubtreeLevel(DFSResult.getSubtreeID(SU))<<

+ '\n');

     return SU;

   }

-  virtual void schedNode(SUnit *, bool) {}

+  /// Callback after a node is scheduled. Mark a newly scheduled tree,

+ notify  /// DFSResults, and resort the priority Q.

+  virtual void schedNode(SUnit *SU, bool IsTopNode) {

+    assert(!IsTopNode && "SchedDFSResult needs bottom-up");

+    if (!ScheduledTrees.test(DFSResult.getSubtreeID(SU))) {

+      ScheduledTrees.set(DFSResult.getSubtreeID(SU));

+      DFSResult.scheduleTree(DFSResult.getSubtreeID(SU));

+      std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);

+    }

+  }

   virtual void releaseTopNode(SUnit *) { /*only called for top roots*/ }



Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp

URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=168773&r1=168772&r2=168773&view=diff

==============================================================================

--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)

+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Tue Nov 27 23:13:28

+++ 2012

@@ -12,7 +12,7 @@

//

//===----------------------------------------------------------------------===//

-#define DEBUG_TYPE "sched-instrs"

+#define DEBUG_TYPE "misched"

#include "llvm/Operator.h"

#include "llvm/Analysis/AliasAnalysis.h"

#include "llvm/Analysis/ValueTracking.h"

@@ -949,6 +949,120 @@

   return "dag." + BB->getFullName();

}

+//===------------------------------------------------------------------

+----===//

+// SchedDFSResult Implementation

+//===------------------------------------------------------------------

+----===//

+

+namespace llvm {

+/// \brief Internal state used to compute SchedDFSResult.

+class SchedDFSImpl {

+  SchedDFSResult &R;

+

+  /// Join DAG nodes into equivalence classes by their subtree.

+  IntEqClasses SubtreeClasses;

+  /// List PredSU, SuccSU pairs that represent data edges between subtrees.

+  std::vector<std::pair<const SUnit*, const SUnit*> > ConnectionPairs;

+

+public:

+  SchedDFSImpl(SchedDFSResult &r): R(r),

+SubtreeClasses(R.DFSData.size()) {}

+

+  /// SubtreID is initialized to zero, set to itself to flag the root

+ of a  /// subtree, set to the parent to indicate an interior node,

+ /// then set to a representative subtree ID during finalization.

+  bool isVisited(const SUnit *SU) const {

+    return R.DFSData[SU->NodeNum].SubtreeID;  }

+

+  /// Initialize this node's instruction count. We don't need to flag

+ the node  /// visited until visitPostorder because the DAG cannot have cycles.

+  void visitPreorder(const SUnit *SU) {

+    R.DFSData[SU->NodeNum].InstrCount = SU->getInstr()->isTransient() ?

+ 0 : 1;  }

+

+  /// Mark this node as either the root of a subtree or an interior

+ /// node. Increment the parent node's instruction count.

+  void visitPostorder(const SUnit *SU, const SDep *PredDep, const SUnit *Parent) {

+    R.DFSData[SU->NodeNum].SubtreeID = SU->NodeNum;

+

+    // Join the child to its parent if they are connected via data dependence

+    // and do not exceed the limit.

+    if (!Parent || PredDep->getKind() != SDep::Data)

+      return;

+

+    unsigned PredCnt = R.DFSData[SU->NodeNum].InstrCount;

+    if (PredCnt > R.SubtreeLimit)

+      return;

+

+    R.DFSData[SU->NodeNum].SubtreeID = Parent->NodeNum;

+

+    // Add the recently finished predecessor's bottom-up descendent count.

+    R.DFSData[Parent->NodeNum].InstrCount += PredCnt;

+    SubtreeClasses.join(Parent->NodeNum, SU->NodeNum);  }

+

+  /// Determine whether the DFS cross edge should be considered a

+ subtree edge  /// or a connection between subtrees.

+  void visitCross(const SDep &PredDep, const SUnit *Succ) {

+    if (PredDep.getKind() == SDep::Data) {

+      // If this is a cross edge to a root, join the subtrees. This happens when

+      // the root was first reached by a non-data dependence.

+      unsigned NodeNum = PredDep.getSUnit()->NodeNum;

+      unsigned PredCnt = R.DFSData[NodeNum].InstrCount;

+      if (R.DFSData[NodeNum].SubtreeID == NodeNum && PredCnt < R.SubtreeLimit) {

+        R.DFSData[NodeNum].SubtreeID = Succ->NodeNum;

+        R.DFSData[Succ->NodeNum].InstrCount += PredCnt;

+        SubtreeClasses.join(Succ->NodeNum, NodeNum);

+        return;

+      }

+    }

+    ConnectionPairs.push_back(std::make_pair(PredDep.getSUnit(),

+ Succ));  }

+

+  /// Set each node's subtree ID to the representative ID and record

+ connections  /// between trees.

+  void finalize() {

+    SubtreeClasses.compress();

+    R.SubtreeConnections.resize(SubtreeClasses.getNumClasses());

+    R.SubtreeConnectLevels.resize(SubtreeClasses.getNumClasses());

+    DEBUG(dbgs() << R.getNumSubtrees() << " subtrees:\n");

+    for (unsigned Idx = 0, End = R.DFSData.size(); Idx != End; ++Idx) {

+      R.DFSData[Idx].SubtreeID = SubtreeClasses[Idx];

+      DEBUG(dbgs() << "  SU(" << Idx << ") in tree "

+            << R.DFSData[Idx].SubtreeID << '\n');

+    }

+    for (std::vector<std::pair<const SUnit*, const SUnit*> >::const_iterator

+           I = ConnectionPairs.begin(), E = ConnectionPairs.end();

+         I != E; ++I) {

+      unsigned PredTree = SubtreeClasses[I->first->NodeNum];

+      unsigned SuccTree = SubtreeClasses[I->second->NodeNum];

+      if (PredTree == SuccTree)

+        continue;

+      unsigned Depth = I->first->getDepth();

+      addConnection(PredTree, SuccTree, Depth);

+      addConnection(SuccTree, PredTree, Depth);

+    }

+  }

+

+protected:

+  /// Called by finalize() to record a connection between trees.

+  void addConnection(unsigned FromTree, unsigned ToTree, unsigned Depth) {

+    if (!Depth)

+      return;

+

+    SmallVectorImpl<SchedDFSResult::Connection> &Connections =

+      R.SubtreeConnections[FromTree];

+    for (SmallVectorImpl<SchedDFSResult::Connection>::iterator

+           I = Connections.begin(), E = Connections.end(); I != E; ++I) {

+      if (I->TreeID == ToTree) {

+        I->Level = std::max(I->Level, Depth);

+        return;

+      }

+    }

+    Connections.push_back(SchedDFSResult::Connection(ToTree, Depth));

+  }

+};

+} // namespace llvm

+

namespace {

/// \brief Manage the stack used by a reverse depth-first search over the DAG.

class SchedDAGReverseDFS {

@@ -961,7 +1075,10 @@

   }

   void advance() { ++DFSStack.back().second; }

-  void backtrack() { DFSStack.pop_back(); }

+  const SDep *backtrack() {

+    DFSStack.pop_back();

+    return DFSStack.empty() ? 0 : llvm::prior(DFSStack.back().second);

+  }

   const SUnit *getCurr() const { return DFSStack.back().first; }

@@ -973,57 +1090,65 @@

};

} // anonymous

-void ScheduleDAGILP::resize(unsigned NumSUnits) {

-  ILPValues.resize(NumSUnits);

-}

-

-ILPValue ScheduleDAGILP::getILP(const SUnit *SU) {

-  return ILPValues[SU->NodeNum];

-}

-

-// A leaf node has an ILP of 1/1.

-static ILPValue initILP(const SUnit *SU) {

-  unsigned Cnt = SU->getInstr()->isTransient() ? 0 : 1;

-  return ILPValue(Cnt, 1 + SU->getDepth()); -}

-

/// Compute an ILP metric for all nodes in the subDAG reachable via depth-first  /// search from this root.

-void ScheduleDAGILP::computeILP(const SUnit *Root) {

+void SchedDFSResult::compute(ArrayRef<SUnit *> Roots) {

   if (!IsBottomUp)

     llvm_unreachable("Top-down ILP metric is unimplemnted");

-  SchedDAGReverseDFS DFS;

-  // Mark a node visited by validating it.

-  ILPValues[Root->NodeNum] = initILP(Root);

-  DFS.follow(Root);

-  for (;;) {

-    // Traverse the leftmost path as far as possible.

-    while (DFS.getPred() != DFS.getPredEnd()) {

-      const SUnit *PredSU = DFS.getPred()->getSUnit();

-      DFS.advance();

-      // If the pred is already valid, skip it.

-      if (ILPValues[PredSU->NodeNum].isValid())

-        continue;

-      ILPValues[PredSU->NodeNum] = initILP(PredSU);

-      DFS.follow(PredSU);

+  SchedDFSImpl Impl(*this);

+  for (ArrayRef<const SUnit*>::const_iterator

+         RootI = Roots.begin(), RootE = Roots.end(); RootI != RootE; ++RootI) {

+    SchedDAGReverseDFS DFS;

+    Impl.visitPreorder(*RootI);

+    DFS.follow(*RootI);

+    for (;;) {

+      // Traverse the leftmost path as far as possible.

+      while (DFS.getPred() != DFS.getPredEnd()) {

+        const SDep &PredDep = *DFS.getPred();

+        DFS.advance();

+        // If the pred is already valid, skip it. We may preorder visit a node

+        // with InstrCount==0 more than once, but it won't affect heuristics

+        // because we don't care about cross edges to leaf copies.

+        if (Impl.isVisited(PredDep.getSUnit())) {

+          Impl.visitCross(PredDep, DFS.getCurr());

+          continue;

+        }

+        Impl.visitPreorder(PredDep.getSUnit());

+        DFS.follow(PredDep.getSUnit());

+      }

+      // Visit the top of the stack in postorder and backtrack.

+      const SUnit *Child = DFS.getCurr();

+      const SDep *PredDep = DFS.backtrack();

+      Impl.visitPostorder(Child, PredDep, PredDep ? DFS.getCurr() : 0);

+      if (DFS.isComplete())

+        break;

     }

-    // Visit the top of the stack in postorder and backtrack.

-    unsigned PredCount = ILPValues[DFS.getCurr()->NodeNum].InstrCount;

-    DFS.backtrack();

-    if (DFS.isComplete())

-      break;

-    // Add the recently finished predecessor's bottom-up descendent count.

-    ILPValues[DFS.getCurr()->NodeNum].InstrCount += PredCount;

+  }

+  Impl.finalize();

+}

+

+/// The root of the given SubtreeID was just scheduled. For all

+subtrees /// connected to this tree, record the depth of the connection

+so that the /// nearest connected subtrees can be prioritized.

+void SchedDFSResult::scheduleTree(unsigned SubtreeID) {

+  for (SmallVectorImpl<Connection>::const_iterator

+         I = SubtreeConnections[SubtreeID].begin(),

+         E = SubtreeConnections[SubtreeID].end(); I != E; ++I) {

+    SubtreeConnectLevels[I->TreeID] =

+      std::max(SubtreeConnectLevels[I->TreeID], I->Level);

+    DEBUG(dbgs() << "  Tree: " << I->TreeID

+          << " @" << SubtreeConnectLevels[I->TreeID] << '\n');

   }

}

 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  void ILPValue::print(raw_ostream &OS) const {

-  if (!isValid())

+  OS << InstrCount << " / " << Length << " = ";  if (!Length)

     OS << "BADILP";

-  OS << InstrCount << " / " << Cycles << " = "

-     << format("%g", ((double)InstrCount / Cycles));

+  else

+    OS << format("%g", ((double)InstrCount / Length));

}

 void ILPValue::dump() const {



Modified: llvm/trunk/test/CodeGen/X86/misched-matrix.ll

URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/misched-matrix.ll?rev=168773&r1=168772&r2=168773&view=diff

==============================================================================

--- llvm/trunk/test/CodeGen/X86/misched-matrix.ll (original)

+++ llvm/trunk/test/CodeGen/X86/misched-matrix.ll Tue Nov 27 23:13:28

+++ 2012

@@ -1,6 +1,12 @@

; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \

; RUN:          -misched-topdown -verify-machineinstrs \

; RUN:     | FileCheck %s -check-prefix=TOPDOWN

+; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \

+; RUN:          -misched=ilpmin -verify-machineinstrs \

+; RUN:     | FileCheck %s -check-prefix=ILPMIN

+; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \

+; RUN:          -misched=ilpmax -verify-machineinstrs \

+; RUN:     | FileCheck %s -check-prefix=ILPMAX

;

; Verify that the MI scheduler minimizes register pressure for a  ; uniform set of bottom-up subtrees (unrolled matrix multiply).

@@ -17,6 +23,68 @@

; TOPDOWN: movl %{{.*}}, 8(

; TOPDOWN: movl %{{.*}}, 12(

; TOPDOWN: %for.end

+;

+; For -misched=ilpmin, verify that each expression subtree is ;

+scheduled independently, and that the imull/adds are interleaved.

+;

+; ILPMIN: %for.body

+; ILPMIN: movl %{{.*}}, (

+; ILPMIN: imull

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: movl %{{.*}}, 4(

+; ILPMIN: imull

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: movl %{{.*}}, 8(

+; ILPMIN: imull

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: imull

+; ILPMIN: addl

+; ILPMIN: movl %{{.*}}, 12(

+; ILPMIN: %for.end

+;

+; For -misched=ilpmax, verify that each expression subtree is ;

+scheduled independently, and that the imull/adds are clustered.

+;

+; ILPMAX: %for.body

+; ILPMAX: movl %{{.*}}, (

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: movl %{{.*}}, 4(

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: movl %{{.*}}, 8(

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: imull

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: addl

+; ILPMAX: movl %{{.*}}, 12(

+; ILPMAX: %for.end

 define void @mmult([4 x i32]* noalias nocapture %m1, [4 x i32]* noalias nocapture %m2,

[4 x i32]* noalias nocapture %m3) nounwind uwtable ssp {





_______________________________________________

llvm-commits mailing list

llvm-commits at cs.uiuc.edu<mailto:llvm-commits at cs.uiuc.edu>

http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121129/3be4831b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 78682 bytes
Desc: image001.png
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121129/3be4831b/attachment.png>


More information about the llvm-commits mailing list