1 salcianu 1.1.2.1  // Matching.java, created Fri Feb  4 16:16:27 2000 by salcianu
  2 cananian 1.1.2.11 // Copyright (C) 2000 Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
  3 salcianu 1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1.2.1  package harpoon.Analysis.PointerAnalysis;
  5 salcianu 1.1.2.1  
  6 salcianu 1.1.2.1  import java.util.Iterator;
  7 salcianu 1.1.2.1  import java.util.Enumeration;
  8 salcianu 1.1.2.1  import java.util.HashSet;
  9 salcianu 1.1.2.1  import java.util.Set;
 10 salcianu 1.1.2.1  
 11 salcianu 1.1.2.8  import harpoon.Util.DataStructs.Relation;
 12 salcianu 1.1.2.10 import harpoon.Util.DataStructs.RelationImpl;
 13 salcianu 1.1.2.10 
 14 salcianu 1.1.2.10 import harpoon.Util.Util;
 15 salcianu 1.1.2.8  
 16 salcianu 1.1.2.1  /**
 17 salcianu 1.1.2.1   * <code>Matching</code> is a wrapper for some functions related to the \
 18 salcianu 1.1.2.1   mapping of nodes due to the interaction of two entities: caller-callee \
 19 salcianu 1.1.2.1   interaction or interthread interaction.<br>
 20 salcianu 1.1.2.1  
 21 salcianu 1.1.2.4   There are five methods, each one implementing a specific rule:
 22 salcianu 1.1.2.4   <ul>
 23 salcianu 1.1.2.4   <li> Rule 0 was added by my to offer a transitive closure to the mapping
 24 salcianu 1.1.2.4   relation. <br>
 25 salcianu 1.1.2.4   <li> Rule 1 doesn't need to be implemented explicitly: we satisfy it by
 26 salcianu 1.1.2.4   starting with the initial mapping and adding stuff to it without ever
 27 salcianu 1.1.2.4   deleting an existent mapping between two nodes.<br>
 28 salcianu 1.1.2.4   <li> Rules 2 and 3 are like in the original paper.<br>
 29 salcianu 1.1.2.4   <li> Rules 22 and 32 are variations of 2 and 3 introduced by me to handle
 30 salcianu 1.1.2.4   the case when a scope reads an outside edges which is in fact an inside edge
 31 salcianu 1.1.2.4   from the same scope (because a thread running in parallel merged together
 32 salcianu 1.1.2.4   some nodes from the same scope). This rule is the logical companion
 33 salcianu 1.1.2.4   of rule 0.
 34 salcianu 1.1.2.4   </ul>
 35 salcianu 1.1.2.4  
 36 salcianu 1.1.2.4   All the methods have an identical interface. They are designed to be
 37 salcianu 1.1.2.4   used in an incremental manner: only the new mappings for <code>n1</code>
 38 salcianu 1.1.2.4   are used. The normal way to use them is in a fixed-point loop. The mappings
 39 salcianu 1.1.2.4   are updated according to the inference rules. If new mappings (i.e.
 40 salcianu 1.1.2.4   mappings that didn't exist previously) are generated those mappings are
 41 salcianu 1.1.2.4   also put in <code>new_info</code> so that they can be used in the new
 42 salcianu 1.1.2.4   interation of the loop. 
 43 salcianu 1.1.2.1   * 
 44 cananian 1.1.2.11  * @author  Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
 45 cananian 1.4       * @version $Id: Matching.java,v 1.4 2004/02/08 03:20:02 cananian Exp $
 46 salcianu 1.1.2.1   */
 47 salcianu 1.1.2.9  abstract class Matching implements java.io.Serializable {
 48 salcianu 1.1.2.1  
 49 salcianu 1.1.2.10     private static final boolean DEBUG = false;
 50 salcianu 1.1.2.10 
 51 salcianu 1.1.2.1      /** Applies rule 0: if there is a mu[i] relation from node1 to node2
 52 salcianu 1.1.2.1          and there is a mu[ib]/mu[i] relation from node2 to node3, then put a
 53 salcianu 1.1.2.1          mu[i] relation from node1 to node2.<br>
 54 salcianu 1.1.2.1          <i>Note</i>: you won't find this rule in the paper; it was added
 55 salcianu 1.1.2.1          by me to fix the algorithm. */
 56 salcianu 1.1.2.10     public static final void rule0
 57 salcianu 1.1.2.10         (Relation mu[], PAWorkList W[], Relation new_info[]) {
 58 salcianu 1.1.2.10         for(int i = 0; i < 2; i++) {
 59 salcianu 1.1.2.4              int ib = 1-i;
 60 cananian 1.4                  for(Object n1O : mu[i].keys()) {
 61 cananian 1.4                      PANode n1 = (PANode) n1O;
 62 salcianu 1.1.2.4  
 63 salcianu 1.1.2.4                  Set new_n1 = new HashSet();
 64 salcianu 1.1.2.10 
 65 salcianu 1.1.2.10                 Set debug_n2s = new HashSet(mu[i].getValues(n1));
 66 salcianu 1.1.2.10 
 67 cananian 1.4                      for(Object n2O : mu[i].getValues(n1)) {
 68 cananian 1.4                          PANode n2 = (PANode) n2O;
 69 salcianu 1.1.2.8                      new_n1.addAll(mu[i].getValues(n2));
 70 salcianu 1.1.2.8                      new_n1.addAll(mu[ib].getValues(n2));
 71 salcianu 1.1.2.4                  }
 72 salcianu 1.1.2.4                  
 73 cananian 1.4                      for(Object n3O : new_n1) {
 74 cananian 1.4                          PANode n3 = (PANode) n3O;
 75 salcianu 1.1.2.10                     if(mu[i].add(n1, n3)) {
 76 salcianu 1.1.2.10                         if(DEBUG)
 77 salcianu 1.1.2.10                             System.out.println("rule0: " + n1 + " -> " + n3);
 78 salcianu 1.1.2.10                         W[i].add(n1);
 79 salcianu 1.1.2.10                         new_info[i].add(n1, n3);
 80 salcianu 1.1.2.10                     }
 81 salcianu 1.1.2.10                 }
 82 salcianu 1.1.2.4              }
 83 salcianu 1.1.2.4          }
 84 salcianu 1.1.2.4      }
 85 salcianu 1.1.2.1  
 86 salcianu 1.1.2.1  
 87 salcianu 1.1.2.1      /** Applies rule 2: matches an outside edge starting from node1 in 
 88 salcianu 1.1.2.1          pig[i] against an inside edge in pig[ib]. As a result, some possibly
 89 salcianu 1.1.2.1          new mappings for node2 will be generated and put in mu[i].
 90 salcianu 1.1.2.1          This rule is designed to be used in an incremental manner: it works
 91 salcianu 1.1.2.1          only with the new mappings of node1. All the new mappings for node2
 92 salcianu 1.1.2.1          will also be put in new_info[i]. If such new mappings appear, 
 93 salcianu 1.1.2.1          all the instances of node2 are added to W[i].*/
 94 salcianu 1.1.2.2      public static final void rule2(PANode node1, Set new_mappings_for_node1,
 95 salcianu 1.1.2.2                     ParIntGraph pig[],
 96 salcianu 1.1.2.1                     PAWorkList W[], Relation mu[], Relation new_info[], 
 97 salcianu 1.1.2.10                    int i, int ib) {
 98 salcianu 1.1.2.1          // nodes3 stands for all the new instances of n3
 99 salcianu 1.1.2.1          // from the inference rule
100 salcianu 1.1.2.2          Set nodes3 = new_mappings_for_node1;
101 salcianu 1.1.2.1  
102 salcianu 1.1.2.10         /*
103 salcianu 1.1.2.10         System.out.println("rule2: node1 = " + node1 + " nodes3 = " + nodes3 +
104 salcianu 1.1.2.10                            " i=" + i + " ib=" + ib);
105 salcianu 1.1.2.10         */
106 salcianu 1.1.2.10 
107 cananian 1.4              for (Object fO : pig[i].G.O.allFlagsForNode(node1)) {
108 cananian 1.4                  String f = (String) fO;
109 salcianu 1.1.2.10 
110 salcianu 1.1.2.1              // nodes2 stands for all the nodes that could play
111 salcianu 1.1.2.1              // the role of n2 from the inference rule
112 salcianu 1.1.2.10             Set nodes2 = pig[i].G.O.pointedNodes(node1, f);
113 salcianu 1.1.2.1              if(nodes2.isEmpty()) continue;
114 salcianu 1.1.2.10 
115 salcianu 1.1.2.1              // nodes4 stands for all the nodes that could play
116 salcianu 1.1.2.1              // the role of n4 from the inference rule
117 salcianu 1.1.2.10             Set nodes4 = pig[ib].G.I.pointedNodes(nodes3, f);
118 salcianu 1.1.2.1              if(nodes4.isEmpty()) continue;
119 salcianu 1.1.2.1  
120 salcianu 1.1.2.1              // set up the relation mu[i] from any node from nodes2
121 salcianu 1.1.2.1              // to any node from nodes4
122 cananian 1.4                  for(Object node2O : nodes2) {
123 cananian 1.4                      PANode node2 = (PANode) node2O;
124 salcianu 1.1.2.1                  boolean changed = false;
125 cananian 1.4                      for(Object node4O : nodes4) {
126 cananian 1.4                          PANode node4 = (PANode) node4O;
127 salcianu 1.1.2.10                     if(mu[i].add(node2, node4)) {
128 salcianu 1.1.2.10                         if(DEBUG)
129 salcianu 1.1.2.10                             System.out.println
130 salcianu 1.1.2.10                                 (node2 + " -" + i + "-> " + node4);
131 salcianu 1.1.2.1                          changed = true;
132 salcianu 1.1.2.7                          new_info[i].add(node2, node4);
133 salcianu 1.1.2.1                      }
134 salcianu 1.1.2.1                  }
135 salcianu 1.1.2.1                  // nodes with new info are put in the worklist
136 salcianu 1.1.2.1                  if(changed) W[i].add(node2);
137 salcianu 1.1.2.1              }
138 salcianu 1.1.2.1          }
139 salcianu 1.1.2.1      }
140 salcianu 1.1.2.1  
141 salcianu 1.1.2.4  
142 salcianu 1.1.2.4  
143 salcianu 1.1.2.4      // TAKE CARE: THREAD UNSAFE
144 salcianu 1.1.2.4      // these prealocated objects gain us some efficiency, they are used
145 salcianu 1.1.2.4      // in rule 22 and rule 32, only to search into the edge ordering relation
146 salcianu 1.1.2.4      static PAEdge inside_edge  = new PAEdge(null, "", null);
147 salcianu 1.1.2.5      static PAEdge out_edge = new PAEdge(null, "", null);
148 salcianu 1.1.2.4  
149 salcianu 1.1.2.4      /** Applies rule 22: matches an outside edge starting from node1 in 
150 salcianu 1.1.2.4          pig[i] against an inside edge from pig[i] (the same analysis scope).
151 salcianu 1.1.2.4          To preserve some precision, rule 22 consider only inside edges that
152 salcianu 1.1.2.4          could be created before the outside edge is read (the edge ordering
153 salcianu 1.1.2.4          info helps us a lot).<br>
154 salcianu 1.1.2.4          Some (new) mappings for node2 will be generated and put in mu[i].
155 salcianu 1.1.2.1          This rule is designed to be used in an incremental manner: it works
156 salcianu 1.1.2.4          only with the new mappings of node1. All the new mappings for node2
157 salcianu 1.1.2.4          will also be put in new_info[i]. If such new mappings appear, 
158 salcianu 1.1.2.4          all the instances of node2 are added to W[i].*/
159 salcianu 1.1.2.4      public static final void rule22(PANode node1, Set new_mappings_for_node1,
160 salcianu 1.1.2.2                     ParIntGraph pig[],
161 salcianu 1.1.2.1                     PAWorkList W[], Relation mu[], Relation new_info[], 
162 salcianu 1.1.2.1                     int i, int ib){
163 salcianu 1.1.2.1          // nodes3 stands for all the new instances of n3
164 salcianu 1.1.2.1          // from the inference rule
165 salcianu 1.1.2.2          Set nodes3 = new_mappings_for_node1;
166 salcianu 1.1.2.1  
167 salcianu 1.1.2.5          out_edge.n1 = node1;
168 salcianu 1.1.2.4  
169 cananian 1.4              for (Object fO : pig[i].G.O.allFlagsForNode(node1)) {
170 cananian 1.4                  String f = (String) fO;
171 salcianu 1.1.2.7  
172 salcianu 1.1.2.1              // nodes2 stands for all the nodes that could play
173 salcianu 1.1.2.1              // the role of n2 from the inference rule
174 salcianu 1.1.2.4              Set nodes2 = pig[i].G.O.pointedNodes(node1,f);
175 salcianu 1.1.2.1              if(nodes2.isEmpty()) continue;
176 salcianu 1.1.2.1              
177 salcianu 1.1.2.5              out_edge.f = f;
178 cananian 1.4                  for(Object node2O : nodes2) {
179 cananian 1.4                      PANode node2 = (PANode) node2O;
180 salcianu 1.1.2.5                  out_edge.n2 = node2;
181 salcianu 1.1.2.1  
182 salcianu 1.1.2.1                  boolean changed = false;
183 salcianu 1.1.2.4  
184 salcianu 1.1.2.4                  // analyze the inside edges that are already created when
185 salcianu 1.1.2.4                  // outside edge is read.
186 salcianu 1.1.2.5  
187 salcianu 1.1.2.5                  Iterator it_edges = null;
188 salcianu 1.1.2.5  
189 salcianu 1.1.2.5                  if(PointerAnalysis.IGNORE_EO)
190 salcianu 1.1.2.7                      it_edges = 
191 salcianu 1.1.2.7                    pig[i].G.I.getEdgesFrom(out_edge.n1, out_edge.f).iterator();
192 salcianu 1.1.2.5                  else
193 salcianu 1.1.2.5                      it_edges = pig[i].eo.getBeforeEdges(out_edge);
194 salcianu 1.1.2.5  
195 salcianu 1.1.2.4                  while(it_edges.hasNext()){
196 salcianu 1.1.2.4                      PAEdge inside_edge = (PAEdge) it_edges.next();
197 salcianu 1.1.2.4                      // only edges started in one of the possible node3 nodes
198 salcianu 1.1.2.4                      if(!nodes3.contains(inside_edge.n1)) continue;
199 salcianu 1.1.2.4                      PANode node4 = inside_edge.n2;
200 salcianu 1.1.2.4                      if(mu[i].add(node2,node4)){
201 salcianu 1.1.2.1                          changed = true;
202 salcianu 1.1.2.4                          new_info[i].add(node2,node4);
203 salcianu 1.1.2.1                      }
204 salcianu 1.1.2.1                  }
205 salcianu 1.1.2.1                  // nodes with new info are put in the worklist
206 salcianu 1.1.2.4                  if(changed) W[i].add(node2);
207 salcianu 1.1.2.4              }
208 salcianu 1.1.2.4          }
209 salcianu 1.1.2.4      }
210 salcianu 1.1.2.4  
211 salcianu 1.1.2.4  
212 salcianu 1.1.2.4      /** Applies rule 3: matches an inside edge starting from node1 in 
213 salcianu 1.1.2.4          pig[i] against an outside edge in pig[ib]. As a result, some possibly
214 salcianu 1.1.2.4          new mappings for node4 will be generated and put in mu[ib].
215 salcianu 1.1.2.4          This rule is designed to be used in an incremental manner: it works
216 salcianu 1.1.2.4          only with the new mappings of node1. All the new mappings for node4
217 salcianu 1.1.2.4          will also be put in new_info[ib]. If such new mappings appear, 
218 salcianu 1.1.2.4          all the instances of node4 are added to W[ib].*/
219 salcianu 1.1.2.4      public static final void rule3(PANode node1, Set new_mappings_for_node1,
220 salcianu 1.1.2.4                     ParIntGraph pig[],
221 salcianu 1.1.2.4                     PAWorkList W[], Relation mu[], Relation new_info[], 
222 salcianu 1.1.2.4                     int i, int ib){
223 salcianu 1.1.2.4          // nodes3 stands for all the new instances of n3
224 salcianu 1.1.2.4          // from the inference rule
225 salcianu 1.1.2.4          Set nodes3 = new_mappings_for_node1;
226 salcianu 1.1.2.4  
227 cananian 1.4              for (Object fO : pig[i].G.I.allFlagsForNode(node1)) {
228 cananian 1.4                  String f = (String) fO;
229 salcianu 1.1.2.4              
230 salcianu 1.1.2.4              // nodes2 stands for all the nodes that could play
231 salcianu 1.1.2.4              // the role of n2 from the inference rule
232 salcianu 1.1.2.4              Set nodes2 = pig[i].G.I.pointedNodes(node1,f);
233 salcianu 1.1.2.4              if(nodes2.isEmpty()) continue;
234 salcianu 1.1.2.4              
235 salcianu 1.1.2.4              // nodes4 stands for all the nodes that could play
236 salcianu 1.1.2.4              // the role of n4 from the inference rule
237 salcianu 1.1.2.4              Set nodes4 = pig[ib].G.O.pointedNodes(nodes3,f);
238 salcianu 1.1.2.4              if(nodes4.isEmpty()) continue;
239 salcianu 1.1.2.4  
240 salcianu 1.1.2.4              // set up the relation mu[ib] from any node from nodes4
241 salcianu 1.1.2.4              // to any node from nodes2
242 cananian 1.4                  for(Object node4O : nodes4) {
243 cananian 1.4                      PANode node4 = (PANode) node4O;
244 salcianu 1.1.2.4                  boolean changed = false;
245 cananian 1.4                      for(Object node2O : nodes2) {
246 cananian 1.4                          PANode node2 = (PANode) node2O;
247 salcianu 1.1.2.7                      if(mu[ib].add(node4, node2)){
248 salcianu 1.1.2.4                          changed = true;
249 salcianu 1.1.2.7                          new_info[ib].add(node4, node2);
250 salcianu 1.1.2.4                      }
251 salcianu 1.1.2.4                  }
252 salcianu 1.1.2.4                  // nodes with new info are put in the worklist
253 salcianu 1.1.2.4                  if(changed) W[ib].add(node4);
254 salcianu 1.1.2.4              }
255 salcianu 1.1.2.4          }       
256 salcianu 1.1.2.4      }
257 salcianu 1.1.2.4  
258 salcianu 1.1.2.4  
259 salcianu 1.1.2.4      /** Applies rule 32: matches an inside edge starting from node1 in 
260 salcianu 1.1.2.4          pig[i] against an outside edge in pig[i] (the same analysis scope). 
261 salcianu 1.1.2.4          To preserve some precision, rule 32 consider only inside edges that
262 salcianu 1.1.2.4          could be created before the outside edge is read (the edge ordering
263 salcianu 1.1.2.4          info helps us a lot).<br>
264 salcianu 1.1.2.4          Some (new) mappings for node2 will be generated and put in mu[i].
265 salcianu 1.1.2.4          This rule is designed to be used in an incremental manner: it works
266 salcianu 1.1.2.4          only with the new mappings of node1. All the new mappings for node2
267 salcianu 1.1.2.4          will also be put in new_info[i]. If such new mappings appear, 
268 salcianu 1.1.2.4          all the instances of node2 are added to W[i].*/
269 salcianu 1.1.2.4      public static final void rule32(PANode node1, Set new_mappings_for_node1,
270 salcianu 1.1.2.4                     ParIntGraph pig[],
271 salcianu 1.1.2.4                     PAWorkList W[], Relation mu[], Relation new_info[], 
272 salcianu 1.1.2.4                     int i, int ib){
273 salcianu 1.1.2.4          // nodes3 stands for all the new instances of n3
274 salcianu 1.1.2.4          // from the inference rule
275 salcianu 1.1.2.4          Set nodes3 = new_mappings_for_node1;
276 salcianu 1.1.2.4  
277 salcianu 1.1.2.4          inside_edge.n1 = node1;
278 salcianu 1.1.2.4  
279 cananian 1.4              for (Object fO : pig[i].G.I.allFlagsForNode(node1)) {
280 cananian 1.4                  String f = (String) fO;
281 salcianu 1.1.2.4              
282 salcianu 1.1.2.4              inside_edge.f  = f;
283 salcianu 1.1.2.5              out_edge.f = f;
284 salcianu 1.1.2.4  
285 salcianu 1.1.2.4              // nodes2 stands for all the nodes that could play
286 salcianu 1.1.2.4              // the role of n2 from the inference rule
287 salcianu 1.1.2.4              Set nodes2 = pig[i].G.I.pointedNodes(node1,f);
288 salcianu 1.1.2.4              if(nodes2.isEmpty()) continue;
289 salcianu 1.1.2.4              
290 cananian 1.4                  for(Object node3O : nodes3) {
291 cananian 1.4                      PANode node3 = (PANode) node3O;
292 salcianu 1.1.2.5                  out_edge.n1 = node3;
293 salcianu 1.1.2.4  
294 cananian 1.4                      for (Object node4O : pig[i].G.O.pointedNodes(node3,f)){
295 cananian 1.4                          PANode node4 = (PANode) node4O;
296 salcianu 1.1.2.5                      out_edge.n2 = node4;
297 salcianu 1.1.2.4                      
298 cananian 1.4                          for(Object node2O : nodes2) {
299 cananian 1.4                              PANode node2 = (PANode) node2O;
300 salcianu 1.1.2.4                          inside_edge.n2 = node2;
301 salcianu 1.1.2.4  
302 salcianu 1.1.2.5                          if(PointerAnalysis.IGNORE_EO || 
303 salcianu 1.1.2.5                             pig[i].eo.wasBefore(inside_edge, out_edge))
304 salcianu 1.1.2.4                              if(mu[ib].add(node4,node2)){
305 salcianu 1.1.2.4                                  new_info[ib].add(node4,node2);
306 salcianu 1.1.2.4                                  W[i].add(node4);
307 salcianu 1.1.2.4                              }
308 salcianu 1.1.2.4                      }
309 salcianu 1.1.2.4                  }
310 salcianu 1.1.2.1              }
311 salcianu 1.1.2.4          }
312 salcianu 1.1.2.1      }
313 salcianu 1.1.2.1  
314 salcianu 1.1.2.1  
315 salcianu 1.1.2.10     // Extends the mapping mu to cope with aliasing into the same scope
316 salcianu 1.1.2.10     public static final void aliasingSameScopeRule
317 salcianu 1.1.2.10         (Relation mu, ParIntGraph pig, PAWorkList W, Relation new_info) {
318 salcianu 1.1.2.10 
319 salcianu 1.1.2.10         Relation um = new RelationImpl();
320 salcianu 1.1.2.10         mu.revert(um);
321 salcianu 1.1.2.10         
322 cananian 1.4              for(Object node5O : um.keys()) {
323 cananian 1.4                  PANode node5 = (PANode) node5O;
324 salcianu 1.1.2.10             Set n1n3 = um.getValues(node5);
325 salcianu 1.1.2.10             if(n1n3.size() < 2) continue;
326 salcianu 1.1.2.10 
327 cananian 1.4                  for(Object node1O : n1n3) {
328 cananian 1.4                      PANode node1 = (PANode) node1O;
329 cananian 1.4                      for(Object node3O : n1n3) {
330 cananian 1.4                          PANode node3 = (PANode) node3O;
331 salcianu 1.1.2.10                     if(node1 == node3) continue;
332 salcianu 1.1.2.10                     aliasingSameScopeRule(node1, node3, mu, pig, W, new_info);
333 salcianu 1.1.2.10                 }
334 salcianu 1.1.2.10             }
335 salcianu 1.1.2.10         }
336 salcianu 1.1.2.10     }
337 salcianu 1.1.2.10 
338 salcianu 1.1.2.10 
339 salcianu 1.1.2.10     // AUX METHOD FOR aliasingSameScopeRule
340 salcianu 1.1.2.10     // Extends the mapping mu to cope with aliasing between node1 and node3
341 salcianu 1.1.2.10     private static final void aliasingSameScopeRule
342 salcianu 1.1.2.10         (PANode node1, PANode node3,
343 salcianu 1.1.2.10          Relation mu, ParIntGraph pig, PAWorkList W, Relation new_info) {
344 salcianu 1.1.2.10 
345 salcianu 1.1.2.10         if(DEBUG)
346 salcianu 1.1.2.10             System.out.println("aliasingSameScopeRule: node1 = " + node1 +
347 salcianu 1.1.2.10                                " node3 = " + node3);
348 salcianu 1.1.2.10 
349 cananian 1.4              for (Object fO : pig.G.I.allFlagsForNode(node3)) {
350 cananian 1.4                  String f = (String) fO;
351 salcianu 1.1.2.10 
352 salcianu 1.1.2.10             Set nodes2 = pig.G.O.pointedNodes(node1, f);
353 salcianu 1.1.2.10             if(nodes2.isEmpty()) continue;
354 salcianu 1.1.2.1  
355 salcianu 1.1.2.10             Set nodes4 = pig.G.I.pointedNodes(node3, f);
356 salcianu 1.1.2.10             if(nodes4.isEmpty()) continue;
357 salcianu 1.1.2.1  
358 salcianu 1.1.2.10             Set mu_nodes4 = new HashSet();
359 cananian 1.4                  for(Object node4O : nodes4) {
360 cananian 1.4                      PANode node4 = (PANode) node4O;
361 salcianu 1.1.2.10                 mu_nodes4.addAll(mu.getValues(node4));
362 salcianu 1.1.2.10             }
363 salcianu 1.1.2.10 
364 cananian 1.4                  for(Object node2O : nodes2) {
365 cananian 1.4                      PANode node2 = (PANode) node2O;
366 salcianu 1.1.2.10 
367 cananian 1.4                      for(Object node6O : mu_nodes4) {
368 cananian 1.4                          PANode node6 = (PANode) node6O;
369 salcianu 1.1.2.10                     if(mu.add(node2, node6)) {
370 salcianu 1.1.2.10                         if(DEBUG)
371 salcianu 1.1.2.10                             System.out.println("  " + node2 + " -> " + node6);
372 salcianu 1.1.2.10                         W.add(node2);
373 salcianu 1.1.2.10                         new_info.add(node2, node6);
374 salcianu 1.1.2.10                     }
375 salcianu 1.1.2.10                 }
376 salcianu 1.1.2.10 
377 salcianu 1.1.2.10 
378 salcianu 1.1.2.10                 if(InterThreadPA.VERY_NEW_MAPPINGS) {
379 cananian 1.4                          for(Object node4O : nodes4) {
380 cananian 1.4                              PANode node4 = (PANode) node4O;
381 salcianu 1.1.2.10                         if(mu.add(node2, node4)) {
382 salcianu 1.1.2.10                             if(DEBUG)
383 salcianu 1.1.2.10                                 System.out.println
384 salcianu 1.1.2.10                                     ("  " + node2 + " -> " + node4);
385 salcianu 1.1.2.10                             W.add(node2);
386 salcianu 1.1.2.10                             new_info.add(node2, node4);
387 salcianu 1.1.2.10                         }
388 salcianu 1.1.2.10                     }
389 salcianu 1.1.2.10                 }
390 salcianu 1.1.2.10             }
391 salcianu 1.1.2.10         }
392 salcianu 1.1.2.10     }
393 salcianu 1.1.2.10 
394 cananian 1.2      }