Files
whetstone_DSL/editor/src/StrategyAwareOptimizer.h
Bill dc94ad7274 Sprint 3 complete: Phases 3g+3h (Steps 68-75), all 75 steps done
Phase 3g — Optimization Pipeline (17/17 tests):
  Step 68: TransformEngine — constant folding, dead code elimination, OptimizationLock warning
  Step 69: StrategyAwareOptimizer — annotation-constrained (@Reclaim allows, @Owner blocks duplication, @Deallocate blocks reorder, @Allocate blocks dynamic)
  Step 70: StrategyValidator — post-optimization invariants (use-after-free, leak, aliasing)
  Step 71: IncrementalOptimizer — transform journal, undo by ID, provenance tracking

Phase 3h — Integration & Validation (26/26 tests):
  Step 72: Pipeline — end-to-end parse→infer→validate→optimize→generate for Python/C++
  Step 73: Error handling — empty ASTs, null roots, nonexistent IDs, unannotated code
  Step 74: Performance benchmarks — 1000-fn AST 1ms, JSON round-trip 4ms, 50 transforms+undo 1ms
  Step 75: APIDocGenerator — structured docs for 23 components across 6 categories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 07:35:37 -07:00

147 lines
5.1 KiB
C++

#pragma once
#include <string>
#include <vector>
#include "ast/ASTNode.h"
#include "ast/Annotation.h"
#include "ast/Expression.h"
#include "ast/Statement.h"
class StrategyAwareOptimizer {
public:
struct OptResult {
bool applied;
std::string warning;
std::string blocked;
int nodesModified;
};
void setRoot(ASTNode* root) { root_ = root; }
OptResult inlineVariable(const std::string& variableId) {
OptResult result{false, "", "", 0};
auto* node = findNode(root_, variableId);
if (!node) return result;
auto constraint = getAnnotationConstraint(node);
if (constraint == Constraint::BlockDuplication) {
result.blocked = "@Owner(Single) blocks inlining (would create alias)";
return result;
}
result.applied = true;
result.nodesModified = 1;
return result;
}
OptResult reorderStatements(const std::string& functionId) {
OptResult result{false, "", "", 0};
auto* fn = findNode(root_, functionId);
if (!fn) return result;
auto constraint = getAnnotationConstraint(fn);
if (constraint == Constraint::BlockReorder) {
result.blocked = "@Deallocate(Explicit) blocks reordering around deallocation points";
return result;
}
result.applied = true;
result.nodesModified = 1;
return result;
}
OptResult duplicateNode(const std::string& nodeId) {
OptResult result{false, "", "", 0};
auto* node = findNode(root_, nodeId);
if (!node) return result;
auto constraint = getAnnotationConstraint(node);
if (constraint == Constraint::BlockDuplication) {
result.blocked = "@Owner(Single) blocks duplication (would create alias)";
return result;
}
if (constraint == Constraint::BlockDynamicAlloc) {
result.blocked = "@Allocate(Static) blocks duplication (would require dynamic allocation)";
return result;
}
result.applied = true;
result.nodesModified = 1;
return result;
}
OptResult optimizeFunction(const std::string& functionId) {
OptResult result{false, "", "", 0};
auto* fn = findNode(root_, functionId);
if (!fn) return result;
auto constraint = getAnnotationConstraint(fn);
if (constraint == Constraint::BlockDuplication) {
result.blocked = "@Owner(Single) blocks optimization (aliasing risk)";
return result;
}
if (constraint == Constraint::BlockReorder) {
result.blocked = "@Deallocate(Explicit) blocks optimization (reorder risk)";
return result;
}
if (constraint == Constraint::BlockDynamicAlloc) {
result.blocked = "@Allocate(Static) blocks optimization (dynamic alloc risk)";
return result;
}
// FreeRestructure or no constraint — proceed
result.applied = true;
result.nodesModified = 1;
return result;
}
private:
ASTNode* root_ = nullptr;
enum class Constraint {
None,
FreeRestructure, // @Reclaim(Tracing) — anything goes
BlockDuplication, // @Owner(Single) — no aliasing
BlockReorder, // @Deallocate(Explicit) — no reordering around dealloc
BlockDynamicAlloc // @Allocate(Static) — no dynamic allocation
};
// Find the dominant annotation constraint for a node (check self + ancestors)
Constraint getAnnotationConstraint(ASTNode* node) {
// Check the node itself and its ancestors for annotations
ASTNode* current = node;
while (current) {
auto annotations = current->getChildren("annotations");
for (auto* anno : annotations) {
if (anno->conceptType == "OwnerAnnotation") {
auto* oa = static_cast<OwnerAnnotation*>(anno);
if (oa->strategy == "Single") return Constraint::BlockDuplication;
}
if (anno->conceptType == "DeallocateAnnotation") {
auto* da = static_cast<DeallocateAnnotation*>(anno);
if (da->strategy == "Explicit") return Constraint::BlockReorder;
}
if (anno->conceptType == "AllocateAnnotation") {
auto* aa = static_cast<AllocateAnnotation*>(anno);
if (aa->strategy == "Static") return Constraint::BlockDynamicAlloc;
}
if (anno->conceptType == "ReclaimAnnotation") {
auto* ra = static_cast<ReclaimAnnotation*>(anno);
if (ra->strategy == "Tracing") return Constraint::FreeRestructure;
}
}
current = current->parent;
}
return Constraint::None;
}
ASTNode* findNode(ASTNode* node, const std::string& id) {
if (!node) return nullptr;
if (node->id == id) return node;
for (auto* child : node->allChildren()) {
auto* found = findNode(child, id);
if (found) return found;
}
return nullptr;
}
};