struct insn_link {
rtx_insn *insn;
unsigned int regno;
+ int insn_count;
struct insn_link *next;
};
sizeof (struct insn_link));
l->insn = insn;
l->regno = regno;
+ l->insn_count = 0;
l->next = next;
return l;
}
static bool reg_bitfield_target_p (rtx, rtx);
static void distribute_notes (rtx, rtx_insn *, rtx_insn *, rtx_insn *,
rtx, rtx, rtx);
-static void distribute_links (struct insn_link *, rtx_insn * = nullptr);
+static void distribute_links (struct insn_link *, rtx_insn * = nullptr,
+ int limit = INT_MAX);
static void mark_used_regs_combine (rtx);
static void record_promoted_value (rtx_insn *, rtx);
static bool unmentioned_reg_p (rtx, rtx);
}
if (only_i3_changed)
- distribute_links (i3links, i3);
+ distribute_links (i3links, i3, param_max_combine_search_insns);
else
{
distribute_links (i3links);
pointing at I3 when I3's destination is changed.
If START is nonnull and an insn, we know that the next location for each
- link is no earlier than START. */
+ link is no earlier than START. LIMIT is the maximum number of nondebug
+ instructions that can be scanned when looking for the next use of a
+ definition. */
static void
-distribute_links (struct insn_link *links, rtx_insn *start)
+distribute_links (struct insn_link *links, rtx_insn *start, int limit)
{
struct insn_link *link, *next_link;
I3 to I2. Also note that not much searching is typically done here
since most links don't point very far away. */
+ int count = 0;
insn = start;
if (!insn || NOTE_P (insn))
insn = NEXT_INSN (link->insn);
+ else
+ count = link->insn_count;
for (;
(insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
|| BB_HEAD (this_basic_block->next_bb) != insn));
}
else if (INSN_P (insn) && reg_set_p (reg, insn))
break;
+ else if (count >= limit)
+ break;
+ else
+ count += 1;
+ link->insn_count = count;
/* If we found a place to put the link, place it there unless there
is already a link to the same insn as LINK at that point. */
@item max-combine-insns
The maximum number of instructions the RTL combiner tries to combine.
+@item max-combine-search-insns
+The maximum number of instructions that the RTL combiner searches in order
+to find the next use of a given register definition. If this limit is reached
+without finding such a use, the combiner will stop trying to optimize the
+definition.
+
+Currently this limit only applies after certain successful combination
+attempts, but it could be extended to other cases in future.
+
@item integer-share-limit
Small integer constants can use a shared data structure, reducing the
compiler's memory usage and increasing its speed. This sets the maximum
Common Joined UInteger Var(param_max_combine_insns) Init(4) IntegerRange(2, 4) Param Optimization
The maximum number of insns combine tries to combine.
+-param=max-combine-search-insns=
+Common Joined UInteger Var(param_max_combine_search_insns) Init(3000) Param Optimization
+The maximum number of instructions that combine searches in order to find the next use of a particular register.
+
-param=max-completely-peel-loop-nest-depth=
Common Joined UInteger Var(param_max_unroll_iterations) Init(8) Param Optimization
The maximum depth of a loop nest we completely peel.