private BlockDataFlowState generateDFState(CFGBlock block) { int totalGlobals = this.uniqueGlobals.get(block.getMethodName()).size(); // Get the original inBitSet for this block BitSet origIn; if (this.cfgBlocksState.containsKey(block)) { origIn = this.cfgBlocksState.get(block).getIn(); } else { origIn = new BitSet(totalGlobals); origIn.set(0, totalGlobals); } // Calculate the in BitSet by taking intersection of predecessors BlockDataFlowState bFlow = new BlockDataFlowState(totalGlobals); // If there exist at least one successor, set Out to all True if (block.getSuccessors().size() > 0) { bFlow.getOut().set(0, totalGlobals); } BitSet out = bFlow.getOut(); for (CFGBlock pred : block.getSuccessors()) { if (this.cfgBlocksState.containsKey(pred)) { out.and(this.cfgBlocksState.get(pred).getIn()); } } calculateGenKillSets(block, bFlow); // Calculate Out BitSet in = bFlow.getIn(); // IN = (OUT - KILL) U GEN in.or(out); in.xor(bFlow.getKill()); in.or(bFlow.getGen()); if (!in.equals(origIn)) { // Add successors to cfgBlocks list for (CFGBlock pred : block.getPredecessors()) { if (!cfgBlocksToProcess.contains(pred)) { cfgBlocksToProcess.add(pred); } } } // Remove this block, since it has been processed cfgBlocksToProcess.remove(block); return bFlow; }
private void calculateGenKillSets(CFGBlock block, BlockDataFlowState bFlow) { for (int i = block.getStatements().size() - 1; i >= 0; i--) { LIRStatement stmt = block.getStatements().get(i); if (stmt.getClass().equals(QuadrupletStmt.class)) { QuadrupletStmt qStmt = (QuadrupletStmt) stmt; if (!qStmt.getDestination().getClass().equals(RegisterName.class)) { updateKillGenSet(block.getMethodName(), qStmt, bFlow); } } else if (stmt.getClass().equals(StoreStmt.class)) { updateKillGenSet(block.getMethodName(), (StoreStmt) stmt, bFlow); } else if (stmt.getClass().equals(CallStmt.class)) { updateKillGenSet(block.getMethodName(), (CallStmt) stmt, bFlow); } } }
private void setExitBlock(String methodName) { for (CFGBlock block : this.mMap.get(methodName).getCfgBlocks()) { if (block.getSuccessors().size() == 0) { // return block; CFGBlock exit = block; BlockDataFlowState entryBlockFlow = new BlockDataFlowState( this.uniqueGlobals.get(methodName).size()); // IN = GEN for entry block calculateGenKillSets(exit, entryBlockFlow); entryBlockFlow.setIn(entryBlockFlow.getGen()); cfgBlocksToProcess.remove(exit); this.cfgBlocksState.put(exit, entryBlockFlow); } } }
private void initialize(String methodName) { this.cfgBlocksToProcess.clear(); HashSet<Name> temp = new HashSet<Name>(); for (CFGBlock block : this.mMap.get(methodName).getCfgBlocks()) { List<LIRStatement> blockStmts = block.getStatements(); for (int i = 0; i < blockStmts.size(); i++) { LIRStatement stmt = blockStmts.get(i); if (stmt.getClass().equals(QuadrupletStmt.class)) { QuadrupletStmt qStmt = (QuadrupletStmt) stmt; if (qStmt.getDestination().isGlobal()) temp.add(qStmt.getDestination()); } else if (stmt.getClass().equals(StoreStmt.class)) { StoreStmt sStmt = (StoreStmt) stmt; temp.add(sStmt.getVariable()); } } this.cfgBlocksToProcess.add(block); } this.uniqueGlobals.put(methodName, new ArrayList<Name>()); this.uniqueGlobals.get(methodName).addAll(temp); }
private void optimize(CFGBlock block) { BlockDataFlowState bFlow = assignmentDefGenerator.getBlockAssignReachingDefs().get(block); QuadrupletStmt qStmt; PopStmt popStmt; PushStmt pushStmt; CmpStmt cStmt; Name newArg1, newArg2, dest; for (LIRStatement stmt : block.getStatements()) { // Reset kill set bFlow.getKill().clear(); if (stmt.getClass().equals(CallStmt.class)) { CallStmt callStmt = (CallStmt) stmt; if (callStmt.getMethodLabel().equals(ProgramFlattener.exceptionHandlerLabel)) continue; // Update BlockDataFlowState kill set assignmentDefGenerator.invalidateFunctionCall(bFlow); // Update BlockDataFlowState in set by using updated kill set bFlow.getIn().xor(bFlow.getKill()); } else if (stmt.getClass().equals(QuadrupletStmt.class)) { qStmt = (QuadrupletStmt) stmt; newArg1 = copyPropagateOnArg(qStmt.getArg1(), bFlow); if (newArg1 != null) { qStmt.setArg1(newArg1); } newArg2 = copyPropagateOnArg(qStmt.getArg2(), bFlow); if (newArg2 != null) { qStmt.setArg2(newArg2); } dest = qStmt.getDestination(); if (dest != null) { // Check if dest is ArrayName and try to optimize index if (dest.getClass().equals(ArrayName.class)) { Name arrIndex = ((ArrayName) dest).getIndex(); Name propagatedName = copyPropagateOnArg(arrIndex, bFlow); if (propagatedName != null) ((ArrayName) dest).setIndex(propagatedName); } } // Update BlockDataFlowState kill set assignmentDefGenerator.updateKillGenSet(dest, bFlow); // Update BlockDataFlowState in set by using updated kill set bFlow.getIn().xor(bFlow.getKill()); // Optimize PopStmt } else if (stmt.getClass().equals(PopStmt.class)) { popStmt = (PopStmt) stmt; newArg1 = copyPropagateOnArg(popStmt.getName(), bFlow); if (newArg1 != null) { popStmt.setName(newArg1); } // Optimize PushStmt } else if (stmt.getClass().equals(PushStmt.class)) { pushStmt = (PushStmt) stmt; newArg1 = copyPropagateOnArg(pushStmt.getName(), bFlow); if (newArg1 != null) { pushStmt.setName(newArg1); } // Optimize CmpStmt } else if (stmt.getClass().equals(CmpStmt.class)) { cStmt = (CmpStmt) stmt; newArg1 = copyPropagateOnArg(cStmt.getArg1(), bFlow); if (newArg1 != null) { cStmt.setArg1(newArg1); } newArg2 = copyPropagateOnArg(cStmt.getArg2(), bFlow); if (newArg2 != null) { cStmt.setArg2(newArg2); } } } }