\documentclass[11pt]{article}
\usepackage{ifthen}
\usepackage{alltt}
% \usepackage{indentfirst}
\usepackage{latexsym}
\usepackage[pdftex]{graphicx}
\usepackage{gdefs}
% \usepackage{logdef}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{setspace}
\usepackage{rotating}
\usepackage{longtable}
\usepackage{hhline}
\usepackage{refs}
\usepackage{graph}
\usepackage{changebar}
\usepackage{array}
\usepackage{wrapfig}
\usepackage[small,compact]{titlesec}
\usepackage{listings}
\usepackage{verbatim}
\usepackage{tweaklist}

\renewcommand{\itemhook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

% this sets the spacings in the enumerate environment
\renewcommand{\enumhook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

% this sets the spacings in the description environment
\renewcommand{\descripthook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

\setlength{\topmargin}{0.0in}
\setlength{\headheight}{0.0in}
\setlength{\headsep}{0.0in}
\setlength{\textwidth}{6.5in}
\setlength{\oddsidemargin}{0.0in}
\setlength{\evensidemargin}{0.0in}
\setlength{\textheight}{9.0in}

\setcounter{topnumber}{5}
\def\topfraction{0.99}
\def\textfraction{0.05}
\def\floatpagefraction{0.9}
\setcounter{bottomnumber}{5}
\def\bottomfraction{0.99}
\setcounter{totalnumber}{10}
\def\dbltopfraction{0.99}
\def\dblfloatpagefraction{0.8}
\setcounter{dbltopnumber}{5}

\setlength{\marginparwidth}{.95in}
\let\oldmarginpar\marginpar
\renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\footnotesize #1]%
{\raggedright\footnotesize #1}}

\let\oldthebibliography=\thebibliography
  \let\endoldthebibliography=\endthebibliography
  \renewenvironment{thebibliography}[1]{%
    \begin{oldthebibliography}{#1}%
      \setlength{\parskip}{0ex}%
      \setlength{\itemsep}{0ex}%
  }%
  {%
    \end{oldthebibliography}%
  }

\lstset{
	basicstyle=\itshape,
	xleftmargin=3em,
	literate={->}{$\rightarrow$}{2}
	{α}{$\alpha$}{1}
	{δ}{$\delta$}{1}
}

\DeclareMathOperator{\extend}{\otimes}

\title{Dataflow Frequency Analysis \\
       CS701 \\
}

\author{Thomas Reps \\ \small[Based on notes taken by Anshul Purohit on November 3, 2015]}
\date{}

\begin{document}           % End of preamble and beginning of text.

\maketitle
\begin{abstract}
This lecture continues the presentation of how to perform Dataflow
Frequency Analysis \cite{PACT:SM02} on the folded DAG structure
generated via the Larus algorithm for collecting a whole-program path.
The frequency-analysis technique can be applied
to the class of bi-distributive dataflow-analysis problems.
This lecture formalizes the technique of generating dataflow-frequency
facts by traversing the DAG representation of a grammar that represents
a whole-program path (without unfolding the DAG).
\end{abstract}

\section{Whole Program Paths}

\begin{figure*}
\begin{center}
  \begin{tabular}{c@{\hspace{10.0ex}}c}
    \includegraphics[height=5.5cm]{figures/cfg.pdf}
    &
    \includegraphics[height=5.5cm]{figures/dag.pdf}
    \\
    (a) & (b)
  \end{tabular}
\end{center}
\vspace*{-2.0ex}
\caption{(a) Example control-flow graph. (b) dag created for the purpose of path-fragment numbering by the Ball-Larus algorithm.}
\label{Fi:CFG}
\end{figure*}

The previous lecture explained Larus's algorithm to collect a ``whole-program path''
(WPP) \cite{PLDI:Larus99}.
The algorithm uses the Sequitur algorithm \cite{JAIR:NMW97} to build a
somewhat degenerate context-free grammar that accepts exactly one
word, which corresponds to the path that was executed by an
instrumented program.
The terminal symbols of the context-free grammar are the acyclic
Ball-Larus path fragments \cite{MICRO:BL96} of the program's control
flow graph.
The whole-program path is returned in the form of a dag, each of whose leaves
is a path fragment.

Consider the control flow graph shown in \figref{CFG}(a) and the dag shown in \figref{CFG}(b),
which is the dag created for the purpose of path-fragment numbering by the Ball-Larus algorithm.
There are eight acyclic path fragments in the dag;
we will refer to three of them, \big[s,1,2,4],
\big[1,2,4], \big[1,3,4,5,6], as ``a,'' ``b,'' and ``c,'' respectively.
The Larus WPP algorithm returns a grammar whose one word represents the
trace of the program execution.
For instance, consider the execution trace
 \big[s,1,2,4] $\big[1,2,4]^{7}$ \big[1,3,4,5,6].
The WPP grammar for this trace is as follows:
\begin{lstlisting}
	S -> aAAAbc
	A -> bb
\end{lstlisting}
This grammar can be represented as a dag (see \figref{WPP}).
It is instructive to consider the tree obtained by unfolding the dag
(see \figref{WPPExpanded}).

\begin{figure*}
\begin{center}
  \includegraphics[height=3.5cm]{figures/wpp.pdf}
\end{center}
\vspace*{-2.0ex}
\caption{Example whole-program path.}
\label{Fi:WPP}
\end{figure*}

\begin{figure*}
\begin{center}
  \includegraphics[width=12.5cm]{figures/wpp-expanded.pdf}
\end{center}
\vspace*{-2.0ex}
\caption{Expansion of the whole-program path from \figref{WPP}.}
\label{Fi:WPPExpanded}
\end{figure*}

\section{Computing Dataflow-Fact Frequencies}

The CFG in \figref{CFG}(a) is the CFG for a program that contains two definitions
of variable $X$, at nodes 2 and 3, respectively.
We will use the example of computing dataflow-fact frequencies for
the most-recent definition-site of variable $X$.
We will show how one can determine that (i) d1 reaches node 2 seven times;
(ii) d2 never reaches node 2;
(iii) d1 never reaches node 5; and
(iv) d2 reaches node 5 once.
The technique works for the class of bi-distributive dataflow-analysis problems \cite{PLDI:Ramalingam96}.
This class of problem includes all gen/kill problems, as well as
copy-constant propagation (which is not a gen/kill problem).

There is a dataflow transformer corresponding to every edge.
The transformer can be represented as either a graph or a matrix
(see \figref{BidirectionalTransformers} and the matrices shown below).
For a bidirectional dataflow-analysis problem, the number of ones in
each column of a dataflow-transformer matrix must be at most 1.

\begin{figure*}
\begin{center}
  \includegraphics[width=11.0cm]{figures/bidirectional-transformers.pdf}
\end{center}
\vspace*{-2.0ex}
\caption{Dataflow transformers for propagating information about the
  most-recent definition-site of variable $X$.
}
\label{Fi:BidirectionalTransformers}
\end{figure*}


For edges $s \rightarrow 1$, $1 \rightarrow 2$, $1 \rightarrow 3$,
$4 \rightarrow 5$, and $5 \rightarrow 6$, the transformer is merely the
identity matrix.
\figref{BidirectionalTransformers} shows the edge transformers in graphical form
for all of the edges.
The transformers can also be represented as the matrices $M_1$, $M_2$, and $M_3$, respectively.
\[
\begin{array}{r@{\hspace{1.0ex}}c@{\hspace{1.0ex}}l@{\hspace{3.0ex}}r@{\hspace{1.0ex}}c@{\hspace{1.0ex}}l@{\hspace{3.0ex}}r@{\hspace{1.0ex}}c@{\hspace{1.0ex}}l}
  M_1 & = & \left(\begin{array}{@{}ccc@{}}
            1 & 0 & 0 \\
            0 & 1 & 0 \\
            0 & 0 & 1  \\
          \end{array}\right)
  &
  M_2 & = & \left(\begin{array}{@{}ccc@{}}
            1 & 1 & 0 \\
            0 & 0 & 0 \\
            0 & 0 & 0  \\
          \end{array}\right)
  &
  M_3 & = & \left(\begin{array}{@{}ccc@{}}
            1 & 0 & 1 \\
            0 & 0 & 0 \\
            0 & 0 & 0  \\
          \end{array}\right) \\[10pt]
\end{array}
\]

The extend operator $\extend$ in this problem is matrix multiplication.
As noted above, the number of ones in each column of the
dataflow-transformer matrix for a bidirectional dataflow-analysis problem
must be at most 1.
It is easy to argue that when two such matrices are multiplied, that
property is preserved.

In the case of the graph representation, the $\extend$ operation amounts
to 2-step graph reachability.
The edge transformer can also be written in functional form as
\[
  \lambda S . ((N \times S) \cup \textrm{gen}),
\]
where $S$ is the characteristic vector of the input set,
$\textrm{gen}$ is a vector that represents reachability from $\Lambda$,
and $N$ is a matrix whose $i^{\textrm{th}}$ row is a vector that
indicates reachability from input fact $d_i$.

Using the definition of edge transformers, the number of times
dataflow fact $d_1$ holds at a particular node can be calculated by
performing reachability on the composition of the edge transformers.
\figref{DataflowTransformersForPath} shows the concatenation of the
edge transformers for the path [s,1,2,4]$[1,2,4]^7$[1,3,4,5,6].
(Note that, for purposes of this computation,
path-fragment $b$ is considered to include the loop's back-edge
$4 \rightarrow 1$.)

\begin{figure*}
\begin{center}
  \includegraphics[width=12.5cm]{figures/dataflow-transformers-for-path.pdf}
\end{center}
\vspace*{-2.0ex}
\caption{Concatenation of the dataflow transformers for propagating
  information about the most-recent definition-site of variable $X$.
}
\label{Fi:DataflowTransformersForPath}
\end{figure*}

Matrices $M(i)$ can be defined for each of the terminal symbols $i$ in
the grammar.
Terminal symbol $b$ corresponds to the path [4,1,2,4].
Matrix $M(b)$ is merely the product the edge-transformer matrices
for the edges in path-fragment $b$:
\[
  M(b) = M_{4,1} \times M_{1,2} \times M_{2,4}.
\]

We also define \emph{frequency-propagation matrices} for terminal-symbol/node
pairs.
For instance, for terminal symbol $b$ and node $i$ (where $i$ may or may not
be part of $b$), the frequency-propagation matrices are denoted by $F_b(i)$.
$F_b(i)$ represents the frequency transformation from
the beginning of a $b$ symbol to just before node $i$ in $b$.
$F_b(1)$ is the edge transformer for the edge $4 \rightarrow 1$.
$F_b(2)$ is the product of the matrices for edges $4 \rightarrow 1$
and $1 \rightarrow 2$.
For all nodes not in the path represented by nonterminal $b$,
the $F_b$ matrix will contain all zeros,
which represents the fact that we do not find these nodes in
path-fragment $b$.

\begin{figure*}
\begin{center}
  \includegraphics[height=4.4cm]{figures/partial-products.pdf}
\end{center}
\vspace*{-2.0ex}
\caption{Partial products.}
\label{Fi:PartialProducts}
\end{figure*}

Using the definitions for the matrix transformers over path fragments
and frequency matrices over terminal-symbols in the grammar, M and F
matrices are defined for the non-terminal symbols of the WPP.
(The $F_S$ matrices, where $S$ is the start symbol of the grammar,
are used to calculate the final dataflow-frequency answers for the
entire path.)
Matrices are defined over the grammar symbols in a bottom-up fashion.
In this case, $M(A)$ and $F_A(.)$ are defined in terms of $M(b)$ and
$F_b(\cdot)$ according to the rule ``$A \rightarrow b b$'':
\begin{eqnarray*}
    M(A) & = & M(b) \times M(b) \\
  F_A(i) & = & F_b(i) + M(b) \times F_b(i)
\end{eqnarray*}
In particular, the two summands in $F_A(i)$ correspond to the two places
in $bb$ where node $i$ may occur.

In general, the computation of $F_P(\cdot)$ for a nonterminal $P$ resembles a
prefix-sum computation over the symbols of the production with $P$ on
the left-hand side.
For instance, in our example the production for $S$ is ``$S \rightarrow aAAAbc$,''
and thus $M(S)$ and $F_S(\cdot)$ are defined as follows:
\begin{eqnarray*}
    M(S) & = & M(a) \times M(A) \times M(A) \times M(A) \times M(b) \times M(c) \\
  F_S(i) & = & F_a(i) + M(a) \times F_A(i) + M(a) \times M(A) \times F_A(i) \\
         &   & \qquad\,\, + M(a) \times M(A) \times M(A) \times F_A(i) + M(a) \times M(A) \times M(A) \times M(A) \times F_b(i) \\
         &   & \qquad\,\, + M(a) \times M(A) \times M(A) \times M(A) \times M(b) \times F_c(i).
\end{eqnarray*}

Finally, the frequency vector for node $i$, denoted by $\textrm{Frequency}(i)$,
can be obtained from the first row of $F_S(i)$, in this case:
\[
  \textrm{Frequency}(i) = (1,0,0) \times F_S(i).
\]
The first element of this vector is the frequency that $\Lambda$
is reachable at node $i$ from $\Lambda$ at the beginning of the path
(i.e., the beginning of execution).
Because at \emph{every} node of the path $\Lambda$ is always reachable
from $\Lambda$ at the beginning of the path, the first element
of $\textrm{Frequency}(i)$ tells us how many times node $i$
occurs in the path.
In general, the $j^{\textrm{th}}$ entry of $\textrm{Frequency}(i)$
indicates the number of times that the $j^{\textrm{th}}$ dataflow fact
holds at node $i$.
Thus, the frequency vector can also be used to compute the \emph{fraction}
of times a particular dataflow fact $j$ holds at node $i$
\[
  \textrm{Fraction}(i,j) = {\textrm{Frequency}(i)(j) \over \textrm{Frequency}(i)(1)}.
\]

{\small
  \bibliography{cs701}
  \bibliographystyle{plain}
}

\end{document}
