diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2024-11-18 19:32:49 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2024-11-18 19:32:49 +0000 |
commit | 716aa5a668388a09b27525dce847d8d36c4c2fab (patch) | |
tree | 48f8f5d72d0addce28c6b682b63cb03f9fa48046 | |
parent | 4712ecde4869cf29c40a7df44e4655939d90d4d8 (diff) | |
download | gcc-716aa5a668388a09b27525dce847d8d36c4c2fab.zip gcc-716aa5a668388a09b27525dce847d8d36c4c2fab.tar.gz gcc-716aa5a668388a09b27525dce847d8d36c4c2fab.tar.bz2 |
aarch64: Add early_ra::record_live_range_failure
So far, early_ra has used a single m_allocation_successful bool
to record whether the current region is still being allocated.
But there are (at least) two reasons why we might pull out of
attempting an allocation:
(1) We can't track the liveness of individual FP allocnos,
due to some awkward subregs.
(2) We're afraid of doing a worse job than the proper allocator.
A later patch needs to distinguish (1) from other reasons, since
(1) means that the liveness information is not trustworthy.
(Currently we assume it is not trustworthy whenever
m_allocation_successful is false, but that's too conservative.)
gcc/
* config/aarch64/aarch64-early-ra.cc
(early_ra::record_live_range_failure): New member function.
(early_ra::m_accurate_live_ranges): New member variable.
(early_ra::start_new_region): Set m_accurate_live_ranges to true.
(early_ra::get_allocno_subgroup): Use record_live_range_failure
to abort the allocation on invalid subregs.
-rw-r--r-- | gcc/config/aarch64/aarch64-early-ra.cc | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64-early-ra.cc b/gcc/config/aarch64/aarch64-early-ra.cc index d6ed7fe..bf8827f 100644 --- a/gcc/config/aarch64/aarch64-early-ra.cc +++ b/gcc/config/aarch64/aarch64-early-ra.cc @@ -439,6 +439,9 @@ private: void start_new_region (); + template<typename T> + void record_live_range_failure (T); + allocno_group_info *create_allocno_group (unsigned int, unsigned int); allocno_subgroup get_allocno_subgroup (rtx); void record_fpr_use (unsigned int); @@ -551,6 +554,10 @@ private: // current function. unsigned int m_call_preserved_fprs; + // True if we have so far been able to track the live ranges of individual + // allocnos. + bool m_accurate_live_ranges; + // True if we haven't yet failed to allocate the current region. bool m_allocation_successful; @@ -1314,10 +1321,30 @@ early_ra::start_new_region () m_dead_insns.truncate (0); m_allocated_fprs = 0; m_call_preserved_fprs = 0; + m_accurate_live_ranges = true; m_allocation_successful = true; m_current_region += 1; } +// Record that we can no longer track the liveness of individual allocnos. +// Call DUMP to dump the reason to a dump file. +template<typename T> +void +early_ra::record_live_range_failure (T dump) +{ + if (!m_accurate_live_ranges) + return; + + m_accurate_live_ranges = false; + m_allocation_successful = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Unable to track live ranges further: "); + dump (); + fprintf (dump_file, "\n"); + } +} + // Create and return an allocno group of size SIZE for register REGNO. // REGNO can be INVALID_REGNUM if the group just exists to allow // other groups to be chained together, and does not have any new @@ -1390,7 +1417,12 @@ early_ra::get_allocno_subgroup (rtx reg) if (!targetm.modes_tieable_p (GET_MODE (SUBREG_REG (reg)), GET_MODE (reg))) { - m_allocation_successful = false; + record_live_range_failure ([&](){ + fprintf (dump_file, "cannot refer to r%d:%s in mode %s", + REGNO (SUBREG_REG (reg)), + GET_MODE_NAME (GET_MODE (SUBREG_REG (reg))), + GET_MODE_NAME (GET_MODE (reg))); + }); return {}; } @@ -1399,7 +1431,10 @@ early_ra::get_allocno_subgroup (rtx reg) SUBREG_BYTE (reg), GET_MODE (reg), &info); if (!info.representable_p) { - m_allocation_successful = false; + record_live_range_failure ([&](){ + fprintf (dump_file, "subreg of r%d is invalid for V0", + REGNO (SUBREG_REG (reg))); + }); return {}; } |