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
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}
StructurizeCFGResult Result