I leaned on the AI assistant more than I should have for the dead-code elimination part and it gave me something that passed maybe two thirds of the cases but missed edge cases around loops.
Start by clarifying the input format (source code or IR), the available time, and the test harness. Then prioritize optimizations by impact and implementation complexity: begin with constant folding/propagation and dead-code elimination, followed by common subexpression elimination, variable reuse, and operation reordering. Implement each pass as a separate module, test incrementally, and use profiling to guide further optimizations.
Pro tip: Focus on correctness first: an optimization that breaks semantics will fail more tests than it passes. Use a pass manager with dependency tracking and validate after each pass to catch regressions early.
Clarify the input format (source or IR), the test harness, time limit, and allowed tools. Identify the language features and optimization opportunities.
Plan a sequence of independent passes (constant folding/propagation, dead-code elimination, CSE, variable reuse, reordering) with clear interfaces and a pass manager to handle dependencies.
Start with the simplest high-impact passes (constant folding, dead-code elimination). Write unit tests for each pass and run the full test suite after each addition to ensure correctness.
Profile the compiler and generated code. Use efficient data structures (e.g., hash consing for CSE, liveness analysis for variable reuse) and consider trade-offs between optimization aggressiveness and compile time.
Run the provided test cases, measure improvements, and iterate on the most impactful optimizations. Ensure all passes preserve program semantics.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.