From 913b42026c9cbe18f9d9a3b81021e1d7ff51cd2e Mon Sep 17 00:00:00 2001 From: abdussamedulutas Date: Thu, 18 Jun 2026 22:47:31 +0300 Subject: [PATCH] =?UTF-8?q?test(opt):=20#104/#105=20beyaz-kutu=20IR=20test?= =?UTF-8?q?leri=20=E2=80=94=20folding=20ve=20DCE=20do=C4=9Fru=20katmanda?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ir.hpp: --optimized bayrağı ile OptimizationManager entegrasyonu - ir_generator.cpp: hasDirectValue/directIntValue okunuyor (katlanmış literal IR'da 0 veriyordu) - run_golden.cmake: OPTIMIZED=1 parametresi ile --optimized desteği - CMakeLists.txt: *.ir_opt.expected → saqut ir --optimized otomatik keşif - opt/folding.ir_opt.expected: 2+3*4 → LOAD_CONST 14 (katlama kanıtı) - opt/dce.ir_opt.expected: LOAD_CONST 99 + CALLHOST print silindi (DCE kanıtı) - Yanıltıcı run-output testleri (folding.expected, dce.expected) kaldırıldı --- CMakeLists.txt | 28 +++++++++++++++++++----- cmake/run_golden.cmake | 18 ++++++++++----- src/cli/commands/ir.hpp | 18 +++++++++++++-- src/ir/ir_generator.cpp | 10 +++++++-- tests/golden/opt/dce.expected | 3 --- tests/golden/opt/dce.ir_opt.expected | 26 ++++++++++++++++++++++ tests/golden/opt/folding.expected | 7 ------ tests/golden/opt/folding.ir_opt.expected | 21 ++++++++++++++++++ 8 files changed, 106 insertions(+), 25 deletions(-) delete mode 100644 tests/golden/opt/dce.expected create mode 100644 tests/golden/opt/dce.ir_opt.expected delete mode 100644 tests/golden/opt/folding.expected create mode 100644 tests/golden/opt/folding.ir_opt.expected diff --git a/CMakeLists.txt b/CMakeLists.txt index b9deca8..0dd02c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,24 +33,42 @@ add_test( COMMAND bash "${CMAKE_SOURCE_DIR}/tests/run.sh" ) -# Golden testleri — tests/golden/**/*.sqt + .expected çiftlerini otomatik keşfet +# Golden testleri — tests/golden/**/*.sqt dosyalarını otomatik keşfet. +# Her .sqt için iki olası expected dosyası kontrol edilir: +# BASE.expected → saqut run (siyah-kutu çıktı testi) +# BASE.ir_opt.expected → saqut ir --optimized (beyaz-kutu IR testi) file(GLOB_RECURSE ALL_GOLDEN_SQT CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/tests/golden/*.sqt" ) foreach(SQT_FILE ${ALL_GOLDEN_SQT}) - # Göreli yoldan test adı üret: fibonacci/fib.sqt → golden_fibonacci_fib file(RELATIVE_PATH REL "${CMAKE_SOURCE_DIR}/tests/golden" "${SQT_FILE}") string(REPLACE ".sqt" "" BASE "${REL}") string(REPLACE "/" "_" TNAME "${BASE}") - set(EXPECTED_FILE "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.expected") - if(EXISTS "${EXPECTED_FILE}") + # Siyah-kutu: saqut run çıktısı + set(RUN_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.expected") + if(EXISTS "${RUN_EXPECTED}") add_test( NAME "golden_${TNAME}" COMMAND ${CMAKE_COMMAND} -DBINARY=${SAQUT_BINARY} -DSOURCE=${SQT_FILE} - -DEXPECTED=${EXPECTED_FILE} + -DEXPECTED=${RUN_EXPECTED} + -P "${GOLDEN_SCRIPT}" + ) + endif() + + # Beyaz-kutu: saqut ir --optimized çıktısı + set(IR_OPT_EXPECTED "${CMAKE_SOURCE_DIR}/tests/golden/${BASE}.ir_opt.expected") + if(EXISTS "${IR_OPT_EXPECTED}") + add_test( + NAME "golden_${TNAME}_ir_opt" + COMMAND ${CMAKE_COMMAND} + -DBINARY=${SAQUT_BINARY} + -DSOURCE=${SQT_FILE} + -DEXPECTED=${IR_OPT_EXPECTED} + -DCOMMAND=ir + -DOPTIMIZED=1 -P "${GOLDEN_SCRIPT}" ) endif() diff --git a/cmake/run_golden.cmake b/cmake/run_golden.cmake index 6da0399..768cf9e 100644 --- a/cmake/run_golden.cmake +++ b/cmake/run_golden.cmake @@ -1,17 +1,23 @@ # run_golden.cmake — tek bir golden test çalıştırır ve çıktıyı karşılaştırır. # -# Kullanım (CMake add_test içinden): -# cmake -DBINARY= -DSOURCE=<.sqt yolu> -DEXPECTED=<.expected yolu> -# [-DCOMMAND=run] -P run_golden.cmake -# -# COMMAND varsayılanı "run". IR testleri için COMMAND=ir geçilir. +# Parametreler (cmake -D ile geçilir): +# BINARY — saqut binary yolu +# SOURCE — test .sqt dosyası (tam yol) +# EXPECTED — beklenen çıktı dosyası (tam yol) +# COMMAND — "run" (varsayılan) veya "ir" +# OPTIMIZED — 1 ise --optimized bayrağı eklenir if(NOT DEFINED COMMAND) set(COMMAND "run") endif() +set(EXTRA_FLAGS "") +if(OPTIMIZED) + list(APPEND EXTRA_FLAGS "--optimized") +endif() + execute_process( - COMMAND "${BINARY}" "${COMMAND}" "file:${SOURCE}" + COMMAND "${BINARY}" "${COMMAND}" ${EXTRA_FLAGS} "file:${SOURCE}" OUTPUT_VARIABLE ACTUAL ERROR_VARIABLE STDERR_OUT RESULT_VARIABLE EXIT_CODE diff --git a/src/cli/commands/ir.hpp b/src/cli/commands/ir.hpp index d11b193..1e05614 100644 --- a/src/cli/commands/ir.hpp +++ b/src/cli/commands/ir.hpp @@ -11,6 +11,8 @@ #include "semantic/structural_validator.hpp" #include "diagnostic/diagnostic_engine.hpp" #include "ir/ir_generator.hpp" +#include "core/config.hpp" +#include "opt/optimization_manager.hpp" inline int cmdIr(const CliArgs& args) { std::string filePath = inputFilePath(args); @@ -41,11 +43,23 @@ inline int cmdIr(const CliArgs& args) { return 1; } - IRGenerator irGenerator; - IRProgram program = irGenerator.generate(ast, symbolTable); + // --optimized: optimize edilmiş AST klonu üzerinden IR üret + ASTNode* activeAst = ast; + ASTNode* optimizedAst = nullptr; + if (args.optimized) { + CompilerConfig cfg; + DiagnosticEngine optDiag; + OptimizationManager mgr(cfg, optDiag); + optimizedAst = mgr.optimize(ast, &symbolTable); + activeAst = optimizedAst; + optDiag.printAll(std::cerr); // W002 vb. uyarılar stderr'e + } + IRGenerator irGenerator; + IRProgram program = irGenerator.generate(activeAst, symbolTable); program.dump(); + delete optimizedAst; // nullptr ise no-op delete ast; for (auto* t : tokens) delete t; return 0; diff --git a/src/ir/ir_generator.cpp b/src/ir/ir_generator.cpp index 947355d..4931f84 100644 --- a/src/ir/ir_generator.cpp +++ b/src/ir/ir_generator.cpp @@ -271,13 +271,19 @@ int IRGenerator::generateExpression(ASTNode* node) { switch (lit->literalType) { case LiteralType::INTEGER: { int value = 0; - if (lit->parserToken.token) + if (lit->hasDirectValue) + value = lit->directIntValue; + else if (lit->parserToken.token) value = std::stoi(lit->parserToken.token->token); emitLoadConst(slot, value); break; } case LiteralType::BOOLEAN: { - int value = (lit->parserToken.token && + int value = 0; + if (lit->hasDirectValue) + value = lit->directIntValue ? 1 : 0; + else + value = (lit->parserToken.token && lit->parserToken.token->token == "true") ? 1 : 0; emitLoadConst(slot, value); break; diff --git a/tests/golden/opt/dce.expected b/tests/golden/opt/dce.expected deleted file mode 100644 index f6c35ff..0000000 --- a/tests/golden/opt/dce.expected +++ /dev/null @@ -1,3 +0,0 @@ -10 -0 -0 diff --git a/tests/golden/opt/dce.ir_opt.expected b/tests/golden/opt/dce.ir_opt.expected new file mode 100644 index 0000000..722683b --- /dev/null +++ b/tests/golden/opt/dce.ir_opt.expected @@ -0,0 +1,26 @@ +IR DUMP + +NAME=hesapla PARAMS=1 SLOTS=6 + 0 LOAD_CONST s1 = 0 + 1 GREATER s2 = s0 > s1 + 2 JIF_FALSE !s2 → 6 + 3 LOAD_CONST s3 = 2 + 4 MUL s4 = s0 * s3 + 5 RETURN s4 + 6 LOAD_CONST s5 = 0 + 7 RETURN s5 + +NAME=main PARAMS=0 SLOTS=7 + 0 LOAD_CONST s0 = 5 + 1 CALL s1 = hesapla(s0) + 2 CALLHOST print(s1) + 3 LOAD_CONST s2 = 0 + 4 CALL s3 = hesapla(s2) + 5 CALLHOST print(s3) + 6 LOAD_CONST s4 = -3 + 7 CALL s5 = hesapla(s4) + 8 CALLHOST print(s5) + 9 LOAD_CONST s6 = 0 + 10 RETURN s6 + +END diff --git a/tests/golden/opt/folding.expected b/tests/golden/opt/folding.expected deleted file mode 100644 index 2198d1f..0000000 --- a/tests/golden/opt/folding.expected +++ /dev/null @@ -1,7 +0,0 @@ -14 -3 -1 -0 -1 -0 -0 diff --git a/tests/golden/opt/folding.ir_opt.expected b/tests/golden/opt/folding.ir_opt.expected new file mode 100644 index 0000000..dd47bd4 --- /dev/null +++ b/tests/golden/opt/folding.ir_opt.expected @@ -0,0 +1,21 @@ +IR DUMP + +NAME=main PARAMS=0 SLOTS=8 + 0 LOAD_CONST s0 = 14 + 1 CALLHOST print(s0) + 2 LOAD_CONST s1 = 3 + 3 CALLHOST print(s1) + 4 LOAD_CONST s2 = 1 + 5 CALLHOST print(s2) + 6 LOAD_CONST s3 = 0 + 7 CALLHOST print(s3) + 8 LOAD_CONST s4 = 1 + 9 CALLHOST print(s4) + 10 LOAD_CONST s5 = 0 + 11 CALLHOST print(s5) + 12 LOAD_CONST s6 = 1 + 13 CALLHOST print(s6) + 14 LOAD_CONST s7 = 0 + 15 RETURN s7 + +END