diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-29 10:53:23 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-29 10:53:23 -0700 |
| commit | f47c7d1ffcd044b74620715072e8721b91819b61 (patch) | |
| tree | e0eea89e23c4903823b12c581ab8dcb3b977fd54 /chapter28b/src/test/java/com/seaofnodes | |
| parent | f7fcac0ac9ebfc11549272fa8c166c26e5418e3f (diff) | |
| download | Simple-f47c7d1ffcd044b74620715072e8721b91819b61.tar.gz Simple-f47c7d1ffcd044b74620715072e8721b91819b61.zip | |
Removing hook between encode and export
Diffstat (limited to 'chapter28b/src/test/java/com/seaofnodes')
| -rw-r--r-- | chapter28b/src/test/java/com/seaofnodes/simple/PhaseTest.java | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/chapter28b/src/test/java/com/seaofnodes/simple/PhaseTest.java b/chapter28b/src/test/java/com/seaofnodes/simple/PhaseTest.java index f2d09c7c..6505009d 100644 --- a/chapter28b/src/test/java/com/seaofnodes/simple/PhaseTest.java +++ b/chapter28b/src/test/java/com/seaofnodes/simple/PhaseTest.java @@ -4,6 +4,10 @@ import com.seaofnodes.graph.GraphObserver; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.CodeGen.Phase; import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.node.FunNode; +import com.seaofnodes.simple.type.TypeInteger; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import org.junit.Test; import static org.junit.Assert.*; @@ -71,11 +75,19 @@ public class PhaseTest { assertEquals(Phase.Serialize,code._phase); code.driver(Phase.Encoding,"riscv","SystemV"); assertNotNull(code._serial); + assertNotNull(code._encoding); CodeGen memory = new CodeGen(SRC).driver("riscv","SystemV",true,false); assertNull(memory._serial); assertEquals(Phase.Export,memory._phase); + // Keeping ideal IR must not force separate images when the caller + // explicitly requests in-memory linking. + CodeGen saved = new CodeGen(SRC).driver(Phase.Serialize); + saved.driver("riscv","SystemV",true,false); + assertNotNull(saved._serial); + assertArrayEquals(memory._encoding._bits.toByteArray(),saved._encoding._bits.toByteArray()); + CodeGen late = new CodeGen(SRC).driver(Phase.Encoding,"riscv","SystemV"); try { late.exportELF(false,false); @@ -84,4 +96,51 @@ public class PhaseTest { assertTrue(expected.getMessage().contains("Serialize before Lower")); } } + + @Test public void testStagedObjectExport() throws Exception { + Path root = Files.createTempDirectory(Files.createDirectories(Path.of("build/objs")),"phase-export-"); + Path src = Files.createDirectories(root.resolve("src")); + Files.createDirectories(src.resolve("Main")); + Files.writeString(src.resolve("Main.smp"),"val run_noInline = { int n -> Helper.twice_noInline(n)+1; };"); + Files.writeString(src.resolve("Main/Helper.smp"),"val twice_noInline = { int n -> n*2; };"); + Path cfile = root.resolve("driver.c"); + Files.writeString(cfile,""" + __attribute__((CALL_CONV)) extern long long run_noInline(long long); + int main(void) { return run_noInline(20)!=41 || run_noInline(-3)!=-5; } + """); + for( boolean direct : new boolean[]{false,true} ) { + Path obj = Files.createDirectories(root.resolve(direct ? "direct" : "driver")); + CodeGen code = new CodeGen(src.toString(),obj.toString(),null,"Main",null,123,true,TypeInteger.BOT) + .driver(Phase.Serialize); + if( direct ) { + code.driver(Phase.RegAlloc,TestC.CPU_PORT,TestC.CALL_CONVENTION); + code.encode(); + } else { + code.driver(Phase.Encoding,TestC.CPU_PORT,TestC.CALL_CONVENTION); + } + // Encoding has already separated the entry object's code from + // its dependency. Export only writes the prepared encodings. + assertNotNull(code._encoding); + for( var block : code._encoding._cfg ) + if( block instanceof FunNode fun ) + assertSame(code._compunits.get("Main"),fun._compunit); + assertFalse(Files.exists(obj.resolve("Main.o"))); + if( direct ) code.exportELF(false,false); + else code.driver(TestC.CPU_PORT,TestC.CALL_CONVENTION,false,false); + assertTrue(Files.exists(obj.resolve("Main.o"))); + assertTrue(Files.exists(obj.resolve("Main/Helper.o"))); + String exe = obj.resolve(TestC.OS.startsWith("Windows") ? "run.exe" : "run").toString(); + assertEquals("",TestC.gcc(code,TestC.CALL_CONVENTION.equals("win64") ? "ms_abi" : "sysv_abi", + cfile.toString(),null,exe)); + } + // The same serialized units can instead form one linked memory image. + CodeGen memory = new CodeGen(src.toString(),root.resolve("memory").toString(),null, + "Main",null,123,true,TypeInteger.BOT).driver(Phase.Serialize); + memory.driver("riscv","SystemV",true,false); + boolean helper = false; + for( var block : memory._encoding._cfg ) + if( block instanceof FunNode fun && fun._compunit==memory._compunits.get("Main/Helper") ) + helper = true; + assertTrue("The combined image includes dependency bodies",helper); + } } |
