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

Reply via email to