feat: implement Phase 4d const-fold transform for select AST
Adds sel_const_fold_pass() — a single-pass bottom-up const-fold that
runs after the Phase 4c flatten loop in parse_select():
4d-1 EQ/NE with either operand SEL_ANY → SEL_TRUE / SEL_FALSE
(checks both child slots — commutativity sort makes SEL_ANY
position non-deterministic after makeSelectNode interning)
4d-2 Identity laws: TRUE&&X→X, X&&TRUE→X, FALSE||X→X, X||FALSE→X
4d-3 Annihilation laws: FALSE&&X→FALSE, TRUE||X→TRUE (symmetric)
4d-4 Complement laws: !TRUE→FALSE, !FALSE→TRUE
Memory semantics:
level==0 (API server): frees orphaned nodes via free_select_node /
sel_free_tree; OOM from makeSelectNode returns original node safely
level>0 (CSE/scheduler): never manually frees; annihilation folds
return the already-interned left/right singleton directly (no
redundant makeSelectNode call); OOM guard unconditional so CSE
mode also degrades gracefully instead of returning NULL
9 new TDD tests added to test_select.c (RED→GREEN verified).
All 166 tests pass (157 prior + 9 Phase 4d).
This commit is contained in:
parent
c2ad96a5e0
commit
b38babb7d6
9 changed files with 3248 additions and 5 deletions
58
src/lib/testsuite/test_resmgr_fixture.c
Normal file
58
src/lib/testsuite/test_resmgr_fixture.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtti.h>
|
||||
|
||||
#include "kv.h"
|
||||
#include "resreq.h"
|
||||
#include "xce/types.h"
|
||||
#include "test_resmgr_fixture.h"
|
||||
|
||||
/* Internal helper to add one resource to the test resmgr */
|
||||
static void add_resource(var resmgr, const char* name, int idx, int valtype)
|
||||
{
|
||||
xce_resource_t* r = calloc(1, sizeof(*r));
|
||||
if (r == NULL) return;
|
||||
r->name = strdup(name);
|
||||
r->idx = idx;
|
||||
r->valtype = valtype;
|
||||
key_add(resmgr, (void*)r->name, r);
|
||||
}
|
||||
|
||||
var make_test_resmgr(void)
|
||||
{
|
||||
kv_params_t params = {
|
||||
.nslots = 64,
|
||||
.keyops = &string_key_ops,
|
||||
.datakiller = NULL, /* we free resources manually in free_test_resmgr */
|
||||
};
|
||||
var resmgr = makeInstance(&kvtab_type, ¶ms);
|
||||
if (resmgr == NULL) return NULL;
|
||||
|
||||
add_resource(resmgr, "type", TEST_RES_TYPE_IDX, XCE_VAL_STRING);
|
||||
add_resource(resmgr, "mem", TEST_RES_MEM_IDX, XCE_VAL_NUMERIC);
|
||||
add_resource(resmgr, "gpu", TEST_RES_GPU_IDX, XCE_VAL_BOOLEAN);
|
||||
add_resource(resmgr, "ncpus", TEST_RES_NCPUS_IDX, XCE_VAL_NUMERIC);
|
||||
add_resource(resmgr, "arch", TEST_RES_ARCH_IDX, XCE_VAL_STRING);
|
||||
|
||||
return resmgr;
|
||||
}
|
||||
|
||||
void free_test_resmgr(var resmgr)
|
||||
{
|
||||
if (resmgr == NULL) return;
|
||||
|
||||
/* Free each xce_resource_t we allocated (datakiller=NULL means kvtab
|
||||
* won't free them, so we must do it here). */
|
||||
const char* names[] = { "type", "mem", "gpu", "ncpus", "arch", NULL };
|
||||
for (int i = 0; names[i] != NULL; i++) {
|
||||
xce_resource_t* r = NULL;
|
||||
int rc = key_find(resmgr, (void*)names[i], (void**)&r);
|
||||
if (rc > 0 && r != NULL) {
|
||||
free(r->name);
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
|
||||
destroy(resmgr);
|
||||
}
|
||||
19
src/lib/testsuite/test_resmgr_fixture.h
Normal file
19
src/lib/testsuite/test_resmgr_fixture.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#if !defined(_TEST_RESMGR_FIXTURE_H_)
|
||||
#define _TEST_RESMGR_FIXTURE_H_
|
||||
|
||||
#include <rtti.h>
|
||||
|
||||
/* Test resource indices — must match make_test_resmgr() registration order */
|
||||
#define TEST_RES_TYPE_IDX 0 /* "type" — RES_TYPE_STRING */
|
||||
#define TEST_RES_MEM_IDX 1 /* "mem" — RES_TYPE_NUMERIC */
|
||||
#define TEST_RES_GPU_IDX 2 /* "gpu" — RES_TYPE_BOOL */
|
||||
#define TEST_RES_NCPUS_IDX 3 /* "ncpus" — RES_TYPE_NUMERIC */
|
||||
#define TEST_RES_ARCH_IDX 4 /* "arch" — RES_TYPE_STRING */
|
||||
|
||||
/* Create a test resmgr with 5 pre-registered resources.
|
||||
* Returns a var (kvtab) that can be passed to parse_select / parse_resreq_primary.
|
||||
* Caller must call free_test_resmgr() when done. */
|
||||
extern var make_test_resmgr(void);
|
||||
extern void free_test_resmgr(var resmgr);
|
||||
|
||||
#endif
|
||||
1365
src/lib/testsuite/test_select.c
Normal file
1365
src/lib/testsuite/test_select.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue