-package org.simantics.scl.compiler.constants;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-\r
-import org.simantics.scl.compiler.common.names.Name;\r
-import org.simantics.scl.compiler.common.names.Named;\r
-import org.simantics.scl.compiler.internal.codegen.optimization.Optimization;\r
-import org.simantics.scl.compiler.internal.codegen.optimization.OptimizationMap;\r
-import org.simantics.scl.compiler.internal.codegen.references.BoundVar;\r
-import org.simantics.scl.compiler.internal.codegen.references.Val;\r
-import org.simantics.scl.compiler.internal.codegen.references.ValRef;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
-import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;\r
-import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-\r
-public class SCLConstant extends DelegateConstant implements Named {\r
-\r
- public Name name; // Needed only for debugging\r
- public SSAFunction definition;\r
- public SSAFunction inlinableDefinition;\r
- public int inlineArity = Integer.MAX_VALUE;\r
- public int inlinePhaseMask = 0xffffffff;\r
- public boolean isPrivate = false; \r
- \r
- public SCLConstant(Name name, Type type) {\r
- super(type);\r
- this.name = name;\r
- }\r
- \r
- public void setInlineArity(int inlineArity, int inlinePhaseMask) {\r
- this.inlineArity = inlineArity;\r
- this.inlinePhaseMask = inlinePhaseMask;\r
- //System.out.println(name + " " + inlineArity + " " + inlinePhaseMask);\r
- }\r
- \r
- public void setPrivate(boolean isPrivate) {\r
- this.isPrivate = isPrivate;\r
- }\r
- \r
- public void setDefinition(SSAFunction definition) {\r
- this.definition = definition;\r
- }\r
- \r
- public SSAFunction getDefinition() {\r
- return definition;\r
- }\r
-\r
- @Override\r
- public void inline(SSASimplificationContext context, LetApply apply) {\r
- if(inlineTailCallToSelf(context, apply)) {\r
- return;\r
- }\r
- /*if(tryBetaReduce(context, apply)) {\r
- return;\r
- }*/\r
- if(basicInline(context, apply)) {\r
- return;\r
- }\r
- trySpecialize(context, apply);\r
- \r
- Optimization opt = OptimizationMap.OPTIMIZATIONS.get(name);\r
- if(opt != null)\r
- opt.inline(context, apply);\r
- }\r
-\r
- static int inlineCount = 0;\r
- \r
- private boolean canInlineInPhase(int phase) {\r
- return ((inlinePhaseMask >> phase)&1) == 1;\r
- }\r
- \r
- private boolean basicInline(SSASimplificationContext context, LetApply apply) {\r
- if(!canInlineInPhase(context.getPhase())) {\r
- //System.out.println("Cannot optimize " + name + " in phase " + context.getPhase());\r
- return false;\r
- }\r
- ValRef functionRef = apply.getFunction();\r
- ValRef[] parameters = apply.getParameters();\r
- SSAFunction def = inlinableDefinition == null ? definition : inlinableDefinition;\r
- if(parameters.length < inlineArity &&\r
- (!isPrivate \r
- || parameters.length != def.getArity() \r
- || hasMoreThanOneOccurences()))\r
- return false;\r
- \r
- //if(def.getArity() == 0)\r
- // return false; // FIXME\r
- \r
- //System.out.println("basicInline: " + apply);\r
- //System.out.println("def: " + def);\r
- \r
- if(isPrivate && !hasMoreThanOneOccurences())\r
- context.removeConstant(name);\r
- else\r
- def = def.copy();\r
- \r
- if(parameters.length >= def.getArity()) {\r
- if(parameters.length != def.getArity())\r
- apply.split(def.getArity());\r
- apply.inline(def);\r
- context.markModified("SCLConstant.beta-constant " + getName());\r
- }\r
- else /*if(parameters.length < def.getArity())*/ {\r
- def.applyTypes(functionRef.getTypeParameters());\r
- def.apply(parameters);\r
- \r
- def.setTarget(apply.getTarget());\r
- new LetFunctions(def).insertBefore(apply);\r
-\r
- apply.remove();\r
- context.markModified("SCLConstant.partial-beta-constant " + getName());\r
- }\r
- \r
- /*Name newName = Name.create(name.module,\r
- name.name + "_S" + (++inlineCount));\r
- SCLConstant newConstant = new SCLConstant(newName, type);\r
- newConstant.setPrivate(true);\r
- newConstant.setDefinition(definition.copy()); */ \r
- /*System.out.println("*** 1 *************************************");\r
- System.out.println(definition);\r
- System.out.println("*** 2 *************************************");\r
- System.out.println(newConstant.definition);\r
- \r
- function.remove();\r
- apply.setFunction(newConstant.createOccurrence(function.getTypeParameters()));\r
- \r
- context.addConstant(newConstant);\r
- \r
- context.markModified();\r
- \r
- newConstant.trySpecialize(context, apply);\r
- */\r
- \r
- return true;\r
- }\r
-\r
- private boolean inlineTailCallToSelf(SSASimplificationContext context, LetApply apply) {\r
- SSAFunction thisFunction = apply.getParent().getParent();\r
- if(thisFunction != definition)\r
- return false;\r
- ValRef ref = apply.getTarget().getOccurrence();\r
- if(ref == null || ref.getNext() != null)\r
- return false;\r
- if(!(ref.getParent() instanceof Jump))\r
- return false;\r
- Jump jump = (Jump)ref.getParent();\r
- if(jump.getParameters().length != 1)\r
- return false;\r
- if(jump.getTarget().getBinding() != thisFunction.getReturnCont())\r
- return false;\r
- if(apply.getParameters().length != thisFunction.getArity())\r
- return false;\r
- \r
- jump.getTarget().remove();\r
- jump.setTarget(thisFunction.getFirstBlock().createOccurrence());\r
- jump.setParameters(apply.getParameters());\r
- \r
- apply.getFunction().remove();\r
- apply.detach();\r
- \r
- context.markModified("SCLConstant.simplify-tail-call");\r
- \r
- return true;\r
- }\r
-\r
- private void trySpecialize(SSASimplificationContext context, LetApply apply) {\r
- if(!isPrivate)\r
- return;\r
- if(hasMoreThanOneOccurences())\r
- return;\r
- if(apply.getParent().getParent() == definition)\r
- return;\r
-\r
- // Specialization of type parameters\r
- {\r
- ValRef functionRef = apply.getFunction();\r
- Type[] pValues = functionRef.getTypeParameters(); \r
- boolean hasComplexTypes = false;\r
- for(Type type : pValues)\r
- if(!(Types.canonical(type) instanceof TVar)) {\r
- hasComplexTypes = true;\r
- break;\r
- }\r
- if(hasComplexTypes) { \r
- /*PrintingContext pc = new PrintingContext();\r
- pc.append(">> BEFORE >>\n");\r
- definition.toString(pc);*/ \r
- \r
- TVar[] pVars = definition.getTypeParameters();\r
- TVar[] pVarsTail;\r
- if(pVars.length == pValues.length)\r
- pVarsTail = TVar.EMPTY_ARRAY;\r
- else {\r
- pVarsTail = Arrays.copyOfRange(pVars, pValues.length, pVars.length);\r
- pVars = Arrays.copyOf(pVars, pValues.length);\r
- }\r
- type = Types.instantiate(type, pValues);\r
- /*pc.append("REPLACE: ");\r
- pc.append(pVars);\r
- pc.append(" -> ");\r
- pc.append(pValues);\r
- pc.append('\n');*/\r
- definition.replace(pVars, pValues);\r
- TVar[] newParameters = Types.freeVarsArray(pValues);\r
- type = Types.forAll(newParameters, type);\r
- functionRef.setTypeParameters(newParameters);\r
- definition.setTypeParameters(Types.concat(newParameters, pVarsTail)); \r
- \r
- /*pc.append(">> AFTER >>\n");\r
- definition.toString(pc);\r
- System.out.println(pc);*/\r
- context.markModified("SCLConstant.specialize-types");\r
- }\r
- }\r
- \r
- if(!definition.getFirstBlock().hasNoOccurences())\r
- // TODO We can flex this requirement if all jumps to the first block\r
- // give same values to the first block\r
- return;\r
- \r
- // Specialization of parameters\r
- ValRef[] parameters = apply.getParameters();\r
- ValRef[] specialization = null;\r
- int arity = Math.min(parameters.length, definition.getArity());\r
- for(int i=0;i<arity;++i) {\r
- Val val = parameters[i].getBinding();\r
- if(val instanceof Constant) {\r
- if(specialization == null)\r
- specialization = new ValRef[arity];\r
- specialization[i] = parameters[i];\r
- }\r
- }\r
- \r
- if(specialization != null)\r
- specialize(context, apply, specialization);\r
- }\r
-\r
- private void specialize(SSASimplificationContext context, LetApply apply,\r
- ValRef[] specialization) {\r
- /*System.out.println("=== SPECIALIZE ====================");\r
- System.out.println(apply);\r
- System.out.println("--------");\r
- System.out.println(definition);\r
- System.out.println("========");*/\r
- // *** Modify apply ******************************* \r
- {\r
- // Handle old parameters\r
- ValRef[] oldParameters = apply.getParameters();\r
- int newParameterCount = oldParameters.length - specialization.length;\r
- for(int i=0;i<specialization.length;++i)\r
- if(specialization[i] == null)\r
- ++newParameterCount; \r
-\r
- if(newParameterCount == 0) {\r
- // If apply would be degenerated, remove it\r
- apply.getTarget().replaceBy(apply.getFunction());\r
- apply.remove();\r
- } \r
- else {\r
- // Create new parameter array\r
- ValRef[] newParameters = new ValRef[newParameterCount];\r
- int k=0;\r
- for(int i=0;i<specialization.length;++i)\r
- if(specialization[i] == null)\r
- newParameters[k++] = oldParameters[i];\r
- else\r
- oldParameters[i].remove(); \r
- for(int i=specialization.length;i<oldParameters.length;++i)\r
- newParameters[k++] = oldParameters[i];\r
- \r
- apply.setParameters(newParameters);\r
- }\r
- }\r
- \r
- // *** Modify definition ************************** \r
- {\r
- SSABlock firstBlock = definition.getFirstBlock();\r
- BoundVar[] parameters = firstBlock.getParameters();\r
- ArrayList<BoundVar> newParameters = new ArrayList<BoundVar>(parameters.length); \r
- for(int i=0;i<specialization.length;++i)\r
- if(specialization[i] != null)\r
- parameters[i].replaceBy(specialization[i]);\r
- else\r
- newParameters.add(parameters[i]);\r
- for(int i=specialization.length;i<parameters.length;++i)\r
- newParameters.add(parameters[i]);\r
- firstBlock.setParameters(newParameters.toArray(new BoundVar[newParameters.size()]));\r
- \r
- type = definition.getType();\r
- }\r
- \r
- /*System.out.println(apply);\r
- System.out.println("--------");\r
- System.out.println(definition);*/\r
- context.markModified("SCLConstant.specialize"); \r
- }\r
-\r
- @Override\r
- public String toString() {\r
- char c = name.name.charAt(0);\r
- if(Character.isJavaIdentifierStart(c) || name.name.charAt(0) == '(' || c == '[')\r
- return name.name;\r
- else\r
- return "(" + name.name + ")";\r
- }\r
-\r
- @Override\r
- public Name getName() {\r
- return name;\r
- }\r
-\r
- public Constant getBase() {\r
- return base;\r
- }\r
- \r
- public boolean isPrivate() {\r
- return isPrivate;\r
- }\r
-\r
- private boolean simplifyConstantFunction(SSASimplificationContext context) {\r
- ValRef constant = definition.isEqualToConstant();\r
- if(constant == null)\r
- return false;\r
- Val binding = constant.getBinding();\r
- if(binding == this)\r
- return false;\r
- if(binding instanceof Constant) {\r
- /*System.out.println(name + " -> " + constant.getBinding());\r
- System.out.println("replace: " + this);\r
- System.out.println("of type: " + this.getType());\r
- System.out.println("by: " + binding);\r
- System.out.println("of type: " + binding.getType());\r
- System.out.println("parameters: " + Types.toString(definition.getTypeParameters()));\r
- System.out.println("parameters2: " + Types.toString(constant.getTypeParameters()));\r
- System.out.println("private: " + isPrivate);*/ \r
- replaceBy(binding,\r
- definition.getTypeParameters(), \r
- constant.getTypeParameters()); \r
- if(isPrivate) {\r
- definition.destroy();\r
- context.removeConstant(name);\r
- }\r
- context.markModified("SCLConstant.simplify-constant");\r
- return true;\r
- }\r
- return false;\r
- }\r
- \r
- public void simplify(SSASimplificationContext context) {\r
- if(!hasNoOccurences() /* TODO why this condition is needed? */) {\r
- if(simplifyConstantFunction(context))\r
- return;\r
- }\r
- /*if(isPrivate)\r
- definition.tryToMakeMonadic(context);*/\r
- definition.simplify(context);\r
- if(inlineArity == Integer.MAX_VALUE && definition.isSimpleEnoughForInline()) {\r
- inlineArity = definition.getArity();\r
- inlinableDefinition = definition.copy();\r
- context.markModified("mark inlineable " + name);\r
- // FIXME this will make self calling function inlinable that may crash the compiler\r
- }\r
- }\r
-\r
- public void saveInlinableDefinition() {\r
- if(inlineArity < Integer.MAX_VALUE)\r
- inlinableDefinition = definition.copy();\r
- }\r
-}\r
+package org.simantics.scl.compiler.constants;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.common.names.Named;
+import org.simantics.scl.compiler.internal.codegen.optimization.Optimization;
+import org.simantics.scl.compiler.internal.codegen.optimization.OptimizationMap;
+import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions;
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class SCLConstant extends DelegateConstant implements Named {
+
+ public Name name; // Needed only for debugging
+ public SSAFunction definition;
+ public SSAFunction inlinableDefinition;
+ public int inlineArity = Integer.MAX_VALUE;
+ public int inlinePhaseMask = 0xffffffff;
+ public boolean isPrivate = false;
+
+ public SCLConstant(Name name, Type type) {
+ super(type);
+ this.name = name;
+ }
+
+ public void setInlineArity(int inlineArity, int inlinePhaseMask) {
+ this.inlineArity = inlineArity;
+ this.inlinePhaseMask = inlinePhaseMask;
+ //System.out.println(name + " " + inlineArity + " " + inlinePhaseMask);
+ }
+
+ public void setPrivate(boolean isPrivate) {
+ this.isPrivate = isPrivate;
+ }
+
+ public void setDefinition(SSAFunction definition) {
+ this.definition = definition;
+ }
+
+ public SSAFunction getDefinition() {
+ return definition;
+ }
+
+ @Override
+ public void inline(SSASimplificationContext context, LetApply apply) {
+ if(inlineTailCallToSelf(context, apply)) {
+ return;
+ }
+ /*if(tryBetaReduce(context, apply)) {
+ return;
+ }*/
+ if(basicInline(context, apply)) {
+ return;
+ }
+ trySpecialize(context, apply);
+
+ Optimization opt = OptimizationMap.OPTIMIZATIONS.get(name);
+ if(opt != null)
+ opt.inline(context, apply);
+ }
+
+ static int inlineCount = 0;
+
+ private boolean canInlineInPhase(int phase) {
+ return ((inlinePhaseMask >> phase)&1) == 1;
+ }
+
+ private boolean basicInline(SSASimplificationContext context, LetApply apply) {
+ if(!canInlineInPhase(context.getPhase())) {
+ //System.out.println("Cannot optimize " + name + " in phase " + context.getPhase());
+ return false;
+ }
+ ValRef functionRef = apply.getFunction();
+ ValRef[] parameters = apply.getParameters();
+ SSAFunction def = inlinableDefinition == null ? definition : inlinableDefinition;
+ if(parameters.length < inlineArity &&
+ (!isPrivate
+ || parameters.length != def.getArity()
+ || hasMoreThanOneOccurences()))
+ return false;
+
+ //if(def.getArity() == 0)
+ // return false; // FIXME
+
+ //System.out.println("basicInline: " + apply);
+ //System.out.println("def: " + def);
+
+ if(isPrivate && !hasMoreThanOneOccurences())
+ context.removeConstant(name);
+ else
+ def = (SSAFunction)def.copy();
+
+ if(parameters.length >= def.getArity()) {
+ if(parameters.length != def.getArity())
+ apply.split(def.getArity());
+ apply.inline(def);
+ context.markModified("SCLConstant.beta-constant " + getName());
+ }
+ else /*if(parameters.length < def.getArity())*/ {
+ def.applyTypes(functionRef.getTypeParameters());
+ def.apply(parameters);
+
+ def.setTarget(apply.getTarget());
+ new LetFunctions(def).insertBefore(apply);
+
+ apply.remove();
+ context.markModified("SCLConstant.partial-beta-constant " + getName());
+ }
+
+ /*Name newName = Name.create(name.module,
+ name.name + "_S" + (++inlineCount));
+ SCLConstant newConstant = new SCLConstant(newName, type);
+ newConstant.setPrivate(true);
+ newConstant.setDefinition(definition.copy()); */
+ /*System.out.println("*** 1 *************************************");
+ System.out.println(definition);
+ System.out.println("*** 2 *************************************");
+ System.out.println(newConstant.definition);
+
+ function.remove();
+ apply.setFunction(newConstant.createOccurrence(function.getTypeParameters()));
+
+ context.addConstant(newConstant);
+
+ context.markModified();
+
+ newConstant.trySpecialize(context, apply);
+ */
+
+ return true;
+ }
+
+ private boolean inlineTailCallToSelf(SSASimplificationContext context, LetApply apply) {
+ SSAFunction thisFunction = apply.getParent().getParent();
+ if(thisFunction != definition)
+ return false;
+ ValRef ref = apply.getTarget().getOccurrence();
+ if(ref == null || ref.getNext() != null)
+ return false;
+ if(!(ref.getParent() instanceof Jump))
+ return false;
+ Jump jump = (Jump)ref.getParent();
+ if(jump.getParameters().length != 1)
+ return false;
+ if(jump.getTarget().getBinding() != thisFunction.getReturnCont())
+ return false;
+ if(apply.getParameters().length != thisFunction.getArity())
+ return false;
+
+ jump.getTarget().remove();
+ jump.setTarget(thisFunction.getFirstBlock().createOccurrence());
+ jump.setParameters(apply.getParameters());
+
+ apply.getFunction().remove();
+ apply.detach();
+
+ context.markModified("SCLConstant.simplify-tail-call");
+
+ return true;
+ }
+
+ private void trySpecialize(SSASimplificationContext context, LetApply apply) {
+ if(!isPrivate)
+ return;
+ if(hasMoreThanOneOccurences())
+ return;
+ if(apply.getParent().getParent() == definition)
+ return;
+
+ // Specialization of type parameters
+ {
+ ValRef functionRef = apply.getFunction();
+ Type[] pValues = functionRef.getTypeParameters();
+ boolean hasComplexTypes = false;
+ for(Type type : pValues)
+ if(!(Types.canonical(type) instanceof TVar)) {
+ hasComplexTypes = true;
+ break;
+ }
+ if(hasComplexTypes) {
+ /*PrintingContext pc = new PrintingContext();
+ pc.append(">> BEFORE >>\n");
+ definition.toString(pc);*/
+
+ TVar[] pVars = definition.getTypeParameters();
+ TVar[] pVarsTail;
+ if(pVars.length == pValues.length)
+ pVarsTail = TVar.EMPTY_ARRAY;
+ else {
+ pVarsTail = Arrays.copyOfRange(pVars, pValues.length, pVars.length);
+ pVars = Arrays.copyOf(pVars, pValues.length);
+ }
+ type = Types.instantiate(type, pValues);
+ /*pc.append("REPLACE: ");
+ pc.append(pVars);
+ pc.append(" -> ");
+ pc.append(pValues);
+ pc.append('\n');*/
+ definition.replace(pVars, pValues);
+ TVar[] newParameters = Types.freeVarsArray(pValues);
+ type = Types.forAll(newParameters, type);
+ functionRef.setTypeParameters(newParameters);
+ definition.setTypeParameters(Types.concat(newParameters, pVarsTail));
+
+ /*pc.append(">> AFTER >>\n");
+ definition.toString(pc);
+ System.out.println(pc);*/
+ context.markModified("SCLConstant.specialize-types");
+ }
+ }
+
+ if(!definition.getFirstBlock().hasNoOccurences())
+ // TODO We can flex this requirement if all jumps to the first block
+ // give same values to the first block
+ return;
+
+ // Specialization of parameters
+ ValRef[] parameters = apply.getParameters();
+ ValRef[] specialization = null;
+ int arity = Math.min(parameters.length, definition.getArity());
+ for(int i=0;i<arity;++i) {
+ Val val = parameters[i].getBinding();
+ if(val instanceof Constant) {
+ if(specialization == null)
+ specialization = new ValRef[arity];
+ specialization[i] = parameters[i];
+ }
+ }
+
+ if(specialization != null)
+ specialize(context, apply, specialization);
+ }
+
+ private void specialize(SSASimplificationContext context, LetApply apply,
+ ValRef[] specialization) {
+ /*System.out.println("=== SPECIALIZE ====================");
+ System.out.println(apply);
+ System.out.println("--------");
+ System.out.println(definition);
+ System.out.println("========");*/
+ // *** Modify apply *******************************
+ {
+ // Handle old parameters
+ ValRef[] oldParameters = apply.getParameters();
+ int newParameterCount = oldParameters.length - specialization.length;
+ for(int i=0;i<specialization.length;++i)
+ if(specialization[i] == null)
+ ++newParameterCount;
+
+ if(newParameterCount == 0) {
+ // If apply would be degenerated, remove it
+ apply.getTarget().replaceBy(apply.getFunction());
+ apply.remove();
+ }
+ else {
+ // Create new parameter array
+ ValRef[] newParameters = new ValRef[newParameterCount];
+ int k=0;
+ for(int i=0;i<specialization.length;++i)
+ if(specialization[i] == null)
+ newParameters[k++] = oldParameters[i];
+ else
+ oldParameters[i].remove();
+ for(int i=specialization.length;i<oldParameters.length;++i)
+ newParameters[k++] = oldParameters[i];
+
+ apply.setParameters(newParameters);
+ }
+ }
+
+ // *** Modify definition **************************
+ {
+ SSABlock firstBlock = definition.getFirstBlock();
+ BoundVar[] parameters = firstBlock.getParameters();
+ ArrayList<BoundVar> newParameters = new ArrayList<BoundVar>(parameters.length);
+ for(int i=0;i<specialization.length;++i)
+ if(specialization[i] != null)
+ parameters[i].replaceBy(specialization[i]);
+ else
+ newParameters.add(parameters[i]);
+ for(int i=specialization.length;i<parameters.length;++i)
+ newParameters.add(parameters[i]);
+ firstBlock.setParameters(newParameters.toArray(new BoundVar[newParameters.size()]));
+
+ type = definition.getType();
+ }
+
+ /*System.out.println(apply);
+ System.out.println("--------");
+ System.out.println(definition);*/
+ context.markModified("SCLConstant.specialize");
+ }
+
+ @Override
+ public String toString() {
+ char c = name.name.charAt(0);
+ if(Character.isJavaIdentifierStart(c) || name.name.charAt(0) == '(' || c == '[')
+ return name.name;
+ else
+ return "(" + name.name + ")";
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+
+ public Constant getBase() {
+ return base;
+ }
+
+ public boolean isPrivate() {
+ return isPrivate;
+ }
+
+ private boolean simplifyConstantFunction(SSASimplificationContext context) {
+ ValRef constant = definition.isEqualToConstant();
+ if(constant == null)
+ return false;
+ Val binding = constant.getBinding();
+ if(binding == this)
+ return false;
+ if(binding instanceof Constant) {
+ /*System.out.println(name + " -> " + constant.getBinding());
+ System.out.println("replace: " + this);
+ System.out.println("of type: " + this.getType());
+ System.out.println("by: " + binding);
+ System.out.println("of type: " + binding.getType());
+ System.out.println("parameters: " + Types.toString(definition.getTypeParameters()));
+ System.out.println("parameters2: " + Types.toString(constant.getTypeParameters()));
+ System.out.println("private: " + isPrivate);*/
+ replaceBy(binding,
+ definition.getTypeParameters(),
+ constant.getTypeParameters());
+ if(isPrivate) {
+ definition.destroy();
+ context.removeConstant(name);
+ }
+ context.markModified("SCLConstant.simplify-constant");
+ return true;
+ }
+ return false;
+ }
+
+ public void simplify(SSASimplificationContext context) {
+ if(!hasNoOccurences() /* TODO why this condition is needed? */) {
+ if(simplifyConstantFunction(context))
+ return;
+ }
+ /*if(isPrivate)
+ definition.tryToMakeMonadic(context);*/
+ definition.simplify(context);
+ if(inlineArity == Integer.MAX_VALUE && definition.isSimpleEnoughForInline()) {
+ inlineArity = definition.getArity();
+ inlinableDefinition = (SSAFunction)definition.copy();
+ context.markModified("mark inlineable " + name);
+ // FIXME this will make self calling function inlinable that may crash the compiler
+ }
+ }
+
+ public void saveInlinableDefinition() {
+ if(inlineArity < Integer.MAX_VALUE)
+ inlinableDefinition = (SSAFunction)definition.copy();
+ }
+
+ public void cleanup() {
+ if(definition != null)
+ definition.cleanup();
+ if(inlinableDefinition != null)
+ inlinableDefinition.cleanup();
+ }
+}