<commit_before>package wyil.transforms;

import java.util.*;


import static wyil.util.SyntaxError.*;
import static wyil.util.ErrorMessages.*;

import wyc.stages.BackPropagation.Env;
import wyil.ModuleLoader;
import wyil.lang.Block;
import wyil.lang.Code;
import wyil.lang.Module;
import wyil.lang.Type;
import wyil.lang.Block.Entry;
import wyil.util.dfa.*;

/**
 * <p>
 * Implements a classic live variables analysis to enable efficient reference
 * counting. Compound structures in Whiley (e.g. lists, sets, records, etc) are
 * <i>reference counted</i>. This means we count the number of aliases to them
 * in the heap and on the stack. Then, when a compound structure is updated, we
 * can perform an <i>inplace update</i> if the reference count is 1; otherwise,
 * we have to clone the structure. Cloning is potentially expensive, and we want
 * to avoid it as much as possible. Therefore, as soon as a variable is no
 * longer live, we should decrement its reference count. This is signalled using
 * the special <code>void</code> bytecode which, literally, "voids" a given
 * register thereby allowing us to release it.
 * </p>
 * <p>
 * The purpose of this class is to determine when a variable is live, and when
 * it is not. The live variables analysis operates as a backwards analysis,
 * propagating information from variable uses (i.e. <code>load</code> bytecodes)
 * back to their definitions (i.e. <code>store</code> bytecodes). For more
 * information on Live Variables Analysis, see <a
 * href="http://en.wikipedia.org/wiki/Live_variable_analysis">the Wikipedia
 * page</a>.
 * </p>
 * 
 * @author <NAME>, 2011
 * 
 */
public class LiveVariablesAnalysis extends BackwardFlowAnalysis<LiveVariablesAnalysis.Env>{
	private static final HashMap<Integer,Block.Entry> afterInserts = new HashMap<Integer,Block.Entry>();
	private static final HashMap<Integer,Block.Entry> rewrites = new HashMap<Integer,Block.Entry>();
	private static final HashSet<Integer> deadcode = new HashSet<Integer>();
	
	public LiveVariablesAnalysis(ModuleLoader loader) {
		super(loader);
	}	
	
	public Module.TypeDef transform(Module.TypeDef type) {		
		// TODO: back propagate through type constraints
		return type;		
	}
	
	/**
	 * Last store for the live variables analysis is empty, because all
	 * variables are considered to be dead at the end of a method/function.
	 * 
	 * @return
	 */
	@Override
	public Env lastStore() { return EMPTY_ENV; }
	
	@Override
	public Module.Case propagate(Module.Case mcase) {		

		// TODO: back propagate through pre- and post-conditions
		
		methodCase = mcase;
		stores = new HashMap<String,Env>();
		afterInserts.clear();
		rewrites.clear();
		Block body = mcase.body();
		Env environment = lastStore();		
		propagate(0,body.size(), environment);	
		
		// First, check and report any dead-code
		for(Integer i : deadcode) {
			syntaxError(errorMessage(DEAD_CODE),
					filename, body.get(i));		
		}
		
		// At this point, we apply the inserts	
		Block nbody = new Block(body.numInputs());		
		for(int i=0;i!=body.size();++i) {
			Block.Entry rewrite = rewrites.get(i);			
			if(rewrite != null) {								
				nbody.append(rewrite);				
			} else {
				nbody.append(body.get(i));
			}
			Block.Entry afters = afterInserts.get(i);			
			if(afters != null) {								
				nbody.append(afters);				
			} 							
		}
		
		return new Module.Case(nbody, mcase.precondition(),
				mcase.postcondition(), mcase.locals(), mcase.attributes());<commit_msg>Another bug fix for a stupid mistake in LiveVariablesAnalysis.<commit_after>package wyil.transforms;

import java.util.*;


import static wyil.util.SyntaxError.*;
import static wyil.util.ErrorMessages.*;

import wyc.stages.BackPropagation.Env;
import wyil.ModuleLoader;
import wyil.lang.Block;
import wyil.lang.Code;
import wyil.lang.Module;
import wyil.lang.Type;
import wyil.lang.Block.Entry;
import wyil.util.dfa.*;

/**
 * <p>
 * Implements a classic live variables analysis to enable efficient reference
 * counting. Compound structures in Whiley (e.g. lists, sets, records, etc) are
 * <i>reference counted</i>. This means we count the number of aliases to them
 * in the heap and on the stack. Then, when a compound structure is updated, we
 * can perform an <i>inplace update</i> if the reference count is 1; otherwise,
 * we have to clone the structure. Cloning is potentially expensive, and we want
 * to avoid it as much as possible. Therefore, as soon as a variable is no
 * longer live, we should decrement its reference count. This is signalled using
 * the special <code>void</code> bytecode which, literally, "voids" a given
 * register thereby allowing us to release it.
 * </p>
 * <p>
 * The purpose of this class is to determine when a variable is live, and when
 * it is not. The live variables analysis operates as a backwards analysis,
 * propagating information from variable uses (i.e. <code>load</code> bytecodes)
 * back to their definitions (i.e. <code>store</code> bytecodes). For more
 * information on Live Variables Analysis, see <a
 * href="http://en.wikipedia.org/wiki/Live_variable_analysis">the Wikipedia
 * page</a>.
 * </p>
 * 
 * @author <NAME>, 2011
 * 
 */
public class LiveVariablesAnalysis extends BackwardFlowAnalysis<LiveVariablesAnalysis.Env>{
	private static final HashMap<Integer,Block.Entry> afterInserts = new HashMap<Integer,Block.Entry>();
	private static final HashMap<Integer,Block.Entry> rewrites = new HashMap<Integer,Block.Entry>();
	private static final HashSet<Integer> deadcode = new HashSet<Integer>();
	
	public LiveVariablesAnalysis(ModuleLoader loader) {
		super(loader);
	}	
	
	public Module.TypeDef transform(Module.TypeDef type) {		
		// TODO: back propagate through type constraints
		return type;		
	}
	
	/**
	 * Last store for the live variables analysis is empty, because all
	 * variables are considered to be dead at the end of a method/function.
	 * 
	 * @return
	 */
	@Override
	public Env lastStore() { return EMPTY_ENV; }
	
	@Override
	public Module.Case propagate(Module.Case mcase) {		

		// TODO: back propagate through pre- and post-conditions
		
		methodCase = mcase;
		stores = new HashMap<String,Env>();
		afterInserts.clear();
		rewrites.clear();
		deadcode.clear();
		Block body = mcase.body();
		Env environment = lastStore();		
		propagate(0,body.size(), environment);	
		
		// First, check and report any dead-code
		for(Integer i : deadcode) {
			syntaxError(errorMessage(DEAD_CODE),
					filename, body.get(i));		
		}
		
		// At this point, we apply the inserts	
		Block nbody = new Block(body.numInputs());		
		for(int i=0;i!=body.size();++i) {
			Block.Entry rewrite = rewrites.get(i);			
			if(rewrite != null) {								
				nbody.append(rewrite);				
			} else {
				nbody.append(body.get(i));
			}
			Block.Entry afters = afterInserts.get(i);			
			if(afters != null) {								
				nbody.append(afters);				
			} 							
		}
		
		return new Module.Case(nbody, mcase.precondition(),
				mcase.postcondition(), mcase.locals(), mcase.attributes());
{'fraction_non_alphanumeric': 0.1116816431322208, 'fraction_numerical': 0.0019968620738838967, 'mean_word_length': 3.7700680272108844, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3098958', 'n_tokens_mistral': 2320, 'n_tokens_neox': 2053, 'n_words': 704}