Beispiel #1
0
  public RPST build() {
    // find canonical regions
    detectRegions();

    // build tree of canonical regions
    RPSTRegion root = new RPSTRegion(cfg.getEntryBlock(), null);
    buildRegionTree(cfg.getEntryBlock(), root);

    // build children
    for (RPSTRegion r : bb2region.values()) {
      for (RPSTRegion r2 = r; r2 != null; r2 = r2.parent) {
        if (r2.parent != null) {
          r2.parent.children.add(r2);
        }
      }
    }

    RPST rpst = new RPST(cfg, new RegionImpl(cfg.getEntryBlock(), null, ParentType.ROOT));
    Map<RPSTRegion, Region> mapR = new HashMap<>();
    a(root, rpst.getRootRegion(), rpst, mapR);
    for (Map.Entry<BasicBlock, RPSTRegion> entry : bb2region.entrySet()) {
      BasicBlock bb = entry.getKey();
      RPSTRegion r = entry.getValue();
      Region r2 = mapR.get(r);
      rpst.addRegion(bb, r2);
    }

    // add non canonical region to the tree
    findNonCanonicalRegions(rpst, rpst.getRootRegion());

    return rpst;
  }
Beispiel #2
0
 private void a(RPSTRegion r, Region r2, RPST rpst, Map<RPSTRegion, Region> mapR) {
   mapR.put(r, r2);
   for (RPSTRegion c : r.children) {
     Region c2 = new RegionImpl(c.entry, c.exit, ParentType.UNDEFINED);
     rpst.addRegion(c2, r2);
     a(c, c2, rpst, mapR);
   }
 }
Beispiel #3
0
  private void findNonCanonicalRegions(RPST rpst, Region region) {
    Set<Region> childrenBefore = new HashSet<>(rpst.getChildren(region));
    if (rpst.getChildCount(region) > 1) {
      boolean found = true;
      while (found) {
        found = false;

        // children ordered by dominance
        List<Region> children = new ArrayList<>(rpst.getChildren(region));
        Collections.sort(
            children,
            new Comparator<Region>() {
              @Override
              public int compare(Region region1, Region region2) {
                return getDomInfo().dominates(region1.getEntry(), region2.getEntry()) ? 1 : -1;
              }
            });

        for (Region child1 : children) {
          for (Region child2 : children) {
            if (!child1.equals(child2)) {
              if (isNonCanonicalRegion(rpst, child1, child2)) {
                Region newRegion =
                    new RegionImpl(child1.getEntry(), child2.getExit(), ParentType.UNDEFINED);
                LOGGER.debug("New non canonical region {}", newRegion);
                rpst.addRegion(newRegion, region);
                rpst.setNewParent(child1, newRegion);
                rpst.setNewParent(child2, newRegion);
                found = true;
                break;
              }
            }
          }
          if (found) {
            break;
          }
        }
      }
    }
    for (Region child : childrenBefore) {
      findNonCanonicalRegions(rpst, child);
    }
  }
Beispiel #4
0
 /** Test if two canonical regions could be merge in one non canonical region. */
 private boolean isNonCanonicalRegion(RPST rpst, Region region1, Region region2) {
   if (!region1.getExit().equals(region2.getEntry())) {
     return false;
   }
   if (rpst.getChildCount(region2) == 0) {
     return false;
   }
   // basic blocks of merged region
   Set<BasicBlock> basicBlocks = new HashSet<>();
   basicBlocks.addAll(rpst.getBasicBlocks(region1));
   basicBlocks.addAll(rpst.getBasicBlocks(region2));
   basicBlocks.add(region2.getExit());
   if (!basicBlocks.containsAll(cfg.getSuccessorsOf(region1.getExit()))) {
     return false;
   }
   if (!basicBlocks.containsAll(cfg.getPredecessorsOf(region1.getExit()))) {
     return false;
   }
   return true;
 }