mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-13 18:30:21 +00:00
Removed unnecesary address-of handling.
This commit is contained in:
parent
45ad6b64b0
commit
13ab7e8da3
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user