Class JitOpUseModel
This implements the Operation Elimination phase of the JitCompiler
using a simple graph
traversal. The result is the set of ops
whose outputs are (or could be) used by a
downstream op. This includes all "sink" ops and all ops on which they depend.
Some of the sink ops are easy to identify. These are ops that have direct effects on memory, control flow, or other aspects of the emulated machine:
- Memory outputs - any p-code op whose output operand is a memory varnode.
- Store ops - a
store
op. - Branch ops - one of
branch
,cbranch
, orbranchind
. - User ops with side effects - a
callother
to a method wherehasSideEffects
=true
. - Errors - e.g.,
unimplemented
,missing userop
.
We identify these ops by invoking JitOp.canBeRemoved()
. Ops that return false
are
"sink" ops.
There is another class of ops to consider as "sinks," though: The definitions of SSA variables
that could be retired. This could be from exiting the passage, flowing to a block with fewer live
variables, or invoking a userop with the Standard strategy (see
JitDataFlowUseropLibrary
). Luckily, we have already performed scope
analysis, so we already know what varnodes are retired. However, to determine what SSA
variables are retired, we have to consider where the retirement happens. For block transitions,
it is always at the end of the block. Thus, we can use
JitDataFlowBlockAnalyzer.getVar(Varnode)
. For userops, we capture the intra-block
analysis state into JitCallOtherOpIf.dfState()
at the time of invocation. We can
then use JitDataFlowState.MiniDFState.getVar(Varnode)
. The defining op for each retired SSA variable is
considered used.
Retirement due to block flow requires a little more attention. Consider an op that defines a variable, where that op exists in a block that ends with a conditional branch. The analyzer does not know which flow the code will take, so we have to consider that it could take either. If for either branch, the variable goes out of scope and is retired, we have to consider the defining op as used.
The remainder of the algorithm is simply an upward traversal of the use-def graph to collect all of the sink ops' dependencies. All the dependencies are considered used.
-
Constructor Summary
ConstructorsConstructorDescriptionJitOpUseModel
(JitAnalysisContext context, JitControlFlowModel cfm, JitDataFlowModel dfm, JitVarScopeModel vsm) Construct the operator use model -
Method Summary
Modifier and TypeMethodDescriptionvoid
For diagnostics: Dump the analysis result to stderrboolean
Check whether the given op node is used.
-
Constructor Details
-
JitOpUseModel
public JitOpUseModel(JitAnalysisContext context, JitControlFlowModel cfm, JitDataFlowModel dfm, JitVarScopeModel vsm) Construct the operator use model- Parameters:
context
- the analysis contextcfm
- the control flow modeldfm
- the data flow modelvsm
- the variable scope model
-
-
Method Details
-
isUsed
Check whether the given op node is used.If the op is used, then it cannot be eliminated.
- Parameters:
op
- the op to check- Returns:
- true if used, i.e., non-removable
-
dumpResult
public void dumpResult()For diagnostics: Dump the analysis result to stderr- See Also:
-