Hanbyul Joo

80 papers A* 27B 1C 1Misc 1Journal 44Unranked 6
YearRankTypeTitle / Venue / Authors
2025 A* conf
SIGGRAPH Asia
Jiye Lee, Chenghui Li, Linh Tran, Shih-En Wei, Jason M. Saragih, Alexander Richard, Hanbyul Joo, Shaojie Bai
2025 J jnl
CoRR
Jiye Lee, Chenghui Li, Linh Tran, Shih-En Wei, Jason M. Saragih, Alexander Richard, Hanbyul Joo, Shaojie Bai
2025 J jnl
CoRR
Hyeonwoo Kim, Sangwon Beak, Hanbyul Joo
2025 J jnl
CoRR
Byungjun Kim, Taeksoo Kim, Junyoung Lee, Hanbyul Joo
2025 J jnl
CoRR
Hyunsoo Cha, Byungjun Kim, Hanbyul Joo
2025 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Kristen Grauman, Andrew Westbury, Eugene Byrne, Vincent Cartillier, Zachary Chavis, Antonino Furnari, Rohit Girdhar, Jackson Hamburger, Hao Jiang, Devansh Kukreja, Miao Liu, Xingyu Liu, Miguel Martin, Tushar Nagarajan, Ilija Radosavovic, Santhosh Kumar Ramakrishnan, Fiona Ryan, Jayant Sharma, Michael Wray, Mengmeng Xu, Eric Zhongcong Xu, Chen Zhao, Siddhant Bansal, Dhruv Batra, Sean Crane, Tien Do, Morrie Doulaty, Akshay Erapalli, Christoph Feichtenhofer, Adriano Fragomeni, Qichen Fu, Abrham Gebreselasie, Cristina González, James Hillis, Xuhua Huang, Yifei Huang, Wenqi Jia, Weslie Khoo, Jáchym Kolár, Satwik Kottur, Anurag Kumar, Federico Landini, Chao Li, Yanghao Li, Zhenqiang Li, Karttikeya Mangalam, Raghava Modhugu, Jonathan Munro, Tullie Murrell, Takumi Nishiyasu, Will Price, Paola Ruiz Puentes, Merey Ramazanova, Leda Sari, Kiran K. Somasundaram, Audrey Southerland, Yusuke Sugano, Ruijie Tao, Minh Vo, Yuchen Wang, Xindi Wu, Takuma Yagi, Ziwei Zhao, Yunyi Zhu, Pablo Arbeláez, David Crandall, Dima Damen, Giovanni Maria Farinella, Christian Fuegen, Bernard Ghanem, Vamsi Krishna Ithapu, C. V. Jawahar, Hanbyul Joo, Kris Kitani, Haizhou Li, Richard A. Newcombe, Aude Oliva, Hyun Soo Park, James M. Rehg, Yoichi Sato, Jianbo Shi, Mike Zheng Shou, Antonio Torralba, Lorenzo Torresani, Mingfei Yan, Jitendra Malik
2025 J jnl
CoRR
Byungjun Kim, Shunsuke Saito, Giljoo Nam, Tomas Simon, Jason M. Saragih, Hanbyul Joo, Junxuan Li
2025 J jnl
CoRR
Kyungwon Cho, Hanbyul Joo
2025 J jnl
CoRR
Sangwon Beak, Hyeonwoo Kim, Hanbyul Joo
2025 J jnl
CoRR
Jeonghyeon Na, Sangwon Baik, Inhee Lee, Junyoung Lee, Hanbyul Joo
2025 J jnl
CoRR
Sungjae Park, Seungho Lee, Mingi Choi, Jiye Lee, Jeonghwan Kim, Jisoo Kim, Hanbyul Joo
2025 A* conf
CVPR
Hyunsoo Cha, Inhee Lee, Hanbyul Joo
2025 A* conf
CVPR
Jeonghwan Kim, Jisoo Kim, Jeonghyeon Na, Hanbyul Joo
2025 J jnl
CoRR
Taeksoo Kim, Hanbyul Joo
2024 conf
ECCV (51)
Hyeonwoo Kim, Sookwan Han, Patrick Kwon, Hanbyul Joo
2024 A* conf
CVPR
Taeksoo Kim, Byungjun Kim, Shunsuke Saito, Hanbyul Joo
2024 J jnl
CoRR
Taeksoo Kim, Byungjun Kim, Shunsuke Saito, Hanbyul Joo
2024 J jnl
CoRR
Patrick Kwon, Hanbyul Joo
2024 A* conf
CVPR
Inhee Lee, Byungjun Kim, Hanbyul Joo
2024 J jnl
CoRR
Inhee Lee, Byungjun Kim, Hanbyul Joo
2024 J jnl
CoRR
Jiye Lee, Hanbyul Joo
2024 A* conf
CVPR
Jiye Lee, Hanbyul Joo
2024 A* conf
CVPR
Hyunsoo Cha, Byungjun Kim, Hanbyul Joo
2024 J jnl
CoRR
Hyunsoo Cha, Byungjun Kim, Hanbyul Joo
2024 J jnl
CoRR
Hyunsoo Cha, Inhee Lee, Hanbyul Joo
2024 J jnl
CoRR
Jeonghwan Kim, Jisoo Kim, Jeonghyeon Na, Hanbyul Joo
2024 J jnl
CoRR
Hyeonwoo Kim, Sookwan Han, Patrick Kwon, Hanbyul Joo
2023 A* conf
ICCV
Sookwan Han, Hanbyul Joo
2023 J jnl
CoRR
Sookwan Han, Hanbyul Joo
2023 A* conf
ICCV
Byungjun Kim, Patrick Kwon, Kwangho Lee, Myunggi Lee, Sookwan Han, Daesik Kim, Hanbyul Joo
2023 J jnl
CoRR
Byungjun Kim, Patrick Kwon, Kwangho Lee, Myunggi Lee, Sookwan Han, Daesik Kim, Hanbyul Joo
2023 A* conf
ICCV
Jiye Lee, Hanbyul Joo
2023 J jnl
CoRR
Jiye Lee, Hanbyul Joo
2023 A* conf
ICCV
Taeksoo Kim, Shunsuke Saito, Hanbyul Joo
2023 J jnl
CoRR
Taeksoo Kim, Shunsuke Saito, Hanbyul Joo
2022 A* conf
CVPR
Gengshan Yang, Minh Vo, Natalia Neverova, Deva Ramanan, Andrea Vedaldi, Hanbyul Joo
2022 A* conf
CVPR
Kristen Grauman, Andrew Westbury, Eugene Byrne, Zachary Chavis, Antonino Furnari, Rohit Girdhar, Jackson Hamburger, Hao Jiang, Miao Liu, Xingyu Liu, Miguel Martin, Tushar Nagarajan, Ilija Radosavovic, Santhosh Kumar Ramakrishnan, Fiona Ryan, Jayant Sharma, Michael Wray, Mengmeng Xu, Eric Zhongcong Xu, Chen Zhao, Siddhant Bansal, Dhruv Batra, Vincent Cartillier, Sean Crane, Tien Do, Morrie Doulaty, Akshay Erapalli, Christoph Feichtenhofer, Adriano Fragomeni, Qichen Fu, Abrham Gebreselasie, Cristina González, James Hillis, Xuhua Huang, Yifei Huang, Wenqi Jia, Weslie Khoo, Jáchym Kolár, Satwik Kottur, Anurag Kumar, Federico Landini, Chao Li, Yanghao Li, Zhenqiang Li, Karttikeya Mangalam, Raghava Modhugu, Jonathan Munro, Tullie Murrell, Takumi Nishiyasu, Will Price, Paola Ruiz Puentes, Merey Ramazanova, Leda Sari, Kiran K. Somasundaram, Audrey Southerland, Yusuke Sugano, Ruijie Tao, Minh Vo, Yuchen Wang, Xindi Wu, Takuma Yagi, Ziwei Zhao, Yunyi Zhu, Pablo Arbeláez, David Crandall, Dima Damen, Giovanni Maria Farinella, Christian Fuegen, Bernard Ghanem, Vamsi Krishna Ithapu, C. V. Jawahar, Hanbyul Joo, Kris Kitani, Haizhou Li, Richard A. Newcombe, Aude Oliva, Hyun Soo Park, James M. Rehg, Yoichi Sato, Jianbo Shi, Mike Zheng Shou, Antonio Torralba, Lorenzo Torresani, Mingfei Yan, Jitendra Malik
2022 A* conf
CVPR
Evonne Ng, Hanbyul Joo, Liwen Hu, Hao Li, Trevor Darrell, Angjoo Kanazawa, Shiry Ginosar
2022 J jnl
CoRR
Evonne Ng, Hanbyul Joo, Liwen Hu, Hao Li, Trevor Darrell, Angjoo Kanazawa, Shiry Ginosar
2022 conf
SIGGRAPH Asia Posters
Deepak Gopinath, Hanbyul Joo, Jungdam Won
2021 J jnl
CoRR
Gengshan Yang, Minh Vo, Natalia Neverova, Deva Ramanan, Andrea Vedaldi, Hanbyul Joo
2021 A* conf
CVPR
Evonne Ng, Shiry Ginosar, Trevor Darrell, Hanbyul Joo
2021 J jnl
CoRR
Xiang Xu, Hanbyul Joo, Greg Mori, Manolis Savva
2021 J jnl
CoRR
Kristen Grauman, Andrew Westbury, Eugene Byrne, Zachary Chavis, Antonino Furnari, Rohit Girdhar, Jackson Hamburger, Hao Jiang, Miao Liu, Xingyu Liu, Miguel Martin, Tushar Nagarajan, Ilija Radosavovic, Santhosh Kumar Ramakrishnan, Fiona Ryan, Jayant Sharma, Michael Wray, Mengmeng Xu, Eric Zhongcong Xu, Chen Zhao, Siddhant Bansal, Dhruv Batra, Vincent Cartillier, Sean Crane, Tien Do, Morrie Doulaty, Akshay Erapalli, Christoph Feichtenhofer, Adriano Fragomeni, Qichen Fu, Christian Fuegen, Abrham Gebreselasie, Cristina González, James Hillis, Xuhua Huang, Yifei Huang, Wenqi Jia, Weslie Khoo, Jáchym Kolár, Satwik Kottur, Anurag Kumar, Federico Landini, Chao Li, Yanghao Li, Zhenqiang Li, Karttikeya Mangalam, Raghava Modhugu, Jonathan Munro, Tullie Murrell, Takumi Nishiyasu, Will Price, Paola Ruiz Puentes, Merey Ramazanova, Leda Sari, Kiran K. Somasundaram, Audrey Southerland, Yusuke Sugano, Ruijie Tao, Minh Vo, Yuchen Wang, Xindi Wu, Takuma Yagi, Yunyi Zhu, Pablo Arbeláez, David Crandall, Dima Damen, Giovanni Maria Farinella, Bernard Ghanem, Vamsi Krishna Ithapu, C. V. Jawahar, Hanbyul Joo, Kris Kitani, Haizhou Li, Richard A. Newcombe, Aude Oliva, Hyun Soo Park, James M. Rehg, Yoichi Sato, Jianbo Shi, Mike Zheng Shou, Antonio Torralba, Lorenzo Torresani, Mingfei Yan, Jitendra Malik
2021 conf
3DV
Hanbyul Joo, Natalia Neverova, Andrea Vedaldi
2021 conf
ICCVW
Yu Rong, Takaaki Shiratori, Hanbyul Joo
2021 J jnl
CoRR
Yu Rong, Takaaki Shiratori, Hanbyul Joo
2021 J jnl
CoRR
Yingdong Qian, Marta Kryven, Tao Gao, Hanbyul Joo, Josh Tenenbaum
2020 A* conf
NeurIPS
Benjamin Biggs, David Novotný, Sébastien Ehrhardt, Hanbyul Joo, Benjamin Graham, Andrea Vedaldi
2020 J jnl
CoRR
Benjamin Biggs, Sébastien Ehrhardt, Hanbyul Joo, Benjamin Graham, Andrea Vedaldi, David Novotný
2020 J jnl
CoRR
Evonne Ng, Hanbyul Joo, Shiry Ginosar, Trevor Darrell
2020 J jnl
CoRR
Hanbyul Joo, Natalia Neverova, Andrea Vedaldi
2020 J jnl
CoRR
Yu Rong, Takaaki Shiratori, Hanbyul Joo
2020 A* conf
CVPR
Shunsuke Saito, Tomas Simon, Jason M. Saragih, Hanbyul Joo
2020 J jnl
CoRR
Shunsuke Saito, Tomas Simon, Jason M. Saragih, Hanbyul Joo
2020 conf
ECCV (12)
Jason Y. Zhang, Sam Pepose, Hanbyul Joo, Deva Ramanan, Jitendra Malik, Angjoo Kanazawa
2020 J jnl
CoRR
Jason Y. Zhang, Sam Pepose, Hanbyul Joo, Deva Ramanan, Jitendra Malik, Angjoo Kanazawa
2020 A* conf
CVPR
Evonne Ng, Donglai Xiang, Hanbyul Joo, Kristen Grauman
2019 A* conf
CVPR
Donglai Xiang, Hanbyul Joo, Yaser Sheikh
2019 J jnl
IEEE Trans. Pattern Anal. Mach. Intell.
Hanbyul Joo, Tomas Simon, Xulong Li, Hao Liu, Lei Tan, Lin Gui, Sean Banerjee, Timothy Godisart, Bart C. Nabbe, Iain A. Matthews, Takeo Kanade, Shohei Nobuhara, Yaser Sheikh
2019 A* conf
ICCV
Gines Hidalgo Martinez, Yaadhav Raaj, Haroon Idrees, Donglai Xiang, Hanbyul Joo, Tomas Simon, Yaser Sheikh
2019 J jnl
CoRR
Gines Hidalgo, Yaadhav Raaj, Haroon Idrees, Donglai Xiang, Hanbyul Joo, Tomas Simon, Yaser Sheikh
2019 J jnl
CoRR
Hanbyul Joo, Tomas Simon, Mina Cikara, Yaser Sheikh
2019 A* conf
CVPR
Hanbyul Joo, Tomas Simon, Mina Cikara, Yaser Sheikh
2019 J jnl
CoRR
Evonne Ng, Donglai Xiang, Hanbyul Joo, Kristen Grauman
2018 J jnl
CoRR
Donglai Xiang, Hanbyul Joo, Yaser Sheikh
2018 A* conf
CVPR
Xiu Li, Hongdong Li, Hanbyul Joo, Yebin Liu, Yaser Sheikh
2018 J jnl
CoRR
Xiu Li, Hongdong Li, Hanbyul Joo, Yebin Liu, Yaser Sheikh
2018 A* conf
CVPR
Hanbyul Joo, Tomas Simon, Yaser Sheikh
2018 J jnl
CoRR
Hanbyul Joo, Tomas Simon, Yaser Sheikh
2017 A* conf
CVPR
Tomas Simon, Hanbyul Joo, Iain A. Matthews, Yaser Sheikh
2017 J jnl
CoRR
Tomas Simon, Hanbyul Joo, Iain A. Matthews, Yaser Sheikh
2016 J jnl
CoRR
Hanbyul Joo, Tomas Simon, Xulong Li, Hao Liu, Lei Tan, Lin Gui, Sean Banerjee, Timothy Godisart, Bart C. Nabbe, Iain A. Matthews, Takeo Kanade, Shohei Nobuhara, Yaser Sheikh
2015 A* conf
ICCV
Hanbyul Joo, Hao Liu, Lei Tan, Lin Gui, Bart C. Nabbe, Iain A. Matthews, Takeo Kanade, Shohei Nobuhara, Yaser Sheikh
2014 A* conf
CVPR
Hanbyul Joo, Hyun Soo Park, Yaser Sheikh
2012 C conf
ICCE
Seong-Jae Lim, Hanbyul Joo, Jihyung Lee, Bon-Ki Koo
2011 B conf
ICIP
Hanbyul Joo, Yekeun Jeong, Olivier Duchenne, In-So Kweon
2009 A* conf
ICRA
Hanbyul Joo, Yekeun Jeong, Olivier Duchenne, Seong-Young Ko, In-So Kweon
2009 conf
ROBIO
Jayoung Kim, Doo-Gyu Kim, Jonghwa Lee, Jihong Lee, Hanbyul Joo, In-So Kweon
2007 Misc conf
MVA
Youngbae Hwang, Hanbyul Joo, Jun-Sik Kim, In-So Kweon
redb/extractors/decompiler/bninja/analysis/cfg-old.py
← Index redb/extractors/decompiler/bninja/analysis/cfg-old.py python
from collections import deque
from enum import Enum

from binaryninja.enums import (
    BranchType,
    InstructionTextTokenType,
)

# Support both package and standalone imports
try:
    from ..utils.hashes import calculate_md5, calculate_sha256
except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_md5, calculate_sha256


class CFGAnalysis:
    def __init__(self, function):
        self.function = function

    def determine_block_type(self, block) -> str:
        """Determine the type of a basic block."""
        # Check if it's a thunk function (usually just a jump or call)
        if len(block.disassembly_text) <= 2 and any(
            "jmp" in line.tokens[0].text.lower() for line in block.disassembly_text
        ):
            return "THUNK"

        # Check if it contains only data (no valid instructions)
        if all(not line.tokens for line in block.disassembly_text):
            return "DATA"

        # Default to code
        return "CODE"

    def extract_cyclomatic_complexity(self):
        """
        Cyclomatic complexity (McCabe’s metric) measures the number of linearly independent paths
        through a function’s control flow graph (CFG).
        The standard formula is:

            M = E - N + 2

        where:
            - E = number of edges in the CFG
            - N = number of nodes (basic blocks)
            - 2 accounts for the entry and exit nodes of a single connected graph
        """
        if self.function is None:
            return 0

        # number of basic blocks
        num_blocks = len(self.function.basic_blocks)
        # number of edges in the graph
        num_edges = sum(
            len(basic_block.outgoing_edges)
            for basic_block in self.function.basic_blocks
        )
        return num_edges - num_blocks + 2

    def extract_function_cfg(self):
        """Extract information about a function CFG and return it as a dictionary."""

        function = self.function
        function_data = {
            "function_address": self.function.start,
            "blocks": [],
            "measures": {
                "cyclomatic_complexity": self.extract_cyclomatic_complexity(),
            },
        }

        if self.function is None:
            return function_data

        # Get the map of the depth associated to every block
        depths = self.get_map_depth()

        # Get the map of the positions associated to every block
        id_maps = self.get_block_id_map()

        # Extract block data with graph structure information
        for block in function.basic_blocks:
            # dominators per every block translated
            dominators = sorted(self.extract_dominators(block, id_maps))

            # post dominators
            post_dominators = sorted(self.extract_post_dominators(block, id_maps))

            # Build block instructions string
            block_instructions = "\n".join(str(line) for line in block.disassembly_text)

            # Determine block type
            block_type = self.determine_block_type(block)

            # Extract successors directly from basic block
            successor_blocks = [edge.target.start for edge in block.outgoing_edges]
            # We ensure a canonical order and we sort the edges
            successor_blocks.sort()

            # Extract predecessors directly from basic block
            predecessor_blocks = [edge.source.start for edge in block.incoming_edges]
            # We ensure a canonical order and we sort the edges
            predecessor_blocks.sort()

            # Determine branch type from outgoing edges
            branch_type = self.determine_branch_type(block)

            instructions_count = len(block.disassembly_text)

            # Create block record
            block_json = {
                "function_address": self.function.start,
                "block_start_address": block.start,
                "block_end_address": block.end,
                "block_size": block.end - block.start,
                "instructions_count": instructions_count,
                "block_instructions_hash": calculate_sha256(block_instructions),
                "predecessor_blocks": predecessor_blocks,
                "successor_blocks": successor_blocks,
                "depth": depths[block.start],
                "position": id_maps[block.start],
                "branch_type": branch_type,
                "block_type": block_type,
                "flags": self.extract_block_flags(block),
                "dominators": dominators,
                "post_dominators": post_dominators,
            }
            function_data["blocks"].append(block_json)

        return function_data

    def extract_dominators(self, bb, id_maps):
        """Extract the dominators normalized"""
        dom_idx = [id_maps[d.start] for d in bb.dominators]
        return dom_idx

    def extract_post_dominators(self, bb, id_maps):
        """Extract the post-dominators normalized"""
        post_dom_idx = [id_maps[d.start] for d in bb.post_dominators]
        return post_dom_idx

    def determine_branch_type(self, block):
        """
        Determine the type of branch at the end of a basic block.
        This combines edge type information with instruction analysis.
        """
        # If no outgoing edges, it might be a return or terminal block
        if not block.outgoing_edges:
            # Check if the last instruction is a return
            for line in reversed(list(block.disassembly_text)):
                if line.tokens and any(
                    token.text.lower() in ["ret", "retn"] for token in line.tokens
                ):
                    return "RETURN"
            return "UNKNOWN"

        # Collect branch types from all outgoing edges
        branch_types = []
        for edge in block.outgoing_edges:
            edge_type = edge.type
            # Map edge type to our branch type enum
            if isinstance(edge_type, str):
                if edge_type == "IndirectCall":
                    branch_types.append("CALL")
                else:
                    branch_types.append("UNKNOWN")
            else:
                # Use our mapping for integer/enum values
                type_mapping = {
                    BranchType.UnconditionalBranch: "DIRECT",
                    BranchType.FalseBranch: "CONDITIONAL",
                    BranchType.TrueBranch: "CONDITIONAL",
                    BranchType.CallDestination: "CALL",
                    BranchType.FunctionReturn: "RETURN",
                    BranchType.SystemCall: "CALL",
                    BranchType.IndirectBranch: "INDIRECT",
                    BranchType.ExceptionBranch: "UNKNOWN",
                    BranchType.UnresolvedBranch: "UNKNOWN",
                    BranchType.UserDefinedBranch: "UNKNOWN",
                }
                branch_types.append(type_mapping.get(edge_type, "UNKNOWN"))

        # Determine overall branch type (prioritize CALL > RETURN > CONDITIONAL > DIRECT)
        if "CALL" in branch_types:
            return "CALL"
        elif "RETURN" in branch_types:
            return "RETURN"
        elif "CONDITIONAL" in branch_types:
            return "CONDITIONAL"
        elif "DIRECT" in branch_types:
            return "DIRECT"
        elif len(block.outgoing_edges) == 1:
            return "FALLTHROUGH"

        # If edge analysis was inconclusive, fall back to instruction analysis
        last_instr = None
        for line in reversed(list(block.disassembly_text)):
            if line.tokens:
                last_instr = line
                break

        if last_instr:
            mnemonic = None
            for token in last_instr.tokens:
                if token.type == InstructionTextTokenType.InstructionToken:
                    mnemonic = token.text.lower()
                    break

            if mnemonic:
                if mnemonic == "call":
                    return "CALL"
                elif mnemonic == "jmp":
                    return "DIRECT"
                elif mnemonic.startswith("j") and mnemonic != "jmp":
                    return "CONDITIONAL"
                elif mnemonic in ["ret", "retn"]:
                    return "RETURN"

        return "UNKNOWN"

    def get_map_depth(self):
        """
        Run a BFS on the basic blocks of the function to assign a depth to every block
        """

        depths = {}
        entry = self.function.get_basic_block_at(self.function.start)

        ### Simple BFS
        q = deque()
        q.append(entry)
        depths[entry.start] = 0

        while q:
            b = q.popleft()
            b_depth = depths[b.start]
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in depths:
                    depths[tgt.start] = b_depth + 1
                    q.append(tgt)

        return depths

    def get_block_id_map(self):
        """
        Assign a unique, sequential ID to each basic block of the function using a BFS starting from the entry block.
        """

        id_map = {}
        entry = self.function.get_basic_block_at(self.function.start)

        q = deque()
        q.append(entry)

        current_id = 0
        id_map[entry.start] = current_id

        while q:
            b = q.popleft()
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in id_map:
                    current_id += 1
                    id_map[tgt.start] = current_id
                    q.append(tgt)

        return id_map

    def extract_block_flags(self, block):
        """
        Get the flags for every basic block. Currently, we implemented these heuristics:
            - if a basic block is the entry node for a function
            - if a basic block is the exit block for a function
            - if a basic block is part of a natural loop
        """
        flags = []

        if block.start == self.function.start:
            flags.append(BlockFlags.EntryBlock.value)

        if any(edge.type == BranchType.FunctionReturn for edge in block.outgoing_edges):
            flags.append(BlockFlags.ExitBlock.value)

        # if this block is in its dominance frontier, then it's part of a natural loop
        if block in block.dominance_frontier:
            flags.append(BlockFlags.LoopBlock.value)

        return flags


class BlockFlags(Enum):
    # generally, the basic block identifying the entry point of the function
    EntryBlock = "EntryBlock"
    # any basic blocks that makes the control flow exiting from the current function
    ExitBlock = "ExitBlock"
    # any block is in a natural loop if it is in its own dominance frontier
    LoopBlock = "LoopBlock"


class BlockType(Enum):
    THUNK = "THUNK"
    DATA = "DATA"
    PADDING = "PADDING"
    CODE = "CODE"