VapourSynth-llvmexpr
Loading...
Searching...
No Matches
analysis::StructurizeCFGPass Class Reference

#include <llvmexpr/analysis/passes/StructurizeCFGPass.hpp>

Inheritance diagram for analysis::StructurizeCFGPass:
Collaboration diagram for analysis::StructurizeCFGPass:

Public Types

using Result = StructurizeCFGResult
Public Types inherited from analysis::AnalysisPass< StructurizeCFGPass, StructurizeCFGResult >
using Result

Public Member Functions

const char * getName () const override
Result run (const std::vector< Token > &tokens, AnalysisManager &am) override
Public Member Functions inherited from analysis::Pass
 Pass ()=default
virtual ~Pass ()=default
 Pass (const Pass &)=delete
Passoperator= (const Pass &)=delete
 Pass (Pass &&)=delete
Passoperator= (Pass &&)=delete

Detailed Description

Computes CFG structuring information for structured-control-flow codegen. Responsibilities:

  • Compute post-dominators (for join point selection)
  • Identify natural loops (backedges + loop body closure)
  • Compute loop follow blocks Depends on: BuildCFGPass, BlockAnalysisPass

Definition at line 84 of file StructurizeCFGPass.hpp.

Member Typedef Documentation

◆ Result

Member Function Documentation

◆ getName()

const char * analysis::StructurizeCFGPass::getName ( ) const
inlinenodiscardoverridevirtual

Implements analysis::Pass.

Definition at line 89 of file StructurizeCFGPass.hpp.

89 {
90 return "StructurizeCFG (Control Flow Structuring) Pass";
91 }

◆ run()

StructurizeCFGPass::Result analysis::StructurizeCFGPass::run ( const std::vector< Token > & tokens,
AnalysisManager & am )
overridevirtual

Implements analysis::AnalysisPass< StructurizeCFGPass, StructurizeCFGResult >.

Definition at line 676 of file StructurizeCFGPass.cpp.

677 {
678 const auto& block_result = am.getResult<BlockAnalysisPass>();
679 const auto& cfg = block_result.cfg_blocks;
680 const auto& stack_safety = am.getResult<StackSafetyPass>();
681
682 Result result;
683
684 if (cfg.empty()) {
685 return result;
686 }
687
688 const auto reachable0 = compute_reachable(cfg);
689 const bool reducible0 = check_reducible(cfg, reachable0);
690
691 const std::vector<CFGBlock>* analysis_cfg = &cfg;
692
693 std::vector<CFGBlock> work_cfg = cfg;
694 std::vector<int> origin_map(cfg.size());
695 for (size_t i = 0; i < cfg.size(); ++i) {
696 origin_map[i] = static_cast<int>(i);
697 }
698
699 constexpr size_t MAX_BLOCKS = 256;
700 constexpr size_t MAX_BLOCKS_RATIO = 8;
701 size_t max_blocks =
702 std::max<size_t>(cfg.size() * MAX_BLOCKS_RATIO, MAX_BLOCKS);
703
704 bool changed =
705 tail_duplicate_trivial_joins(work_cfg, origin_map, max_blocks);
706 if (!reducible0) {
707 changed |= node_split_make_reducible(work_cfg, origin_map, max_blocks);
708 }
709
710 if (changed) {
711 result.structured_cfg_blocks = std::move(work_cfg);
712 result.structured_block_origin = std::move(origin_map);
713 analysis_cfg = &result.structured_cfg_blocks;
714
715 result.structured_stack_depth_in.resize(
716 result.structured_cfg_blocks.size(), -1);
717 for (size_t i = 0; i < result.structured_cfg_blocks.size(); ++i) {
718 int orig = result.structured_block_origin[i];
719 if (orig >= 0 && static_cast<size_t>(orig) <
720 stack_safety.stack_depth_in.size()) {
721 result.structured_stack_depth_in[i] =
722 stack_safety.stack_depth_in[(size_t)orig];
723 }
724 }
725 }
726
727 const auto reachable = compute_reachable(*analysis_cfg);
728 result.reducible = check_reducible(*analysis_cfg, reachable);
729 result.success = result.reducible;
730
731 result.ipdom.assign(analysis_cfg->size(), -1);
732 result.innermost_loop_header.assign(analysis_cfg->size(), -1);
733
734 const auto dom = compute_dominators(*analysis_cfg, reachable);
735 const auto pdom = compute_postdominators(*analysis_cfg, reachable);
736
737 int n = (int)analysis_cfg->size();
738 result.ipdom = compute_ipdom_vector(pdom, n, reachable);
739
740 compute_natural_loops(result, *analysis_cfg, reachable, dom);
741 compute_loop_follow(result);
742 compute_innermost_loop_header(result, reachable);
743
744 return result;
745}

References analysis::AnalysisManager::getResult().


The documentation for this class was generated from the following files: