]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/CodeGeneration.java
Merge "Make it possible to debug SCL compiler in production builds"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / CodeGeneration.java
index 470b8e9f0701c0418fb08bf02757e0b4717616d5..f0b9f735e68b7b6522b46423e188f7a0ca95feba 100644 (file)
@@ -17,6 +17,7 @@ import org.simantics.scl.compiler.constants.ThisConstant;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
 import org.simantics.scl.compiler.elaboration.macros.StandardMacroRule;
+import org.simantics.scl.compiler.elaboration.modules.DerivedProperty;
 import org.simantics.scl.compiler.elaboration.modules.InlineProperty;
 import org.simantics.scl.compiler.elaboration.modules.MethodImplementation;
 import org.simantics.scl.compiler.elaboration.modules.PrivateProperty;
@@ -25,8 +26,8 @@ import org.simantics.scl.compiler.elaboration.modules.SCLValueProperty;
 import org.simantics.scl.compiler.elaboration.modules.TypeClass;
 import org.simantics.scl.compiler.elaboration.modules.TypeClassInstance;
 import org.simantics.scl.compiler.elaboration.modules.TypeClassMethod;
-import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.references.Val;
 import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule;
@@ -37,7 +38,6 @@ import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;
 import org.simantics.scl.compiler.internal.codegen.utils.CodeBuilderUtils;
 import org.simantics.scl.compiler.internal.codegen.utils.CodeBuildingException;
 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
-import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
 import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;
@@ -53,18 +53,20 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
 import org.simantics.scl.compiler.types.exceptions.MatchException;
 import org.simantics.scl.compiler.types.util.MultiFunction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.procedure.TObjectObjectProcedure;
 import gnu.trove.procedure.TObjectProcedure;
 
 public class CodeGeneration {
-    
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CodeGeneration.class);
+
     public static final int OPTIMIZATION_PHASES = 2;
     
+    CompilationContext compilationContext;
     ErrorLog errorLog;
-    Environment environment;
-    JavaNamingPolicy namingPolicy;
-    JavaTypeTranslator javaTypeTranslator;
     JavaReferenceValidator<Object, Object, Object, Object> validator;
     ConcreteModule module;
     ModuleBuilder moduleBuilder;
@@ -75,29 +77,23 @@ public class CodeGeneration {
     Map<String, byte[]> classes;
     
     @SuppressWarnings("unchecked")
-    public CodeGeneration(ErrorLog errorLog,
-            Environment environment,
-            JavaNamingPolicy namingPolicy, JavaTypeTranslator javaTypeTranslator,
+    public CodeGeneration(CompilationContext compilationContext,
             JavaReferenceValidator<?, ?, ?, ?> javaReferenceValidator,
-            ConcreteModule module) {
-        this.errorLog = errorLog;
-        this.environment = environment;
-        this.namingPolicy = namingPolicy;
-        this.javaTypeTranslator = javaTypeTranslator;
+            ConcreteModule module) {    
+        this.compilationContext = compilationContext;
+        this.errorLog = compilationContext.errorLog;
         this.module = module;
         this.validator = (JavaReferenceValidator<Object, Object, Object, Object>) javaReferenceValidator;
         
-        moduleBuilder = new ModuleBuilder(namingPolicy, javaTypeTranslator);
+        moduleBuilder = new ModuleBuilder(compilationContext.namingPolicy, compilationContext.javaTypeTranslator);
     }
     
     public void simplifyValues() {
-        //System.out.println("===== Simplify values =====");
+        //LOGGER.info("===== Simplify values =====");
         
         Collection<SCLValue> values = module.getValues();
-        SimplificationContext simplificationContext = 
-                new SimplificationContext(environment, errorLog, 
-                        javaTypeTranslator, validator);
-        //System.out.println("-----------------------------------------------");
+        SimplificationContext simplificationContext = new SimplificationContext(compilationContext, validator);
+        //LOGGER.info("-----------------------------------------------");
         SCLValue[] valueArray = values.toArray(new SCLValue[values.size()]);
         
         for(SCLValue value : valueArray) {
@@ -109,23 +105,21 @@ public class CodeGeneration {
         
         // Simplify
         for(SCLValue value : valueArray) {
-            //System.out.println("BEFORE " + value.getName() + " = " + value.getExpression());
+            //LOGGER.info("BEFORE " + value.getName() + " = " + value.getExpression());
             value.getSimplifiedExpression(simplificationContext);
-            //System.out.println("AFTER " + value.getName() + " = " + value.getExpression());
+            //LOGGER.info("AFTER " + value.getName() + " = " + value.getExpression());
         }
     }
     
     public void convertToSSA() {
-        ModuleWriter mw = new ModuleWriter(namingPolicy.getModuleClassName());
+        ModuleWriter mw = new ModuleWriter(compilationContext.namingPolicy.getModuleClassName(), compilationContext.lineLocator);
         for(SCLValue value : module.getValues()) {
-            //System.out.println(value.getName().name + " :: " + value.getType());
+            //LOGGER.info(value.getName().name + " :: " + value.getType());
             Expression expression = value.getExpression();
             if(expression == null)
                 continue;
 
             Name name = value.getName();
-            DecomposedExpression decomposed = 
-                    DecomposedExpression.decompose(expression);
             
             SCLConstant constant = new SCLConstant(name, value.getType());
             value.setValue(constant);            
@@ -135,13 +129,18 @@ public class CodeGeneration {
                     decomposed.typeParameters, 
                     decomposed.returnType, 
                     decomposed.parameterTypes));*/
+            boolean isDerived = false;
             for(SCLValueProperty prop : value.getProperties()) {
                 if(prop instanceof InlineProperty) {
                     InlineProperty inlineProperty = (InlineProperty)prop;
                     constant.setInlineArity(inlineProperty.arity, inlineProperty.phaseMask);
                 }
                 else if(prop == PrivateProperty.INSTANCE)
-                    constant.setPrivate(true);
+                    constant.setPrivate(!isDerived);
+                else if(prop == DerivedProperty.INSTANCE) {
+                    constant.setPrivate(false);
+                    isDerived = true;
+                }
             }
         }
         // This is quite hackish optimization that can be possibly removed when
@@ -154,7 +153,7 @@ public class CodeGeneration {
             if(constant.getTypeParameters().length > 0)
                 continue;
             
-            //System.out.println(value.getName() + " <- " + constant.getValue().getName());
+            //LOGGER.info(value.getName() + " <- " + constant.getValue().getName());
             value.setValue(constant.getValue().getValue());
             value.setExpression(null); // HMM??
         }*/
@@ -165,7 +164,7 @@ public class CodeGeneration {
                     continue;
      
                 DecomposedExpression decomposed = 
-                        DecomposedExpression.decompose(expression);
+                        DecomposedExpression.decompose(errorLog, expression);
     
                 CodeWriter w = mw.createFunction((SCLConstant)value.getValue(),
                         decomposed.typeParameters,
@@ -177,9 +176,12 @@ public class CodeGeneration {
                 IVal[] parameterVals = w.getParameters();
                 for(int i=0;i<decomposed.parameters.length;++i)
                     decomposed.parameters[i].setVal(parameterVals[i]);
-                w.return_(decomposed.body.toVal(environment, w));            
+                w.return_(expression.location, decomposed.body.toVal(compilationContext, w));            
             } catch(RuntimeException e) {
-                errorLog.setExceptionPosition(value.getExpression().location);
+                long location = value.getExpression().location;
+                if(location == Locations.NO_LOCATION)
+                    location = value.definitionLocation;
+                errorLog.setExceptionPosition(location);
                 throw e;
             }
         }
@@ -191,25 +193,25 @@ public class CodeGeneration {
     }
     
     public void optimizeSSA() {
-        if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION) {
-            System.out.println("=== SSA before optimization ====================================");
-            System.out.println(ssaModule);            
+        if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_OPTIMIZATION && SCLCompilerConfiguration.debugFilter(module.getName())) {
+            LOGGER.info("=== SSA before optimization ====================================");
+            LOGGER.info("{}", ssaModule);            
         }
         if(SCLCompilerConfiguration.DEBUG)
         ssaModule.validate();
         int optCount = 0;
         for(int phase=0;phase<OPTIMIZATION_PHASES;++phase) {
-            while(optCount++ < 100 && ssaModule.simplify(environment, phase)) {
-                //System.out.println("simplify " + optCount);
-                //System.out.println("================================================================");
-                //System.out.println(ssaModule);        
+            while(optCount++ < 100 && ssaModule.simplify(compilationContext.environment, phase)) {
+                //LOGGER.info("simplify " + optCount);
+                //LOGGER.info("================================================================");
+                //LOGGER.info(ssaModule);        
             }
             if(phase == 0)
                 ssaModule.saveInlinableDefinitions();
         }
-        if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING) {
-            System.out.println("=== SSA before lambda lifting ==================================");
-            System.out.println(ssaModule);            
+        if(SCLCompilerConfiguration.SHOW_SSA_BEFORE_LAMBDA_LIFTING && SCLCompilerConfiguration.debugFilter(module.getName())) {
+            LOGGER.info("=== SSA before lambda lifting ==================================");
+            LOGGER.info("{}", ssaModule);            
         }
         ssaModule.lambdaLift(errorLog);
         //ssaModule.validate();
@@ -219,9 +221,9 @@ public class CodeGeneration {
     }
     
     public void generateCode() {
-        if(SCLCompilerConfiguration.SHOW_FINAL_SSA) {
-            System.out.println("=== Final SSA ==================================================");
-            System.out.println(ssaModule);
+        if(SCLCompilerConfiguration.SHOW_FINAL_SSA && SCLCompilerConfiguration.debugFilter(module.getName())) {
+            LOGGER.info("=== Final SSA ==================================================");
+            LOGGER.info("{}", ssaModule);
         }
         try {
             ssaModule.generateCode(moduleBuilder);
@@ -229,7 +231,7 @@ public class CodeGeneration {
             errorLog.log(e.getMessage());
         }
         if(SCLCompilerConfiguration.TRACE_MAX_METHOD_SIZE && moduleBuilder.getMethodSizeCounter() != null)
-            System.out.println("[Max method size] " + module.getName() + ": " + moduleBuilder.getMethodSizeCounter());
+            LOGGER.info("[Max method size] " + module.getName() + ": " + moduleBuilder.getMethodSizeCounter());
         classes = moduleBuilder.getClasses();
     }
     
@@ -242,12 +244,12 @@ public class CodeGeneration {
                 if(constructor.parameterTypes.length != 1) {                    
                     String javaName = MethodBuilderBase.getClassName(dataType.getTypeDesc());
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + javaName);
+                        LOGGER.info("Create class " + javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, javaName, "java/lang/Object");
                     cf.setSourceFile("_SCL_DataType");
                     CodeBuilderUtils.makeRecord(cf, constructor.name.name,
                             Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "c", 
-                            javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
+                            compilationContext.javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
                             true);
                     moduleBuilder.addClass(cf);
                 }
@@ -257,7 +259,7 @@ public class CodeGeneration {
                 // Create supertype
                 {
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + javaName);
+                        LOGGER.info("Create class " + javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder,
                             Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC,
                             javaName, "java/lang/Object");
@@ -269,12 +271,12 @@ public class CodeGeneration {
                 // Create constructors
                 for(Constructor constructor : dataType.constructors) {
                     if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                        System.out.println("Create class " + constructor.javaName);
+                        LOGGER.info("Create class " + constructor.javaName);
                     ClassBuilder cf = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, constructor.javaName, javaName);
                     cf.setSourceFile("_SCL_DataType");
                     CodeBuilderUtils.makeRecord(cf, constructor.name.name,
                             Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "c", 
-                            javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
+                            compilationContext.javaTypeTranslator.toTypeDescs(constructor.parameterTypes),
                             true);
                     moduleBuilder.addClass(cf);
                 }
@@ -287,7 +289,7 @@ public class CodeGeneration {
             final JavaTypeTranslator javaTypeTranslator = moduleBuilder.getJavaTypeTranslator();
             
             if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-                System.out.println("Create class " + typeClass.javaName);
+                LOGGER.info("Create class " + typeClass.javaName);
             final ClassBuilder cf = new ClassBuilder(moduleBuilder,
                     Opcodes.ACC_INTERFACE | Opcodes.ACC_PUBLIC,
                     typeClass.javaName, "java/lang/Object");
@@ -338,7 +340,7 @@ public class CodeGeneration {
         final JavaTypeTranslator javaTypeTranslator = moduleBuilder.getJavaTypeTranslator();
         
         if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
-            System.out.println("Create class " + instance.javaName);
+            LOGGER.info("Create class " + instance.javaName);
         final ClassBuilder cb = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, instance.javaName, "java/lang/Object",
                 instance.typeClass.javaName);
         cb.setSourceFile("_SCL_TypeClassInstance");
@@ -369,7 +371,7 @@ public class CodeGeneration {
                 } catch (MatchException e) {
                     throw new InternalCompilerError("Method " + method.getName() + " has too high arity.");
                 }
-                //System.out.println("Interface types: " + Arrays.toString(types));
+                //LOGGER.info("Interface types: " + Arrays.toString(types));
                 TypeDesc[] parameterTypeDescs = javaTypeTranslator.toTypeDescs(mfun.parameterTypes);
                 TypeDesc returnTypeDesc = javaTypeTranslator.toTypeDesc(mfun.returnType); 
                 MethodBuilder mb = cb.addMethod(Opcodes.ACC_PUBLIC, method.getJavaName(), 
@@ -379,7 +381,7 @@ public class CodeGeneration {
                 MethodImplementation implementation = 
                         instance.methodImplementations.get(method.getName());
                 if(implementation.isDefault) {
-                    IVal function = environment.getValue(implementation.name).getValue();
+                    IVal function = compilationContext.environment.getValue(implementation.name).getValue();
                     
                     Val[] parameters = new Val[method.getArity() + 1];
                     MultiFunction mfun2;
@@ -406,7 +408,7 @@ public class CodeGeneration {
                     MultiFunction mfun2;
                     try {
                         mfun2 = Types.matchFunction(Types.removeForAll(function.getType()), parameters.length);
-                        //System.out.println("Implementation types: " + Arrays.toString(functionTypes));
+                        //LOGGER.info("Implementation types: " + Arrays.toString(functionTypes));
                     } catch (MatchException e) {
                         throw new InternalCompilerError(e);
                     }