Package compiler.liveness

Source Code of compiler.liveness.LivenessAnalyser

package compiler.liveness;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

import compiler.asmcode.AsmInstr;
import compiler.asmcode.AsmLABEL;
import compiler.asmcode.AsmMOVE;
import compiler.frames.Label;
import compiler.frames.Temp;

public class LivenessAnalyser
{
  private static class Instruction
  {
    private AsmInstr instruction = null;
   
    private LinkedList<Instruction> prev;
    private LinkedList<Instruction> next;
   
    private HashSet<Temp> in = null;
    private HashSet<Temp> out = null;
   
    private boolean changed = false;
   
    public Instruction(AsmInstr instruction)
    {
      this.instruction = instruction;
     
      in = new HashSet<Temp>();
      out = new HashSet<Temp>();
      prev = new LinkedList<Instruction>();
      next = new LinkedList<Instruction>();
    }
   
    public void addIn(Temp var)
    {
      if (!in.contains(var))
      {
        in.add(var);
        this.changed = true;
      }
    }
   
    public void addOut(Temp var)
    {
      if (!out.contains(var))
      {
        out.add(var);
        this.changed = true;
      }
    }
   
    public void addNext(Instruction ins)
    {
      next.add(ins);
    }
   
    public void addPred(Instruction ins)
    {
      prev.add(ins);
    }
   
    public AsmInstr getInstruction()
    {
      return instruction;
    }

    public HashSet<Temp> getIn()
    {
      return in;
    }

    public HashSet<Temp> getOut()
    {
      return out;
    }

    public LinkedList<Instruction> getNexts()
    {
      return next;
    }

    public void reset()
    {
      this.changed = false;
    }
   
    public boolean hasChanged()
    {
      return this.changed;
    }
  }
 
  public static LinkedList<LivenessEdge> analyze(LinkedList<AsmInstr> asmCode)
  {
   
   
    // Create instruction list table and populate it
    LinkedList<Instruction> instructionList = new LinkedList<Instruction>();
   
    // Build code execution graph
    HashMap<Label, Instruction> labels = new HashMap<Label, Instruction>();
   
    // Dummy first instruction
    Instruction previousInstr = null;
   
    // Find labels
    for (AsmInstr instr : asmCode)
    {
      // Add labels to labels map
      if (instr instanceof AsmLABEL)
      {
        labels.put(((AsmLABEL)instr).labels.get(0), new Instruction(instr));
      }
    }
   
    for (AsmInstr instr : asmCode)
    {
      Instruction instruction = null;
     
      // Grab previously created instruction object if the AsmInstr is a label
      if (instr instanceof AsmLABEL)
      {
        instruction = labels.get(instr.labels.get(0));
      }
      else
      {
        instruction = new Instruction(instr);
      }
     
      // Add to flat instruction list
      instructionList.add(instruction);
   
      // Link instructions
      if (previousInstr != null)
      {
        previousInstr.addNext(instruction);
        instruction.addPred(previousInstr);
      }
     
      // Link labeled instructions
        if (!(instr instanceof AsmLABEL) && !instr.labels.isEmpty())
      {
        for (Label lbl : instr.labels)
        {
          if (!labels.containsKey(lbl))
            continue;
         
          labels.get(lbl).addPred(instruction);
          instruction.addNext(labels.get(lbl));
        }
      }
       
        previousInstr = instruction;
    }   
   
    // Repeat algorithm until there are changes made
    do
    {
      // Reset changed counters for instructions
      resetInstructionChangedStatus(instructionList);
     
      for (Instruction instr : instructionList)
      {
        // Add all used to IN
        for (Temp use : instr.getInstruction().uses)
        {
          instr.addIn(use);
        }
       
        // Add all "out but not defined" to IN
        for (Temp out : instr.getOut())
        {
          if (!instr.getInstruction().defs.contains(out))
          {
            instr.addIn(out);
          }
        }
       
        // Add all ins of next commands to out
        for (Instruction nextIns : instr.getNexts())
        {
          for (Temp ins : nextIns.getIn())
          {
            instr.addOut(ins);
          }
        }
      }
     
    } while(instructionsChanged(instructionList));
   
    // Get interference graph
    return getInterferenceGraph(instructionList);
  }
 
  private static LinkedList<LivenessEdge> getInterferenceGraph(LinkedList<Instruction> instructions)
  {
    HashSet<LivenessEdge> edges = new HashSet<LivenessEdge>();
   
    for (Instruction instruction : instructions)
    {
      // Move instruction is being handled separately
      if (instruction.getInstruction() instanceof AsmMOVE)
      {
        AsmMOVE mov = (AsmMOVE)instruction.getInstruction();
       
        // Liveout
        for (Temp liveOut : instruction.getOut())
        {
          if (!mov.defs.get(0).equals(liveOut))
          {
            // Add edge that is not the same as assigned variable
            edges.add(new LivenessEdge(mov.defs.get(0), liveOut));
          }
        }
      }
      else
      {
        for (Temp defs : instruction.getInstruction().defs)
        {
          for (Temp liveOut : instruction.getOut())
          {
            edges.add(new LivenessEdge(defs, liveOut));
          }
        }
      }
    }
   
    return new LinkedList<LivenessEdge>(edges);
  }
 
  private static boolean instructionsChanged(LinkedList<Instruction> instructions)
  {
    boolean changed = false;
   
    for (Instruction instruction : instructions)
    {
      changed = changed || instruction.hasChanged();
    }
   
    return changed;
  }
 
  private static void resetInstructionChangedStatus(LinkedList<Instruction> instructions)
  {
    for (Instruction instruction : instructions)
    {
      instruction.reset();
    }
  }
}
TOP

Related Classes of compiler.liveness.LivenessAnalyser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.