Skip to content

Instantly share code, notes, and snippets.

@garybernhardt
Created July 26, 2012 03:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save garybernhardt/3180009 to your computer and use it in GitHub Desktop.
Save garybernhardt/3180009 to your computer and use it in GitHub Desktop.
An excerpt from GCC's reload.c
static int
find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
enum reload_type type, int opnum, int dont_share)
{
rtx in = *p_in;
int i;
/* We can't merge two reloads if the output of either one is
earlyclobbered. */
if (earlyclobber_operand_p (out))
return n_reloads;
/* We can use an existing reload if the class is right
and at least one of IN and OUT is a match
and the other is at worst neutral.
(A zero compared against anything is neutral.)
For targets with small register classes, don't use existing reloads
unless they are for the same thing since that can cause us to need
more reload registers than we otherwise would. */
for (i = 0; i < n_reloads; i++)
if ((reg_class_subset_p (rclass, rld[i].rclass)
|| reg_class_subset_p (rld[i].rclass, rclass))
/* If the existing reload has a register, it must fit our class. */
&& (rld[i].reg_rtx == 0
|| TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
true_regnum (rld[i].reg_rtx)))
&& ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
&& (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
|| (out != 0 && MATCHES (rld[i].out, out)
&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
&& (small_register_class_p (rclass)
|| targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
return i;
/* Reloading a plain reg for input can match a reload to postincrement
that reg, since the postincrement's value is the right value.
Likewise, it can match a preincrement reload, since we regard
the preincrementation as happening before any ref in this insn
to that register. */
for (i = 0; i < n_reloads; i++)
if ((reg_class_subset_p (rclass, rld[i].rclass)
|| reg_class_subset_p (rld[i].rclass, rclass))
/* If the existing reload has a register, it must fit our
class. */
&& (rld[i].reg_rtx == 0
|| TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
true_regnum (rld[i].reg_rtx)))
&& out == 0 && rld[i].out == 0 && rld[i].in != 0
&& ((REG_P (in)
&& GET_RTX_CLASS (GET_CODE (rld[i].in)) == RTX_AUTOINC
&& MATCHES (XEXP (rld[i].in, 0), in))
|| (REG_P (rld[i].in)
&& GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
&& MATCHES (XEXP (in, 0), rld[i].in)))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
&& (small_register_class_p (rclass)
|| targetm.small_register_classes_for_mode_p (VOIDmode))
&& MERGABLE_RELOADS (type, rld[i].when_needed,
opnum, rld[i].opnum))
{
/* Make sure reload_in ultimately has the increment,
not the plain register. */
if (REG_P (in))
*p_in = rld[i].in;
return i;
}
return n_reloads;
}
@kyleterry
Copy link

WHAT THE FUCK

@lukaszkorecki
Copy link

Ah yes

https://gcc.gnu.org/wiki/reload

Reload does everything, and probably no one exactly knows how much that is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment