<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
{mso-style-priority:99;
mso-style-link:"Plain Text Char";
margin:0in;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Arial","sans-serif";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Balloon Text Char";
margin:0in;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";}
span.PlainTextChar
{mso-style-name:"Plain Text Char";
mso-style-priority:99;
mso-style-link:"Plain Text";
font-family:"Arial","sans-serif";}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-priority:99;
mso-style-link:"Balloon Text";
font-family:"Tahoma","sans-serif";}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="2050" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoPlainText">Hi Andrew,<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">This test<o:p></o:p></p>
<p class="MsoPlainText">llc llvm\test\CodeGen\X86\misched-matrix.ll -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched -misched=ilpmin -verify-machineinstrs<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">fails with assertion on VC10. I hope you see the attached picture.<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText"><img width="1170" height="418" id="Picture_x0020_1" src="cid:image001.png@01CDCE41.031D4B60"><o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">- Elena<o:p></o:p></p>
<p class="MsoPlainText">-----Original Message-----<br>
From: llvm-commits-bounces@cs.uiuc.edu [mailto:llvm-commits-bounces@cs.uiuc.edu] On Behalf Of Andrew Trick<br>
Sent: Wednesday, November 28, 2012 07:13<br>
To: llvm-commits@cs.uiuc.edu<br>
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<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Author: atrick<o:p></o:p></p>
<p class="MsoPlainText">Date: Tue Nov 27 23:13:28 2012<o:p></o:p></p>
<p class="MsoPlainText">New Revision: 168773<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=168773&view=rev">
<span style="color:windowtext;text-decoration:none">http://llvm.org/viewvc/llvm-project?rev=168773&view=rev</span></a><o:p></o:p></p>
<p class="MsoPlainText">Log:<o:p></o:p></p>
<p class="MsoPlainText">misched: Analysis that partitions the DAG into subtrees.<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">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<o:p></o:p></p>
<p class="MsoPlainText">modes: -misched-ilpmin and -misched-ilpmax.<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Modified:<o:p></o:p></p>
<p class="MsoPlainText"> llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h<o:p></o:p></p>
<p class="MsoPlainText"> llvm/trunk/lib/CodeGen/MachineScheduler.cpp<o:p></o:p></p>
<p class="MsoPlainText"> llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp<o:p></o:p></p>
<p class="MsoPlainText"> llvm/trunk/test/CodeGen/X86/misched-matrix.ll<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h<o:p></o:p></p>
<p class="MsoPlainText">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h?rev=168773&r1=168772&r2=168773&view=diff">
<span style="color:windowtext;text-decoration:none">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h?rev=168773&r1=168772&r2=168773&view=diff</span></a><o:p></o:p></p>
<p class="MsoPlainText">==============================================================================<o:p></o:p></p>
<p class="MsoPlainText">--- llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h (original)<o:p></o:p></p>
<p class="MsoPlainText">+++ llvm/trunk/include/llvm/CodeGen/ScheduleDFS.h Tue Nov 27 23:13:28
<o:p></o:p></p>
<p class="MsoPlainText">+++ 2012<o:p></o:p></p>
<p class="MsoPlainText">@@ -14,38 +14,41 @@<o:p></o:p></p>
<p class="MsoPlainText">#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H<o:p></o:p></p>
<p class="MsoPlainText">#define LLVM_CODEGEN_SCHEDULEDAGILP_H<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">+#include "llvm/CodeGen/ScheduleDAG.h"<o:p></o:p></p>
<p class="MsoPlainText">#include "llvm/Support/DataTypes.h"<o:p></o:p></p>
<p class="MsoPlainText">#include <vector><o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> namespace llvm {<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> class raw_ostream;<o:p></o:p></p>
<p class="MsoPlainText">+class IntEqClasses;<o:p></o:p></p>
<p class="MsoPlainText">class ScheduleDAGInstrs;<o:p></o:p></p>
<p class="MsoPlainText">class SUnit;<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// \brief Represent the ILP of the subDAG rooted at a DAG node.<o:p></o:p></p>
<p class="MsoPlainText">+///<o:p></o:p></p>
<p class="MsoPlainText">+/// When computed using bottom-up DFS, this metric assumes that the DAG
<o:p></o:p></p>
<p class="MsoPlainText">+is a /// forest of trees with roots at the bottom of the schedule branching upward.<o:p></o:p></p>
<p class="MsoPlainText">struct ILPValue {<o:p></o:p></p>
<p class="MsoPlainText"> unsigned InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">- unsigned Cycles;<o:p></o:p></p>
<p class="MsoPlainText">-<o:p></o:p></p>
<p class="MsoPlainText">- ILPValue(): InstrCount(0), Cycles(0) {}<o:p></o:p></p>
<p class="MsoPlainText">+ /// Length may either correspond to depth or height, depending on
<o:p></o:p></p>
<p class="MsoPlainText">+ direction, /// and cycles or nodes depending on context.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned Length;<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- ILPValue(unsigned count, unsigned cycles):<o:p></o:p></p>
<p class="MsoPlainText">- InstrCount(count), Cycles(cycles) {}<o:p></o:p></p>
<p class="MsoPlainText">-<o:p></o:p></p>
<p class="MsoPlainText">- bool isValid() const { return Cycles > 0; }<o:p></o:p></p>
<p class="MsoPlainText">+ ILPValue(unsigned count, unsigned length):<o:p></o:p></p>
<p class="MsoPlainText">+ InstrCount(count), Length(length) {}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> // Order by the ILP metric's value.<o:p></o:p></p>
<p class="MsoPlainText"> bool operator<(ILPValue RHS) const {<o:p></o:p></p>
<p class="MsoPlainText">- return (uint64_t)InstrCount * RHS.Cycles<o:p></o:p></p>
<p class="MsoPlainText">- < (uint64_t)Cycles * RHS.InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">+ return (uint64_t)InstrCount * RHS.Length<o:p></o:p></p>
<p class="MsoPlainText">+ < (uint64_t)Length * RHS.InstrCount;<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"> bool operator>(ILPValue RHS) const {<o:p></o:p></p>
<p class="MsoPlainText"> return RHS < *this;<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"> bool operator<=(ILPValue RHS) const {<o:p></o:p></p>
<p class="MsoPlainText">- return (uint64_t)InstrCount * RHS.Cycles<o:p></o:p></p>
<p class="MsoPlainText">- <= (uint64_t)Cycles * RHS.InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">+ return (uint64_t)InstrCount * RHS.Length<o:p></o:p></p>
<p class="MsoPlainText">+ <= (uint64_t)Length * RHS.InstrCount;<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"> bool operator>=(ILPValue RHS) const {<o:p></o:p></p>
<p class="MsoPlainText"> return RHS <= *this;<o:p></o:p></p>
<p class="MsoPlainText">@@ -58,25 +61,88 @@<o:p></o:p></p>
<p class="MsoPlainText">#endif<o:p></o:p></p>
<p class="MsoPlainText">};<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">-/// \brief Compute the values of each DAG node for an ILP metric.<o:p></o:p></p>
<p class="MsoPlainText">+/// \brief Compute the values of each DAG node for various metrics during DFS.<o:p></o:p></p>
<p class="MsoPlainText">///<o:p></o:p></p>
<p class="MsoPlainText">-/// This metric assumes that the DAG is a forest of trees with roots at the -/// bottom of the schedule.<o:p></o:p></p>
<p class="MsoPlainText">-class ScheduleDAGILP {<o:p></o:p></p>
<p class="MsoPlainText">+/// ILPValues summarize the DAG subtree rooted at each node up to ///
<o:p></o:p></p>
<p class="MsoPlainText">+SubtreeLimit. ILPValues are also valid for interior nodes of a subtree,
<o:p></o:p></p>
<p class="MsoPlainText">+not /// just the root.<o:p></o:p></p>
<p class="MsoPlainText">+class SchedDFSResult {<o:p></o:p></p>
<p class="MsoPlainText">+ friend class SchedDFSImpl;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Per-SUnit data computed during DFS for various metrics.<o:p></o:p></p>
<p class="MsoPlainText">+ struct NodeData {<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned SubtreeID;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ NodeData(): InstrCount(0), SubtreeID(0) {} };<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Record a connection between subtrees and the connection level.<o:p></o:p></p>
<p class="MsoPlainText">+ struct Connection {<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned TreeID;<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned Level;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ Connection(unsigned tree, unsigned level): TreeID(tree),
<o:p></o:p></p>
<p class="MsoPlainText">+ Level(level) {} };<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText"> bool IsBottomUp;<o:p></o:p></p>
<p class="MsoPlainText">- std::vector<ILPValue> ILPValues;<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned SubtreeLimit;<o:p></o:p></p>
<p class="MsoPlainText">+ /// DFS results for each SUnit in this DAG.<o:p></o:p></p>
<p class="MsoPlainText">+ std::vector<NodeData> DFSData;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ // For each subtree discovered during DFS, record its connections to
<o:p></o:p></p>
<p class="MsoPlainText">+ other // subtrees.<o:p></o:p></p>
<p class="MsoPlainText">+ std::vector<SmallVector<Connection, 4> > SubtreeConnections;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Cache the current connection level of each subtree.<o:p></o:p></p>
<p class="MsoPlainText">+ /// This mutable array is updated during scheduling.<o:p></o:p></p>
<p class="MsoPlainText">+ std::vector<unsigned> SubtreeConnectLevels;<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> public:<o:p></o:p></p>
<p class="MsoPlainText">- ScheduleDAGILP(bool IsBU): IsBottomUp(IsBU) {}<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSResult(bool IsBU, unsigned lim)<o:p></o:p></p>
<p class="MsoPlainText">+ : IsBottomUp(IsBU), SubtreeLimit(lim) {}<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Clear the results.<o:p></o:p></p>
<p class="MsoPlainText">+ void clear() {<o:p></o:p></p>
<p class="MsoPlainText">+ DFSData.clear();<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeConnections.clear();<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeConnectLevels.clear();<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// \brief Initialize the result data with the size of the DAG.<o:p></o:p></p>
<p class="MsoPlainText">- void resize(unsigned NumSUnits);<o:p></o:p></p>
<p class="MsoPlainText">+ void resize(unsigned NumSUnits) {<o:p></o:p></p>
<p class="MsoPlainText">+ DFSData.resize(NumSUnits);<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- /// \brief Compute the ILP metric for the subDAG at this root.<o:p></o:p></p>
<p class="MsoPlainText">- void computeILP(const SUnit *Root);<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Compute various metrics for the DAG with given roots.<o:p></o:p></p>
<p class="MsoPlainText">+ void compute(ArrayRef<SUnit *> Roots);<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// \brief Get the ILP value for a DAG node.<o:p></o:p></p>
<p class="MsoPlainText">- ILPValue getILP(const SUnit *SU);<o:p></o:p></p>
<p class="MsoPlainText">+ ///<o:p></o:p></p>
<p class="MsoPlainText">+ /// A leaf node has an ILP of 1/1.<o:p></o:p></p>
<p class="MsoPlainText">+ ILPValue getILP(const SUnit *SU) {<o:p></o:p></p>
<p class="MsoPlainText">+ return ILPValue(DFSData[SU->NodeNum].InstrCount, 1 +
<o:p></o:p></p>
<p class="MsoPlainText">+ SU->getDepth()); }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief The number of subtrees detected in this DAG.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned getNumSubtrees() const { return SubtreeConnectLevels.size();
<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Get the ID of the subtree the given DAG node belongs to.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned getSubtreeID(const SUnit *SU) {<o:p></o:p></p>
<p class="MsoPlainText">+ return DFSData[SU->NodeNum].SubtreeID; }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Get the connection level of a subtree.<o:p></o:p></p>
<p class="MsoPlainText">+ ///<o:p></o:p></p>
<p class="MsoPlainText">+ /// For bottom-up trees, the connection level is the latency depth
<o:p></o:p></p>
<p class="MsoPlainText">+ (in cycles) /// of the deepest connection to another subtree.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned getSubtreeLevel(unsigned SubtreeID) {<o:p></o:p></p>
<p class="MsoPlainText">+ return SubtreeConnectLevels[SubtreeID]; }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// \brief Scheduler callback to update SubtreeConnectLevels when a
<o:p></o:p></p>
<p class="MsoPlainText">+ tree is /// initially scheduled.<o:p></o:p></p>
<p class="MsoPlainText">+ void scheduleTree(unsigned SubtreeID);<o:p></o:p></p>
<p class="MsoPlainText">};<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp<o:p></o:p></p>
<p class="MsoPlainText">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=168773&r1=168772&r2=168773&view=diff">
<span style="color:windowtext;text-decoration:none">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=168773&r1=168772&r2=168773&view=diff</span></a><o:p></o:p></p>
<p class="MsoPlainText">==============================================================================<o:p></o:p></p>
<p class="MsoPlainText">--- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original)<o:p></o:p></p>
<p class="MsoPlainText">+++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Tue Nov 27 23:13:28 2012<o:p></o:p></p>
<p class="MsoPlainText">@@ -2054,58 +2054,99 @@<o:p></o:p></p>
<p class="MsoPlainText">namespace {<o:p></o:p></p>
<p class="MsoPlainText">/// \brief Order nodes by the ILP metric.<o:p></o:p></p>
<p class="MsoPlainText">struct ILPOrder {<o:p></o:p></p>
<p class="MsoPlainText">- ScheduleDAGILP *ILP;<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSResult *DFSResult;<o:p></o:p></p>
<p class="MsoPlainText">+ BitVector *ScheduledTrees;<o:p></o:p></p>
<p class="MsoPlainText"> bool MaximizeILP;<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- ILPOrder(ScheduleDAGILP *ilp, bool MaxILP): ILP(ilp), MaximizeILP(MaxILP) {}<o:p></o:p></p>
<p class="MsoPlainText">+ ILPOrder(SchedDFSResult *dfs, BitVector *schedtrees, bool MaxILP)<o:p></o:p></p>
<p class="MsoPlainText">+ : DFSResult(dfs), ScheduledTrees(schedtrees), MaximizeILP(MaxILP)
<o:p></o:p></p>
<p class="MsoPlainText">+ {}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// \brief Apply a less-than relation on node priority.<o:p></o:p></p>
<p class="MsoPlainText">+ ///<o:p></o:p></p>
<p class="MsoPlainText">+ /// (Return true if A comes after B in the Q.)<o:p></o:p></p>
<p class="MsoPlainText"> bool operator()(const SUnit *A, const SUnit *B) const {<o:p></o:p></p>
<p class="MsoPlainText">- // Return true if A comes after B in the Q.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned SchedTreeA = DFSResult->getSubtreeID(A);<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned SchedTreeB = DFSResult->getSubtreeID(B);<o:p></o:p></p>
<p class="MsoPlainText">+ if (SchedTreeA != SchedTreeB) {<o:p></o:p></p>
<p class="MsoPlainText">+ // Unscheduled trees have lower priority.<o:p></o:p></p>
<p class="MsoPlainText">+ if (ScheduledTrees->test(SchedTreeA) != ScheduledTrees->test(SchedTreeB))<o:p></o:p></p>
<p class="MsoPlainText">+ return ScheduledTrees->test(SchedTreeB);<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ // Trees with shallower connections have have lower priority.<o:p></o:p></p>
<p class="MsoPlainText">+ if (DFSResult->getSubtreeLevel(SchedTreeA)<o:p></o:p></p>
<p class="MsoPlainText">+ != DFSResult->getSubtreeLevel(SchedTreeB)) {<o:p></o:p></p>
<p class="MsoPlainText">+ return DFSResult->getSubtreeLevel(SchedTreeA)<o:p></o:p></p>
<p class="MsoPlainText">+ < DFSResult->getSubtreeLevel(SchedTreeB);<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText"> if (MaximizeILP)<o:p></o:p></p>
<p class="MsoPlainText">- return ILP->getILP(A) < ILP->getILP(B);<o:p></o:p></p>
<p class="MsoPlainText">+ return DFSResult->getILP(A) < DFSResult->getILP(B);<o:p></o:p></p>
<p class="MsoPlainText"> else<o:p></o:p></p>
<p class="MsoPlainText">- return ILP->getILP(A) > ILP->getILP(B);<o:p></o:p></p>
<p class="MsoPlainText">+ return DFSResult->getILP(A) > DFSResult->getILP(B);<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText">};<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// \brief Schedule based on the ILP metric.<o:p></o:p></p>
<p class="MsoPlainText">class ILPScheduler : public MachineSchedStrategy {<o:p></o:p></p>
<p class="MsoPlainText">- ScheduleDAGILP ILP;<o:p></o:p></p>
<p class="MsoPlainText">+ /// In case all subtrees are eventually connected to a common root
<o:p></o:p></p>
<p class="MsoPlainText">+ through /// data dependence (e.g. reduction), place an upper limit on their size.<o:p></o:p></p>
<p class="MsoPlainText">+ ///<o:p></o:p></p>
<p class="MsoPlainText">+ /// FIXME: A subtree limit is generally good, but in the situation
<o:p></o:p></p>
<p class="MsoPlainText">+ commented /// above, where multiple similar subtrees feed a common
<o:p></o:p></p>
<p class="MsoPlainText">+ root, we should /// only split at a point where the resulting subtrees will be balanced.<o:p></o:p></p>
<p class="MsoPlainText">+ /// (a motivating test case must be found).<o:p></o:p></p>
<p class="MsoPlainText">+ static const unsigned SubtreeLimit = 16;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSResult DFSResult;<o:p></o:p></p>
<p class="MsoPlainText">+ BitVector ScheduledTrees;<o:p></o:p></p>
<p class="MsoPlainText"> ILPOrder Cmp;<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> std::vector<SUnit*> ReadyQ;<o:p></o:p></p>
<p class="MsoPlainText">public:<o:p></o:p></p>
<p class="MsoPlainText"> ILPScheduler(bool MaximizeILP)<o:p></o:p></p>
<p class="MsoPlainText">- : ILP(/*BottomUp=*/true), Cmp(&ILP, MaximizeILP) {}<o:p></o:p></p>
<p class="MsoPlainText">+ : DFSResult(/*BottomUp=*/true, SubtreeLimit),<o:p></o:p></p>
<p class="MsoPlainText">+ Cmp(&DFSResult, &ScheduledTrees, MaximizeILP) {}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> virtual void initialize(ScheduleDAGMI *DAG) {<o:p></o:p></p>
<p class="MsoPlainText"> ReadyQ.clear();<o:p></o:p></p>
<p class="MsoPlainText">- ILP.resize(DAG->SUnits.size());<o:p></o:p></p>
<p class="MsoPlainText">+ DFSResult.clear();<o:p></o:p></p>
<p class="MsoPlainText">+ DFSResult.resize(DAG->SUnits.size());<o:p></o:p></p>
<p class="MsoPlainText">+ ScheduledTrees.clear();<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> virtual void registerRoots() {<o:p></o:p></p>
<p class="MsoPlainText">- for (std::vector<SUnit*>::const_iterator<o:p></o:p></p>
<p class="MsoPlainText">- I = ReadyQ.begin(), E = ReadyQ.end(); I != E; ++I) {<o:p></o:p></p>
<p class="MsoPlainText">- ILP.computeILP(*I);<o:p></o:p></p>
<p class="MsoPlainText">- }<o:p></o:p></p>
<p class="MsoPlainText">+ DFSResult.compute(ReadyQ);<o:p></o:p></p>
<p class="MsoPlainText">+ ScheduledTrees.resize(DFSResult.getNumSubtrees());<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> /// Implement MachineSchedStrategy interface.<o:p></o:p></p>
<p class="MsoPlainText"> /// -----------------------------------------<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">+ /// Callback to select the highest priority node from the ready Q.<o:p></o:p></p>
<p class="MsoPlainText"> virtual SUnit *pickNode(bool &IsTopNode) {<o:p></o:p></p>
<p class="MsoPlainText"> if (ReadyQ.empty()) return NULL;<o:p></o:p></p>
<p class="MsoPlainText"> pop_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);<o:p></o:p></p>
<p class="MsoPlainText"> SUnit *SU = ReadyQ.back();<o:p></o:p></p>
<p class="MsoPlainText"> ReadyQ.pop_back();<o:p></o:p></p>
<p class="MsoPlainText"> IsTopNode = false;<o:p></o:p></p>
<p class="MsoPlainText">- DEBUG(dbgs() << "*** Scheduling " << *SU->getInstr()<o:p></o:p></p>
<p class="MsoPlainText">- << " ILP: " << ILP.getILP(SU) << '\n');<o:p></o:p></p>
<p class="MsoPlainText">+ DEBUG(dbgs() << "*** Scheduling " << "SU(" << SU->NodeNum << "): "<o:p></o:p></p>
<p class="MsoPlainText">+ << *SU->getInstr()<o:p></o:p></p>
<p class="MsoPlainText">+ << " ILP: " << DFSResult.getILP(SU)<o:p></o:p></p>
<p class="MsoPlainText">+ << " Tree: " << DFSResult.getSubtreeID(SU) << " @"<o:p></o:p></p>
<p class="MsoPlainText">+ << DFSResult.getSubtreeLevel(DFSResult.getSubtreeID(SU))<<
<o:p></o:p></p>
<p class="MsoPlainText">+ '\n');<o:p></o:p></p>
<p class="MsoPlainText"> return SU;<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- virtual void schedNode(SUnit *, bool) {}<o:p></o:p></p>
<p class="MsoPlainText">+ /// Callback after a node is scheduled. Mark a newly scheduled tree,
<o:p></o:p></p>
<p class="MsoPlainText">+ notify /// DFSResults, and resort the priority Q.<o:p></o:p></p>
<p class="MsoPlainText">+ virtual void schedNode(SUnit *SU, bool IsTopNode) {<o:p></o:p></p>
<p class="MsoPlainText">+ assert(!IsTopNode && "SchedDFSResult needs bottom-up");<o:p></o:p></p>
<p class="MsoPlainText">+ if (!ScheduledTrees.test(DFSResult.getSubtreeID(SU))) {<o:p></o:p></p>
<p class="MsoPlainText">+ ScheduledTrees.set(DFSResult.getSubtreeID(SU));<o:p></o:p></p>
<p class="MsoPlainText">+ DFSResult.scheduleTree(DFSResult.getSubtreeID(SU));<o:p></o:p></p>
<p class="MsoPlainText">+ std::make_heap(ReadyQ.begin(), ReadyQ.end(), Cmp);<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> virtual void releaseTopNode(SUnit *) { /*only called for top roots*/ }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Modified: llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp<o:p></o:p></p>
<p class="MsoPlainText">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=168773&r1=168772&r2=168773&view=diff">
<span style="color:windowtext;text-decoration:none">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp?rev=168773&r1=168772&r2=168773&view=diff</span></a><o:p></o:p></p>
<p class="MsoPlainText">==============================================================================<o:p></o:p></p>
<p class="MsoPlainText">--- llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp (original)<o:p></o:p></p>
<p class="MsoPlainText">+++ llvm/trunk/lib/CodeGen/ScheduleDAGInstrs.cpp Tue Nov 27 23:13:28
<o:p></o:p></p>
<p class="MsoPlainText">+++ 2012<o:p></o:p></p>
<p class="MsoPlainText">@@ -12,7 +12,7 @@<o:p></o:p></p>
<p class="MsoPlainText">//<o:p></o:p></p>
<p class="MsoPlainText">//===----------------------------------------------------------------------===//<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">-#define DEBUG_TYPE "sched-instrs"<o:p></o:p></p>
<p class="MsoPlainText">+#define DEBUG_TYPE "misched"<o:p></o:p></p>
<p class="MsoPlainText">#include "llvm/Operator.h"<o:p></o:p></p>
<p class="MsoPlainText">#include "llvm/Analysis/AliasAnalysis.h"<o:p></o:p></p>
<p class="MsoPlainText">#include "llvm/Analysis/ValueTracking.h"<o:p></o:p></p>
<p class="MsoPlainText">@@ -949,6 +949,120 @@<o:p></o:p></p>
<p class="MsoPlainText"> return "dag." + BB->getFullName();<o:p></o:p></p>
<p class="MsoPlainText">}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">+//===------------------------------------------------------------------<o:p></o:p></p>
<p class="MsoPlainText">+----===//<o:p></o:p></p>
<p class="MsoPlainText">+// SchedDFSResult Implementation<o:p></o:p></p>
<p class="MsoPlainText">+//===------------------------------------------------------------------<o:p></o:p></p>
<p class="MsoPlainText">+----===//<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+namespace llvm {<o:p></o:p></p>
<p class="MsoPlainText">+/// \brief Internal state used to compute SchedDFSResult.<o:p></o:p></p>
<p class="MsoPlainText">+class SchedDFSImpl {<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSResult &R;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Join DAG nodes into equivalence classes by their subtree.<o:p></o:p></p>
<p class="MsoPlainText">+ IntEqClasses SubtreeClasses;<o:p></o:p></p>
<p class="MsoPlainText">+ /// List PredSU, SuccSU pairs that represent data edges between subtrees.<o:p></o:p></p>
<p class="MsoPlainText">+ std::vector<std::pair<const SUnit*, const SUnit*> > ConnectionPairs;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+public:<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSImpl(SchedDFSResult &r): R(r), <o:p></o:p></p>
<p class="MsoPlainText">+SubtreeClasses(R.DFSData.size()) {}<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// SubtreID is initialized to zero, set to itself to flag the root
<o:p></o:p></p>
<p class="MsoPlainText">+ of a /// subtree, set to the parent to indicate an interior node,
<o:p></o:p></p>
<p class="MsoPlainText">+ /// then set to a representative subtree ID during finalization.<o:p></o:p></p>
<p class="MsoPlainText">+ bool isVisited(const SUnit *SU) const {<o:p></o:p></p>
<p class="MsoPlainText">+ return R.DFSData[SU->NodeNum].SubtreeID; }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Initialize this node's instruction count. We don't need to flag
<o:p></o:p></p>
<p class="MsoPlainText">+ the node /// visited until visitPostorder because the DAG cannot have cycles.<o:p></o:p></p>
<p class="MsoPlainText">+ void visitPreorder(const SUnit *SU) {<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[SU->NodeNum].InstrCount = SU->getInstr()->isTransient() ?
<o:p></o:p></p>
<p class="MsoPlainText">+ 0 : 1; }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Mark this node as either the root of a subtree or an interior
<o:p></o:p></p>
<p class="MsoPlainText">+ /// node. Increment the parent node's instruction count.<o:p></o:p></p>
<p class="MsoPlainText">+ void visitPostorder(const SUnit *SU, const SDep *PredDep, const SUnit *Parent) {<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[SU->NodeNum].SubtreeID = SU->NodeNum;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ // Join the child to its parent if they are connected via data dependence<o:p></o:p></p>
<p class="MsoPlainText">+ // and do not exceed the limit.<o:p></o:p></p>
<p class="MsoPlainText">+ if (!Parent || PredDep->getKind() != SDep::Data)<o:p></o:p></p>
<p class="MsoPlainText">+ return;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned PredCnt = R.DFSData[SU->NodeNum].InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">+ if (PredCnt > R.SubtreeLimit)<o:p></o:p></p>
<p class="MsoPlainText">+ return;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[SU->NodeNum].SubtreeID = Parent->NodeNum;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ // Add the recently finished predecessor's bottom-up descendent count.<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[Parent->NodeNum].InstrCount += PredCnt;<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeClasses.join(Parent->NodeNum, SU->NodeNum); }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Determine whether the DFS cross edge should be considered a
<o:p></o:p></p>
<p class="MsoPlainText">+ subtree edge /// or a connection between subtrees.<o:p></o:p></p>
<p class="MsoPlainText">+ void visitCross(const SDep &PredDep, const SUnit *Succ) {<o:p></o:p></p>
<p class="MsoPlainText">+ if (PredDep.getKind() == SDep::Data) {<o:p></o:p></p>
<p class="MsoPlainText">+ // If this is a cross edge to a root, join the subtrees. This happens when<o:p></o:p></p>
<p class="MsoPlainText">+ // the root was first reached by a non-data dependence.<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned NodeNum = PredDep.getSUnit()->NodeNum;<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned PredCnt = R.DFSData[NodeNum].InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">+ if (R.DFSData[NodeNum].SubtreeID == NodeNum && PredCnt < R.SubtreeLimit) {<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[NodeNum].SubtreeID = Succ->NodeNum;<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[Succ->NodeNum].InstrCount += PredCnt;<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeClasses.join(Succ->NodeNum, NodeNum);<o:p></o:p></p>
<p class="MsoPlainText">+ return;<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ ConnectionPairs.push_back(std::make_pair(PredDep.getSUnit(),
<o:p></o:p></p>
<p class="MsoPlainText">+ Succ)); }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ /// Set each node's subtree ID to the representative ID and record
<o:p></o:p></p>
<p class="MsoPlainText">+ connections /// between trees.<o:p></o:p></p>
<p class="MsoPlainText">+ void finalize() {<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeClasses.compress();<o:p></o:p></p>
<p class="MsoPlainText">+ R.SubtreeConnections.resize(SubtreeClasses.getNumClasses());<o:p></o:p></p>
<p class="MsoPlainText">+ R.SubtreeConnectLevels.resize(SubtreeClasses.getNumClasses());<o:p></o:p></p>
<p class="MsoPlainText">+ DEBUG(dbgs() << R.getNumSubtrees() << " subtrees:\n");<o:p></o:p></p>
<p class="MsoPlainText">+ for (unsigned Idx = 0, End = R.DFSData.size(); Idx != End; ++Idx) {<o:p></o:p></p>
<p class="MsoPlainText">+ R.DFSData[Idx].SubtreeID = SubtreeClasses[Idx];<o:p></o:p></p>
<p class="MsoPlainText">+ DEBUG(dbgs() << " SU(" << Idx << ") in tree "<o:p></o:p></p>
<p class="MsoPlainText">+ << R.DFSData[Idx].SubtreeID << '\n');<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ for (std::vector<std::pair<const SUnit*, const SUnit*> >::const_iterator<o:p></o:p></p>
<p class="MsoPlainText">+ I = ConnectionPairs.begin(), E = ConnectionPairs.end();<o:p></o:p></p>
<p class="MsoPlainText">+ I != E; ++I) {<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned PredTree = SubtreeClasses[I->first->NodeNum];<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned SuccTree = SubtreeClasses[I->second->NodeNum];<o:p></o:p></p>
<p class="MsoPlainText">+ if (PredTree == SuccTree)<o:p></o:p></p>
<p class="MsoPlainText">+ continue;<o:p></o:p></p>
<p class="MsoPlainText">+ unsigned Depth = I->first->getDepth();<o:p></o:p></p>
<p class="MsoPlainText">+ addConnection(PredTree, SuccTree, Depth);<o:p></o:p></p>
<p class="MsoPlainText">+ addConnection(SuccTree, PredTree, Depth);<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+protected:<o:p></o:p></p>
<p class="MsoPlainText">+ /// Called by finalize() to record a connection between trees.<o:p></o:p></p>
<p class="MsoPlainText">+ void addConnection(unsigned FromTree, unsigned ToTree, unsigned Depth) {<o:p></o:p></p>
<p class="MsoPlainText">+ if (!Depth)<o:p></o:p></p>
<p class="MsoPlainText">+ return;<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+ SmallVectorImpl<SchedDFSResult::Connection> &Connections =<o:p></o:p></p>
<p class="MsoPlainText">+ R.SubtreeConnections[FromTree];<o:p></o:p></p>
<p class="MsoPlainText">+ for (SmallVectorImpl<SchedDFSResult::Connection>::iterator<o:p></o:p></p>
<p class="MsoPlainText">+ I = Connections.begin(), E = Connections.end(); I != E; ++I) {<o:p></o:p></p>
<p class="MsoPlainText">+ if (I->TreeID == ToTree) {<o:p></o:p></p>
<p class="MsoPlainText">+ I->Level = std::max(I->Level, Depth);<o:p></o:p></p>
<p class="MsoPlainText">+ return;<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ Connections.push_back(SchedDFSResult::Connection(ToTree, Depth));<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+};<o:p></o:p></p>
<p class="MsoPlainText">+} // namespace llvm<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">namespace {<o:p></o:p></p>
<p class="MsoPlainText">/// \brief Manage the stack used by a reverse depth-first search over the DAG.<o:p></o:p></p>
<p class="MsoPlainText">class SchedDAGReverseDFS {<o:p></o:p></p>
<p class="MsoPlainText">@@ -961,7 +1075,10 @@<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText"> void advance() { ++DFSStack.back().second; }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- void backtrack() { DFSStack.pop_back(); }<o:p></o:p></p>
<p class="MsoPlainText">+ const SDep *backtrack() {<o:p></o:p></p>
<p class="MsoPlainText">+ DFSStack.pop_back();<o:p></o:p></p>
<p class="MsoPlainText">+ return DFSStack.empty() ? 0 : llvm::prior(DFSStack.back().second);<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> const SUnit *getCurr() const { return DFSStack.back().first; }<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">@@ -973,57 +1090,65 @@<o:p></o:p></p>
<p class="MsoPlainText">};<o:p></o:p></p>
<p class="MsoPlainText">} // anonymous<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">-void ScheduleDAGILP::resize(unsigned NumSUnits) {<o:p></o:p></p>
<p class="MsoPlainText">- ILPValues.resize(NumSUnits);<o:p></o:p></p>
<p class="MsoPlainText">-}<o:p></o:p></p>
<p class="MsoPlainText">-<o:p></o:p></p>
<p class="MsoPlainText">-ILPValue ScheduleDAGILP::getILP(const SUnit *SU) {<o:p></o:p></p>
<p class="MsoPlainText">- return ILPValues[SU->NodeNum];<o:p></o:p></p>
<p class="MsoPlainText">-}<o:p></o:p></p>
<p class="MsoPlainText">-<o:p></o:p></p>
<p class="MsoPlainText">-// A leaf node has an ILP of 1/1.<o:p></o:p></p>
<p class="MsoPlainText">-static ILPValue initILP(const SUnit *SU) {<o:p></o:p></p>
<p class="MsoPlainText">- unsigned Cnt = SU->getInstr()->isTransient() ? 0 : 1;<o:p></o:p></p>
<p class="MsoPlainText">- return ILPValue(Cnt, 1 + SU->getDepth()); -}<o:p></o:p></p>
<p class="MsoPlainText">-<o:p></o:p></p>
<p class="MsoPlainText">/// Compute an ILP metric for all nodes in the subDAG reachable via depth-first /// search from this root.<o:p></o:p></p>
<p class="MsoPlainText">-void ScheduleDAGILP::computeILP(const SUnit *Root) {<o:p></o:p></p>
<p class="MsoPlainText">+void SchedDFSResult::compute(ArrayRef<SUnit *> Roots) {<o:p></o:p></p>
<p class="MsoPlainText"> if (!IsBottomUp)<o:p></o:p></p>
<p class="MsoPlainText"> llvm_unreachable("Top-down ILP metric is unimplemnted");<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText">- SchedDAGReverseDFS DFS;<o:p></o:p></p>
<p class="MsoPlainText">- // Mark a node visited by validating it.<o:p></o:p></p>
<p class="MsoPlainText">- ILPValues[Root->NodeNum] = initILP(Root);<o:p></o:p></p>
<p class="MsoPlainText">- DFS.follow(Root);<o:p></o:p></p>
<p class="MsoPlainText">- for (;;) {<o:p></o:p></p>
<p class="MsoPlainText">- // Traverse the leftmost path as far as possible.<o:p></o:p></p>
<p class="MsoPlainText">- while (DFS.getPred() != DFS.getPredEnd()) {<o:p></o:p></p>
<p class="MsoPlainText">- const SUnit *PredSU = DFS.getPred()->getSUnit();<o:p></o:p></p>
<p class="MsoPlainText">- DFS.advance();<o:p></o:p></p>
<p class="MsoPlainText">- // If the pred is already valid, skip it.<o:p></o:p></p>
<p class="MsoPlainText">- if (ILPValues[PredSU->NodeNum].isValid())<o:p></o:p></p>
<p class="MsoPlainText">- continue;<o:p></o:p></p>
<p class="MsoPlainText">- ILPValues[PredSU->NodeNum] = initILP(PredSU);<o:p></o:p></p>
<p class="MsoPlainText">- DFS.follow(PredSU);<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDFSImpl Impl(*this);<o:p></o:p></p>
<p class="MsoPlainText">+ for (ArrayRef<const SUnit*>::const_iterator<o:p></o:p></p>
<p class="MsoPlainText">+ RootI = Roots.begin(), RootE = Roots.end(); RootI != RootE; ++RootI) {<o:p></o:p></p>
<p class="MsoPlainText">+ SchedDAGReverseDFS DFS;<o:p></o:p></p>
<p class="MsoPlainText">+ Impl.visitPreorder(*RootI);<o:p></o:p></p>
<p class="MsoPlainText">+ DFS.follow(*RootI);<o:p></o:p></p>
<p class="MsoPlainText">+ for (;;) {<o:p></o:p></p>
<p class="MsoPlainText">+ // Traverse the leftmost path as far as possible.<o:p></o:p></p>
<p class="MsoPlainText">+ while (DFS.getPred() != DFS.getPredEnd()) {<o:p></o:p></p>
<p class="MsoPlainText">+ const SDep &PredDep = *DFS.getPred();<o:p></o:p></p>
<p class="MsoPlainText">+ DFS.advance();<o:p></o:p></p>
<p class="MsoPlainText">+ // If the pred is already valid, skip it. We may preorder visit a node<o:p></o:p></p>
<p class="MsoPlainText">+ // with InstrCount==0 more than once, but it won't affect heuristics<o:p></o:p></p>
<p class="MsoPlainText">+ // because we don't care about cross edges to leaf copies.<o:p></o:p></p>
<p class="MsoPlainText">+ if (Impl.isVisited(PredDep.getSUnit())) {<o:p></o:p></p>
<p class="MsoPlainText">+ Impl.visitCross(PredDep, DFS.getCurr());<o:p></o:p></p>
<p class="MsoPlainText">+ continue;<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ Impl.visitPreorder(PredDep.getSUnit());<o:p></o:p></p>
<p class="MsoPlainText">+ DFS.follow(PredDep.getSUnit());<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ // Visit the top of the stack in postorder and backtrack.<o:p></o:p></p>
<p class="MsoPlainText">+ const SUnit *Child = DFS.getCurr();<o:p></o:p></p>
<p class="MsoPlainText">+ const SDep *PredDep = DFS.backtrack();<o:p></o:p></p>
<p class="MsoPlainText">+ Impl.visitPostorder(Child, PredDep, PredDep ? DFS.getCurr() : 0);<o:p></o:p></p>
<p class="MsoPlainText">+ if (DFS.isComplete())<o:p></o:p></p>
<p class="MsoPlainText">+ break;<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText">- // Visit the top of the stack in postorder and backtrack.<o:p></o:p></p>
<p class="MsoPlainText">- unsigned PredCount = ILPValues[DFS.getCurr()->NodeNum].InstrCount;<o:p></o:p></p>
<p class="MsoPlainText">- DFS.backtrack();<o:p></o:p></p>
<p class="MsoPlainText">- if (DFS.isComplete())<o:p></o:p></p>
<p class="MsoPlainText">- break;<o:p></o:p></p>
<p class="MsoPlainText">- // Add the recently finished predecessor's bottom-up descendent count.<o:p></o:p></p>
<p class="MsoPlainText">- ILPValues[DFS.getCurr()->NodeNum].InstrCount += PredCount;<o:p></o:p></p>
<p class="MsoPlainText">+ }<o:p></o:p></p>
<p class="MsoPlainText">+ Impl.finalize();<o:p></o:p></p>
<p class="MsoPlainText">+}<o:p></o:p></p>
<p class="MsoPlainText">+<o:p></o:p></p>
<p class="MsoPlainText">+/// The root of the given SubtreeID was just scheduled. For all
<o:p></o:p></p>
<p class="MsoPlainText">+subtrees /// connected to this tree, record the depth of the connection
<o:p></o:p></p>
<p class="MsoPlainText">+so that the /// nearest connected subtrees can be prioritized.<o:p></o:p></p>
<p class="MsoPlainText">+void SchedDFSResult::scheduleTree(unsigned SubtreeID) {<o:p></o:p></p>
<p class="MsoPlainText">+ for (SmallVectorImpl<Connection>::const_iterator<o:p></o:p></p>
<p class="MsoPlainText">+ I = SubtreeConnections[SubtreeID].begin(),<o:p></o:p></p>
<p class="MsoPlainText">+ E = SubtreeConnections[SubtreeID].end(); I != E; ++I) {<o:p></o:p></p>
<p class="MsoPlainText">+ SubtreeConnectLevels[I->TreeID] =<o:p></o:p></p>
<p class="MsoPlainText">+ std::max(SubtreeConnectLevels[I->TreeID], I->Level);<o:p></o:p></p>
<p class="MsoPlainText">+ DEBUG(dbgs() << " Tree: " << I->TreeID<o:p></o:p></p>
<p class="MsoPlainText">+ << " @" << SubtreeConnectLevels[I->TreeID] << '\n');<o:p></o:p></p>
<p class="MsoPlainText"> }<o:p></o:p></p>
<p class="MsoPlainText">}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void ILPValue::print(raw_ostream &OS) const {<o:p></o:p></p>
<p class="MsoPlainText">- if (!isValid())<o:p></o:p></p>
<p class="MsoPlainText">+ OS << InstrCount << " / " << Length << " = "; if (!Length)<o:p></o:p></p>
<p class="MsoPlainText"> OS << "BADILP";<o:p></o:p></p>
<p class="MsoPlainText">- OS << InstrCount << " / " << Cycles << " = "<o:p></o:p></p>
<p class="MsoPlainText">- << format("%g", ((double)InstrCount / Cycles));<o:p></o:p></p>
<p class="MsoPlainText">+ else<o:p></o:p></p>
<p class="MsoPlainText">+ OS << format("%g", ((double)InstrCount / Length));<o:p></o:p></p>
<p class="MsoPlainText">}<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> void ILPValue::dump() const {<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">Modified: llvm/trunk/test/CodeGen/X86/misched-matrix.ll<o:p></o:p></p>
<p class="MsoPlainText">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/misched-matrix.ll?rev=168773&r1=168772&r2=168773&view=diff">
<span style="color:windowtext;text-decoration:none">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/misched-matrix.ll?rev=168773&r1=168772&r2=168773&view=diff</span></a><o:p></o:p></p>
<p class="MsoPlainText">==============================================================================<o:p></o:p></p>
<p class="MsoPlainText">--- llvm/trunk/test/CodeGen/X86/misched-matrix.ll (original)<o:p></o:p></p>
<p class="MsoPlainText">+++ llvm/trunk/test/CodeGen/X86/misched-matrix.ll Tue Nov 27 23:13:28
<o:p></o:p></p>
<p class="MsoPlainText">+++ 2012<o:p></o:p></p>
<p class="MsoPlainText">@@ -1,6 +1,12 @@<o:p></o:p></p>
<p class="MsoPlainText">; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \<o:p></o:p></p>
<p class="MsoPlainText">; RUN: -misched-topdown -verify-machineinstrs \<o:p></o:p></p>
<p class="MsoPlainText">; RUN: | FileCheck %s -check-prefix=TOPDOWN<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: -misched=ilpmin -verify-machineinstrs \<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: | FileCheck %s -check-prefix=ILPMIN<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: llc < %s -march=x86-64 -mcpu=core2 -pre-RA-sched=source -enable-misched \<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: -misched=ilpmax -verify-machineinstrs \<o:p></o:p></p>
<p class="MsoPlainText">+; RUN: | FileCheck %s -check-prefix=ILPMAX<o:p></o:p></p>
<p class="MsoPlainText">;<o:p></o:p></p>
<p class="MsoPlainText">; Verify that the MI scheduler minimizes register pressure for a ; uniform set of bottom-up subtrees (unrolled matrix multiply).<o:p></o:p></p>
<p class="MsoPlainText">@@ -17,6 +23,68 @@<o:p></o:p></p>
<p class="MsoPlainText">; TOPDOWN: movl %{{.*}}, 8(<o:p></o:p></p>
<p class="MsoPlainText">; TOPDOWN: movl %{{.*}}, 12(<o:p></o:p></p>
<p class="MsoPlainText">; TOPDOWN: %for.end<o:p></o:p></p>
<p class="MsoPlainText">+;<o:p></o:p></p>
<p class="MsoPlainText">+; For -misched=ilpmin, verify that each expression subtree is ;
<o:p></o:p></p>
<p class="MsoPlainText">+scheduled independently, and that the imull/adds are interleaved.<o:p></o:p></p>
<p class="MsoPlainText">+;<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: %for.body<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: movl %{{.*}}, (<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: movl %{{.*}}, 4(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: movl %{{.*}}, 8(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: movl %{{.*}}, 12(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMIN: %for.end<o:p></o:p></p>
<p class="MsoPlainText">+;<o:p></o:p></p>
<p class="MsoPlainText">+; For -misched=ilpmax, verify that each expression subtree is ;
<o:p></o:p></p>
<p class="MsoPlainText">+scheduled independently, and that the imull/adds are clustered.<o:p></o:p></p>
<p class="MsoPlainText">+;<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: %for.body<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: movl %{{.*}}, (<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: movl %{{.*}}, 4(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: movl %{{.*}}, 8(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: imull<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: addl<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: movl %{{.*}}, 12(<o:p></o:p></p>
<p class="MsoPlainText">+; ILPMAX: %for.end<o:p></o:p></p>
<p class="MsoPlainText"><o:p></o:p></p>
<p class="MsoPlainText"> define void @mmult([4 x i32]* noalias nocapture %m1, [4 x i32]* noalias nocapture %m2,<o:p></o:p></p>
<p class="MsoPlainText">[4 x i32]* noalias nocapture %m3) nounwind uwtable ssp {<o:p></o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText"><o:p> </o:p></p>
<p class="MsoPlainText">_______________________________________________<o:p></o:p></p>
<p class="MsoPlainText">llvm-commits mailing list<o:p></o:p></p>
<p class="MsoPlainText"><a href="mailto:llvm-commits@cs.uiuc.edu"><span style="color:windowtext;text-decoration:none">llvm-commits@cs.uiuc.edu</span></a><o:p></o:p></p>
<p class="MsoPlainText"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits"><span style="color:windowtext;text-decoration:none">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</span></a><o:p></o:p></p>
</div>
<p>---------------------------------------------------------------------<br>
Intel Israel (74) Limited</p>
<p>This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</p></body>
</html>