Example #1
0
 // TODO simplify this mess - if IRTuples knew what block they were in
 public void RemoveStatement(IRTuple stmt)
 {
     foreach (IRBlock block in this.GetSetOfAllBlocks())
     {
         block.RemoveStatement(stmt);
     }
 }
Example #2
0
    private static void DeadCodeElimination(IRGraph graph)
    {
        Dictionary <Ident, IRIdent> identAnalysis = SimpleVariableAnalysis(graph);

        Queue <Ident> worklist = new Queue <Ident>(identAnalysis.Keys);

        while (worklist.Count > 0)
        {
            Ident   ident    = worklist.Dequeue();
            IRIdent identObj = identAnalysis[ident];

            if (identObj.CountUsesites() == 0)
            {
                IRTuple defStatement = identObj.GetDefsite();

                if (!defStatement.HasSideEffects())
                {
                    Console.WriteLine("SSA: Deleting tuple: " + defStatement.toString() + " as it is dead code");

                    HashSet <Ident> usedVars = defStatement.GetUsedVars();
                    foreach (Ident used in usedVars)
                    {
                        IRIdent usedObj = identAnalysis[used];
                        usedObj.DeleteUsesite(defStatement);
                        worklist.Enqueue(used);
                    }

                    graph.RemoveStatement(defStatement);
                }
            }
        }
    }
Example #3
0
    public static void Main(string [] args)
    {
        List <IRTuple> irstream = new List <IRTuple>();

        irstream.Add(new IRTuple(IrOp.LABEL, "F$1"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "T", "R2"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "A", "R0"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "B", "R1"));
        irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "C", 0));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "D", "A"));
        irstream.Add(new IRTuple(IrOp.LABEL, "L$1"));
        irstream.Add(new IRTupleTwoOp(IrOp.ADD, "C", "C", "B"));
        irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$1", 1));
        irstream.Add(new IRTupleTwoOp(IrOp.SUB, "D", "D", "T$1"));
        irstream.Add(new IRTupleOneOpImm <int>(IrOp.STORE, "T$2", 0));
        irstream.Add(new IRTupleTwoOp(IrOp.LTE, "T$3", "D", "T$2"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.JMPF, "L$1", "T$3"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R0", "C"));
        irstream.Add(new IRTupleOneOpIdent(IrOp.STORE, "R2", "T"));

        IRGraph graph = new IRGraph(irstream);

        List <string>         livein;
        List <List <string> > liveouts;

        graph.ComputeLiveness(out livein, out liveouts);

        Dictionary <string, string> registerAllocation = Allocate.run(liveouts, livein);

        List <IRTuple> irstream_out = new List <IRTuple>();

        foreach (IRTuple irt in irstream)
        {
            IRTuple translated = irt.TranslateNames(registerAllocation);
            irstream_out.Add(translated);
        }

        Console.WriteLine();
        foreach (var kvp in registerAllocation)
        {
            Console.WriteLine("{0} : {1}", kvp.Key, kvp.Value);
        }
        Console.WriteLine();

        foreach (IRTuple irt in irstream_out)
        {
            irt.Print();
            Console.WriteLine();
        }
    }
Example #4
0
    // Split an IR stream into this graph; firsts and lasts are maps of indices of the first and last index in the stream of each block
    private void SplitStream(List <IRTuple> tuples, out SortedDictionary <int, int> firsts, out SortedDictionary <int, int> lasts)
    {
        firsts = new SortedDictionary <int, int>();
        lasts  = new SortedDictionary <int, int>();

        int currentIndex = BLOCK_INDEX_INITIAL; // The next block index in the graph

        firsts[currentIndex]      = 0;          // By definition, the very first tuple is the first tuple in the first block
        this.blocks[currentIndex] = new IRBlock(currentIndex);
        this.blocks[currentIndex].AppendStatement(tuples[0]);

        int j = 1;

        while (j < tuples.Count)
        {
            IRTuple tuple = tuples[j];

            if (IsTerminator(tuple))
            {
                this.blocks[currentIndex].AppendStatement(tuple);
                lasts[currentIndex] = j;

                // If we find a statement that closes current block and there is not one obviously opened by the following tuple, create a new block
                if (j != tuples.Count - 1 && !IsLeader(tuples[j + 1]))
                {
                    currentIndex++;
                    this.blocks[currentIndex] = new IRBlock(currentIndex);
                    firsts[currentIndex]      = j + 1;
                }
            }

            else
            {
                if (IsLeader(tuple))
                {
                    lasts[currentIndex] = j - 1;
                    // If we find a statement that starts a block, create a new block
                    currentIndex++;
                    this.blocks[currentIndex] = new IRBlock(currentIndex);
                    firsts[currentIndex]      = j;
                }
                this.blocks[currentIndex].AppendStatement(tuple);
            }
            j++;
            if (j == tuples.Count)
            {
                lasts[currentIndex] = j - 1;
            }
        }
    }
Example #5
0
 // Establish pointers between each block in the graph and its successor blocks
 private void LinkSuccessors(SortedDictionary <int, int> firsts, SortedDictionary <int, int> lasts)
 {
     foreach (KeyValuePair <int, IRBlock> pair in this.blocks)
     {
         IRBlock block = pair.Value;
         IRTuple tup   = block.GetLast(); // Get last statement in block
         if (tup.getOp() == IrOp.JMP)
         {
             foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks)
             {
                 IRBlock block0 = pair0.Value;
                 IRTuple tup0   = block0.GetFirst();
                 if (tup0.getOp() == IrOp.LABEL && tup0.getDest() == tup.getDest())
                 {
                     block.AddSuccessor(block0);
                 }
             }
         }
         else if (tup.getOp() == IrOp.JMPF)
         {
             foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks)
             {
                 IRBlock block0 = pair0.Value;
                 IRTuple tup0   = block0.GetFirst();
                 if (tup0.getOp() == IrOp.LABEL && tup0.getDest() == ((IRTupleOneOpIdent)tup).getDest())
                 {
                     block.AddSuccessor(block0);
                 }
                 else if (firsts[block0.GetIndex()] == lasts[block.GetIndex()] + 1)
                 {
                     block.AddSuccessor(block0);
                 }
             }
         }
         else
         {
             foreach (KeyValuePair <int, IRBlock> pair0 in this.blocks)
             {
                 IRBlock block0 = pair0.Value;
                 if (firsts[block0.GetIndex()] == lasts[block.GetIndex()] + 1)
                 {
                     block.AddSuccessor(block0);
                 }
             }
         }
     }
 }
Example #6
0
    private static void RenameTupleSourcesHelper(IRTuple tuple, Ident replaceIdent, int numbering)
    {
        Console.WriteLine();
        Console.Write("Before: ");
        tuple.Print();
        Console.WriteLine();

        if (tuple.GetType() == typeof(IRTupleTwoOp))
        {
            IRTupleTwoOp twoTuple = (IRTupleTwoOp)tuple;

            if (twoTuple.getSrc2() == replaceIdent)
            {
                twoTuple.setSrc2(RenameVar(replaceIdent, numbering));
            }

            if (twoTuple.getSrc1() == replaceIdent)
            {
                twoTuple.setSrc1(RenameVar(replaceIdent, numbering));
            }
        }
        else if (tuple.GetType() == typeof(IRTupleOneOpIdent))
        {
            IRTupleOneOpIdent oneTuple = (IRTupleOneOpIdent)tuple;
            if (oneTuple.getSrc1() == replaceIdent)
            {
                oneTuple.setSrc1(RenameVar(replaceIdent, numbering));
            }
        }
        else
        {
            throw new Exception("You need to deal with more types: " + tuple.GetType());
        }

        Console.Write("After: ");
        tuple.Print();
        Console.WriteLine();
    }
Example #7
0
    public static void Main(string [] args)
    {
        IRTuple[] tuples = { new IRTuple(IrOp.LABEL,               "F$1"),
                             new IRTupleOneOpIdent(IrOp.STORE,     "T",   "R$2"),
                             new IRTupleOneOpIdent(IrOp.STORE,     "A",   "R$0"),
                             new IRTupleOneOpIdent(IrOp.STORE,     "B",   "R$1"),
                             new IRTupleOneOpImm <int>(IrOp.STORE, "C",        0),
                             new IRTupleOneOpIdent(IrOp.STORE,     "D",   "A"),
                             new IRTuple(IrOp.LABEL,               "L$1"),
                             new IRTupleTwoOp(IrOp.ADD,            "C",   "C",    "B"),
                             new IRTupleOneOpImm <int>(IrOp.STORE, "T$1",      1),
                             new IRTupleTwoOp(IrOp.SUB,            "D",   "D",    "T$1"),
                             new IRTupleOneOpImm <int>(IrOp.STORE, "T$2",      0),
                             new IRTupleTwoOp(IrOp.LTE,            "T$3", "D",    "T$2"),
                             new IRTupleOneOpIdent(IrOp.JMPF,      "L$1", "T$3"),
                             new IRTupleOneOpIdent(IrOp.STORE,     "R$0", "C"),
                             new IRTupleOneOpIdent(IrOp.STORE,     "R$2", "T") };

        Dictionary <string, string> translations = new Dictionary <string, string>()
        {
            { "R$0", "R$0" },
            { "R$1", "R$1" },
            { "R$2", "R$2" },
            { "D", "R$1" },
            { "C", "R$2" },
            { "B", "R$3" },
            { "A", "R$0" },
            { "T", "R$4" },
            { "T$1", "R$0" },
            { "T$2", "R$0" },
            { "T$3", "R$0" }
        };

        foreach (IRTuple irt in tuples)
        {
            irt.Print();

            HashSet <Ident> usedvars = irt.GetUsedVars();
            Console.Write("\tUses: ");
            foreach (Ident ident in usedvars)
            {
                Console.Write(ident + " ");
            }

            HashSet <Ident> definedvars = irt.GetDefinedVars();
            Console.Write("\tDefines: ");
            foreach (Ident ident in definedvars)
            {
                Console.Write(ident + " ");
            }

            Console.WriteLine();
        }

        Console.WriteLine("-------");

        foreach (IRTuple irt in tuples)
        {
            IRTuple translated = irt.TranslateNames(translations);
            translated.Print();
            Console.WriteLine();
        }
    }
Example #8
0
 public void RemoveStatement(IRTuple stat)
 {
     this.statements.Remove(stat);
 }
Example #9
0
    private static void RenameTupleSourcesHelper(IRTuple tuple, Ident replaceIdent, int numbering)
    {
        Console.WriteLine();
        Console.Write("Before: ");
        tuple.Print();
        Console.WriteLine();

        if (tuple.GetType() == typeof(IRTupleTwoOp))
        {
          IRTupleTwoOp twoTuple = (IRTupleTwoOp)tuple;

          if (twoTuple.getSrc2() == replaceIdent)
        twoTuple.setSrc2(RenameVar(replaceIdent, numbering));

          if (twoTuple.getSrc1() == replaceIdent)
        twoTuple.setSrc1(RenameVar(replaceIdent, numbering));

        } else if (tuple.GetType() == typeof(IRTupleOneOpIdent)) {
          IRTupleOneOpIdent oneTuple = (IRTupleOneOpIdent)tuple;
          if (oneTuple.getSrc1() == replaceIdent)
        oneTuple.setSrc1(RenameVar(replaceIdent, numbering));

        } else throw new Exception("You need to deal with more types: " + tuple.GetType());

        Console.Write("After: ");
        tuple.Print();
        Console.WriteLine();
    }
Example #10
0
 public void DeleteUsesite(IRTuple stmt)
 {
     this.usesites.Remove(stmt);
 }
Example #11
0
    // Backward pass to determine liveness at each point in the block
    public void ComputeLiveouts()
    {
        this.liveouts.Clear();

        Stack <List <string> > reversed = new Stack <List <string> >(); // Because this is a backward pass, lists will be found in reverse
        HashSet <Ident>        lo       = new HashSet <Ident>(this.liveout);

        // Extract liveness information for last statement in block
        IRTuple last = this.statements[this.statements.Count - 1];

        HashSet <Ident> prevdef  = last.GetDefinedVars();
        string          deflabel = "";

        foreach (Ident ident in prevdef)
        {
            deflabel = ident;
        }

        HashSet <Ident> prevused = last.GetUsedVars();

        List <string> lastliveout = new List <string>();

        lastliveout.Add(deflabel);
        foreach (Ident ident in lo)
        {
            lastliveout.Add(ident);
        }

        reversed.Push(lastliveout);

        Console.WriteLine();
        for (int i = this.statements.Count - 2; i >= 0; i--) // Start from second-last statement, as we already have liveout for last one
        {
            IRTuple tup = this.statements[i];

            if (lo.Contains(deflabel))
            {
                lo.Remove(deflabel); // Remove whatever is defined in the next statement
            }
            foreach (Ident ident in prevused)
            {
                if (!lo.Contains(ident))
                {
                    lo.Add(ident); // Add whatever is used in the next statement
                }
            }

            deflabel = "";
            prevdef  = tup.GetDefinedVars();
            foreach (Ident ident in prevdef)
            {
                deflabel = ident;
            }

            prevused = tup.GetUsedVars();

            List <string> currentliveout = new List <string>();
            currentliveout.Add(deflabel);

            foreach (Ident ident in lo)
            {
                currentliveout.Add(ident);
            }
            reversed.Push(currentliveout);
        }

        while (reversed.Count > 0)
        {
            this.liveouts.Add(reversed.Pop());
        }
    }
Example #12
0
 // Return whether a tuple is of the type that may terminate a block
 private bool IsTerminator(IRTuple tuple)
 {
     return(tuple.getOp() == IrOp.JMP || tuple.getOp() == IrOp.JMPF || tuple.getOp() == IrOp.RET);
 }
Example #13
0
 // Return whether a tuple is of the type that may start a block
 private bool IsLeader(IRTuple tuple)
 {
     return(tuple.getOp() == IrOp.FUNC || tuple.getOp() == IrOp.LABEL);
 }
Example #14
0
 public IRIdent(Ident name, IRTuple defsite)
 {
     this.name     = name;
     this.defsite  = defsite;
     this.usesites = new HashSet <IRTuple>();
 }
Example #15
0
 /* Forwarding functions */
 public void AppendStatement(IRTuple stat)
 {
     this.statements.Add(stat);
 }
Example #16
0
 public void AddUsesite(IRTuple stmt)
 {
     this.usesites.Add(stmt);
 }
Example #17
0
 public void InsertStatement(IRTuple stat, int index)
 {
     this.statements.Insert(index, stat);
 }
Example #18
0
    public static string IRToARM(IRTuple IR)
    {
        IRTupleOneOpIdent IROOI = IR as IRTupleOneOpIdent;
        IRTupleOneOpImm<string> IROOImm = IR as IRTupleOneOpImm<string>;
        IRTupleTwoOp IRTO = IR as IRTupleTwoOp;
        if(IR.getOp() == IrOp.NEG){
            return "Neg " + IROOI.getDest();
        }
        if(IR.getOp() == IrOp.ADD){
            return "ADD " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
        }
        if(IR.getOp() == IrOp.SUB){
            return "SUB " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
        }
        if(IR.getOp() == IrOp.AND){
            return "AND " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
        }
        if(IR.getOp() == IrOp.MUL){
            if(IRTO.getDest() != IRTO.getSrc1()){
                return "MUL " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
            }
            else{
                return "MUL " + IRTO.getDest() + ", " + IRTO.getSrc2() + ", " + IRTO.getSrc1();
            }
        }
        if(IR.getOp() == IrOp.CALL){
            string str = "STRMFD sp, {R1-R12, lr}\n";
            str += "BL " + IROOI.getDest();
            if(IR.getDest()[0] == 'R'){
                str = "MOV " + IROOI.getSrc1() + ", R0";
            }
            else{
                str = "LDR " + IROOI.getSrc1() + ", R0";
            }
            return str;
        }
        if(IR.getOp() == IrOp.RET){
            string str = "";
            if(IR.getDest()[0] == 'R'){
                str = "MOV R0, " + IR.getDest();
            }
            else{
                str = "LDR R0, " + IR.getDest();
            }
            str += "\nLDMFD sp, {R1-R12, pc}";
            return str;
        }
        // DIV

        if(IR.getOp() == IrOp.EQU){
            string str =  "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2()  +'\n';
            str += "MOVEQ " + IRTO.getDest() + ", #1\n";
            str += "MOVNE " + IRTO.getDest() + ", #0";
            return str;
        }
        if(IR.getOp() == IrOp.NEQ){
            string str =  "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2()  +'\n';
            str += "MOVEQ " + IRTO.getDest() + ", #0\n";
            str += "MOVNE " + IRTO.getDest() + ", #1";
            return str;
        }
        if(IR.getOp() == IrOp.LT){
            string str =  "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2()  +'\n';
            str += "MOVGE " + IRTO.getDest() + ", #0\n";
            str += "MOVLT " + IRTO.getDest() + ", #1";
            return str;
        }
        if(IR.getOp() == IrOp.GT){
            string str =  "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2()  +'\n';
            str += "MOVLE " + IRTO.getDest() + ", #0\n";
            str += "MOVGT " + IRTO.getDest() + ", #1";
            return str;
        }
        if(IR.getOp() == IrOp.JMP){
            return "JMP " + IR.getDest();
        }
        if(IR.getOp() == IrOp.JMPF){
            string str = "CMP " + IROOI.getSrc1() + ", #0\n";
            str += "JMPEQ " + IROOI.getDest();
            return str;
        }
        if(IR.getOp() == IrOp.LABEL){
            return IR.getDest() + ':';
        }
        if(IR.getOp() == IrOp.FUNC) {
            return IR.getDest() + ':';
        }
        // MOD
        if(IR.getOp() == IrOp.NOT){
            return "MVN " + IROOI.getDest() + ", " + IROOI.getSrc1();
        }
        if(IR.getOp() == IrOp.OR){
            return "ORR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
        }
        if(IR.getOp() == IrOp.XOR){
            return "EOR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2();
        }
        if(IR.getOp() == IrOp.STORE){
            if(IR.getDest()[0] == 'R'){
                return "LDR " + IROOI.getDest() + ", " + IROOI.getSrc1();
            }
            return "STR " + IROOI.getDest() + ", " + IROOI.getSrc1();
        }
        IR.Print();
        return "";
    }
Example #19
0
    public static string IRToARM(IRTuple IR)
    {
        IRTupleOneOpIdent        IROOI   = IR as IRTupleOneOpIdent;
        IRTupleOneOpImm <string> IROOImm = IR as IRTupleOneOpImm <string>;
        IRTupleTwoOp             IRTO    = IR as IRTupleTwoOp;

        if (IR.getOp() == IrOp.NEG)
        {
            return("Neg " + IROOI.getDest());
        }
        if (IR.getOp() == IrOp.ADD)
        {
            return("ADD " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
        }
        if (IR.getOp() == IrOp.SUB)
        {
            return("SUB " + IR.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
        }
        if (IR.getOp() == IrOp.AND)
        {
            return("AND " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
        }
        if (IR.getOp() == IrOp.MUL)
        {
            if (IRTO.getDest() != IRTO.getSrc1())
            {
                return("MUL " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
            }
            else
            {
                return("MUL " + IRTO.getDest() + ", " + IRTO.getSrc2() + ", " + IRTO.getSrc1());
            }
        }
        if (IR.getOp() == IrOp.CALL)
        {
            string str = "STRMFD sp, {R1-R12, lr}\n";
            str += "BL " + IROOI.getDest();
            if (IR.getDest()[0] == 'R')
            {
                str = "MOV " + IROOI.getSrc1() + ", R0";
            }
            else
            {
                str = "LDR " + IROOI.getSrc1() + ", R0";
            }
            return(str);
        }
        if (IR.getOp() == IrOp.RET)
        {
            string str = "";
            if (IR.getDest()[0] == 'R')
            {
                str = "MOV R0, " + IR.getDest();
            }
            else
            {
                str = "LDR R0, " + IR.getDest();
            }
            str += "\nLDMFD sp, {R1-R12, pc}";
            return(str);
        }
        // DIV

        if (IR.getOp() == IrOp.EQU)
        {
            string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n';
            str += "MOVEQ " + IRTO.getDest() + ", #1\n";
            str += "MOVNE " + IRTO.getDest() + ", #0";
            return(str);
        }
        if (IR.getOp() == IrOp.NEQ)
        {
            string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n';
            str += "MOVEQ " + IRTO.getDest() + ", #0\n";
            str += "MOVNE " + IRTO.getDest() + ", #1";
            return(str);
        }
        if (IR.getOp() == IrOp.LT)
        {
            string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n';
            str += "MOVGE " + IRTO.getDest() + ", #0\n";
            str += "MOVLT " + IRTO.getDest() + ", #1";
            return(str);
        }
        if (IR.getOp() == IrOp.GT)
        {
            string str = "CMP " + IRTO.getSrc1() + ", " + IRTO.getSrc2() + '\n';
            str += "MOVLE " + IRTO.getDest() + ", #0\n";
            str += "MOVGT " + IRTO.getDest() + ", #1";
            return(str);
        }
        if (IR.getOp() == IrOp.JMP)
        {
            return("JMP " + IR.getDest());
        }
        if (IR.getOp() == IrOp.JMPF)
        {
            string str = "CMP " + IROOI.getSrc1() + ", #0\n";
            str += "JMPEQ " + IROOI.getDest();
            return(str);
        }
        if (IR.getOp() == IrOp.LABEL)
        {
            return(IR.getDest() + ':');
        }
        if (IR.getOp() == IrOp.FUNC)
        {
            return(IR.getDest() + ':');
        }
        // MOD
        if (IR.getOp() == IrOp.NOT)
        {
            return("MVN " + IROOI.getDest() + ", " + IROOI.getSrc1());
        }
        if (IR.getOp() == IrOp.OR)
        {
            return("ORR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
        }
        if (IR.getOp() == IrOp.XOR)
        {
            return("EOR " + IRTO.getDest() + ", " + IRTO.getSrc1() + ", " + IRTO.getSrc2());
        }
        if (IR.getOp() == IrOp.STORE)
        {
            if (IR.getDest()[0] == 'R')
            {
                return("LDR " + IROOI.getDest() + ", " + IROOI.getSrc1());
            }
            return("STR " + IROOI.getDest() + ", " + IROOI.getSrc1());
        }
        IR.Print();
        return("");
    }