-
Notifications
You must be signed in to change notification settings - Fork 9
Annotated CAST Part 2: Main Functionality for Each Pass
Ryan Sullivant edited this page May 17, 2022
·
5 revisions
Here we highlight the main functionality provided by each Annotated CAST pass.
- Collapsing ids of
AnnCastNamenodes stating with zero. This is mainly necessary for CAST generated on the GCC side, since GCC assigns random ids (read as multiple digit ids) to identifiers. - Determining
AnnCastNamenodes are global variables. We say that something is global if it is used at the module scope. If a name node is used at the module scope, we add it toPipelineState'smodule_node.used_varsdict. This dict is used byPipelineState's methodsis_global_var()andall_globals_dict(). - Determining if a
AnnCastCallnode has an associatedAnnCastFunctionDef, and determining theinvocation_indexof the Call node.
- Store the container scope for each
AnnCastNamenode. - Keep track of accessed variables (read from), modified variables (assigned to), and used variables (accessed or modified) for each container. This included propagating up accessed, modified, and used variables to enclosing container scopes. For locals, the propagation stops at the closest function container scope, but for globals it continues until the module scope.
- Determine if an
AnnCastCallnode should be a GrFN 2.2 type Call, and if so, make a deep copy of its associatedAnnCastFunctionDef. - Create
GrfnContainerSrcReffor each container. This is used to populate GrFN container metadata.
- Determine container scope dependent versions for each
AnnCastNamenode, and create GrFNVariableNodes for modified variables. - Populate container top and bottom interfaces. For If and Loop containers, used variables are propagated through the top interface, and modified variables are propagated through the bottom interface. For Calls and FunctionDefs arguments/parameters and used globals are propagated through the top interface, while modified globals and return value (if existent) is propagated through the bottom interface.
- For CAST coming from Python, dummy assignments are added at the top of functions so that variable propagation is in line with CAST coming from GCC.
- Creating GrFN variables for If and Loop interfaces.
- Creating GrFN variables for any
AnnCastNamenodes which don't already have a GrFN variable associated with them. - Aliasing versions for variables across container scopes. For example, for an If or Loop container the
INIT_VERSIONof a variable entering the body is the aliased to the highest version of that variable appearing in the If/Loop conditional expression. This aliasing ensures that linking GrFN variables "locally" within container scopes will produce correct adjacencies. - Creating and setting up If and Loop GrFN Condition node and If GrFN Decision node.
- Create GrFN
LITERALorASSIGNLambdaNodesfor all explicit/from source assignments. - Create GrFN
LITERALorASSIGNLambdaNodesfor function arguments and function return values.
- Populate
expr_strattribute of allAnnCastnodes. - Combine node
expr_str's to generate lambda expressions for eachLambdaNodeincluding interfaces, assignments, conditions, and decisions
- Build
GroundedFunctionNetworkgraph including
- creating
LambdaNode's for each interface, decision, and condition - creating
HyperEdgesbetween GrFNVariableNode's andLambdaNodes - creating subgraphs for each container, and adding nodes to the appropriate subgraph
Note: The stuff about pass prototype below should be moved somewhere else I think.
Each pass does a traversal of the annotated CAST, which means that code for the visitor pattern is repeated on any given pass. To facilitate implementing a new pass, we have a prototype of the visitor code that can be used as a starting point for a new pass. This prototype can be found at automates/program_analysis/CAST2GrFN/visitors/ann_cast_prototype.py