- 
                Notifications
    You must be signed in to change notification settings 
- Fork 25
WI #1750 Add DFA support #1751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WI #1750 Add DFA support #1751
Conversation
…260_CFG_DFA_SemanticDomainLite_IntegrateAsAnalyzer # Conflicts: # TypeCobol.Analysis.Test/CfgTestUtils.cs # TypeCobol.Analysis.Test/TypeCobol.Analysis.Test.csproj
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are my suggestions for improvement
- The WithDfamode for CFG building is the same as theExtendedmode, the only difference is on the generic arguments for the block type. We could decouple CFG building from DFA by removing the need for typing the block data (i.e. stored asobject, DFA builder would have to cast when reading)
- general remarks
- remove locks
- restrict visibilities where possible to avoid misuses
- remove unused code
- some test code may be factorized
 
- Some reports collect results during the Node phase, others may work on a CompilationUnitafter parsing has completed so it is confusing on how to use theIReportinterface. Maybe create 2 sorts of reports (one is tied to the parsing process, the other directly uses the results) ?
- @smedilol also suggested that the process of determining how variables are affected by each statement (currently in ZCallPgmReport.ComputeUsePointDefPathsmethod) should be moved into a separate class for future reuse.
See other following remarks.
| Assert.IsNotNull(dfaBuilder.Cfg.AllBlocks[1].Data.Gen); | ||
| Assert.AreEqual("{0, 2}", dfaBuilder.Cfg.AllBlocks[1].Data.Gen.ToString()); | ||
| //MOVE 2 TO I | ||
| Assert.IsTrue(dfaBuilder.Cfg.AllBlocks[1].Data.Gen.Get(0)); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it redundant to test the set bits after having already checked the ToString result ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I aggree, but it's just because I follow the same kind of logic: checking instructions.
| /// <summary> | ||
| /// Visitor to Collect all level 88 symbols. | ||
| /// </summary> | ||
| class Level88SymbolCollector : AbstractSymbolAndTypeVisitor<Dictionary<Symbol, Symbol>, Dictionary<Symbol, Symbol>> | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit lost here... ParentSymbol is never updated so this class will associate the given ParentSymbol to any level 88 found under it. But can't we simply use Owner of the level 88 to get this info ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are collecting level 88 symbols and we associate to each such symbol its parent, accumulator variable "symbol", is reused for all such symbols having different parents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok now I see that the collector works for every 88-levels found under initial parent symbol (and not only those located directly under it).
| private void OnDefPoint(DataFlowGraphBuilder<Node, Symbol> dfaBuilder, DfaDefPoint<Node, Symbol> dp) | ||
| { | ||
| VariableSymbol sym = (VariableSymbol)dp.Variable; | ||
| Symbol parent = null; | ||
| if (sym.Level == 88 && sym.Value != null && Level88SymbolParentSymbolMap != null && Level88SymbolParentSymbolMap.TryGetValue(sym, out parent)) | ||
| {//Now say that it is the parent variable which is the target of the definition. | ||
| dp.Variable = parent; | ||
| dp.UserData = sym; | ||
| } | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact this is true in every Cobol program, a DEF on a 88 level is in fact a DEF on its parent variable so I think this logic should be moved to DefaultDataFlowGraphBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No this is a hack here, to make DFA think that when there is a level 88 variable assignment, it is it's parent variable which is assigned, DFA must track by the CALL the parent variable value changing and not the level 88 children variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, all I say is that this logic should be moved to DefaultDataFlowGraphBuilder otherwise all reports or class that would use the DFA results will have to perform this hack on their own, it must be factorized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum... I think it is a contextual logic, not sure that factorizinf such logic, will lead to a generic pattern.
| /// Dfa test for call module report | ||
| /// </summary> | ||
| [TestClass] | ||
| public class DfaCallPgmReport | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 2 tests are duplicate with the 2 in CLI, should we keep them ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because theses are for CLI using the -cfg WithDfa and -zcr options in the command line arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On one hand the CLI tests are more complete because they also cover the new options, on the other hand the tests in TypeCobol.Analysis are easier to debug because they run in the same process...
I'm ok to keep them both but as they are duplicates, we'll have to keep in mind that changes made on one have to be copied on the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but anyway they still to be different tests.
| /// </summary> | ||
| /// <typeparam name="I">Instruction generic Type</typeparam> | ||
| /// <typeparam name="V">Used Variable generic Type</typeparam> | ||
| public class DfaDefPoint<I, V> | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that all properties of this class should be readonly except UserData. This is compatible with the current usages except for the hack on SET statements for 88 levels (see my remark in ZCallPgmReport.cs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok for "UserData" variable, "Variable" is used by the ZCallPgmReport hack, other variables can be made internal set.
This is not the purpose here , but we can image that we can use the same hack to detect parent variable indirectly targeted by their REDEFINES or RENAMES variables.
| /// </summary> | ||
| /// <typeparam name="I">Instruction generic Type</typeparam> | ||
| /// <typeparam name="V">Used Variable generic Type</typeparam> | ||
| public class DfaUsePoint<I, V> | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same remark as for DEF points, I'll leave it as it is now until we decide for the DEF points properties accessibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same answer as for DEF.
1260 dfa minor refactorings
| Replaced by #1802. | 
According to an internal discussion, this PR is created on a branch which will be the base branch for DFA integration discussions, reports and requests.