Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.ir.dataflow.analyses;
  
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
 
 public class LoadLocalVarPlacementNode extends FlowGraphNode {
     public LoadLocalVarPlacementNode(DataFlowProblem probBasicBlock n) {
         super(probn);
     }
 
     @Override
     public void init() {
          = new HashSet<LocalVariable>();
          = new HashSet<LocalVariable>();
     }
 
     public void buildDataFlowVars(Instr i) {
         // Nothing to do -- because we are going to simply use non-closure, non-self, non-block LocalVariables as our data flow variables
         // rather than build a new data flow type for it
     }
 
     public void initSolnForNode() {
         if ( == .getScope().cfg().getExitBB()) {
         }
     }
 
     public void compute_MEET(Edge eBasicBlock sourceFlowGraphNode pred) {
         LoadLocalVarPlacementNode n = (LoadLocalVarPlacementNodepred;
         .addAll(n.outRequiredLoads);
     }
 
     public boolean applyTransferFunction() {
         IRScope scope = .getScope();
         boolean scopeBindingHasEscaped = scope.bindingHasEscaped();
 
         Set<LocalVariable>  reqdLoads = new HashSet<LocalVariable>();
         List<Instr>         instrs    = .getInstrs();
         ListIterator<Instrit        = instrs.listIterator(instrs.size());
 
         while (it.hasPrevious()) {
             Instr i = it.previous();
             // System.out.println("-----\nInstr " + i);
             // System.out.println("Before: " + java.util.Arrays.toString(reqdLoads.toArray()));
 
             // Right away, clear the variable defined by this instruction -- it doesn't have to be loaded!
             if (i instanceof ResultInstrreqdLoads.remove(((ResultInstri).getResult());
 
             // Process calls specially -- these are the sites of binding loads!
             if (i instanceof CallBase) {
                 CallBase call = (CallBasei;
                 Operand o = call.getClosureArg(null);
                 if (o != null && o instanceof WrappedIRClosure) {
                     IRClosure cl = ((WrappedIRClosureo).getClosure();
 
                     // Variables defined in the closure do not need to be loaded anymore at
                     // program points before the call, because they will be loaded after the
                     // call completes to fetch the latest value.
                     //
                     // Allocate a new hash-set and modify it to get around ConcurrentModificationException on reqdLoads
                     Set<LocalVariablenewReqdLoads = new HashSet<LocalVariable>(reqdLoads);
                     for (LocalVariable vreqdLoads) {
                         if (cl.definesLocalVariable(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!
                 if (scopeBindingHasEscaped || call.targetRequiresCallersBinding()) {
                     reqdLoads.clear();
                 } else {
                     // All variables not defined in the current scope have to be always loaded
                     // because of multi-threading scenarios where some other scope
                     // could update this variable concurrently.
                     //
                     // Allocate a new hash-set and modify it to get around ConcurrentModificationException on reqdLoads
                     Set<LocalVariablenewReqdLoads = new HashSet<LocalVariable>(reqdLoads);
                    for (LocalVariable vreqdLoads) {
                        if (!scope.definesLocalVariable(v)) newReqdLoads.remove(v);
                    }
                    reqdLoads = newReqdLoads;
                }
            } else if (scopeBindingHasEscaped && (i.getOperation() == .)) {
                // global-var tracing can execute closures set up in previous trace-var calls
                // in which case we would have the 'scopeBindingHasEscaped' flag set to true
                reqdLoads.clear();
            }
            if (i.getOperation() == .) {
                LocalVariable lv = ((StoreLocalVarInstr)i).getLocalVar();
                if (!lv.isSelf()) reqdLoads.add(lv);
            } else {
                // The variables used as arguments will need to be loaded
                // %self is local to every scope and never crosses scope boundaries and need not be spilled/refilled
                for (Variable x : i.getUsedVariables()) {
                    if ((x instanceof LocalVariable) && !((LocalVariable)x).isSelf()) {
                        reqdLoads.add((LocalVariable)x);
                    }
                }
            }
            // System.out.println("After: " + java.util.Arrays.toString(reqdLoads.toArray()));
        }
        // At the beginning of the scope and rescue block entries, required loads can be discarded
        // since all these loads will be executed there.
        if (( == .getScope().cfg().getEntryBB()) || .isRescueEntry()) {
            reqdLoads.clear();
        }
        if (.equals(reqdLoads)) {
            //System.out.println("\n For CFG " + problem.getCFG() + " BB " + _bb.getID());
            //System.out.println("\t--> IN reqd loads   : " + java.util.Arrays.toString(_inReqdLoads.toArray()));
            //System.out.println("\t--> OUT reqd loads  : " + java.util.Arrays.toString(_outReqdLoads.toArray()));
            return false;
        } else {
             = reqdLoads;
            return true;
        }
    }
    @Override
    public String toString() {
        return "";
    }
    private TemporaryVariable getLocalVarReplacement(LocalVariable vIRScope scopeMap<OperandOperandvarRenameMap) {
         TemporaryVariable value = (TemporaryVariable)varRenameMap.get(v);
         if (value == null) {
             value = scope.getNewTemporaryVariable("%t_" + v.getName());
             varRenameMap.put(vvalue);
         }
         return value;
    }
    public void addLoads(Map<OperandOperandvarRenameMap) {
        IRScope scope                  = blp.getScope();
        boolean isEvalScript           = scope instanceof IREvalScript;
        boolean scopeBindingHasEscaped = scope.bindingHasEscaped();
        List<Instr>         instrs    = .getInstrs();
        ListIterator<Instrit        = instrs.listIterator(instrs.size());
        Set<LocalVariable>  reqdLoads = new HashSet<LocalVariable>();
        while (it.hasPrevious()) {
            Instr i = it.previous();
            // Right away, clear the variable defined by this instruction -- it doesn't have to be loaded!
            if (i instanceof ResultInstrreqdLoads.remove(((ResultInstri).getResult());
            if (i instanceof CallBase) {
                CallBase call = (CallBasei;
                Operand o = call.getClosureArg(null);
                if (o != null && o instanceof WrappedIRClosure) {
                    IRClosure cl = ((WrappedIRClosureo).getClosure();
                    // 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!  Rest can wait ..
                    //
                    // Allocate a new hash-set and modify it to get around ConcurrentModificationException on reqdLoads
                    Set<LocalVariablenewReqdLoads = new HashSet<LocalVariable>(reqdLoads);
                    it.next();
                    for (LocalVariable v : reqdLoads) {
                        if (cl.definesLocalVariable(v)) {
                            it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
                            it.previous();
                            newReqdLoads.remove(v);
                        }
                    }
                    it.previous();
                    reqdLoads = newReqdLoads;
                }
                // In this case, we are going to blindly load everything
                if (scopeBindingHasEscaped || call.targetRequiresCallersBinding()) {
                    it.next();
                    for (LocalVariable vreqdLoads) {
                        it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
                        it.previous();
                    }
                    it.previous();
                    reqdLoads.clear();
                } else {
                    // All variables not defined in the current scope have to be always loaded
                    // because of multi-threading scenarios where some other scope
                    // could update this variable concurrently.
                    //
                    // Allocate a new hash-set and modify it to get around ConcurrentModificationException on reqdLoads
                    Set<LocalVariablenewReqdLoads = new HashSet<LocalVariable>(reqdLoads);
                    it.next();
                    for (LocalVariable vreqdLoads) {
                        if (!scope.definesLocalVariable(v)) {
                            it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
                            it.previous();
                            newReqdLoads.remove(v);
                        }
                    }
                    it.previous();
                    reqdLoads = newReqdLoads;
                }
            } else if (scopeBindingHasEscaped && (i.getOperation() == .)) {
                // global-var tracing can execute closures set up in previous trace-var calls
                // in which case we would have the 'scopeBindingHasEscaped' flag set to true
                it.next();
                for (LocalVariable v : reqdLoads) {
                    it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
                    it.previous();
                }
                it.previous();
                reqdLoads.clear();
            }
            if (i.getOperation() == .) {
                LocalVariable lv = ((StoreLocalVarInstr)i).getLocalVar();
                if (!lv.isSelf()) {
                    reqdLoads.add(lv);
                    // SSS FIXME: Why is this reqd again?  Document with example
                    // Make sure there is a replacement var for all local vars
                    getLocalVarReplacement(lvscopevarRenameMap);
                }
            } else {
                // The variables used as arguments will need to be loaded
                // %self is local to every scope and never crosses scope boundaries and need not be spilled/refilled
                for (Variable v : i.getUsedVariables()) {
                    if (!(v instanceof LocalVariable)) continue;
                    LocalVariable lv = (LocalVariable)v;
                    if (!lv.isSelf()) {
                        reqdLoads.add(lv);
                        // SSS FIXME: Why is this reqd again?  Document with example
                        // Make sure there is a replacement var for all local vars
                        getLocalVarReplacement(lvscopevarRenameMap);
                    }
                }
            }
        }
        // Add loads on entry of a rescue block.
        if (.isRescueEntry()) {
            for (LocalVariable v : reqdLoads) {
                it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
            }
        }
        // Load first use of variables in closures
        if ((scope instanceof IRClosure) && ( == .getScope().cfg().getEntryBB())) {
            // System.out.println("\n[In Entry BB] For CFG " + problem.getScope().cfg() + ":");
            // System.out.println("\t--> Reqd loads   : " + java.util.Arrays.toString(reqdLoads.toArray()));
            for (LocalVariable v : reqdLoads) {
                if (scope.usesLocalVariable(v) || scope.definesLocalVariable(v)) {
                    if (isEvalScript || !(v instanceof ClosureLocalVariable) || (scope != ((ClosureLocalVariable)v).)) {
                        it.add(new LoadLocalVarInstr(scopegetLocalVarReplacement(vscopevarRenameMap), v));
                    }
                }
            }
        }
    }
    // On entry to flow graph node:  Variables that need to be loaded from the heap binding
    // On exit from flow graph node: Variables that need to be loaded from the heap binding
New to GrepCode? Check out our FAQ X