Skip to content

Optimization presets: implement -O0, -O1, -O2, -O3 pass pipelines #84

@yudongusa

Description

@yudongusa

Background

Currently the `PassManager` is a flat, user-assembled sequence. Production compilers expose standard optimization levels (-O0 through -O3) that choose a well-tuned sequence of passes. Users and frontends need this — nobody wants to manually compose 20 passes.

Proposed API

// llvm-transforms/src/pipeline.rs
pub enum OptLevel { O0, O1, O2, O3 }

pub fn build_pipeline(level: OptLevel) -> PassManager {
    let mut pm = PassManager::new();
    match level {
        OptLevel::O0 => { /* no passes */ }
        OptLevel::O1 => {
            pm.add_function_pass(Mem2Reg);
            pm.add_function_pass(DeadCodeElim);
            pm.add_function_pass(ConstProp);
        }
        OptLevel::O2 => {
            // O1 passes +
            pm.add_function_pass(Inliner::default());
            pm.add_function_pass(Gvn);
            pm.add_function_pass(LoopUnroll::default());
        }
        OptLevel::O3 => {
            // O2 passes +
            pm.add_function_pass(LoopVectorize::default());
            pm.add_module_pass(Ipa);
        }
    }
    pm
}

Required new passes for O2/O3

Acceptance criteria

  • build_pipeline(OptLevel) function in llvm-transforms
  • O0 and O1 pipelines working with current passes
  • Integration test: same .ll file run through O0 vs O2 produces semantically equivalent but measurably smaller IR
  • Benchmark showing wall-clock speedup of O2 vs O0 on the sample.ll fixture
  • Exposed in the examples/tikv_jit example via a --opt-level flag

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions