public boolean applyTransferFunction() { BindingLoadPlacementProblem blp = (BindingLoadPlacementProblem) _prob; Set<Variable> reqdLoads = new HashSet<Variable>(_inReqdLoads); List<Instr> instrs = _bb.getInstrs(); ListIterator<Instr> it = instrs.listIterator(instrs.size()); while (it.hasPrevious()) { Instr i = it.previous(); if (i.operation == Operation.BINDING_STORE) continue; // Right away, clear the variable defined by this instruction -- it doesn't have to be loaded! Variable r = i.getResult(); if (r != null) reqdLoads.remove(r); // Process calls specially -- these are the sites of binding loads! if (i instanceof CallInstr) { CallInstr call = (CallInstr) i; Operand o = call.getClosureArg(); if ((o != null) && (o instanceof MetaObject)) { IRClosure cl = (IRClosure) ((MetaObject) o).scope; CFG cl_cfg = cl.getCFG(); BindingLoadPlacementProblem cl_blp = new BindingLoadPlacementProblem(); cl_blp.initLoadsOnScopeExit(reqdLoads); cl_blp.setup(cl_cfg); cl_blp.compute_MOP_Solution(); cl_cfg.setDataFlowSolution(cl_blp.getName(), cl_blp); if (call.requiresBinding()) { reqdLoads.clear(); } // Variables defined in the closure do not need to be loaded anymore at // program points before the call. Set<Variable> newReqdLoads = new HashSet<Variable>(reqdLoads); for (Variable v : reqdLoads) { if (cl_blp.scopeDefinesVariable(v)) newReqdLoads.remove(v); } reqdLoads = newReqdLoads; } // In this case, we are going to blindly load everything -- so, at the call site, pending // loads dont carry over! else if (call.requiresBinding()) { reqdLoads.clear(); } } // The variables used as arguments will need to be loaded for (Variable x : i.getUsedVariables()) { if (x instanceof LocalVariable) reqdLoads.add(x); } } // At the beginning of the scope, required loads can be discarded. if (_bb == _prob.getCFG().getEntryBB()) reqdLoads.clear(); if (_outReqdLoads.equals(reqdLoads)) { return false; } else { _outReqdLoads = reqdLoads; return true; } }
public void addLoads() { BindingLoadPlacementProblem blp = (BindingLoadPlacementProblem) _prob; IRExecutionScope s = blp.getCFG().getScope(); List<Instr> instrs = _bb.getInstrs(); ListIterator<Instr> it = instrs.listIterator(instrs.size()); Set<Variable> reqdLoads = new HashSet<Variable>(_inReqdLoads); while (it.hasPrevious()) { Instr i = it.previous(); if (i.operation == Operation.BINDING_STORE) continue; // Right away, clear the variable defined by this instruction -- it doesn't have to be loaded! Variable r = i.getResult(); if (r != null) reqdLoads.remove(r); if (i instanceof CallInstr) { CallInstr call = (CallInstr) i; Operand o = call.getClosureArg(); if ((o != null) && (o instanceof MetaObject)) { CFG cl_cfg = ((IRClosure) ((MetaObject) o).scope).getCFG(); BindingLoadPlacementProblem cl_blp = (BindingLoadPlacementProblem) cl_cfg.getDataFlowSolution(blp.getName()); // Only those variables that are defined in the closure, and are in the required loads set // will need to be loaded from the binding after the call! Set<Variable> newReqdLoads = new HashSet<Variable>(reqdLoads); it.next(); for (Variable v : reqdLoads) { if (cl_blp.scopeDefinesVariable(v)) { it.add(new LoadFromBindingInstr(v, s, v.getName())); it.previous(); newReqdLoads.remove(v); } } it.previous(); reqdLoads = newReqdLoads; // add loads in the closure ((BindingLoadPlacementProblem) cl_cfg.getDataFlowSolution(blp.getName())).addLoads(); } else if (call.requiresBinding()) { it.next(); for (Variable v : reqdLoads) { it.add(new LoadFromBindingInstr(v, s, v.getName())); it.previous(); } it.previous(); reqdLoads.clear(); } } // The variables used as arguments will need to be loaded for (Variable x : i.getUsedVariables()) { if (x instanceof LocalVariable) reqdLoads.add(x); } } // Load first use of variables in closures if ((s instanceof IRClosure) && (_bb == _prob.getCFG().getEntryBB())) { /** * System.out.println("\n[In Entry BB] For CFG " + _prob.getCFG() + ":"); * System.out.println("\t--> Reqd loads : " + java.util.Arrays.toString(reqdLoads.toArray())); */ for (Variable v : reqdLoads) { if (blp.scopeUsesVariable(v)) { it.add(new LoadFromBindingInstr(v, s, v.getName())); } } } }