From 8fbe49f2723fc0bad3ec4e08cf6dcb430e107845 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 29 May 2020 18:49:10 +0200 Subject: [PATCH] Fixed problem where an unused assigned variable is not taken properly into account when deciding whether it is possible to coalesce two variable live range equivalence classes. Closes #464 --- .../Pass4RegisterUpliftCombinations.java | 9 +++++- src/test/ref/problem-ma-var-overwrite.asm | 8 +++--- src/test/ref/problem-ma-var-overwrite.log | 28 +++++++++---------- src/test/ref/problem-ma-var-overwrite.sym | 7 +++-- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java index de4866636..90b814c86 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java @@ -198,10 +198,17 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base { * @return true if there is an overlapping register allocation */ private static boolean isStatementAllocationOverlapping(Program program, Statement statement) { + VariableReferenceInfos variableReferenceInfos = program.getVariableReferenceInfos(); LiveRangeVariablesEffective.AliveCombinations aliveCombinations = program.getLiveRangeVariablesEffective().getAliveCombinations(statement); for(LiveRangeVariablesEffective.AliveCombination combination : aliveCombinations.getAll()) { LinkedHashMap usedRegisters = new LinkedHashMap<>(); Collection aliveAtStmt = combination.getEffectiveAliveAtStmt(); + final Collection stmtDefinedVars = variableReferenceInfos.getDefinedVars(statement); + if(!aliveAtStmt.containsAll(stmtDefinedVars)) { + // Also add the variables assigned by the statement. They are written to even if they are not used later - so they are used! + aliveAtStmt = new LinkedHashSet<>(aliveAtStmt); + aliveAtStmt.addAll(stmtDefinedVars); + } Pass2AliasElimination.Aliases aliasesAtStmt = combination.getEffectiveAliasesAtStmt(); for(VariableRef varRef : aliveAtStmt) { Variable var = program.getSymbolInfos().getVariable(varRef); @@ -210,7 +217,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base { if(allocationClass != null && !allocationClass.contains(varRef)) { // Examine if the var is an alias of a var in the allocation class boolean overlap = true; - if(aliasesAtStmt!=null) { + if(aliasesAtStmt != null) { Pass2AliasElimination.AliasSet aliasSet = aliasesAtStmt.findAliasSet(varRef); if(aliasSet != null) { for(VariableRef aliasVar : aliasSet.getVars()) { diff --git a/src/test/ref/problem-ma-var-overwrite.asm b/src/test/ref/problem-ma-var-overwrite.asm index f0fcd58e4..408689a30 100644 --- a/src/test/ref/problem-ma-var-overwrite.asm +++ b/src/test/ref/problem-ma-var-overwrite.asm @@ -25,8 +25,8 @@ main: { test: { .label colorMem = $d800 .label other = $c000 - .label dst = 4 - .label __1 = 4 + .label dst = 6 + .label __1 = 6 .label diff = 4 .label videoMem = 4 // dst @@ -42,11 +42,11 @@ test: { sbc.z diff+1 sta.z diff+1 // other + ((unsigned int)diff) + lda.z diff clc - lda.z __1 adc #other sta.z __1+1 // dst = other + ((unsigned int)diff) diff --git a/src/test/ref/problem-ma-var-overwrite.log b/src/test/ref/problem-ma-var-overwrite.log index e1397776a..db48a1094 100644 --- a/src/test/ref/problem-ma-var-overwrite.log +++ b/src/test/ref/problem-ma-var-overwrite.log @@ -305,7 +305,6 @@ Uplifting [] best 136 combination zp[2]:2 [ h1 ] Uplifting [main] best 136 combination Coalescing zero page register [ zp[2]:4 [ test::videoMem#0 ] ] with [ zp[2]:8 [ test::diff#1 ] ] - score: 1 Coalescing zero page register [ zp[2]:6 [ test::dst ] ] with [ zp[2]:10 [ test::$1 ] ] - score: 1 -Coalescing zero page register [ zp[2]:4 [ test::videoMem#0 test::diff#1 ] ] with [ zp[2]:6 [ test::dst test::$1 ] ] - score: 1 ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -356,8 +355,8 @@ main: { test: { .label colorMem = $d800 .label other = $c000 - .label dst = 4 - .label __1 = 4 + .label dst = 6 + .label __1 = 6 .label diff = 4 .label videoMem = 4 // [7] (byte*) test::dst ← (byte*) 0 -- pbuz1=pbuc1 @@ -373,12 +372,12 @@ test: { lda #>colorMem sbc.z diff+1 sta.z diff+1 - // [9] (byte*~) test::$1 ← (const byte*) test::other#0 + (word)(byte*)(word) test::diff#1 -- pbuz1=pbuc1_plus_vwuz1 + // [9] (byte*~) test::$1 ← (const byte*) test::other#0 + (word)(byte*)(word) test::diff#1 -- pbuz1=pbuc1_plus_vwuz2 + lda.z diff clc - lda.z __1 adc #other sta.z __1+1 // [10] (byte*) test::dst ← (byte*~) test::$1 @@ -428,20 +427,21 @@ FINAL SYMBOL TABLE (void()) main() (label) main::@return (void()) test((byte*) test::videoMem , (byte*) test::colorMem , (byte*) test::other) -(byte*~) test::$1 zp[2]:4 202.0 +(byte*~) test::$1 zp[2]:6 202.0 (label) test::@return (byte*) test::colorMem (const byte*) test::colorMem#0 colorMem = (byte*) 55296 (byte*) test::diff (word) test::diff#1 diff zp[2]:4 101.0 -(byte*) test::dst loadstore zp[2]:4 151.5 +(byte*) test::dst loadstore zp[2]:6 151.5 (byte*) test::other (const byte*) test::other#0 other = (byte*) 49152 (byte*) test::videoMem (byte*) test::videoMem#0 videoMem zp[2]:4 56.0 zp[2]:2 [ h1 ] -zp[2]:4 [ test::videoMem#0 test::diff#1 test::dst test::$1 ] +zp[2]:4 [ test::videoMem#0 test::diff#1 ] +zp[2]:6 [ test::dst test::$1 ] FINAL ASSEMBLER @@ -490,8 +490,8 @@ main: { test: { .label colorMem = $d800 .label other = $c000 - .label dst = 4 - .label __1 = 4 + .label dst = 6 + .label __1 = 6 .label diff = 4 .label videoMem = 4 // dst @@ -509,12 +509,12 @@ test: { sbc.z diff+1 sta.z diff+1 // other + ((unsigned int)diff) - // [9] (byte*~) test::$1 ← (const byte*) test::other#0 + (word)(byte*)(word) test::diff#1 -- pbuz1=pbuc1_plus_vwuz1 + // [9] (byte*~) test::$1 ← (const byte*) test::other#0 + (word)(byte*)(word) test::diff#1 -- pbuz1=pbuc1_plus_vwuz2 + lda.z diff clc - lda.z __1 adc #other sta.z __1+1 // dst = other + ((unsigned int)diff) diff --git a/src/test/ref/problem-ma-var-overwrite.sym b/src/test/ref/problem-ma-var-overwrite.sym index 8a81731bd..af06fe52d 100644 --- a/src/test/ref/problem-ma-var-overwrite.sym +++ b/src/test/ref/problem-ma-var-overwrite.sym @@ -5,17 +5,18 @@ (void()) main() (label) main::@return (void()) test((byte*) test::videoMem , (byte*) test::colorMem , (byte*) test::other) -(byte*~) test::$1 zp[2]:4 202.0 +(byte*~) test::$1 zp[2]:6 202.0 (label) test::@return (byte*) test::colorMem (const byte*) test::colorMem#0 colorMem = (byte*) 55296 (byte*) test::diff (word) test::diff#1 diff zp[2]:4 101.0 -(byte*) test::dst loadstore zp[2]:4 151.5 +(byte*) test::dst loadstore zp[2]:6 151.5 (byte*) test::other (const byte*) test::other#0 other = (byte*) 49152 (byte*) test::videoMem (byte*) test::videoMem#0 videoMem zp[2]:4 56.0 zp[2]:2 [ h1 ] -zp[2]:4 [ test::videoMem#0 test::diff#1 test::dst test::$1 ] +zp[2]:4 [ test::videoMem#0 test::diff#1 ] +zp[2]:6 [ test::dst test::$1 ]