From 13ab7e8da372322417df347270531f2f801d86a5 Mon Sep 17 00:00:00 2001
From: jespergravgaard <jesper@balmangravgaard.dk>
Date: Thu, 6 Feb 2020 18:19:02 +0100
Subject: [PATCH] Removed unnecesary address-of handling.

---
 .../java/dk/camelot64/kickc/Compiler.java     |   2 +-
 .../passes/PassNStructAddressOfRewriting.java | 127 ------------------
 .../PassNStructUnwoundPlaceholderRemoval.java |  45 +++++++
 3 files changed, 46 insertions(+), 128 deletions(-)
 delete mode 100644 src/main/java/dk/camelot64/kickc/passes/PassNStructAddressOfRewriting.java
 create mode 100644 src/main/java/dk/camelot64/kickc/passes/PassNStructUnwoundPlaceholderRemoval.java

diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java
index be097bcd2..88ff0411f 100644
--- a/src/main/java/dk/camelot64/kickc/Compiler.java
+++ b/src/main/java/dk/camelot64/kickc/Compiler.java
@@ -302,7 +302,7 @@ public class Compiler {
       optimizations.add(new Pass2ConditionalAndOrRewriting(program));
       optimizations.add(new PassNAddBooleanCasts(program));
       optimizations.add(new PassNStructPointerRewriting(program));
-      optimizations.add(new PassNStructAddressOfRewriting(program));
+      optimizations.add(new PassNStructUnwoundPlaceholderRemoval(program));
       optimizations.add(new PassNArrayElementAddressOfRewriting(program));
       optimizations.add(new Pass2ConditionalJumpSequenceImprovement(program));
       optimizations.add(new Pass2ConstantRValueConsolidation(program));
diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNStructAddressOfRewriting.java b/src/main/java/dk/camelot64/kickc/passes/PassNStructAddressOfRewriting.java
deleted file mode 100644
index 652090f6c..000000000
--- a/src/main/java/dk/camelot64/kickc/passes/PassNStructAddressOfRewriting.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package dk.camelot64.kickc.passes;
-
-import dk.camelot64.kickc.model.ControlFlowBlock;
-import dk.camelot64.kickc.model.Program;
-import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
-import dk.camelot64.kickc.model.operators.Operators;
-import dk.camelot64.kickc.model.statements.Statement;
-import dk.camelot64.kickc.model.statements.StatementAssignment;
-import dk.camelot64.kickc.model.statements.StatementLValue;
-import dk.camelot64.kickc.model.symbols.Symbol;
-import dk.camelot64.kickc.model.symbols.Variable;
-import dk.camelot64.kickc.model.types.SymbolTypePointer;
-import dk.camelot64.kickc.model.types.SymbolTypeStruct;
-import dk.camelot64.kickc.model.values.*;
-
-import java.util.Collection;
-import java.util.ListIterator;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Rewrite struct address-of to use the first member if the struct is unwound
- */
-public class PassNStructAddressOfRewriting extends Pass2SsaOptimization {
-
-   public PassNStructAddressOfRewriting(Program program) {
-      super(program);
-   }
-
-   @Override
-   public boolean step() {
-      AtomicBoolean modified = new AtomicBoolean(false);
-
-      // Examine all expressions
-      ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
-         Value value = programValue.get();
-         if(value instanceof ConstantSymbolPointer) {
-            ConstantSymbolPointer constantSymbolPointer = (ConstantSymbolPointer) value;
-            SymbolRef toSymbolRef = constantSymbolPointer.getToSymbol();
-            Symbol toSymbol = getScope().getSymbol(toSymbolRef);
-            if(toSymbol.getType() instanceof SymbolTypeStruct) {
-               RValue rewrite = rewriteStructAddressOf((SymbolVariableRef) toSymbol.getRef());
-               if(rewrite != null) {
-                  programValue.set(rewrite);
-                  getLog().append("Rewriting struct address-of to first member " + value.toString(getProgram()));
-                  modified.set(true);
-               }
-            }
-         }
-      });
-
-      // Examine all statements
-      for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
-         for(Statement statement : block.getStatements()) {
-            if(statement instanceof StatementAssignment) {
-               StatementAssignment assignment = (StatementAssignment) statement;
-               if(Operators.ADDRESS_OF.equals(assignment.getOperator())) {
-                  RValue rValue = assignment.getrValue2();
-                  if(rValue instanceof SymbolVariableRef) {
-                     Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) rValue);
-                     if(toSymbol.getType() instanceof SymbolTypeStruct) {
-                        RValue rewrite = rewriteStructAddressOf((SymbolVariableRef) toSymbol.getRef());
-                        if(rewrite != null) {
-                           assignment.setOperator(null);
-                           assignment.setrValue2(rewrite);
-                           getLog().append("Rewriting struct address-of to first member " + assignment.toString(getProgram(), false));
-                        }
-                        modified.set(true);
-                     }
-                  }
-               }
-            }
-         }
-      }
-
-      // Remove all StructUnwoundPlaceholder assignments for C-classic structs
-      for(ControlFlowBlock block : getGraph().getAllBlocks()) {
-         ListIterator<Statement> stmtIt = block.getStatements().listIterator();
-         while(stmtIt.hasNext()) {
-            Statement statement = stmtIt.next();
-            if(statement instanceof StatementAssignment) {
-               StatementAssignment assignment = (StatementAssignment) statement;
-               if(assignment.getrValue2() instanceof StructUnwoundPlaceholder && assignment.getlValue() instanceof VariableRef)
-                  if(getScope().getVariable((SymbolVariableRef) assignment.getlValue()).isStructClassic()) {
-                     getLog().append("Removing C-classic struct-unwound assignment "+assignment.toString(getProgram(), false));
-                     stmtIt.remove();
-                  }
-            }
-         }
-      }
-      return modified.get();
-   }
-
-   private RValue rewriteStructAddressOf(SymbolVariableRef toSymbol) {
-      Variable variable = getScope().getVar(toSymbol);
-
-      // Constant struct values do not need rewriting
-      if(variable.isKindConstant())
-         return null;
-
-      // Hacky way to handle PHI-masters
-      if(variable.isKindPhiMaster()) {
-         Collection<Variable> versions = variable.getScope().getVersions(variable);
-         for(Variable version : versions) {
-            if(variable.isVariable()) {
-               variable = version;
-               break;
-            }
-         }
-      }
-
-      StatementLValue toSymbolAssignment = getGraph().getAssignment(variable.getVariableRef());
-      if(toSymbolAssignment instanceof StatementAssignment) {
-         StatementAssignment assignment = (StatementAssignment) toSymbolAssignment;
-         if(assignment.getrValue2() instanceof StructUnwoundPlaceholder) {
-            // Found placeholder assignment!
-            StructUnwoundPlaceholder placeholder = (StructUnwoundPlaceholder) assignment.getrValue2();
-            RValue firstUnwoundMember = placeholder.getUnwoundMembers().get(0);
-            if(firstUnwoundMember instanceof SymbolRef) {
-               SymbolRef firstMember = (SymbolRef) firstUnwoundMember;
-               return new ConstantCastValue(new SymbolTypePointer(placeholder.getTypeStruct()), new ConstantSymbolPointer(firstMember));
-            }
-         }
-      }
-      return null;
-   }
-
-}
diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNStructUnwoundPlaceholderRemoval.java b/src/main/java/dk/camelot64/kickc/passes/PassNStructUnwoundPlaceholderRemoval.java
new file mode 100644
index 000000000..6cbe6df74
--- /dev/null
+++ b/src/main/java/dk/camelot64/kickc/passes/PassNStructUnwoundPlaceholderRemoval.java
@@ -0,0 +1,45 @@
+package dk.camelot64.kickc.passes;
+
+import dk.camelot64.kickc.model.ControlFlowBlock;
+import dk.camelot64.kickc.model.Program;
+import dk.camelot64.kickc.model.statements.Statement;
+import dk.camelot64.kickc.model.statements.StatementAssignment;
+import dk.camelot64.kickc.model.values.StructUnwoundPlaceholder;
+import dk.camelot64.kickc.model.values.SymbolVariableRef;
+import dk.camelot64.kickc.model.values.VariableRef;
+
+import java.util.ListIterator;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Rewrite struct address-of to use the first member if the struct is unwound
+ */
+public class PassNStructUnwoundPlaceholderRemoval extends Pass2SsaOptimization {
+
+   public PassNStructUnwoundPlaceholderRemoval(Program program) {
+      super(program);
+   }
+
+   @Override
+   public boolean step() {
+      AtomicBoolean modified = new AtomicBoolean(false);
+
+      // Remove all StructUnwoundPlaceholder assignments for C-classic structs
+      for(ControlFlowBlock block : getGraph().getAllBlocks()) {
+         ListIterator<Statement> stmtIt = block.getStatements().listIterator();
+         while(stmtIt.hasNext()) {
+            Statement statement = stmtIt.next();
+            if(statement instanceof StatementAssignment) {
+               StatementAssignment assignment = (StatementAssignment) statement;
+               if(assignment.getrValue2() instanceof StructUnwoundPlaceholder && assignment.getlValue() instanceof VariableRef)
+                  if(getScope().getVariable((SymbolVariableRef) assignment.getlValue()).isStructClassic()) {
+                     getLog().append("Removing C-classic struct-unwound assignment "+assignment.toString(getProgram(), false));
+                     stmtIt.remove();
+                  }
+            }
+         }
+      }
+      return modified.get();
+   }
+
+}