mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Now handling uncalled procedures.
This commit is contained in:
parent
416184894f
commit
5905c1d5b6
@ -1,10 +1,8 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementCalling;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
|
||||
import java.util.*;
|
||||
@ -92,26 +90,6 @@ public interface Graph {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all called procedures in the graph
|
||||
*
|
||||
* @return All called procedures
|
||||
*/
|
||||
default Set<ProcedureRef> getAllCalledProcedures() {
|
||||
Set<ProcedureRef> calledProcedures = new LinkedHashSet<>();
|
||||
for(Graph.Block block : getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCalling) {
|
||||
StatementCalling call = (StatementCalling) statement;
|
||||
ProcedureRef procedureRef = call.getProcedure();
|
||||
calledProcedures.add(procedureRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
return calledProcedures;
|
||||
}
|
||||
|
||||
|
||||
default String toString(Program program) {
|
||||
StringBuffer out = new StringBuffer();
|
||||
for(Graph.Block block : getAllBlocks()) {
|
||||
|
@ -550,6 +550,18 @@ public class Program {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an entire procedure.
|
||||
* Removes the entire control flow graph and all symbols.
|
||||
* Does not check that the removal results in a legal program.
|
||||
* @param procedureRef The procedure to remove.
|
||||
*/
|
||||
public void removeProcedure(ProcedureRef procedureRef) {
|
||||
Procedure procedure = getScope().getProcedure(procedureRef);
|
||||
procedure.getScope().remove(procedure);
|
||||
procedureCompilations.remove(procedureRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the block the entry of a procedure, ie. the first block of the code of the procedure.
|
||||
*
|
||||
@ -580,4 +592,5 @@ public class Program {
|
||||
}
|
||||
return entryPointBlocks;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Graph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementCalling;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.passes.utils.ProcedureUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Eliminate uncalled methods */
|
||||
@ -19,10 +19,10 @@ public class Pass1EliminateUncalledProcedures extends Pass1Base {
|
||||
super(program);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
Set<ProcedureRef> calledProcedures = getGraph().getAllCalledProcedures();
|
||||
//calledProcedures.add(getProgram().getStartProcedure());
|
||||
Set<ProcedureRef> calledProcedures = getAllCalledProcedures(getGraph());
|
||||
|
||||
Set<ProcedureRef> unusedProcedures = new LinkedHashSet<>();
|
||||
Collection<Procedure> allProcedures = getProgram().getScope().getAllProcedures(true);
|
||||
@ -39,6 +39,25 @@ public class Pass1EliminateUncalledProcedures extends Pass1Base {
|
||||
return unusedProcedures.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all called procedures in a control flow graph
|
||||
*
|
||||
* @return All called procedures
|
||||
*/
|
||||
public static Set<ProcedureRef> getAllCalledProcedures(Graph graph) {
|
||||
Set<ProcedureRef> calledProcedures = new LinkedHashSet<>();
|
||||
for(Graph.Block block : graph.getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementCalling) {
|
||||
StatementCalling call = (StatementCalling) statement;
|
||||
ProcedureRef procedureRef = call.getProcedure();
|
||||
calledProcedures.add(procedureRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
return calledProcedures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removed a procedure from the program (the symbol in the symbol table and all blocks in the control flow graph)
|
||||
*
|
||||
@ -49,12 +68,7 @@ public class Pass1EliminateUncalledProcedures extends Pass1Base {
|
||||
if(program.getLog().isVerbosePass1CreateSsa()) {
|
||||
program.getLog().append("Removing unused procedure " + procedureRef);
|
||||
}
|
||||
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
||||
List<Graph.Block> procedureBlocks = program.getGraph().getScopeBlocks(procedureRef);
|
||||
for(var procedureBlock : procedureBlocks) {
|
||||
program.getGraph().remove(procedureBlock.getLabel());
|
||||
}
|
||||
procedure.getScope().remove(procedure);
|
||||
program.removeProcedure(procedureRef);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.utils.AliasReplacer;
|
||||
|
||||
import dk.camelot64.kickc.passes.utils.StatementsBetween;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -10,13 +10,15 @@ public class ProcedureUtils {
|
||||
/**
|
||||
* Determines if a procedure is an entry point.
|
||||
* Entry points are:
|
||||
* - the starting procedure (typically main())
|
||||
* - interrupts
|
||||
* - any procedure where address-of is used in the code.
|
||||
* <ul>
|
||||
* <li> the starting procedure (typically main())
|
||||
* <li> interrupts
|
||||
* <li> any procedure where address-of is used in the code.
|
||||
* </ul>
|
||||
* TODO: Should all stack call procedures be included (probably no!)
|
||||
* TODO: Also look at kickasm/asm uses! (Maybe also look at some directive like "__export" )
|
||||
*
|
||||
* @param procedure The procedure to examine
|
||||
* @param procedureRef The procedure to examine
|
||||
* @param program The program
|
||||
* @return true if the procedure is an entry point
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
package dk.camelot64.kickc.passes.utils;
|
||||
|
||||
import dk.camelot64.kickc.model.Graph;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
Loading…
x
Reference in New Issue
Block a user