diff options
author | Alexandre Oliva <oliva@adacore.com> | 2018-07-31 21:19:13 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2018-07-31 21:19:13 +0000 |
commit | fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2 (patch) | |
tree | f227c6802b9656b6bc7d3b3f090e9b9d78f1bb4b /gcc/final.c | |
parent | e540ccc0e281a6e30c14e55b39334db27e55b3bf (diff) | |
download | gcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.zip gcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.tar.gz gcc-fa6fd7b7afece6e0cfe197c9419ea3346d3c60b2.tar.bz2 |
Introduce instance discriminators
With -gnateS, the Ada compiler sets itself up to output discriminators
for different instantiations of generics, but the middle and back ends
have lacked support for that. This patch introduces the missing bits,
translating the GNAT-internal representation of the per-file instance
map to an instance_table that maps decls to instance discriminators.
From: Alexandre Oliva <oliva@adacore.com>, Olivier Hainque <hainque@adacore.com>
for gcc/ChangeLog
* debug.h (decl_to_instance_map_t): New type.
(decl_to_instance_map): Declare.
(maybe_create_decl_to_instance_map): New inline function.
* final.c (bb_discriminator, last_bb_discriminator): New statics,
to track basic block discriminators.
(final_start_function_1): Initialize them.
(final_scan_insn_1): On NOTE_INSN_BASIC_BLOCK, track
bb_discriminator.
(decl_to_instance_map): New variable.
(map_decl_to_instance, maybe_set_discriminator): New functions.
(notice_source_line): Set discriminator.
for gcc/ada/ChangeLog
* trans.c: Include debug.h.
(file_map): New static variable.
(gigi): Set it. Create decl_to_instance_map when needed.
(Subprogram_Body_to_gnu): Pass gnu_subprog_decl to...
(Sloc_to_locus): ... this. Add decl parm, map it to instance.
* gigi.h (Sloc_to_locus): Adjust declaration.
for gcc/testsuite/ChangeLog
* gnat.dg/dinst.adb: New.
* gnat.dg/dinst_pkg.ads, gnat.dg/dinst_pkg.adb: New.
Co-Authored-By: Olivier Hainque <hainque@adacore.com>
From-SVN: r263182
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/gcc/final.c b/gcc/final.c index 6fa4acd..a8338e0 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -122,12 +122,20 @@ static int last_linenum; /* Column number of last NOTE. */ static int last_columnnum; -/* Last discriminator written to assembly. */ +/* Discriminator written to assembly. */ static int last_discriminator; -/* Discriminator of current block. */ +/* Discriminator to be written to assembly for current instruction. + Note: actual usage depends on loc_discriminator_kind setting. */ static int discriminator; +/* Discriminator identifying current basic block among others sharing + the same locus. */ +static int bb_discriminator; + +/* Basic block discriminator for previous instruction. */ +static int last_bb_discriminator; + /* Highest line number in current block. */ static int high_block_linenum; @@ -1701,6 +1709,7 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen, last_linenum = LOCATION_LINE (prologue_location); last_columnnum = LOCATION_COLUMN (prologue_location); last_discriminator = discriminator = 0; + last_bb_discriminator = bb_discriminator = 0; high_block_linenum = high_function_linenum = last_linenum; @@ -2236,8 +2245,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, if (targetm.asm_out.unwind_emit) targetm.asm_out.unwind_emit (asm_out_file, insn); - discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; - + bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; break; case NOTE_INSN_EH_REGION_BEG: @@ -3144,6 +3152,58 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p, } + +/* Map DECLs to instance discriminators. This is allocated and + defined in ada/gcc-interfaces/trans.c, when compiling with -gnateS. */ + +decl_to_instance_map_t *decl_to_instance_map; + +/* Return the instance number assigned to DECL. */ + +static inline int +map_decl_to_instance (const_tree decl) +{ + int *inst; + + if (!decl_to_instance_map || !decl || !DECL_P (decl)) + return 0; + + inst = decl_to_instance_map->get (decl); + + if (!inst) + return 0; + + return *inst; +} + +/* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC. */ + +static inline void +maybe_set_discriminator (location_t loc) +{ + if (!decl_to_instance_map) + discriminator = bb_discriminator; + else + { + tree block = LOCATION_BLOCK (loc); + + while (block && TREE_CODE (block) == BLOCK + && !inlined_function_outer_scope_p (block)) + block = BLOCK_SUPERCONTEXT (block); + + tree decl; + + if (!block) + decl = current_function_decl; + else if (DECL_P (block)) + decl = block; + else + decl = block_ultimate_origin (block); + + discriminator = map_decl_to_instance (decl); + } +} + /* Return whether a source line note needs to be emitted before INSN. Sets IS_STMT to TRUE if the line should be marked as a possible breakpoint location. */ @@ -3178,6 +3238,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt) filename = xloc.file; linenum = xloc.line; columnnum = xloc.column; + maybe_set_discriminator (loc); force_source_line = true; } else if (override_filename) @@ -3192,6 +3253,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt) filename = xloc.file; linenum = xloc.line; columnnum = xloc.column; + maybe_set_discriminator (INSN_LOCATION (insn)); } else { |