duskphantom_middle/transform/
ultimate_pass.rs

1// Copyright 2024 Duskphantom Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// SPDX-License-Identifier: Apache-2.0
16
17use anyhow::Result;
18
19use crate::{config::CONFIG, Program};
20
21use super::{
22    block_fuse, dead_code_elim, func_inline, inst_combine, load_store_elim, loop_optimization,
23    make_parallel, mem2reg, redundance_elim, sink_code,
24};
25
26#[allow(unused)]
27pub fn optimize_program(program: &mut Program, level: usize) -> Result<bool> {
28    mem2reg::optimize_program(program)?;
29    main_loop(program)?;
30    if CONFIG.open_auto_parallel {
31        make_parallel::optimize_program::<5>(program)?;
32    }
33    eval_and_prune(program)?;
34    sink_code::optimize_program(program)?;
35    Ok(true)
36}
37
38pub fn main_loop(program: &mut Program) -> Result<bool> {
39    loop {
40        let mut changed = false;
41
42        // Inline functions
43        changed |= func_inline::optimize_program(program)?;
44
45        // Simplify code
46        changed |= eval_and_prune(program)?;
47
48        // Remove redundancy
49        changed |= redundance_elim::optimize_program(program)?;
50
51        // Optimize loop
52        // TODO add changed and timing info for this pass
53        // TODO remove inst_combine in loop_optimization
54        loop_optimization::optimize_program(program)?;
55
56        // Fuse blocks
57        changed |= block_fuse::optimize_program(program)?;
58
59        // Break if unchanged
60        if !changed {
61            break;
62        }
63    }
64    Ok(true)
65}
66
67pub fn eval_and_prune(program: &mut Program) -> Result<bool> {
68    let mut changed = false;
69    loop {
70        let mut c = false;
71        c |= inst_combine::optimize_program(program)?;
72        c |= load_store_elim::optimize_program(program)?;
73        c |= dead_code_elim::optimize_program(program)?;
74        changed |= c;
75        if !c {
76            break;
77        }
78    }
79    Ok(changed)
80}