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; }
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); } }
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); } }
/** 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; }