ReqExplicit

public final class ReqExplicit extends DataFlowAnalyzer

Storage activity analyzer.

This analysis finds, for each location in the code, the pointer variables whose derivatives must be computed, assigned, allocated, or deallocated, even if they are not (yet) active. This analysis must be done after activity is completed, because it uses activity (cf 1st case of reqX). All usages of this analysis can be found by grep “PointerActiveUsage”.

Example, with pointers: allocate(V) ; V=0.0 ; P=&V ; ... V=X ; Y=*P ; deallocate(V) P is not active at the time of P=&V. However this must be differentiated into Pd = &Vd because later Y=*P will be active and differentiated into Yd=*Pd which requires Pd to be explicitly pointing to Vd. Moreover, Vd must be allocated and deallocated together with V. The “Required” Storage Activity info is a BoolVector of ALLKIND (but applies only to pointers?), with a boolean true when the zone’s derivative may be needed (allocated) downstream. When this boolean is true downstream an allocate for this pointer, then we must add an allocate for the differentiated pointer. Conversely, there is an “avlX” info analysis (“maybe-present”) that propagates forward the zones of the pointers for which the derivative pointer may be present (allocated) at the current location. When this boolean is true upstream a “free” of this pointer, then we must add a free of for the differentiated pointer.

Feature: derives from DataFlowAnalyzer : OK
Feature: able to analyze recursive code: OK
Feature: distinguishes structure elemts: OK
Feature: takes  care  of  pointer dests: OK
Feature: refine on loop-local variables: only during TOPDOWN_2 phase
Feature: std method for call arguments : OK
Feature: able to analyze sub-flow-graph: OK

Methods

analyze

protected boolean analyze()

Run Storage Activity analysis on the curUnit. Runs backwards towards pointers’ definitions and malloc, then forwards towards pointers’ free(). Return value is meaningless when we are in a runTopDownAnalysis().

compareChannelZoneDataDownstream

protected boolean compareChannelZoneDataDownstream(int mpZone, Block refBlock)

Special comparison for ReqX info attached to a message-passing zone. Dummy implementation, may need to be revised…

compareChannelZoneDataUpstream

protected boolean compareChannelZoneDataUpstream(int mpZone, Block refBlock)

Special comparison for ReqX info attached to a message-passing zone. Dummy implementation, may need to be revised…

compareDownstreamValues

protected boolean compareDownstreamValues()

Compares ReqX info arriving from downstream the exit of this curBlock with same info stored here at the previous sweep. If different, updates the stored value and returns modified status “true”. For loops, comparison is done also on the infoTmpCycle value. For AVAILABLE fgPhase (analyzeForward()), no copy is required here because this is the last use of “infoTmp” and “infoTmpCycle”.

compareUpstreamValues

protected boolean compareUpstreamValues()

Compares ReqX info arriving from downstream the entry of this curBlock with same info stored here at the previous sweep. If different, updates the stored value and returns modified status “true”. For loops, comparison is done also on the infoTmpCycle value. For REQUIRED fgPhase (analyzeBackward()), no copy is required here because this is the last use of “infoTmp” and “infoTmpCycle”.

copyAnnotation

public static void copyAnnotation(ActivityPattern curActivity, Tree fromTree, Tree toTree)

If there is an annotation about ReqX on “fromTree” for activity “curActivity”, copies it onto “toTree”.

cumulCycleValueWithAdditional

protected void cumulCycleValueWithAdditional(SymbolTable commonSymbolTable)

cumulValueWithAdditional

protected void cumulValueWithAdditional(SymbolTable commonSymbolTable)

diffZonesManaged

public BoolVector diffZonesManaged(ActivityPattern pattern)
Returns

the BoolVector of the pointer public zones indices whose differentials are managed during Unit, i.e. they are AvlX at exit of Unit and they are possibly overwritten during the Unit. This should be true in particular if the unit makes the pointer point to some new address and this address’es memory is still allocated, which implies it is the context’s responsibility to free it afterwards.

diffZonesRequired

public BoolVector diffZonesRequired(ActivityPattern pattern)
Returns

the BoolVector of the pointer public zones indices whose differentials are required at Unit entry, i.e. they are ReqX at entry of Unit and they are possibly read or written during the Unit. This should be true in particular if the unit derefs the destination (upon entry into “unit”) of the diff of a pointer, which must therefore point upon entry to some allocated diff memory location.

formalArgsPointerActivity

public static boolean[] formalArgsPointerActivity(ActivityPattern pattern, int nbArgs)
Returns

an array of booleans, one for each formal argument, true when the differentiated formal argument is needed because its memory location is reqX either upon entry or upon exit.

getValueFlowingBack

protected boolean getValueFlowingBack()

getValueFlowingThrough

protected boolean getValueFlowingThrough()

initializeCGForUnit

protected Object initializeCGForUnit()

Initializes the context of Unit “unit” for the current cgPhase of this analysis.

initializeCumulValue

protected void initializeCumulValue()

initializeInitBlock

protected void initializeInitBlock()

initializeUnit

protected void initializeUnit()

Initializations before each ReqX analysis of “curUnit”. Creates the BlockStorage’s that will store the info and infoCycle propagated by the current analysis, at the two ends of each Block.

isAnnotatedReqX

public static boolean isAnnotatedReqX(ActivityPattern pattern, Tree tree)

True when this tree has been annotated ReqX for the given activity context.

isPointerActiveArg

public static boolean isPointerActiveArg(ActivityPattern curActivity, int rankInShape)
Returns

true when the given FORMAL elementary argument to the Unit must have a differentiated counterpart (although it may be non-active) because this formal argument (either parameter or global or side-effect…) is a pointer and is either both overwritten during the call and reqX upon exit from the call or is both reqX upon entry in the call and accessed (read or written) during the call. Also returns true for non-pointer formal args that are marked reqX upon call entry, which is the case for variables whose address is assigned into a reqX pointer inside the call (cf F90:cm22).

isPointerActiveCall

public boolean isPointerActiveCall(Tree callTree, Unit callingUnit, Unit calledUnit, SymbolTable callSymbolTable, Instruction callInstruction, BoolVector avlX, BoolVector reqX, TapList reqXResult)
Returns

true when “callTree”, a particular call to a Unit (although it may be non-active) must be differentiated because one of its ACTUAL arguments (either parameter or global or side-effect…) is a pointer and is both reqX JUST DOWNSTREAM the call and overwritten during the call. NOTE: we believe we must not make the call ReqX when a pointer arg is reqX UPSTREAM the call and read during the call, (although this makes the arg itself reqX when the call is reqX, cf F90:cm04) because this is true only when the arg is read to fill another pointer arg which is itself active of reqX, and therefore the call will be found ReqX anyway. Moreover, this would find too many reqX calls. Also, the call must be differentiated if one of its actual arguments is a pointer and is avlX JUST UPSTREAM the call and overwritten during the call.

isPointerActiveUnit

public boolean isPointerActiveUnit(ActivityPattern curActivity)
Returns

true when the given Unit (although it may be non-active) must be differentiated because one of its FORMAL arguments (either parameter or global or side-effect…) is a pointer and is overwritten during the Unit and (it is either reqX upon exit from some call or avlX upon entry into some call). This happens when at least one call to it is ReqX or AvlX. (cf isPointerActiveCall() ; Read the NOTE on method isPointerActiveCall() ). Also, when both reqX and avlX are empty, which may mean that the Unit is not called by the call tree that contains the differentiated part (at least in the given code), the Unit is considered PointerActive when at least one of the pointers it overwrites is active some time in the differentiated part. We do that so that routines that are outside the call tree but do prepare pointers, get differentiated and can be used to prepare the diff pointers.

propagateValuesBackwardThroughBlock

protected boolean propagateValuesBackwardThroughBlock()

Propagates info through “curBlock”, upstream (i.e. backwards). This occurs only for the BOTTOMUP_1 and TOPDOWN_2 cgPhases.

propagateValuesForwardThroughBlock

protected boolean propagateValuesForwardThroughBlock()

Propagates info through “curBlock”, downstream (i.e. forwards). This occurs only for the BOTTOMUP_3 and TOPDOWN_4 cgPhases.

run

protected void run(TapList<Unit> rootUnits)

Run Storage Activity analysis on the CallGraph under “rootUnits” or on the complete CallGraph if “rootUnits” is null. Runs bottom-up, then top-down, then bottom-up, then top-down.

runAnalysis

public static void runAnalysis(CallGraph callGraph, TapList<DiffRoot> rootUnits)

Main trigger method. Runs Storage Activity analysis under the rootUnits.

setAnnotatedReqX

public static void setAnnotatedReqX(ActivityPattern pattern, Tree tree)

Annotate this tree as ReqX for the given activity context.

setCurBlockEtc

protected void setCurBlockEtc(Block block)

Set curBlock, curSymbolTable, nDZ, vectorMap’s.

Parameters
  • block – The new current Block.

setEmptyCumulAndCycleValues

protected void setEmptyCumulAndCycleValues()

terminateCGForUnit

protected void terminateCGForUnit()

Concluding operations on the given curUnit, called at the end of each bottom-up or top-down cgPhase.

terminateFGForBlock

protected void terminateFGForBlock()

terminateUnit

protected boolean terminateUnit()

Terminates ReqX analysis on “curUnit”. Return value is meaningful only in the bottom-up cgPhases: true means that the analysis result has changed since last time.