Changes to build code
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 4b3df19f8241d9705f1e21a5bf50e46c2e05578d..2e922b4bbef51473e906503aa8327fb62ccb4677 100644 (file)
@@ -9,6 +9,8 @@ public class BuildCode {
     Hashtable paramstable;
     Hashtable tempstable;
     int tag=0;
+    String localsprefix="__locals__";
+    String paramsprefix="__params__";
     private static final boolean GENERATEPRECISEGC=true;
 
     public BuildCode(State st, Hashtable temptovar) {
@@ -23,6 +25,7 @@ public class BuildCode {
        PrintWriter outclassdefs=null;
        PrintWriter outstructs=null;
        PrintWriter outmethodheader=null;
+       PrintWriter outmethod=null;
        try {
            OutputStream str=new FileOutputStream("structdefs.h");
            outstructs=new java.io.PrintWriter(str, true);
@@ -30,6 +33,8 @@ public class BuildCode {
            outmethodheader=new java.io.PrintWriter(str, true);
            str=new FileOutputStream("classdefs.h");
            outclassdefs=new java.io.PrintWriter(str, true);
+           str=new FileOutputStream("methods.c");
+           outmethod=new java.io.PrintWriter(str, true);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
@@ -42,6 +47,22 @@ public class BuildCode {
        }
        outstructs.close();
        outmethodheader.close();
+
+       /* Build the actual methods */
+       outmethod.println("#include \"methodheaders.h\"");
+       Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
+       while(classit.hasNext()) {
+           ClassDescriptor cn=(ClassDescriptor)classit.next();
+           generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
+           Iterator methodit=cn.getMethods();
+           while(methodit.hasNext()) {
+               /* Classify parameters */
+               MethodDescriptor md=(MethodDescriptor)methodit.next();
+               FlatMethod fm=state.getMethodFlat(md);
+               generateFlatMethod(fm,outmethod);
+           }
+       }
+       outmethod.close();
     }
 
     private void generateTempStructs(FlatMethod fm) {
@@ -97,7 +118,7 @@ public class BuildCode {
 
            /* Output parameter structure */
            if (GENERATEPRECISEGC) {
-               output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"params {");
+               output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
                output.println("  int type;");
                for(int i=0;i<objectparams.numPointers();i++) {
                    TempDescriptor temp=objectparams.getPointer(i);
@@ -109,7 +130,7 @@ public class BuildCode {
 
            /* Output temp structure */
            if (GENERATEPRECISEGC) {
-               output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"temps {");
+               output.println("struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps {");
                output.println("  int type;");
                for(int i=0;i<objecttemps.numPointers();i++) {
                    TempDescriptor temp=objecttemps.getPointer(i);
@@ -125,11 +146,11 @@ public class BuildCode {
            /* Output method declaration */
            if (md.getReturnType()!=null)
                headersout.print(md.getReturnType().getSafeSymbol()+" ");
-           headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"(");
+           headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
            
            boolean printcomma=false;
            if (GENERATEPRECISEGC) {
-               headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"params * base");
+               headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
                printcomma=true;
            }
            for(int i=0;i<objectparams.numPrimitives();i++) {
@@ -145,12 +166,211 @@ public class BuildCode {
 
     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
        MethodDescriptor md=fm.getMethod();
+       ClassDescriptor cn=md.getClassDesc();
        ParamsObject objectparams=(ParamsObject)paramstable.get(md);
 
        generateHeader(md,output);
        /* Print code */
+       output.println(" {");
        
-       output.println("}");
+       if (GENERATEPRECISEGC) {
+           output.println("   struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_temps "+localsprefix+";");
+       }
+       TempObject objecttemp=(TempObject) tempstable.get(md);
+       for(int i=0;i<objecttemp.numPrimitives();i++) {
+           TempDescriptor td=objecttemp.getPrimitive(i);
+           TypeDescriptor type=td.getType();
+           if (type.isClass())
+               output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+           else
+               output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
+       }
+       
+
+       /* Generate labels first */
+       HashSet tovisit=new HashSet();
+       HashSet visited=new HashSet();
+       int labelindex=0;
+       Hashtable nodetolabel=new Hashtable();
+       tovisit.add(fm.methodEntryNode());
+       FlatNode current_node=null;
+
+
+       //Assign labels 1st
+       //Node needs a label if it is
+       while(!tovisit.isEmpty()) {
+           FlatNode fn=(FlatNode)tovisit.iterator().next();
+           tovisit.remove(fn);
+           visited.add(fn);
+           for(int i=0;i<fn.numNext();i++) {
+               FlatNode nn=fn.getNext(i);
+               if(i>0) {
+                   //1) Edge >1 of node
+                   nodetolabel.put(nn,new Integer(labelindex++));
+               }
+               if (!visited.contains(nn)) {
+                   tovisit.add(nn);
+               } else {
+                   //2) Join point
+                   nodetolabel.put(nn,new Integer(labelindex++));
+               }
+           }
+       }
+
+       //Do the actual code generation
+       tovisit=new HashSet();
+       visited=new HashSet();
+       tovisit.add(fm.methodEntryNode());
+       while(current_node!=null||!tovisit.isEmpty()) {
+           if (current_node==null) {
+               current_node=(FlatNode)tovisit.iterator().next();
+               tovisit.remove(current_node);
+           }
+           visited.add(current_node);
+           if (nodetolabel.containsKey(current_node))
+               output.println("L"+nodetolabel.get(current_node)+":");
+           if (current_node.numNext()==0) {
+               output.print("   ");
+               generateFlatNode(fm, current_node, output);
+               current_node=null;
+           } else if(current_node.numNext()==1) {
+               output.print("   ");
+               generateFlatNode(fm, current_node, output);
+               FlatNode nextnode=current_node.getNext(0);
+               if (visited.contains(nextnode)) {
+                   output.println("goto L"+nodetolabel.get(nextnode));
+                   current_node=null;
+               } else
+                   current_node=nextnode;
+           } else if (current_node.numNext()==2) {
+               /* Branch */
+               output.print("   ");
+               generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
+               if (!visited.contains(current_node.getNext(1)))
+                   tovisit.add(current_node.getNext(1));
+               if (visited.contains(current_node.getNext(0))) {
+                   output.println("goto L"+nodetolabel.get(current_node.getNext(0)));
+                   current_node=null;
+               } else
+                   current_node=current_node.getNext(0);
+           } else throw new Error();
+       }
+       output.println("}\n\n");
+    }
+
+    private String generateTemp(FlatMethod fm, TempDescriptor td) {
+       MethodDescriptor md=fm.getMethod();
+       TempObject objecttemps=(TempObject) tempstable.get(md);
+       if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
+           return td.getSafeSymbol();
+       }
+
+       if (objecttemps.isLocalPtr(td)) {
+           return localsprefix+"."+td.getSafeSymbol();
+       }
+
+       if (objecttemps.isParamPtr(td)) {
+           return paramsprefix+"->"+td.getSafeSymbol();
+       }
+       throw new Error();
+    }
+
+    private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
+       switch(fn.kind()) {
+       case FKind.FlatCall:
+           generateFlatCall(fm, (FlatCall) fn,output);
+           return;
+       case FKind.FlatFieldNode:
+           generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
+           return;
+       case FKind.FlatSetFieldNode:
+           generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
+           return;
+       case FKind.FlatNew:
+           generateFlatNew(fm, (FlatNew) fn,output);
+           return;
+       case FKind.FlatOpNode:
+           generateFlatOpNode(fm, (FlatOpNode) fn,output);
+           return;
+       case FKind.FlatCastNode:
+           generateFlatCastNode(fm, (FlatCastNode) fn,output);
+           return;
+       case FKind.FlatLiteralNode:
+           generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
+           return;
+       case FKind.FlatReturnNode:
+           generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
+           return;
+       case FKind.FlatNop:
+           output.println("/* nop */");
+           return;
+       }
+       throw new Error();
+
+    }
+
+    private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
+       MethodDescriptor md=fm.getMethod();
+       ClassDescriptor cn=md.getClassDesc();
+       output.println("   {");
+       boolean needcomma=false;
+       if (GENERATEPRECISEGC) {
+           output.print("       struct "+cn.getSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __paramlist__={");
+           if (fc.getThis()!=null) {
+               output.print(generateTemp(fm,fc.getThis()));
+               needcomma=true;
+           }
+           output.println("};");
+       }
+       output.print("       ");
+
+       /* TODO: Virtual dispatch */
+       if (fc.getReturnType()!=null)
+           output.print(generateTemp(fm,fc.getReturnType())+"=");
+       output.print(cn.getSafeSymbol()+md.getSafeSymbol()++"_"+md.getSafeMethodDescriptor()+"(");
+       needcomma=false;
+       if (GENERATEPRECISEGC) {
+           output.println("__parameterlist__");
+           needcomma=true;
+       }
+       output.println(");");
+       output.println("   }");
+    }
+
+    private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
+       output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
+    }
+
+    private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
+       output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
+    }
+
+    private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
+    }
+
+    private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
+       if (fon.getOp().getOp()==Operation.ASSIGN)
+           output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
+       else if (fon.getRight()!=null)
+           output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
+       else
+           output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
+    }
+
+    private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
+       /* TODO: Make call into runtime */
+       output.println(fcn.getDst()+"=("+fcn.getType().getSafeSymbol()+")"+fcn.getSrc()+";");
+    }
+
+    private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
+    }
+
+    private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
+       output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
+    }
+
+    private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
+       output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
     }
 
     private void generateHeader(MethodDescriptor md, PrintWriter output) {
@@ -160,11 +380,11 @@ public class BuildCode {
        
        if (md.getReturnType()!=null)
            output.print(md.getReturnType().getSafeSymbol()+" ");
-       output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"(");
+       output.print(cn.getSafeSymbol()+md.getSafeSymbol()++"_"+md.getSafeMethodDescriptor()+"(");
        
        boolean printcomma=false;
        if (GENERATEPRECISEGC) {
-           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"params * base");
+           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
            printcomma=true;
        }
        for(int i=0;i<objectparams.numPrimitives();i++) {
@@ -174,6 +394,6 @@ public class BuildCode {
            printcomma=true;
            output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
        }
-       output.println(") {");
+       output.print(")");
     }
 }