On Wed, Jan 28, 2015 at 3:04 PM, Cary Coutant <ccout...@google.com> wrote: > > >> +static subprog_entry * > >> +add_subprog_entry (tree decl, bool is_inlined) > >> +{ > >> + subprog_entry **slot; > >> + subprog_entry *entry; > >> + > >> + slot = subprog_table->find_slot_with_hash (decl, DECL_UID (decl), > >> INSERT); > >> + if (*slot == HTAB_EMPTY_ENTRY) > >> + { > >> + entry = XCNEW (struct subprog_entry); > >> + entry->decl = decl; > >> + entry->is_inlined = is_inlined; > >> + entry->subprog_num = 0; > >> + *slot = entry; > >> + } > >> + else if (is_inlined) > > > > When will the logic go into else branch? > > When we already have an entry for the given subprogram (e.g., the same > subroutine gets inlined in multiple places). > > > >> +/* For two-level line tables, a map from block number to an > >> + inlined call chain. */ > >> + > >> +struct block_entry > >> +{ > >> + unsigned int block_num; > >> + struct subprog_entry *subprog; > >> + struct block_entry *caller; > >> + location_t caller_loc; > >> +}; > >> + > >> +struct block_hasher : typed_free_remove <block_entry> > >> +{ > >> + typedef block_entry value_type; > >> + typedef unsigned int compare_type; > >> + static hashval_t hash (const value_type *); > >> + static bool equal (const value_type *, const compare_type *); > >> +}; > >> + > >> +inline hashval_t > >> +block_hasher::hash (const value_type *p) > >> +{ > >> + return (hashval_t) p->block_num; > >> +} > >> + > >> +inline bool > >> +block_hasher::equal (const value_type *p1, const compare_type *p2) > >> +{ > >> + return p1->block_num == *p2; > >> +} > >> + > >> +static hash_table<block_hasher> *block_table; > > > > Not quite clear why we need block_table. This table is not gonna be > > emitted. And we can easily get subprog_entry through block->block_num > > When final_scan_insn() calls dwarf2out_begin_block(), all it passes is > a block number. I don't know a way to get from block number to the > block, so I traverse all the blocks of a function when > dwarf2out_begin_function() is called, and build this table. Now in > dwarf2out_source_line, I can look at the current block number and tell > what the inline call stack is.
Is it correct that block_num has 1-1 mapping with block_table. And block_table has 1-1 mapping with logical_table? Dehao > > > >> +#ifdef DEBUG_TWO_LEVEL > >> + static unsigned int level = 0; > >> +#endif > >> + > >> + if (block == NULL) > >> + return; > >> + > >> +#ifdef DEBUG_TWO_LEVEL > > > > Shall this be controlled by dump options with TDF_DETAILS dump_flag? > > I don't see the need -- I'll rip this out before submitting for trunk. > I'd have ripped it out already, but thought it might be useful for a > little while longer. > > > >> + block_num = BLOCK_NUMBER (block); > >> + slot = block_table->find_slot_with_hash (&block_num, (hashval_t) > >> block_num, INSERT); > >> + if (*slot != HTAB_EMPTY_ENTRY) > > > > Instead of return, can you assert that the data stored in *slot is > > consistent with the new data? Or should *slot never be > > HTAB_EMPTY_ENTRY? > > It should probably be consistent, but I wasn't absolutely sure, and I > didn't want to have the compiler crash when either version of the data > is probably good enough. It might not be empty, because I might have > already added the block number to the table in the loop over the > parent node's BLOCK_FRAGMENT_CHAIN. (I may not need to have that loop > at all, if it's always the case that the blocks in > BLOCK_FRAGMENT_CHAIN are also contained in the subtree under > BLOCK_SUBBLOCKS. I'm being conservative here.) > > -cary