From 927552e2e8a43aab9d803979c782a1542571220d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 14 Apr 2016 13:29:07 -0400 Subject: [PATCH 87/91] FIXME: introduce function_reader::create_cfg --- gcc/rtl/rtl-frontend.c | 137 ++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/gcc/rtl/rtl-frontend.c b/gcc/rtl/rtl-frontend.c index 6180f62..4f02168 100644 --- a/gcc/rtl/rtl-frontend.c +++ b/gcc/rtl/rtl-frontend.c @@ -349,6 +349,9 @@ class function_reader : public rtx_reader tree parse_mem_expr (const char *desc); private: + void create_cfg (); + + private: struct uid_hash : int_hash {}; hash_map m_insns_by_uid; auto_vec m_fixups; @@ -603,70 +606,7 @@ function_reader::create_function () //struct function *fn = ; // DECL_STRUCT_FUNCTION (node->decl); //push_cfun (fn); - /* Create bare-bones cfg. This creates the entry and exit blocks. */ -#if 1 - init_empty_tree_cfg_for_function (cfun); -#else - init_flow (cfun); -#endif - - /* Populate with basic blocks. - - We can't call create_basic_block and use the regular RTL block-creation - hooks, since this creates NOTE_INSN_BASIC_BLOCK instances. We don't - want to do that; we want to use the notes we were provided with. - - The term "index" has two meanings for basic blocks in a CFG: - (a) the "index" field within struct basic_block_def. - (b) the index of a basic_block within the cfg's x_basic_block_info - vector, as accessed via BASIC_BLOCK_FOR_FN. - - These can get out-of-sync when basic blocks are optimized away. - They get back in sync by "compact_blocks". - We make the assumption that the CFG has been compacted, and - so we reconstruct cfun->cfg->x_basic_block_info->m_vecdata with NULL - values in it for any missing basic blocks, so that (a) == (b) for - all of the blocks we create. The doubly-linked list of basic - blocks (next_bb/prev_bb) skip over these "holes". */ - - /* Ensure that the vector of basic_block pointers is big enough. */ - unsigned highest_bb_idx = bitmap_last_set_bit (&m_bb_indices); - size_t new_size = highest_bb_idx + 1; - if (basic_block_info_for_fn (cfun)->length () < new_size) - vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size); - - /* Populate the vector. */ - unsigned bb_idx; - bitmap_iterator bi; - basic_block after = ENTRY_BLOCK_PTR_FOR_FN (cfun); - gcc_assert (after); - EXECUTE_IF_SET_IN_BITMAP (&m_bb_indices, 0, bb_idx, bi) - { - /* The entry and exit blocks were already created above. */ - if (bb_idx == ENTRY_BLOCK || bb_idx == EXIT_BLOCK) - continue; - basic_block bb = alloc_block (); - init_rtl_bb_info (bb); - bb->index = bb_idx; - bb->flags = BB_NEW | BB_RTL; - link_block (bb, after); - - n_basic_blocks_for_fn (cfun)++; - SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb); - //df_bb_refs_record (bb->index, false); - //update_bb_for_insn (bb); - BB_SET_PARTITION (bb, BB_UNPARTITIONED); - - /* Tag the block so that we know it has been used when considering - other basic block notes. */ - bb->aux = bb; - - after = bb; - } - - - /* TODO: create edges. */ - + create_cfg (); cfun->curr_properties = (PROP_cfg | PROP_rtl); //pop_cfun (); @@ -725,6 +665,75 @@ function_reader::get_insn_by_uid (int uid) return m_insns_by_uid.get (uid); } +/* Create cfun's CFG and populate with blocks (TODO: and edges), a helper + function for function_reader::create_function (). + + We can't call create_basic_block and use the regular RTL block-creation + hooks, since this creates NOTE_INSN_BASIC_BLOCK instances. We don't + want to do that; we want to use the notes we were provided with. + + The term "index" has two meanings for basic blocks in a CFG: + (a) the "index" field within struct basic_block_def. + (b) the index of a basic_block within the cfg's x_basic_block_info + vector, as accessed via BASIC_BLOCK_FOR_FN. + + These can get out-of-sync when basic blocks are optimized away. + They get back in sync by "compact_blocks". + We make the assumption that the CFG has been compacted, and + so we reconstruct cfun->cfg->x_basic_block_info->m_vecdata with NULL + values in it for any missing basic blocks, so that (a) == (b) for + all of the blocks we create. The doubly-linked list of basic + blocks (next_bb/prev_bb) skips over these "holes". */ + +void +function_reader::create_cfg () +{ + /* Create bare-bones cfg. This creates the entry and exit blocks. */ +#if 1 + init_empty_tree_cfg_for_function (cfun); +#else + init_flow (cfun); +#endif + + /* Ensure that the vector of basic_block pointers is big enough. */ + unsigned highest_bb_idx = bitmap_last_set_bit (&m_bb_indices); + size_t new_size = highest_bb_idx + 1; + if (basic_block_info_for_fn (cfun)->length () < new_size) + vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size); + + /* Populate the vector. */ + unsigned bb_idx; + bitmap_iterator bi; + basic_block after = ENTRY_BLOCK_PTR_FOR_FN (cfun); + gcc_assert (after); + EXECUTE_IF_SET_IN_BITMAP (&m_bb_indices, 0, bb_idx, bi) + { + /* The entry and exit blocks were already created above. */ + if (bb_idx == ENTRY_BLOCK || bb_idx == EXIT_BLOCK) + continue; + basic_block bb = alloc_block (); + init_rtl_bb_info (bb); + bb->index = bb_idx; + bb->flags = BB_NEW | BB_RTL; + link_block (bb, after); + + n_basic_blocks_for_fn (cfun)++; + SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb); + //df_bb_refs_record (bb->index, false); + //update_bb_for_insn (bb); + BB_SET_PARTITION (bb, BB_UNPARTITIONED); + + /* Tag the block so that we know it has been used when considering + other basic block notes. */ + bb->aux = bb; + + after = bb; + } + + /* TODO: create edges. */ + +} + /* Locate and run PASS_NAME on cfun. */ static void -- 1.8.5.3