public void attachLivenessInfo(FlowGraph flowGraph, FlowGraphDecorator flowGraphDecorator) { for (Function function : flowGraph.getFunctions()) { // Perform liveness analysis TransferFunction<LiveVariableState> transferFunction = new LiveVariableTransferFunction(); BackwardAnalysis<LiveVariableState> analysis = new BackwardAnalysis<LiveVariableState>(flowGraphDecorator, function); Map<Node, LiveVariableState> states = analysis.solve(transferFunction); // Attach live variables to each basic block for (BasicBlock basicBlock : function.getBlocks()) { LiveVariableState state = transferFunction.join(flowGraphDecorator, states, basicBlock.getLastNode()); Set<Integer> liveVariables = state.getLiveVariables(); // NOTE: The EdgeTransfer function may use the conditional variable contained in an if node. // We check if the last node of the basic block is an if node, and if it is, we add // the conditional variable to the set of live variables. if (basicBlock.getLastNode() instanceof IfNode) { IfNode ifNode = (IfNode) basicBlock.getLastNode(); liveVariables.add(ifNode.getConditionVar()); } int[] result = new int[liveVariables.size()]; Iterator<Integer> iterator = liveVariables.iterator(); int i = 0; while (iterator.hasNext()) { result[i] = iterator.next(); i++; } basicBlock.setLiveVariables(result); } } }
/** 11.13 and 11.1.2 assignment with left-hand-side identifier reference. */ @Override public void visit(WriteVariableNode n, State state) { Value v = state.readRegister(n.getValueRegister()); m.visitWriteVariable(n, v, state); Set<ObjectLabel> objs = state.writeVariable(n.getVariableName(), v, true); Function f = n.getBlock().getFunction(); if (f.getParameterNames().contains(n.getVariableName())) { // TODO: review ObjectLabel arguments_obj = new ObjectLabel(f.getEntry().getFirstNode(), Kind.ARGUMENTS); state.writeProperty( arguments_obj, Integer.toString(f.getParameterNames().indexOf(n.getVariableName())), v); } m.visitPropertyWrite(n, objs, Value.makeTemporaryStr(n.getVariableName())); m.visitVariableOrProperty( n.getVariableName(), n.getSourceLocation(), v, state.getContext(), state); }
/** Transfer ordinary and exceptional return for the given call node and callee entry. */ public void transferReturn( AbstractNode call_node, BasicBlock callee_entry, Context caller_context, Context callee_context, Context edge_context) { if (call_node instanceof BeginForInNode) { for (EndForInNode endNode : ((BeginForInNode) call_node).getEndNodes()) { BasicBlock end_block = endNode.getBlock(); if (c.getAnalysisLatticeElement().getState(end_block, callee_context) != null) // (EndForInNode uses same context as corresponding BeginForInNode) c.addToWorklist(end_block, callee_context); } } else { // call_node is an ordinary call node Function callee = callee_entry.getFunction(); BasicBlock ordinary_exit = callee.getOrdinaryExit(); BasicBlock exceptional_exit = callee.getExceptionalExit(); State ordinary_exit_state = c.getAnalysisLatticeElement() .getState( ordinary_exit, callee_context); // (ReturnNode uses same context as corresponding function entry // node) State exceptional_exit_state = c.getAnalysisLatticeElement().getState(exceptional_exit, callee_context); NodeAndContext<Context> caller = new NodeAndContext<>(call_node, caller_context); if (ordinary_exit_state != null) { if (ordinary_exit.getFirstNode() instanceof ReturnNode) { ReturnNode returnNode = (ReturnNode) ordinary_exit.getFirstNode(); transferReturn( returnNode.getReturnValueRegister(), ordinary_exit, ordinary_exit_state.clone(), caller, edge_context); } else throw new AnalysisException("ReturnNode expected"); } if (exceptional_exit_state != null) { transferExceptionalReturn( exceptional_exit, exceptional_exit_state.clone(), caller, edge_context); } } }