Files
TheRock/rocm-systems/projects/rocprofiler-systems/external/dyninst/instructionAPI/doc/API/Expression.tex
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

144 lines
6.2 KiB
TeX

\subsection{Expression Class}
\label{sec:expression}
An \code{Expression} is an AST representation of how the value of an operand is
computed.
The \code{Expression} class extends the \code{InstructionAST} class by adding the concept of
evaluation to the nodes of an \code{InstructionAST}. Evaluation attempts to determine
the \code{Result} of the
computation that the AST being evaluated represents. It will fill in results of
as many of the nodes in the tree as possible, and if full evaluation is
possible, it will return the result of the computation performed by the tree.
Permissible leaf nodes of an \code{Expression} tree are RegisterAST and Immediate
objects. Permissible internal nodes are \code{BinaryFunction} and Dereference objects.
An \code{Expression} may represent an immediate value, the contents of a register, or
the contents of memory at a given address, interpreted as a particular type.
The \code{Result}s in an \code{Expression} tree contain a type and a value. Their values may
be an undefined value or an instance of their associated type. When two \code{Result}s
are combined using a \code{BinaryFunction}, the \code{BinaryFunction} specifies the output
type. Sign extension, type promotion, truncation, and all other necessary
conversions are handled automatically based on the input types and the output
type. If both of the \code{Result}s that are combined have defined values, the
combination will also have a defined value; otherwise, the combination's value
will be undefined. For more information, see
Section~\ref{sec:result}, Section~\ref{sec:binaryFunction}, and
Section~\ref{sec:dereference}.
A user may specify the result of evaluating a given \code{Expression}. This mechanism
is designed to allow the user to provide a Dereference or RegisterAST with
information about the state of memory or registers. It may additionally be used
to change the value of an Immediate or to specify the result of a
\code{BinaryFunction}. This mechanism may be used to support other advanced analyses.
In order to make it more convenient to specify the results of particular
subexpressions, the \code{bind} method is provided. \code{bind} allows the user
to specify that a given subexpression has a particular value everywhere that it
appears in an expression. For example, if the state of certain registers is
known at the time an instruction is executed, a user can \code{bind} those
registers to their known values throughout an \code{Expression}.
The evaluation mechanism, as mentioned above, will evaluate as many
sub-\/expressions of an expression as possible. Any operand that is more
complicated than a single immediate value, however, will depend on register or
memory values. The \code{Result}s of evaluating each subexpression are cached
automatically using the \code{setValue} mechanism. The \code{Expression} then attempts
to determine its \code{Result} based on the \code{Result}s of its children. If this \code{Result} can
be determined (most likely because register contents have been filled in via
\code{setValue} or \code{bind}), it will be returned from \code{eval}; if it can
not be determined, a \code{Result} with an undefined value will be returned. See Figure
6 for an illustration of this concept; the operand represented is
\code{[ \code{EBX} + \code{4} $\ast$ \code{EAX} ]}.
The contents of \code{EBX} and \code{EAX} have been determined through some
outside mechanism, and have been defined with \code{setValue}. The \code{eval}
mechanism proceeds to determine the address being read by the \code{Dereference}, since
this information can be determined given the contents of the registers. This
address is available from the Dereference through its child in the tree, even
though calling \code{eval} on the Dereference returns a \code{Result} with an
undefined value.
\begin{figure}
\centering
\includegraphics{fig/deref-eval}
\caption{Applying \code{eval} to a Dereference tree with two registers
having user-provided values.}
\label{fig:deref-eval}
\end{figure}
\begin{apient}
typedef boost::shared_ptr<Expression> Ptr
\end{apient}
\apidesc{
A type definition for a reference-counted pointer to an \code{Expression}.
}
\begin{apient}
const Result & eval() const
\end{apient}
\apidesc{
If the \code{Expression} can be evaluated, returns a \code{Result}
containing its value. Otherwise returns an undefined \code{Result}.
}
\begin{apient}
const setValue(const Result & knownValue)
\end{apient}
\apidesc{
Sets the result of \code{eval} for this \code{Expression} to
\code{knownValue}.
}
\begin{apient}
void clearValue()
\end{apient}
\apidesc{
\code{clearValue} sets the contents of this \code{Expression} to undefined.
The next time \code{eval} is called, it will recalculate the value of the
\code{Expression}.
}
\begin{apient}
int size() const
\end{apient}
\apidesc{
\code{size} returns the size of this \code{Expression}'s \code{Result}, in
bytes.
}
\begin{apient}
bool bind(Expression * expr, const Result & value)
\end{apient}
\apidesc{
\code{bind} searches for all instances of the Expression \code{expr} within
this Expression, and sets the result of \code{eval} for those subexpressions
to \code{value}. \code{bind} returns \code{true} if at least one instance of
\code{expr} was found in this Expression.
\code{bind} does not operate on subexpressions that happen to evaluate to
the same value. For example, if a dereference of \code{0xDEADBEEF} is bound
to 0, and a register is bound to \code{0xDEADBEEF}, a deference of that
register is not bound to 0.
}
\begin{apient}
virtual void apply(Visitor *)
\end{apient}
\apidesc{
\code{apply} applies a \code{Visitor} to this \code{Expression}. Visitors
perform postfix-order traversal of the ASTs represented by an
\code{Expression}, with user-defined actions performed at each node of the
tree. We present a thorough discussion with examples in Section
\ref{sec:visitor}.
}
\begin{apient}
virtual void getChildren(std::vector<Expression::Ptr> & children) const
\end{apient}
\apidesc{
\code{getChildren} may be called on an \code{Expression} taking a vector of
\code{ExpressionPtr}s, rather than \code{InstructionAST}Ptrs. All children
which are \code{Expression}s will be appended to \code{children}.
}