# An Automatic Transformer from Sequential to Parallel Java Code
## 4 Method Call Analysis
### Data Dependence Analysis  
Accessing data shared among threads should be properly guarded. We used a tool proposed in one of our previous works, which provides a set of APIs to extract data dependence for methods [38]. This approach analyzes both variables and method calls inside a method to define its input set (i.e., the set of variables read) and output set (i.e., the set of variables written). Algorithm 3 shows the instructions executed when performing the data dependence analysis. The statement of the method call is retrieved; hence, the input set and the output set of the statement are defined. Therefore, for every following statement, the intersection between sets is computed; if the intersection has at least one element, the statement will be returned since it is the data-dependent statement where the synchronization must be inserted; conversely, the step goes to the next statement. If there is no data-dependent statement, the last statement of the method is returned. ```
functionDataDependenceAnalysis(m, mCall, ddStatement) \(s_{1}\gets getStatement(m,mCall)\) \(inputSetS_{1}\gets getInputSet(s_{1})\) \(outputSetS_{1}\gets getOutputSet(s_{1})\) \(index\gets indexOf(m,s_{1})\) for\(i\gets index+1,m.getStatements().length()-1\)do \(s_{2}\gets m.getStatements().get(i)\) \(inputSetS_{2}\gets getInputSet(s_{2})\) \(outputSetS_{2}\gets getOutputSet(s_{2})\) if\(checkIntersections(inputSetS_{1},outputSetS_{1},inputSetS_{2},outputSetS_{2})\)then return\(s_{2}\) endif endfor \(lastStatement\gets getLastStatement(m)\) return\(lastStatement\) endfunction
```  
**Algorithm 3** The instructions performed by the data dependence analysis. Listing 2 shows several statements. For lines with an assignment, such as lines 1 and 2, the output set consists of the variable being assigned and the variables modified by the called method, discovered by inspecting the called method. Hence, for line 1, the output set consists of variable le, and for line 2, the output set consists of variable in2; let us suppose that no variables are written in the called methods. The input set comprises all variablespassed to the called method and the variables read within the called method. Therefore, for line 1, the input set consists of the aMessage variable, and for line 2, its input set consists of the file2 variable; let us suppose that no variables are read in the called methods. For methods that are called on an instance, using a variable holding the reference, such as the calls at lines 3, 4, 5, and 6, the variable holding the reference is part of the input set, because when executing the method call, such a variable will be read to properly dispatch the message. Hence, variables buf and tp are the input sets for line 4, and variables implicitModel and tokenizer are the input sets for lines 5 and 6, respectively. For lines 3, 4, 5, and 6, their respective output sets will have all the variables written in the called method, along with the variables used to call the method (e.g., context for line 3, tp and buf for line 4, etc.) if the called method writes some of the attributes in the same instance. Once the said two sets are defined for the concerned statement, the analysis is repeated for every following statement to find any data dependencies. Listing 3 shows an example of the data dependence analysis. For line 74, method getRandomlyNamedLoggerContextVO() is the one we are analyzing, and the method call is found within a variable declaration expression; hence, as stated before, we consider this instruction feasible. Then, starting from line 75, the data dependence analysis is performed to find a data-dependent statement, which is found on line 79 because variable lvO is assigned to e.loggerContextVO field. The data-dependent statement represents the point where the main thread will have to wait for the forked thread to finish before it can continue with its execution. **Listing 3.