Example: Using Variables

In quad format, variables are stored in pseudo-registers. There are an infinite number of pseudo-registers. Pseudo-registers have an associated type: int, float, long, double, or object reference.

We will compute for each pseudo-register the set of quads that define that register ('def' set) and the set of quads that use that register ('use' set). This can be used, for example, to calculate 'gen' and 'kill' sets in the reaching definition dataflow problem.

This, again, is a flow-insensitive problem. We don't need to know about the basic blocks, so we simply make a quad visitor.

import joeq.Class.*;
import joeq.Compiler.Quad.*;
import joeq.Main.Helper;
import joeq.Util.Templates.ListIterator;
import java.util.*;
 
public class FindDefsAndUses extends QuadVisitor.EmptyVisitor {
    
    private Map registersToDefs=new HashMap(); // Register -> List
    private Map registersToUses=new HashMap(); // Register -> List
 
    public void visitQuad(Quad q) {
        ListIterator.RegisterOperand i = 
            q.getDefinedRegisters().registerOperandIterator();
        while (i.hasNext())
            addToMultiMap(registersToDefs, 
                         i.nextRegisterOperand().getRegister(), q);
        ListIterator.RegisterOperand j = 
            q.getUsedRegisters().registerOperandIterator();
 
        while (j.hasNext())
            addToMultiMap(registersToUses, 
                         j.nextRegisterOperand().getRegister(), q);
    }
    private void addToMultiMap(Map m, Object key, Object value) {
        List s = (List)m.get(key);
        if (s == null) m.put(key, s = new LinkedList());
        s.add(value);
    }
    public String toString() { 
        return "Defs: "+registersToDefs+
            "\nUses: "+registersToUses; 
    }
 
    public static void main(String[] args) {
        jq_Class[] c = new jq_Class[args.length];
        for (int i = 0; i < args.length; i++) {
            c[i] = (jq_Class)Helper.load(args[i]);
        }
 
        FindDefsAndUses fdu = new FindDefsAndUses();
 
        for (int i = 0; i < args.length; i++) {
            Helper.runPass(c[i], fdu);
        }
 
        System.out.println(fdu.toString());
    }
}

The important point is that quads include methods getDefinedRegisters() and getUsedRegisters() that return a list of registers that are defined/used by that quad. The visitQuad method simply iterates over those lists and adds the quads to a multi-map keyed on the register.

<-- previous home next -->