<s>
static
int
rename_chain
(
tag_insn_info
*
insn_info
,
tag_map_t
&
tag_map
,
du_head_p
head
)
{
unsigned
dest_regno
=
head
->
regno
;
if
(
head
->
cannot_rename
||
head
->
renamed
)
return
1
;
HARD_REG_SET
unavailable
;
enum
reg_class
super_class
=
init_unavailable
(
insn_info
,
tag_map
,
head
,
&
unavailable
)
;
unsigned
new_regno
=
find_rename_reg
(
head
,
super_class
,
&
unavailable
,
dest_regno
,
false
)
;
if
(
new_regno
!=
dest_regno
&&
regrename_do_replace
(
head
,
new_regno
)
)
{
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
)
)
fprintf
(
dump_file
,
"\tInsn %d: Renamed %d to %d\n"
,
INSN_UID
(
insn_info
->
insn
)
,
dest_regno
,
new_regno
)
;
return
new_regno
;
}
return
1
;
}
</s>

Find a suitable and available register and rename the chain of occurrences of the register defined in the def/use chain headed by HEAD in which INSN exists . CUR_TAG , TAGS and TAG_MAP are used to determine which registers are unavailable due to a potential collision due to the rename . The routine returns the register number in case of a successful rename or -1 to indicate failure .


<s> static int rename_dest ( tag_insn_info * insn_info , tag_map_t & tag_map ) { struct du_chain * chain = NULL ; du_head_p head = NULL ; int i ; unsigned dest_regno = REGNO ( insn_info -> dest ) ; if ( unsafe_rename_p ( dest_regno ) ) return - 1 ; rtx_insn * insn = insn_info -> insn ; operand_rr_info * dest_op_info = insn_rr [ INSN_UID ( insn ) ] . op_info ; for ( i = 0 ; i < dest_op_info -> n_chains ; i ++ ) { if ( dest_op_info -> heads [ i ] -> regno != dest_regno ) continue ; head = dest_op_info -> heads [ i ] ; if ( ! head -> first ) head = regrename_chain_from_id ( head -> id ) ; for ( chain = head -> first ; chain ; chain = chain -> next_use ) if ( chain -> insn == insn ) return rename_chain ( insn_info , tag_map , head ) ; } return - 1 ; } </s>

Go through the def/use chains for the register and find the chain for this insn to rename . The function returns the hard register number in case of a successful rename and -1 otherwise .


<s> bool single_dest_per_chain ( const rtx & t ATTRIBUTE_UNUSED , insn_info_list_t * v , void * arg ATTRIBUTE_UNUSED ) { for ( int i = v -> length ( ) - 1 ; i >= 1 ; i -- ) { tag_insn_info * insn_info = ( * v ) [ i ] ; for ( int j = v -> length ( ) - 2 ; j >= 0 ; j -- ) { if ( in_same_chain ( insn_info -> insn , ( * v ) [ j ] -> insn , REGNO ( insn_info -> dest ) ) ) { v -> ordered_remove ( j ) ; i = v -> length ( ) ; break ; } } } return true ; } </s>

Callback function to traverse the tag map and drop loads that have the same destination and and in the same chain of occurrence . Routine always returns true to allow traversal through all of TAG_MAP .


<s> static bool unsafe_rename_p ( unsigned regno ) { if ( regno <= R8_REGNUM || ( regno >= V0_REGNUM && regno < V8_REGNUM ) ) return true ; switch ( regno ) { case LR_REGNUM : case HARD_FRAME_POINTER_REGNUM : case FRAME_POINTER_REGNUM : case STACK_POINTER_REGNUM : return true ; } return false ; } </s>

Return true if REGNO is not safe to rename .


<s> static bool valid_src_p ( rtx src , rtx_insn * insn , struct loop * loop , bool * pre_post , rtx * base , rtx * offset , bool load_pair ) { subrtx_var_iterator :: array_type array ; rtx x = NULL_RTX ; FOR_EACH_SUBRTX_VAR ( iter , array , src , NONCONST ) if ( MEM_P ( * iter ) ) { x = * iter ; break ; } if ( ! x ) return false ; struct aarch64_address_info addr ; machine_mode mode = GET_MODE ( x ) ; if ( ! aarch64_classify_address ( & addr , XEXP ( x , 0 ) , mode , true ) ) return false ; if ( addr . type != ADDRESS_REG_IMM && addr . type != ADDRESS_REG_WB && addr . type != ADDRESS_REG_REG && addr . type != ADDRESS_REG_UXTW && addr . type != ADDRESS_REG_SXTW ) return false ; unsigned regno = REGNO ( addr . base ) ; if ( global_regs [ regno ] || fixed_regs [ regno ] ) return false ; if ( addr . type == ADDRESS_REG_WB ) { unsigned code = GET_CODE ( XEXP ( x , 0 ) ) ; * pre_post = true ; * base = addr . base ; if ( code == PRE_MODIFY || code == POST_MODIFY ) * offset = addr . offset ; else { unsigned int_offset = GET_MODE_SIZE ( mode ) . to_constant ( ) ; if ( load_pair && ( code == POST_INC || code == POST_DEC ) ) int_offset *= 2 ; * offset = GEN_INT ( int_offset ) ; } return true ; } else if ( addr . type == ADDRESS_REG_IMM || addr . type == ADDRESS_REG_REG ) { if ( ! iv_p ( insn , addr . base , loop ) ) return false ; * base = addr . base ; * offset = addr . offset ; return true ; } return false ; } </s>

Return true if SRC is a strided load in the LOOP , false otherwise . If it is a strided load , set the BASE and OFFSET . Also , if this is a pre/post increment load , set PRE_POST to true .