1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-11 04:37:29 +00:00

Optimized block successor closure slightly.

This commit is contained in:
jespergravgaard 2020-06-01 22:17:01 +02:00
parent 0359c85846
commit 513a71ce64
18 changed files with 193 additions and 90 deletions

View File

@ -360,6 +360,7 @@ public class Compiler {
optimizations.add(new PassNStatementIndices(program));
optimizations.add(() -> {
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
return false;
});
optimizations.add(new Pass2UnaryNotSimplification(program));
@ -372,6 +373,7 @@ public class Compiler {
});
optimizations.add(() -> {
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
return false;
});
optimizations.add(() -> {
@ -433,6 +435,7 @@ public class Compiler {
loopUnrolling.add(new PassNStatementIndices(program));
loopUnrolling.add(() -> {
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
return false;
});
loopUnrolling.add(() -> {
@ -481,6 +484,7 @@ public class Compiler {
constantOptimizations.add(new PassNStatementIndices(program));
constantOptimizations.add(() -> {
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
return false;
});
constantOptimizations.add(new Pass2NopCastInlining(program));
@ -571,6 +575,7 @@ public class Compiler {
program.clearStatementInfos();
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
pass2AssertSSA();
// Phi mem coalesce removes as many variables introduced by phi lifting as possible - as long as their live ranges do not overlap
@ -585,6 +590,7 @@ public class Compiler {
program.clearStatementIndices();
program.clearStatementInfos();
program.clearVariableReferenceInfos();
program.clearControlFlowBlockSuccessorClosure();
program.clearLiveRangeVariables();
program.clearLiveRangeVariablesEffective();
new PassNStatementIndices(program).execute();

View File

@ -143,6 +143,7 @@ public class AsmFragmentTemplateSynthesizer {
* @return The map with all best fragments from the cache file. null if the cache file is not found.
*/
private Map<String, AsmFragmentTemplate> loadBestFragmentCache(Path cacheFolder, CompileLog log) {
final Date before = new Date();
if(cacheFolder == null) {
return null;
}
@ -173,8 +174,10 @@ public class AsmFragmentTemplateSynthesizer {
}
cacheLine = fragmentCacheReader.readLine();
}
final Date after = new Date();
final long millis = after.getTime() - before.getTime();
if(log.isVerboseFragmentLog())
log.append("Loaded cached fragments " + bestFragmentCache.size() + " from " + cacheFile.getPath());
log.append("Loaded cached fragments " + bestFragmentCache.size() + " from " + cacheFile.getPath() + " in " + millis + "ms");
return bestFragmentCache;
} catch(IOException e) {
throw new RuntimeException("Error loading fragment cache file " + baseFragmentFolder, e);
@ -189,6 +192,7 @@ public class AsmFragmentTemplateSynthesizer {
* @param log The compile log
*/
public void saveBestFragmentCache(CompileLog log) {
Date before = new Date();
if(this.cacheFolder == null) {
return;
}
@ -202,8 +206,10 @@ public class AsmFragmentTemplateSynthesizer {
fragmentFilePrint.println(fragmentTemplate.getBody());
}
fragmentFilePrint.close();
final Date after = new Date();
final long millis = after.getTime() - before.getTime();
if(log.isVerboseFragmentLog())
log.append("Saved cached fragments " + this.bestFragmentCache.size() + " to " + cacheFile.getPath());
log.append("Saved cached fragments " + this.bestFragmentCache.size() + " to " + cacheFile.getPath() + " in " + millis + "ms");
} catch(IOException e) {
throw new RuntimeException("Error saving fragment cache file " + cacheFile, e);
} catch(StringIndexOutOfBoundsException e) {

View File

@ -0,0 +1,48 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
/** The transitive closure of control flow graph blocks */
public class ControlFlowBlockSuccessorClosure {
/** For each block this is the closure of all successor blocks. */
private Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure;
public ControlFlowBlockSuccessorClosure(Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure) {
this.blockSuccessorClosure = blockSuccessorClosure;
}
/**
* Get all variables used or defined inside a block and its successors (including any called method)
*
* @param labelRef The block to examine
* @return All used variables
*/
public Collection<VariableRef> getSuccessorClosureReferencedVars(LabelRef labelRef, VariableReferenceInfos varInfos) {
ArrayList<VariableRef> variableRefs = new ArrayList<>();
final Collection<LabelRef> successors = blockSuccessorClosure.get(labelRef);
successors.forEach(labelRef1 -> variableRefs.addAll(varInfos.getReferencedVars(labelRef1)));
return variableRefs;
}
public String getSizeInfo() {
StringBuilder sizeInfo = new StringBuilder();
if(blockSuccessorClosure != null) {
sizeInfo.append("SIZE blockSuccessorClosure ").append(blockSuccessorClosure.size()).append(" labels ");
int sub = 0;
for(Collection<LabelRef> labelRefs : blockSuccessorClosure.values()) {
sub += labelRefs.size();
}
sizeInfo.append(" ").append(sub).append(" labels").append("\n");
}
return sizeInfo.toString();
}
}

View File

@ -33,15 +33,17 @@ public class LiveRangeVariablesEffectiveCallPaths implements LiveRangeVariablesE
/** Variables (normally) alive at each statement by index. */
private Map<Integer, Collection<VariableRef>> statementLiveVariables;
/**
* Information about which procedures reference which variables.
*/
/** Information about which procedures reference which variables. */
private VariableReferenceInfos referenceInfo;
public LiveRangeVariablesEffectiveCallPaths(Program program, Map<ProcedureRef, CallPaths> procedureCallPaths, LiveRangeVariables liveRangeVariables, VariableReferenceInfos referenceInfo) {
/** Information about which blocks follow other blocks. */
private ControlFlowBlockSuccessorClosure blockSuccessorClosure;
public LiveRangeVariablesEffectiveCallPaths(Program program, Map<ProcedureRef, CallPaths> procedureCallPaths, LiveRangeVariables liveRangeVariables, VariableReferenceInfos referenceInfo, ControlFlowBlockSuccessorClosure blockSuccessorClosure) {
this.program = program;
this.procedureCallPaths = procedureCallPaths;
this.referenceInfo = referenceInfo;
this.blockSuccessorClosure = blockSuccessorClosure;
this.statementLiveVariables = new LinkedHashMap<>();
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) {
@ -106,7 +108,7 @@ public class LiveRangeVariablesEffectiveCallPaths implements LiveRangeVariablesE
if(scope instanceof Procedure) {
Procedure procedure = (Procedure) scope;
callPaths = procedureCallPaths.get(procedure.getRef());
referencedInProcedure = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef());
referencedInProcedure = blockSuccessorClosure.getSuccessorClosureReferencedVars(procedure.getRef().getLabelRef(), referenceInfo);
} else {
callPaths = new CallPaths(ROOT_PROCEDURE);
// Interrupt is called outside procedure scope - create initial call-path.

View File

@ -79,6 +79,8 @@ public class Program {
private CallGraph callGraph;
/** Cached information about the variables referenced by blocks/statements. PASS 1-4 (CACHED ON-DEMAND) */
private VariableReferenceInfos variableReferenceInfos;
/** Cached information about the closure of all block successors. */
private ControlFlowBlockSuccessorClosure blockSuccessorClosure;
/** Information about dominators of all blocks. PASS 2U-4 (CACHED ON-DEMAND) */
private DominatorsGraph dominators;
/** Cached information about symbols. Contains a symbol table cache for fast access. PASS 3-4 (CACHED ON-DEMAND) */
@ -339,6 +341,16 @@ public class Program {
this.variableReferenceInfos = null;
}
public ControlFlowBlockSuccessorClosure getControlFlowBlockSuccessorClosure() {
if(blockSuccessorClosure == null)
this.blockSuccessorClosure = new PassNCalcBlockSuccessorClosure(this).calculate();
return blockSuccessorClosure;
}
public void clearControlFlowBlockSuccessorClosure() {
this.blockSuccessorClosure = null;
}
public DominatorsGraph getDominators() {
if(dominators == null)
this.dominators = new PassNCalcDominators(this).calculate();

View File

@ -203,7 +203,7 @@ public class Registers {
@Override
public int hashCode() {
return Objects.hash(zp, bytes, nonRelocatable);
return zp;
}
}

View File

@ -11,7 +11,7 @@ public class StatementInfos {
/** The control flow graph. */
private ControlFlowGraph graph;
/** Maps statement index to block label. */
/** Maps statement index to block. */
private Map<Integer, ControlFlowBlock> stmtBlocks;
/** Maps statement index to statement. */

View File

@ -20,9 +20,6 @@ import java.util.stream.Collectors;
*/
public class VariableReferenceInfos {
/** For each block this is the closure of all successor blocks. */
private Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure;
/** References to variables/constants by block label. */
private Map<LabelRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> blockVarReferences;
@ -124,12 +121,10 @@ public class VariableReferenceInfos {
}
public VariableReferenceInfos(
Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure,
Map<SymbolVariableRef, Collection<ReferenceToSymbolVar>> symbolVarReferences,
Map<LabelRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> blockVarReferences,
Map<Integer, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> statementVarReferences
) {
this.blockSuccessorClosure = blockSuccessorClosure;
this.symbolVarReferences = symbolVarReferences;
this.blockVarReferences = blockVarReferences;
this.statementVarReferences = statementVarReferences;
@ -137,14 +132,6 @@ public class VariableReferenceInfos {
public String getSizeInfo() {
StringBuilder sizeInfo = new StringBuilder();
if(blockSuccessorClosure != null) {
sizeInfo.append("SIZE blockSuccessorClosure ").append(blockSuccessorClosure.size()).append(" labels ");
int sub = 0;
for(Collection<LabelRef> labelRefs : blockSuccessorClosure.values()) {
sub += labelRefs.size();
}
sizeInfo.append(" ").append(sub).append(" labels").append("\n");
}
{
sizeInfo.append("SIZE symbolVarReferences ").append(symbolVarReferences.size()).append(" SymbolVariableRefs ");
int sub = 0;
@ -182,28 +169,6 @@ public class VariableReferenceInfos {
return PassNCalcVariableReferenceInfos.getReferencedVars(rValue);
}
/**
* Get all variables used or defined inside a block and its successors (including any called method)
*
* @param labelRef The block to examine
* @return All used variables
*/
public Collection<VariableRef> getReferencedVars(LabelRef labelRef) {
ArrayList<VariableRef> variableRefs = new ArrayList<>();
blockSuccessorClosure.get(labelRef)
.forEach(labelRef1 -> blockVarReferences
.get(labelRef1)
.stream()
.filter(referenceToSymbolVar -> referenceToSymbolVar.getReferenced() instanceof VariableRef)
.forEach(referenceToSymbolVar -> {
if(!variableRefs.contains(referenceToSymbolVar.getReferenced()))
variableRefs.add((VariableRef) referenceToSymbolVar.getReferenced());
}
)
);
return variableRefs;
}
/**
* Get the variables defined by a statement
*
@ -213,7 +178,7 @@ public class VariableReferenceInfos {
public Collection<VariableRef> getDefinedVars(Statement stmt) {
Collection<ReferenceToSymbolVar> referenceToSymbolVars = statementVarReferences.get(stmt.getIndex());
// TODO: This may cause problems since it is a sign that the maps are out of date!
if(referenceToSymbolVars==null)
if(referenceToSymbolVars == null)
return new ArrayList<>();
return referenceToSymbolVars
.stream()
@ -255,6 +220,26 @@ public class VariableReferenceInfos {
.collect(Collectors.toList());
}
/**
* Get the variables referenced (used or defined) in a block.
*
* @param labelRef The label of the block.
* @return The referenced variables
*/
public Collection<VariableRef> getReferencedVars(LabelRef labelRef) {
ArrayList<VariableRef> variableRefs = new ArrayList<>();
blockVarReferences
.get(labelRef)
.stream()
.filter(referenceToSymbolVar -> referenceToSymbolVar.getReferenced() instanceof VariableRef)
.forEach(referenceToSymbolVar -> {
if(!variableRefs.contains(referenceToSymbolVar.getReferenced()))
variableRefs.add((VariableRef) referenceToSymbolVar.getReferenced());
}
);
return variableRefs;
}
/**
* Determines if a variable is unused
*

View File

@ -32,6 +32,7 @@ public class Pass1AssertUsedVars extends Pass1Base {
new PassNStatementIndices(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
ControlFlowBlock beginBlock = getProgram().getGraph().getBlock(new LabelRef(SymbolRef.BEGIN_BLOCK_NAME));
@ -44,6 +45,7 @@ public class Pass1AssertUsedVars extends Pass1Base {
}
assertUsedVars(beginBlock, null, referenceInfos, defined, new LinkedHashSet<>());
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
getProgram().clearStatementIndices();
return false;
}

View File

@ -26,6 +26,7 @@ public class Pass1CallVoidReturns extends Pass2SsaOptimization {
public boolean step() {
new PassNStatementIndices(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -59,6 +60,7 @@ public class Pass1CallVoidReturns extends Pass2SsaOptimization {
}
getProgram().clearStatementIndices();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
return false;
}

View File

@ -37,6 +37,7 @@ public class Pass2LoopHeadConstantIdentification extends Pass2SsaOptimization {
boolean modified = optimizeLoopHead(loopHeadBlock, loop, variableReferenceInfos);
if(modified) {
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
getProgram().clearStatementInfos();
getProgram().clearLoopSet();
getProgram().clearDominators();

View File

@ -31,6 +31,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
public boolean step() {
new PassNStatementIndices(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
boolean modified = false;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -138,6 +139,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
}
getProgram().clearVariableReferenceInfos();
getProgram().clearControlFlowBlockSuccessorClosure();
getProgram().clearStatementIndices();
return modified;
}

View File

@ -0,0 +1,62 @@
package dk.camelot64.kickc.passes.calcs;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.ControlFlowBlockSuccessorClosure;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementCallExecute;
import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.ProcedureRef;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
/** Calculates {@link dk.camelot64.kickc.model.ControlFlowBlockSuccessorClosure}. */
public class PassNCalcBlockSuccessorClosure extends PassNCalcBase<ControlFlowBlockSuccessorClosure> {
public PassNCalcBlockSuccessorClosure(Program program) {
super(program);
}
@Override
public ControlFlowBlockSuccessorClosure calculate() {
LinkedHashMap<LabelRef, Collection<LabelRef>> blockSuccessors = new LinkedHashMap<>();
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
LabelRef blockLabel = block.getLabel();
LinkedHashSet<LabelRef> successorClosure = new LinkedHashSet<>();
findSuccessorClosure(block.getLabel(), successorClosure, new ArrayList<>());
blockSuccessors.put(blockLabel, successorClosure);
}
return new ControlFlowBlockSuccessorClosure(blockSuccessors);
}
/**
* Recursively get all blocks in the closure of successors & calls for a specific block
*
* @param labelRef The block to examine
* @param successorClosure the set of all blocks that are successors (including called methods).
* @param visited The blocks already visited during the search. Used to stop infinite recursion.
*/
private void findSuccessorClosure(LabelRef labelRef, LinkedHashSet<LabelRef> successorClosure, Collection<LabelRef> visited) {
if(labelRef == null || visited.contains(labelRef))
return;
visited.add(labelRef);
ControlFlowBlock block = getProgram().getGraph().getBlock(labelRef);
if(block == null)
return;
successorClosure.add(labelRef);
findSuccessorClosure(block.getDefaultSuccessor(), successorClosure, visited);
findSuccessorClosure(block.getConditionalSuccessor(), successorClosure, visited);
findSuccessorClosure(block.getCallSuccessor(), successorClosure, visited);
// Also handle stack-calls
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementCallExecute) {
final ProcedureRef calledProcRef = ((StatementCallExecute) statement).getProcedure();
findSuccessorClosure(calledProcRef.getLabelRef(), successorClosure, visited);
}
}
}
}

View File

@ -42,10 +42,11 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
*/
public static Map<ProcedureRef, Collection<VariableRef>> calculateProcedureReferencedVars(Program program) {
VariableReferenceInfos referenceInfo = program.getVariableReferenceInfos();
final ControlFlowBlockSuccessorClosure blockSuccessorClosure = program.getControlFlowBlockSuccessorClosure();
Collection<Procedure> allProcedures = program.getScope().getAllProcedures(true);
Map<ProcedureRef, Collection<VariableRef>> procReferencedVars = new LinkedHashMap<>();
for(Procedure procedure : allProcedures) {
Collection<VariableRef> referencedVars = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef());
Collection<VariableRef> referencedVars = blockSuccessorClosure.getSuccessorClosureReferencedVars(procedure.getRef().getLabelRef(), referenceInfo);
procReferencedVars.put(procedure.getRef(), referencedVars);
}
return procReferencedVars;

View File

@ -33,18 +33,20 @@ public class PassNCalcLiveRangesEffectiveCallPaths extends PassNCalcBase<LiveRan
*/
private LiveRangeVariables liveRangeVariables;
/**
* Information about which procedures reference which variables.
*/
/** Information about which procedures reference which variables. */
private VariableReferenceInfos referenceInfo;
/** Information about which blocks follow other blocks. */
private ControlFlowBlockSuccessorClosure blockSuccessorClosure;
@Override
public LiveRangeVariablesEffectiveCallPaths calculate() {
this.liveRangeVariables = getProgram().getLiveRangeVariables();
this.referenceInfo = getProgram().getVariableReferenceInfos();
this.blockSuccessorClosure = getProgram().getControlFlowBlockSuccessorClosure();
this.procedureCallPaths = new LinkedHashMap<>();
populateProcedureCallPaths();
LiveRangeVariablesEffectiveCallPaths aliveEffective = new LiveRangeVariablesEffectiveCallPaths(getProgram(), procedureCallPaths, liveRangeVariables, referenceInfo);
LiveRangeVariablesEffectiveCallPaths aliveEffective = new LiveRangeVariablesEffectiveCallPaths(getProgram(), procedureCallPaths, liveRangeVariables, referenceInfo, blockSuccessorClosure);
return aliveEffective;
//getLog().append("Calculated effective variable live ranges");
}
@ -92,7 +94,7 @@ public class PassNCalcLiveRangesEffectiveCallPaths extends PassNCalcBase<LiveRan
// Make sure we have populated the call-paths of the calling procedure
populateProcedureCallPaths(callerProcedure, visited);
// Find variables referenced in caller procedure
Collection<VariableRef> referencedInCaller = referenceInfo.getReferencedVars(callerProcedure.getRef().getLabelRef());
Collection<VariableRef> referencedInCaller = blockSuccessorClosure.getSuccessorClosureReferencedVars(callerProcedure.getRef().getLabelRef(), referenceInfo);
// For each caller path - create a new call-path
LiveRangeVariablesEffectiveCallPaths.CallPaths callerPaths = procedureCallPaths.get(callerProcedure.getRef());
if(callerPaths!=null)

View File

@ -22,8 +22,6 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
@Override
public VariableReferenceInfos calculate() {
LinkedHashMap<LabelRef, Collection<LabelRef>> blockSuccessors = new LinkedHashMap<>();
Map<SymbolVariableRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> symbolVarReferences = new LinkedHashMap<>();
Map<LabelRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> blockVarReferences = new LinkedHashMap<>();
Map<Integer, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> statementVarReferences = new LinkedHashMap<>();
@ -57,12 +55,7 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
}
}
}
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
LabelRef blockLabel = block.getLabel();
LinkedHashSet<LabelRef> successorClosure = new LinkedHashSet<>();
findSuccessorClosure(block.getLabel(), successorClosure, new ArrayList<>());
blockSuccessors.put(blockLabel, successorClosure);
}
// Gather symbols in the symbol table referencing other variables/constants
Collection<Variable> allVariables = getProgram().getScope().getAllVars(true);
for(Variable referencingVar : allVariables) {
@ -77,7 +70,7 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
}
});
}
return new VariableReferenceInfos(blockSuccessors, symbolVarReferences, blockVarReferences, statementVarReferences);
return new VariableReferenceInfos(symbolVarReferences, blockVarReferences, statementVarReferences);
}
/**
@ -181,34 +174,6 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
return referenced;
}
/**
* Recursively get all blocks in the closure of successors & calls for a specific block
*
* @param labelRef The block to examine
* @param successorClosure the set of all blocks that are successors (including called methods).
* @param visited The blocks already visited during the search. Used to stop infinite recursion.
*/
private void findSuccessorClosure(LabelRef labelRef, LinkedHashSet<LabelRef> successorClosure, Collection<LabelRef> visited) {
if(labelRef == null || visited.contains(labelRef))
return;
visited.add(labelRef);
ControlFlowBlock block = getProgram().getGraph().getBlock(labelRef);
if(block == null)
return;
successorClosure.add(labelRef);
findSuccessorClosure(block.getDefaultSuccessor(), successorClosure, visited);
findSuccessorClosure(block.getConditionalSuccessor(), successorClosure, visited);
findSuccessorClosure(block.getCallSuccessor(), successorClosure, visited);
// Also handle stack-calls
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementCallExecute) {
final ProcedureRef calledProcRef = ((StatementCallExecute) statement).getProcedure();
findSuccessorClosure(calledProcRef.getLabelRef(), successorClosure, visited);
}
}
}
/**
* Get the variables defined by a statement
*

View File

@ -140,6 +140,13 @@ public class TestFragments {
testFragments("fragments-complex", signaturesComplex);
}
// @Test
// public void testPointers() throws IOException {
// List<String> signatures = Arrays.asList("vbuz1=pbuz2_derefidx_vbuc1");
// testFragments("fragments-complex", signatures);
// }
@Test
public void testFragmentsExist() {
testFragmentExists("vbuaa=pbuc2_derefidx_vbuxx");

View File

@ -4308,8 +4308,8 @@ public class TestPrograms {
@BeforeClass
public static void setUp() {
Path asmFragmentBaseFolder = new File("src/main/fragment/").toPath();
Path asmFragmentCacheFolder = null;
asmFragmentSynthesizer = new AsmFragmentTemplateSynthesizer(asmFragmentBaseFolder, TargetCpu.MOS6502X, asmFragmentCacheFolder, new CompileLog());
// Path asmFragmentCacheFolder = new File("src/main/fragment/cache").toPath();
asmFragmentSynthesizer = new AsmFragmentTemplateSynthesizer(asmFragmentBaseFolder, TargetCpu.MOS6502X, null, new CompileLog());
}
@AfterClass