public boolean definesLocalVariable(Variable v) { if (definedLocalVars == null) setUpUseDefLocalVarMaps(); if (definedLocalVars.contains(v)) return true; for (IRClosure cl : getClosures()) { if (cl.definesLocalVariable(v)) return true; } return false; }
public boolean canReceiveNonlocalReturns() { if (this.canReceiveNonlocalReturns) { return true; } boolean canReceiveNonlocalReturns = false; for (IRClosure cl : getClosures()) { if (cl.hasNonlocalReturns || cl.canReceiveNonlocalReturns()) { canReceiveNonlocalReturns = true; } } return canReceiveNonlocalReturns; }
// // This can help use eliminate writes to %block that are not used since this is // a special local-variable, not programmer-defined local-variable public void computeScopeFlags() { if (flagsComputed) { return; } // init canModifyCode = true; canCaptureCallersBinding = false; usesZSuper = false; usesEval = false; usesBackrefOrLastline = false; // NOTE: bindingHasEscaped is the crucial flag and it effectively is // unconditionally true whenever it has a call that receives a closure. // See CallInstr.computeRequiresCallersBindingFlag bindingHasEscaped = (this instanceof IREvalScript); // for eval scopes, bindings are considered escaped ... hasBreakInstrs = false; hasNonlocalReturns = false; canReceiveBreaks = false; canReceiveNonlocalReturns = false; // recompute flags -- we could be calling this method different times // definitely once after ir generation and local optimizations propagates constants locally // but potentially at a later time after doing ssa generation and constant propagation if (cfg == null) { computeScopeFlags(false, getInstrs()); } else { boolean receivesClosureArg = false; for (BasicBlock b : cfg.getBasicBlocks()) { receivesClosureArg = computeScopeFlags(receivesClosureArg, b.getInstrs()); } } // Compute flags for nested closures (recursively) and set derived flags. for (IRClosure cl : getClosures()) { cl.computeScopeFlags(); if (cl.hasBreakInstrs || cl.canReceiveBreaks) { canReceiveBreaks = true; } if (cl.hasNonlocalReturns || cl.canReceiveNonlocalReturns) { canReceiveNonlocalReturns = true; } if (cl.usesZSuper()) { usesZSuper = true; } } flagsComputed = true; }
public String toStringInstrs() { StringBuilder b = new StringBuilder(); int i = 0; for (Instr instr : instrList) { if (i > 0) b.append("\n"); b.append(" ").append(i).append('\t').append(instr); i++; } if (!nestedClosures.isEmpty()) { b.append("\n\n------ Closures encountered in this scope ------\n"); for (IRClosure c : nestedClosures) b.append(c.toStringBody()); b.append("------------------------------------------------\n"); } return b.toString(); }
public void setUpUseDefLocalVarMaps() { definedLocalVars = new java.util.HashSet<Variable>(); usedLocalVars = new java.util.HashSet<Variable>(); for (BasicBlock bb : cfg().getBasicBlocks()) { for (Instr i : bb.getInstrs()) { for (Variable v : i.getUsedVariables()) { if (v instanceof LocalVariable) usedLocalVars.add(v); } if (i instanceof ResultInstr) { Variable v = ((ResultInstr) i).getResult(); if (v instanceof LocalVariable) definedLocalVars.add(v); } } } for (IRClosure cl : getClosures()) { cl.setUpUseDefLocalVarMaps(); } }
/* Record an end block -- not all scope implementations can handle them */ @Override public void recordEndBlock(IRClosure endBlockClosure) { if (endBlocks == null) endBlocks = new ArrayList<IRClosure>(); endBlockClosure.setBeginEndBlock(); endBlocks.add(endBlockClosure); }
/* Record a begin block -- not all scope implementations can handle them */ @Override public void recordBeginBlock(IRClosure beginBlockClosure) { if (beginBlocks == null) beginBlocks = new ArrayList<IRClosure>(); beginBlockClosure.setBeginEndBlock(); beginBlocks.add(beginBlockClosure); }
public void resetDFProblemsState() { dfProbs = new HashMap<String, DataFlowProblem>(); for (IRClosure c : nestedClosures) c.resetDFProblemsState(); }