<s> void MipsFrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { MachineBasicBlock :: iterator MBBI = MBB . getLastNonDebugInstr ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; MipsFunctionInfo * MipsFI = MF . getInfo < MipsFunctionInfo > ( ) ; const MipsInstrInfo & TII = * static_cast < const MipsInstrInfo * > ( MF . getTarget ( ) . getInstrInfo ( ) ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; int NumBytes = ( int ) MFI -> getStackSize ( ) ; int FPOffset = MipsFI -> getFPStackOffset ( ) ; int RAOffset = MipsFI -> getRAStackOffset ( ) ; unsigned NewReg = 0 ; int NewImm = 0 ; bool ATUsed = false ; if ( hasFP ( MF ) ) { BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: ADDu ) , Mips :: SP ) . addReg ( Mips :: FP ) . addReg ( Mips :: ZERO ) ; ATUsed = expandRegLargeImmPair ( Mips :: SP , FPOffset , NewReg , NewImm , MBB , MBBI ) ; BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: LW ) , Mips :: FP ) . addImm ( NewImm ) . addReg ( NewReg ) ; if ( ATUsed ) BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: ATMACRO ) ) ; } if ( MFI -> adjustsStack ( ) ) { expandRegLargeImmPair ( Mips :: SP , RAOffset , NewReg , NewImm , MBB , MBBI ) ; BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: LW ) , Mips :: RA ) . addImm ( NewImm ) . addReg ( NewReg ) ; if ( ATUsed ) BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: ATMACRO ) ) ; } if ( NumBytes ) { expandRegLargeImmPair ( Mips :: SP , NumBytes , NewReg , NewImm , MBB , MBBI ) ; BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: ADDiu ) , Mips :: SP ) . addReg ( NewReg ) . addImm ( NewImm ) ; if ( ATUsed ) BuildMI ( MBB , MBBI , dl , TII . get ( Mips :: ATMACRO ) ) ; } } </s>

Mips Mips Mips Mips Mips Mips Mips Mips Mips 0 0 Mips::ADDu Mips::SP Mips::FP Mips::ZERO Mips::SP Mips::LW Mips::FP Mips::ATMACRO Mips::SP Mips::LW Mips::RA Mips::ATMACRO Mips::SP Mips::ADDiu Mips::SP Mips::ATMACRO


<s> virtual const MipsRegisterInfo & getRegisterInfo ( ) const { return RI ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> bool AArch64TargetLowering :: isProfitableToHoist ( Instruction * I ) const { if ( I -> getOpcode ( ) != Instruction :: FMul ) return true ; if ( ! I -> hasOneUse ( ) ) return true ; Instruction * User = I -> user_back ( ) ; if ( ! ( User -> getOpcode ( ) == Instruction :: FSub || User -> getOpcode ( ) == Instruction :: FAdd ) ) return true ; const TargetOptions & Options = getTargetMachine ( ) . Options ; const Function * F = I -> getFunction ( ) ; const DataLayout & DL = F -> getParent ( ) -> getDataLayout ( ) ; Type * Ty = User -> getOperand ( 0 ) -> getType ( ) ; return ! ( isFMAFasterThanFMulAndFAdd ( * F , Ty ) && isOperationLegalOrCustom ( ISD :: FMA , getValueType ( DL , Ty ) ) && ( Options . AllowFPOpFusion == FPOpFusion :: Fast || Options . UnsafeFPMath ) ) ; } </s>

Return true if it is profitable to hoist instruction in the then/else to before if .


<s> bool X86FrameLowering :: hasFP ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const MachineModuleInfo & MMI = MF . getMMI ( ) ; const TargetRegisterInfo * RegInfo = TM . getRegisterInfo ( ) ; return ( MF . getTarget ( ) . Options . DisableFramePointerElim ( MF ) || RegInfo -> needsStackRealignment ( MF ) || MFI -> hasVarSizedObjects ( ) || MFI -> isFrameAddressTaken ( ) || MF . hasMSInlineAsm ( ) || MF . getInfo < X86MachineFunctionInfo > ( ) -> getForceFramePointer ( ) || MMI . callsUnwindInit ( ) || MMI . callsEHReturn ( ) ) ; } </s>

hasFP - Return true if the specified function should have a dedicated frame pointer register .


<s> static void mips_for_each_saved_gpr_and_fpr ( HOST_WIDE_INT sp_offset , mips_save_restore_fn fn ) { machine_mode fpr_mode ; int regno ; const struct mips_frame_info * frame = & cfun -> machine -> frame ; HOST_WIDE_INT offset ; unsigned int mask ; offset = frame -> gp_sp_offset - sp_offset ; mask = frame -> mask ; if ( TARGET_MICROMIPS ) umips_build_save_restore ( fn , & mask , & offset ) ; for ( regno = GP_REG_LAST ; regno >= GP_REG_FIRST ; regno -- ) if ( BITSET_P ( mask , regno - GP_REG_FIRST ) ) { if ( regno == RETURN_ADDR_REGNUM ) cfun -> machine -> frame . ra_fp_offset = offset + sp_offset ; mips_save_restore_reg ( word_mode , regno , offset , fn ) ; offset -= UNITS_PER_WORD ; } offset = cfun -> machine -> frame . fp_sp_offset - sp_offset ; fpr_mode = ( TARGET_SINGLE_FLOAT ? SFmode : DFmode ) ; for ( regno = FP_REG_LAST - MAX_FPRS_PER_FMT + 1 ; regno >= FP_REG_FIRST ; regno -= MAX_FPRS_PER_FMT ) if ( BITSET_P ( cfun -> machine -> frame . fmask , regno - FP_REG_FIRST ) ) { if ( ! TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT && ( fixed_regs [ regno ] || fixed_regs [ regno + 1 ] ) ) { if ( fixed_regs [ regno ] ) mips_save_restore_reg ( SFmode , regno + 1 , offset , fn ) ; else mips_save_restore_reg ( SFmode , regno , offset , fn ) ; } else mips_save_restore_reg ( fpr_mode , regno , offset , fn ) ; offset -= GET_MODE_SIZE ( fpr_mode ) ; } } </s>

Call FN for each register that is saved by the current function . SP_OFFSET is the offset of the current stack pointer from the start of the frame .


<s> inline bool vgpr_1reg_mode_p ( machine_mode mode ) { if ( VECTOR_MODE_P ( mode ) ) mode = GET_MODE_INNER ( mode ) ; return ( mode == SImode || mode == SFmode || mode == HImode || mode == HFmode || mode == QImode || mode == BImode ) ; } </s>

Return true if MODE is valid for 1 VGPR register .


<s> void PPCAIXAsmPrinter :: SetupMachineFunction ( MachineFunction & MF ) { CurrentFnDescSym = getSymbol ( & MF . getFunction ( ) ) ; MCSectionXCOFF * FnDescSec = OutStreamer -> getContext ( ) . getXCOFFSection ( CurrentFnDescSym -> getName ( ) , XCOFF :: XMC_DS , XCOFF :: XTY_SD , XCOFF :: C_HIDEXT , SectionKind :: getData ( ) ) ; cast < MCSymbolXCOFF > ( CurrentFnDescSym ) -> setContainingCsect ( FnDescSec ) ; return AsmPrinter :: SetupMachineFunction ( MF ) ; } </s>

This should be called when a new MachineFunction is being processed from runOnMachineFunction .


<s>
bool
Emitter
<
CodeEmitter
>
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
MMI
=
&
getAnalysis
<
MachineModuleInfo
>
(
)
;
MCE
.
setModuleInfo
(
MMI
)
;
II
=
TM
.
getInstrInfo
(
)
;
TD
=
TM
.
getTargetData
(
)
;
Is64BitMode
=
TM
.
getSubtarget
<
X86Subtarget
>
(
)
.
is64Bit
(
)
;
IsPIC
=
TM
.
getRelocationModel
(
)
==
Reloc
::
PIC_
;
do
{
DEBUG
(
dbgs
(
)
<<
"JITTing function '"
<<
MF
.
getFunction
(
)
->
getName
(
)
<<
"'\n"
)
;
MCE
.
startFunction
(
MF
)
;
for
(
MachineFunction
::
iterator
MBB
=
MF
.
begin
(
)
,
E
=
MF
.
end
(
)
;
MBB
!=
E
;
++
MBB
)
{
MCE
.
StartMachineBasicBlock
(
MBB
)
;
for
(
MachineBasicBlock
::
const_iterator
I
=
MBB
->
begin
(
)
,
E
=
MBB
->
end
(
)
;
I
!=
E
;
++
I
)
{
const
TargetInstrDesc
&
Desc
=
I
->
getDesc
(
)
;
emitInstruction
(
*
I
,
&
Desc
)
;
if
(
Desc
.
getOpcode
(
)
==
X86
::
MOVPC32r
)
emitInstruction
(
*
I
,
&
II
->
get
(
X86
::
POP32r
)
)
;
NumEmitted
++
;
}
}
}
while
(
MCE
.
finishFunction
(
MF
)
)
;
return
false
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> void SITargetLowering :: finalizeLowering ( MachineFunction & MF ) const { MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; SIMachineFunctionInfo * Info = MF . getInfo < SIMachineFunctionInfo > ( ) ; const GCNSubtarget & ST = MF . getSubtarget < GCNSubtarget > ( ) ; const SIRegisterInfo * TRI = Subtarget -> getRegisterInfo ( ) ; const SIInstrInfo * TII = ST . getInstrInfo ( ) ; if ( Info -> isEntryFunction ( ) ) { reservePrivateMemoryRegs ( getTargetMachine ( ) , MF , * TRI , * Info ) ; } assert ( ! TRI -> isSubRegister ( Info -> getScratchRSrcReg ( ) , Info -> getStackPtrOffsetReg ( ) ) ) ; if ( Info -> getStackPtrOffsetReg ( ) != AMDGPU :: SP_REG ) MRI . replaceRegWith ( AMDGPU :: SP_REG , Info -> getStackPtrOffsetReg ( ) ) ; if ( Info -> getScratchRSrcReg ( ) != AMDGPU :: PRIVATE_RSRC_REG ) MRI . replaceRegWith ( AMDGPU :: PRIVATE_RSRC_REG , Info -> getScratchRSrcReg ( ) ) ; if ( Info -> getFrameOffsetReg ( ) != AMDGPU :: FP_REG ) MRI . replaceRegWith ( AMDGPU :: FP_REG , Info -> getFrameOffsetReg ( ) ) ; Info -> limitOccupancy ( MF ) ; if ( ST . isWave32 ( ) && ! MF . empty ( ) ) { for ( auto & MBB : MF ) { for ( auto & MI : MBB ) { TII -> fixImplicitOperands ( MI ) ; } } } if ( ST . needsAlignedVGPRs ( ) ) { for ( unsigned I = 0 , E = MRI . getNumVirtRegs ( ) ; I != E ; ++ I ) { const Register Reg = Register :: index2VirtReg ( I ) ; const TargetRegisterClass * RC = MRI . getRegClassOrNull ( Reg ) ; if ( ! RC ) continue ; int NewClassID = getAlignedAGPRClassID ( RC -> getID ( ) ) ; if ( NewClassID != - 1 ) MRI . setRegClass ( Reg , TRI -> getRegClass ( NewClassID ) ) ; } } TargetLoweringBase :: finalizeLowering ( MF ) ; } </s>

Execute target specific actions to finalize target lowering .


<s>
const
char
*
output_move_quad
(
rtx
*
operands
)
{
if
(
REG_P
(
operands
[
0
]
)
)
{
if
(
MEM_P
(
operands
[
1
]
)
)
{
switch
(
GET_CODE
(
XEXP
(
operands
[
1
]
,
0
)
)
)
{
case
REG
:
output_asm_insn
(
"ldm%(ia%)\t%m1, %M0"
,
operands
)
;
break
;
case
LABEL_REF
:
case
CONST
:
output_asm_insn
(
"adr%?\t%0, %1"
,
operands
)
;
output_asm_insn
(
"ldm%(ia%)\t%0, %M0"
,
operands
)
;
break
;
default
:
gcc_unreachable
(
)
;
}
}
else
{
rtx
ops
[
2
]
;
int
dest
,
src
,
i
;
gcc_assert
(
REG_P
(
operands
[
1
]
)
)
;
dest
=
REGNO
(
operands
[
0
]
)
;
src
=
REGNO
(
operands
[
1
]
)
;
if
(
dest
<
src
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
ops
[
0
]
=
gen_rtx_REG
(
SImode
,
dest
+
i
)
;
ops
[
1
]
=
gen_rtx_REG
(
SImode
,
src
+
i
)
;
output_asm_insn
(
"mov%?\t%0, %1"
,
ops
)
;
}
else
for
(
i
=
3
;
i
>=
0
;
i
)
{
ops
[
0
]
=
gen_rtx_REG
(
SImode
,
dest
+
i
)
;
ops
[
1
]
=
gen_rtx_REG
(
SImode
,
src
+
i
)
;
output_asm_insn
(
"mov%?\t%0, %1"
,
ops
)
;
}
}
}
else
{
gcc_assert
(
MEM_P
(
operands
[
0
]
)
)
;
gcc_assert
(
REG_P
(
operands
[
1
]
)
)
;
gcc_assert
(
!
reg_overlap_mentioned_p
(
operands
[
1
]
,
operands
[
0
]
)
)
;
switch
(
GET_CODE
(
XEXP
(
operands
[
0
]
,
0
)
)
)
{
case
REG
:
output_asm_insn
(
"stm%(ia%)\t%m0, %M1"
,
operands
)
;
break
;
default
:
gcc_unreachable
(
)
;
}
}
return
""
;
}
</s>

Output assembler code to perform a quadword move insn with operands OPERANDS .


<s> long compute_frame_size ( int size ) { if ( cfun -> static_chain_decl != NULL ) size += ( 1 * UNITS_PER_WORD ) ; xtensa_current_frame_size = XTENSA_STACK_ALIGN ( size + current_function_outgoing_args_size + ( WINDOW_SIZE * UNITS_PER_WORD ) ) ; return xtensa_current_frame_size ; } </s>

Typical stack layout should looks like this after the function 's prologue : | | -- ^ | | \ | | | arguments saved | Increasing | | on the stack | addresses PARENT arg pointer - > | | / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | - space for argument split between regs & stack -- CHILD | | \ < -- ( return address here ) | | other call | | saved registers | | / -- frame pointer - > | | \ ___ | | local | | | variables |f | | / |r -- |a | | \ |m | | outgoing |e | | arguments | | Decreasing ( hard ) frame pointer | | / | | addresses and stack pointer - > | | / _|_ | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- V


<s> rtx sh_try_omit_signzero_extend ( rtx extended_op , rtx_insn * insn ) { if ( REG_P ( extended_op ) ) extended_op = extended_op ; else if ( GET_CODE ( extended_op ) == SUBREG && REG_P ( SUBREG_REG ( extended_op ) ) ) extended_op = SUBREG_REG ( extended_op ) ; else return NULL_RTX ; if ( GET_MODE ( extended_op ) != SImode ) return NULL_RTX ; set_of_reg s = sh_find_set_of_reg ( extended_op , insn , prev_nonnote_nondebug_insn_bb ) ; if ( s . set_src == NULL_RTX ) return NULL_RTX ; if ( t_reg_operand ( s . set_src , VOIDmode ) || negt_reg_operand ( s . set_src , VOIDmode ) ) return extended_op ; else if ( sh_is_logical_t_store_expr ( s . set_src , s . insn ) ) return extended_op ; return NULL_RTX ; } </s>

Given the operand that is extended in a sign/zero extend insn , and the insn , try to figure out whether the sign/zero extension can be replaced by a simple reg-reg copy . If so , the replacement reg rtx is returned , NULL_RTX otherwise .


<s> FastISel * MipsTargetLowering :: createFastISel ( FunctionLoweringInfo & funcInfo , const TargetLibraryInfo * libInfo ) const { const MipsTargetMachine & TM = static_cast < const MipsTargetMachine & > ( funcInfo . MF -> getTarget ( ) ) ; bool UseFastISel = TM . Options . EnableFastISel && Subtarget . hasMips32 ( ) && ! Subtarget . hasMips32r6 ( ) && ! Subtarget . inMips16Mode ( ) && ! Subtarget . inMicroMipsMode ( ) ; if ( ! TM . isPositionIndependent ( ) || ! TM . getABI ( ) . IsO32 ( ) || LargeGOT ) UseFastISel = false ; return UseFastISel ? Mips :: createFastISel ( funcInfo , libInfo ) : nullptr ; } </s>

This method returns a target specific FastISel object , or null if the target does not support `` fast '' ISel .

Mips Mips Mips Mips Mips Mips Mips Mips Mips::createFastISel


<s> bool isGlobal ( ) const { return Kind == MachineOperand :: MO_GlobalAddress ; } </s>

isGlobal - Tests if this is a MO_GlobalAddress operand .


<s> bool AArch64TargetLowering :: isLegalAddImmediate ( int64_t Immed ) const { if ( ( Immed >> 12 ) == 0 || ( ( Immed & 0xfff ) == 0 && Immed >> 24 == 0 ) ) return true ; return false ; } </s>

Return true if the specified immediate is legal add immediate , that is the target has add instructions which can add a register and the immediate without having to materialize the immediate into a register .


<s> static sbitmap rs6000_get_separate_components ( void ) { rs6000_stack_t * info = rs6000_stack_info ( ) ; if ( WORLD_SAVE_P ( info ) ) return NULL ; if ( TARGET_SPE_ABI ) return NULL ; sbitmap components = sbitmap_alloc ( 32 ) ; bitmap_clear ( components ) ; gcc_assert ( ! ( info -> savres_strategy & SAVE_MULTIPLE ) && ! ( info -> savres_strategy & REST_MULTIPLE ) ) ; if ( ( info -> savres_strategy & SAVE_INLINE_GPRS ) && ( info -> savres_strategy & REST_INLINE_GPRS ) ) { int reg_size = TARGET_32BIT ? 4 : 8 ; int offset = info -> gp_save_offset ; if ( info -> push_p ) offset += info -> total_size ; for ( unsigned regno = info -> first_gp_reg_save ; regno < 32 ; regno ++ ) { if ( IN_RANGE ( offset , - 0x8000 , 0x7fff ) && rs6000_reg_live_or_pic_offset_p ( regno ) ) bitmap_set_bit ( components , regno ) ; offset += reg_size ; } } if ( frame_pointer_needed ) bitmap_clear_bit ( components , HARD_FRAME_POINTER_REGNUM ) ; if ( ( TARGET_TOC && TARGET_MINIMAL_TOC ) || ( flag_pic == 1 && DEFAULT_ABI == ABI_V4 ) || ( flag_pic && DEFAULT_ABI == ABI_DARWIN ) ) bitmap_clear_bit ( components , RS6000_PIC_OFFSET_TABLE_REGNUM ) ; if ( info -> lr_save_p && ! ( flag_pic && ( DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN ) ) && ( info -> savres_strategy & SAVE_INLINE_GPRS ) && ( info -> savres_strategy & REST_INLINE_GPRS ) && ( info -> savres_strategy & SAVE_INLINE_FPRS ) && ( info -> savres_strategy & REST_INLINE_FPRS ) && ( info -> savres_strategy & SAVE_INLINE_VRS ) && ( info -> savres_strategy & REST_INLINE_VRS ) ) { int offset = info -> lr_save_offset ; if ( info -> push_p ) offset += info -> total_size ; if ( IN_RANGE ( offset , - 0x8000 , 0x7fff ) ) bitmap_set_bit ( components , 0 ) ; } return components ; } </s>


<s> static bool sh_pass_in_reg_p ( const CUMULATIVE_ARGS & cum , machine_mode mode , const_tree type ) { return ( ( type == 0 || ( ! TREE_ADDRESSABLE ( type ) && ( ! ( TARGET_HITACHI || cum . renesas_abi ) || ! ( AGGREGATE_TYPE_P ( type ) || ( ! TARGET_FPU_ANY && ( GET_MODE_CLASS ( mode ) == MODE_FLOAT && GET_MODE_SIZE ( mode ) > GET_MODE_SIZE ( SFmode ) ) ) ) ) ) ) && ! cum . force_mem && ( TARGET_SH2E ? ( ( mode ) == BLKmode ? ( ( cum . arg_count [ ( int ) SH_ARG_INT ] * UNITS_PER_WORD + int_size_in_bytes ( type ) ) <= NPARM_REGS ( SImode ) * UNITS_PER_WORD ) : ( ( sh_round_reg ( cum , mode ) + sh_hard_regno_nregs ( BASE_ARG_REG ( mode ) , mode ) ) <= NPARM_REGS ( mode ) ) ) : sh_round_reg ( cum , mode ) < NPARM_REGS ( mode ) ) ) ; } </s>

Return true if arg of the specified mode should be be passed in a register or false otherwise .


<s> const char * RISCVTargetLowering :: getTargetNodeName ( unsigned Opcode ) const { switch ( ( RISCVISD :: NodeType ) Opcode ) { case RISCVISD :: FIRST_NUMBER : break ; case RISCVISD :: RET_FLAG : return "RISCVISD::RET_FLAG" ; case RISCVISD :: URET_FLAG : return "RISCVISD::URET_FLAG" ; case RISCVISD :: SRET_FLAG : return "RISCVISD::SRET_FLAG" ; case RISCVISD :: MRET_FLAG : return "RISCVISD::MRET_FLAG" ; case RISCVISD :: CALL : return "RISCVISD::CALL" ; case RISCVISD :: SELECT_CC : return "RISCVISD::SELECT_CC" ; case RISCVISD :: BuildPairF64 : return "RISCVISD::BuildPairF64" ; case RISCVISD :: SplitF64 : return "RISCVISD::SplitF64" ; case RISCVISD :: TAIL : return "RISCVISD::TAIL" ; case RISCVISD :: SLLW : return "RISCVISD::SLLW" ; case RISCVISD :: SRAW : return "RISCVISD::SRAW" ; case RISCVISD :: SRLW : return "RISCVISD::SRLW" ; case RISCVISD :: DIVW : return "RISCVISD::DIVW" ; case RISCVISD :: DIVUW : return "RISCVISD::DIVUW" ; case RISCVISD :: REMUW : return "RISCVISD::REMUW" ; case RISCVISD :: FMV_W_X_RV64 : return "RISCVISD::FMV_W_X_RV64" ; case RISCVISD :: FMV_X_ANYEXTW_RV64 : return "RISCVISD::FMV_X_ANYEXTW_RV64" ; case RISCVISD :: READ_CYCLE_WIDE : return "RISCVISD::READ_CYCLE_WIDE" ; case RISCVISD :: VINSERTT64_W : return "RISCVISD::VINSERTT64_W" ; case RISCVISD :: VINSERTB64_W : return "RISCVISD::VINSERTB64_W" ; case RISCVISD :: VEXTRACTT64_W : return "RISCVISD::VEXTRACTT64_W" ; case RISCVISD :: VEXTRACTB64_W : return "RISCVISD::VEXTRACTB64_W" ; } return nullptr ; } </s>

getTargetNodeName - This method returns the name of a target specific


<s> bool isMem ( RegisterKind RegKind , bool HasIndex ) const { return ( Kind == KindMem && Mem . RegKind == RegKind && ( HasIndex || ! Mem . Index ) ) ; } </s>


<s> bool HexagonInstrInfo :: areMemAccessesTriviallyDisjoint ( MachineInstr & MIa , MachineInstr & MIb , AliasAnalysis * AA ) const { if ( MIa . hasUnmodeledSideEffects ( ) || MIb . hasUnmodeledSideEffects ( ) || MIa . hasOrderedMemoryRef ( ) || MIb . hasOrderedMemoryRef ( ) ) return false ; if ( MIa . mayLoad ( ) && ! isMemOp ( MIa ) && MIb . mayLoad ( ) && ! isMemOp ( MIb ) ) return true ; unsigned BasePosA , OffsetPosA ; if ( ! getBaseAndOffsetPosition ( MIa , BasePosA , OffsetPosA ) ) return false ; const MachineOperand & BaseA = MIa . getOperand ( BasePosA ) ; unsigned BaseRegA = BaseA . getReg ( ) ; unsigned BaseSubA = BaseA . getSubReg ( ) ; unsigned BasePosB , OffsetPosB ; if ( ! getBaseAndOffsetPosition ( MIb , BasePosB , OffsetPosB ) ) return false ; const MachineOperand & BaseB = MIb . getOperand ( BasePosB ) ; unsigned BaseRegB = BaseB . getReg ( ) ; unsigned BaseSubB = BaseB . getSubReg ( ) ; if ( BaseRegA != BaseRegB || BaseSubA != BaseSubB ) return false ; unsigned SizeA = getMemAccessSize ( MIa ) ; unsigned SizeB = getMemAccessSize ( MIb ) ; const MachineOperand & OffA = MIa . getOperand ( OffsetPosA ) ; const MachineOperand & OffB = MIb . getOperand ( OffsetPosB ) ; if ( ! MIa . getOperand ( OffsetPosA ) . isImm ( ) || ! MIb . getOperand ( OffsetPosB ) . isImm ( ) ) return false ; int OffsetA = isPostIncrement ( MIa ) ? 0 : OffA . getImm ( ) ; int OffsetB = isPostIncrement ( MIb ) ? 0 : OffB . getImm ( ) ; if ( OffsetA > OffsetB ) { uint64_t OffDiff = ( uint64_t ) ( ( int64_t ) OffsetA - ( int64_t ) OffsetB ) ; return SizeB <= OffDiff ; } if ( OffsetA < OffsetB ) { uint64_t OffDiff = ( uint64_t ) ( ( int64_t ) OffsetB - ( int64_t ) OffsetA ) ; return SizeA <= OffDiff ; } return false ; } </s>

Sometimes , it is possible for the target to tell , even without aliasing information , that two MIs access different memory addresses .


<s>
X86TargetMachine
::
X86TargetMachine
(
const
Target
&
T
,
const
std
::
string
&
TT
,
const
std
::
string
&
FS
,
bool
is64Bit
)
:
LLVMTargetMachine
(
T
,
TT
)
,
Subtarget
(
TT
,
FS
,
is64Bit
)
,
FrameInfo
(
*
this
,
Subtarget
)
,
ELFWriterInfo
(
is64Bit
,
true
)
{
DefRelocModel
=
getRelocationModel
(
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
Default
)
{
if
(
Subtarget
.
isTargetDarwin
(
)
)
{
if
(
Subtarget
.
is64Bit
(
)
)
setRelocationModel
(
Reloc
::
PIC_
)
;
else
setRelocationModel
(
Reloc
::
DynamicNoPIC
)
;
}
else
if
(
Subtarget
.
isTargetWin64
(
)
)
setRelocationModel
(
Reloc
::
PIC_
)
;
else
setRelocationModel
(
Reloc
::
Static
)
;
}
assert
(
getRelocationModel
(
)
!=
Reloc
::
Default
&&
"Relocation mode not picked"
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
DynamicNoPIC
)
{
if
(
is64Bit
)
setRelocationModel
(
Reloc
::
PIC_
)
;
else
if
(
!
Subtarget
.
isTargetDarwin
(
)
)
setRelocationModel
(
Reloc
::
Static
)
;
}
if
(
getRelocationModel
(
)
==
Reloc
::
Static
&&
Subtarget
.
isTargetDarwin
(
)
&&
is64Bit
)
setRelocationModel
(
Reloc
::
PIC_
)
;
if
(
getRelocationModel
(
)
==
Reloc
::
Static
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
)
;
}
else
if
(
Subtarget
.
is64Bit
(
)
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
RIPRel
)
;
}
else
if
(
Subtarget
.
isTargetCygMing
(
)
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
)
;
}
else
if
(
Subtarget
.
isTargetDarwin
(
)
)
{
if
(
getRelocationModel
(
)
==
Reloc
::
PIC_
)
Subtarget
.
setPICStyle
(
PICStyles
::
StubPIC
)
;
else
{
assert
(
getRelocationModel
(
)
==
Reloc
::
DynamicNoPIC
)
;
Subtarget
.
setPICStyle
(
PICStyles
::
StubDynamicNoPIC
)
;
}
}
else
if
(
Subtarget
.
isTargetELF
(
)
)
{
Subtarget
.
setPICStyle
(
PICStyles
::
GOT
)
;
}
if
(
Subtarget
.
getPICStyle
(
)
==
PICStyles
::
)
setRelocationModel
(
Reloc
::
Static
)
;
}
</s>


<s> bool mayNeedRelaxation ( const MCInst & Inst ) const override { return false ; } </s>

Check whether the given instruction may need relaxation .


<s>
SDValue
ARM64TargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
isVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
SDLoc
DL
,
SelectionDAG
&
DAG
)
const
{
CCAssignFn
*
RetCC
=
CallConv
==
CallingConv
::
WebKit_JS
RetCC_ARM64_WebKit_JS
:
RetCC_ARM64_AAPCS
;
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
CCState
CCInfo
(
CallConv
,
isVarArg
,
DAG
.
getMachineFunction
(
)
,
getTargetMachine
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
CCInfo
.
AnalyzeReturn
(
Outs
,
RetCC
)
;
SDValue
Flag
;
SmallVector
<
SDValue
,
4
>
RetOps
(
1
,
Chain
)
;
for
(
unsigned
i
=
0
,
realRVLocIdx
=
0
;
i
!=
RVLocs
.
size
(
)
;
++
i
,
++
realRVLocIdx
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
SDValue
Arg
=
OutVals
[
realRVLocIdx
]
;
switch
(
VA
.
getLocInfo
(
)
)
{
default
:
llvm_unreachable
(
"Unknown loc info!"
)
;
case
CCValAssign
::
Full
:
break
;
case
CCValAssign
::
BCvt
:
Arg
=
DAG
.
getNode
(
ISD
::
BITCAST
,
DL
,
VA
.
getLocVT
(
)
,
Arg
)
;
break
;
}
Chain
=
DAG
.
getCopyToReg
(
Chain
,
DL
,
VA
.
getLocReg
(
)
,
Arg
,
Flag
)
;
Flag
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
VA
.
getLocReg
(
)
,
VA
.
getLocVT
(
)
)
)
;
}
RetOps
[
0
]
=
Chain
;
if
(
Flag
.
getNode
(
)
)
RetOps
.
push_back
(
Flag
)
;
return
DAG
.
getNode
(
ARM64ISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
RetOps
)
;
}
</s>

This hook must be implemented to lower outgoing return values , described by the Outs array , into the specified DAG .


<s> static void ix86_output_indirect_branch_via_reg ( rtx call_op , bool sibcall_p ) { char thunk_name_buf [ 32 ] ; char * thunk_name ; enum indirect_thunk_prefix need_prefix = indirect_thunk_need_prefix ( current_output_insn ) ; int regno = REGNO ( call_op ) ; if ( cfun -> machine -> indirect_branch_type != indirect_branch_thunk_inline ) { if ( cfun -> machine -> indirect_branch_type == indirect_branch_thunk ) SET_HARD_REG_BIT ( indirect_thunks_used , regno ) ; indirect_thunk_name ( thunk_name_buf , regno , need_prefix , false ) ; thunk_name = thunk_name_buf ; } else thunk_name = NULL ; if ( sibcall_p ) ix86_output_jmp_thunk_or_indirect ( thunk_name , regno ) ; else { if ( thunk_name != NULL ) { if ( REX_INT_REGNO_P ( regno ) && ix86_indirect_branch_cs_prefix ) fprintf ( asm_out_file , "\tcs\n" ) ; fprintf ( asm_out_file , "\tcall\t" ) ; assemble_name ( asm_out_file , thunk_name ) ; putc ( '\n' , asm_out_file ) ; return ; } char indirectlabel1 [ 32 ] ; char indirectlabel2 [ 32 ] ; ASM_GENERATE_INTERNAL_LABEL ( indirectlabel1 , INDIRECT_LABEL , indirectlabelno ++ ) ; ASM_GENERATE_INTERNAL_LABEL ( indirectlabel2 , INDIRECT_LABEL , indirectlabelno ++ ) ; fputs ( "\tjmp\t" , asm_out_file ) ; assemble_name_raw ( asm_out_file , indirectlabel2 ) ; fputc ( '\n' , asm_out_file ) ; ASM_OUTPUT_INTERNAL_LABEL ( asm_out_file , indirectlabel1 ) ; ix86_output_jmp_thunk_or_indirect ( thunk_name , regno ) ; ASM_OUTPUT_INTERNAL_LABEL ( asm_out_file , indirectlabel2 ) ; fputs ( "\tcall\t" , asm_out_file ) ; assemble_name_raw ( asm_out_file , indirectlabel1 ) ; fputc ( '\n' , asm_out_file ) ; } } </s>

Output indirect branch via a call and return thunk . CALL_OP is a register which contains the branch target . XASM is the assembly template for CALL_OP . Branch is a tail call if SIBCALL_P is true . A normal call is converted to : call __x86_indirect_thunk_reg and a tail call is converted to : jmp __x86_indirect_thunk_reg


<s> Optional < Value * > X86TTIImpl :: simplifyDemandedUseBitsIntrinsic ( InstCombiner & IC , IntrinsicInst & II , APInt DemandedMask , KnownBits & Known , bool & KnownBitsComputed ) const { switch ( II . getIntrinsicID ( ) ) { default : break ; case Intrinsic :: x86_mmx_pmovmskb : case Intrinsic :: x86_sse_movmsk_ps : case Intrinsic :: x86_sse2_movmsk_pd : case Intrinsic :: x86_sse2_pmovmskb_128 : case Intrinsic :: x86_avx_movmsk_ps_256 : case Intrinsic :: x86_avx_movmsk_pd_256 : case Intrinsic :: x86_avx2_pmovmskb : { unsigned ArgWidth ; if ( II . getIntrinsicID ( ) == Intrinsic :: x86_mmx_pmovmskb ) { ArgWidth = 8 ; } else { auto * ArgType = cast < FixedVectorType > ( II . getArgOperand ( 0 ) -> getType ( ) ) ; ArgWidth = ArgType -> getNumElements ( ) ; } APInt DemandedElts = DemandedMask . zextOrTrunc ( ArgWidth ) ; Type * VTy = II . getType ( ) ; if ( DemandedElts . isNullValue ( ) ) { return ConstantInt :: getNullValue ( VTy ) ; } Known . Zero . setBitsFrom ( ArgWidth ) ; KnownBitsComputed = true ; break ; } } return None ; } </s>

Can be used to implement target-specific instruction combining .


<s> bool HexagonPassConfig :: addPostRegAlloc ( ) { const HexagonTargetMachine & TM = getHexagonTargetMachine ( ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) if ( ! DisableHexagonCFGOpt ) addPass ( createHexagonCFGOptimizer ( TM ) ) ; return false ; } </s>

This method may be implemented by targets that want to run passes after register allocation pass pipeline but before prolog-epilog insertion .

Hexagon Hexagon Hexagon Hexagon Hexagon Hexagon


<s> void SystemZInstrInfo :: loadRegFromStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , Register DestReg , int FrameIdx , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { DebugLoc DL = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned LoadOpcode , StoreOpcode ; getLoadStoreOpcodes ( RC , LoadOpcode , StoreOpcode ) ; addFrameReference ( BuildMI ( MBB , MBBI , DL , get ( LoadOpcode ) , DestReg ) , FrameIdx ) ; } </s>

Load the specified register of the given register class from the specified stack frame index .


<s>
bool
TVMContinuationsHoist
::
optimize
(
)
{
bool
Changed
=
false
;
for
(
auto
*
MI
:
DeleteMIs
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Erasing unused: "
<<
*
MI
<<
"\n"
)
;
MI
->
eraseFromParent
(
)
;
}
for
(
const
auto
&
Pair
:
Info
)
{
auto
TargetMBB
=
Pair
.
first
;
const
auto
&
Instrs
=
Pair
.
second
.
Instructions
;
if
(
Instrs
.
size
(
)
<
2
)
continue
;
Changed
=
true
;
auto
CommonDom
=
Instrs
.
front
(
)
->
getParent
(
)
;
for
(
auto
CurNextMI
:
drop_begin
(
Instrs
,
1
)
)
{
assert
(
CommonDom
&&
"PUSHCONT_MBB with null parent"
)
;
assert
(
CurNextMI
->
getParent
(
)
&&
"PUSHCONT_MBB with null parent"
)
;
CommonDom
=
MDT
->
findNearestCommonDominator
(
CommonDom
,
CurNextMI
->
getParent
(
)
)
;
}
MachineInstr
*
FoundMI
=
nullptr
;
for
(
auto
I
=
CommonDom
->
instr_rbegin
(
)
,
E
=
CommonDom
->
instr_rend
(
)
;
I
!=
E
;
++
I
)
{
MachineInstr
&
MI
=
*
I
;
if
(
MI
.
getOpcode
(
)
==
TVM
::
PUSHCONT_MBB
&&
MI
.
getOperand
(
1
)
.
getMBB
(
)
==
TargetMBB
)
{
FoundMI
=
&
MI
;
break
;
}
}
unsigned
MBBReg
=
0
;
if
(
FoundMI
)
{
MBBReg
=
FoundMI
->
getOperand
(
0
)
.
getReg
(
)
;
FoundMI
->
clearRegisterDeads
(
MBBReg
)
;
}
else
{
MachineInstr
*
InsertBefore
=
&
*
CommonDom
->
getFirstInstrTerminator
(
)
;
unsigned
FirstOpReg
=
InsertBefore
->
getOperand
(
0
)
.
getReg
(
)
;
if
(
TargetRegisterInfo
::
isVirtualRegister
(
FirstOpReg
)
&&
MRI
->
hasOneDef
(
FirstOpReg
)
)
{
MachineInstr
*
I
=
MRI
->
getVRegDef
(
FirstOpReg
)
;
if
(
I
->
getOpcode
(
)
!=
TVM
::
PHI
&&
I
->
getParent
(
)
==
InsertBefore
->
getParent
(
)
)
InsertBefore
=
I
;
}
MBBReg
=
MRI
->
createVirtualRegister
(
&
TVM
::
I257RegClass
)
;
BuildMI
(
*
CommonDom
,
InsertBefore
,
DebugLoc
(
)
,
TII
->
get
(
TVM
::
PUSHCONT_MBB
)
,
MBBReg
)
.
addMBB
(
TargetMBB
)
.
addImm
(
0
)
;
}
for
(
auto
CurDefMI
:
Instrs
)
{
if
(
FoundMI
&&
FoundMI
==
CurDefMI
)
continue
;
auto
OldDefMO
=
CurDefMI
->
getOperand
(
0
)
;
assert
(
OldDefMO
.
isReg
(
)
&&
"PUSHCONT_MBB def is not reg"
)
;
CurDefMI
->
eraseFromParent
(
)
;
MRI
->
replaceRegWith
(
OldDefMO
.
getReg
(
)
,
MBBReg
)
;
}
MRI
->
clearKillFlags
(
MBBReg
)
;
}
return
Changed
;
}
</s>

Apply VPlan-to-VPlan optimizations to Plan , including induction recipe optimizations , dead recipe removal , replicate region optimizations and block merging .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const { AU . setPreservesCFG ( ) ; AU . addRequired < MachineDominatorTree > ( ) ; AU . addPreserved < MachineDominatorTree > ( ) ; AU . addRequired < MachineLoopInfo > ( ) ; AU . addPreserved < MachineLoopInfo > ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> static void aarch64_update_cpp_builtins ( cpp_reader * pfile ) { aarch64_def_or_undef ( flag_unsafe_math_optimizations , "__ARM_FP_FAST" , pfile ) ; builtin_define_with_int_value ( "__ARM_ARCH" , aarch64_architecture_version ) ; builtin_define_with_int_value ( "__ARM_SIZEOF_MINIMAL_ENUM" , flag_short_enums ? 1 : 4 ) ; aarch64_def_or_undef ( TARGET_BIG_END , "__AARCH64EB__" , pfile ) ; aarch64_def_or_undef ( TARGET_BIG_END , "__ARM_BIG_ENDIAN" , pfile ) ; aarch64_def_or_undef ( ! TARGET_BIG_END , "__AARCH64EL__" , pfile ) ; aarch64_def_or_undef ( TARGET_FLOAT , "__ARM_FEATURE_FMA" , pfile ) ; if ( TARGET_FLOAT || TARGET_SIMD ) { builtin_define_with_int_value ( "__ARM_FP" , 0x0E ) ; builtin_define ( "__ARM_FP16_FORMAT_IEEE" ) ; builtin_define ( "__ARM_FP16_ARGS" ) ; } else cpp_undef ( pfile , "__ARM_FP" ) ; aarch64_def_or_undef ( TARGET_FP_F16INST , "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC" , pfile ) ; aarch64_def_or_undef ( TARGET_SIMD_F16INST , "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC" , pfile ) ; aarch64_def_or_undef ( TARGET_SIMD , "__ARM_FEATURE_NUMERIC_MAXMIN" , pfile ) ; aarch64_def_or_undef ( TARGET_SIMD , "__ARM_NEON" , pfile ) ; aarch64_def_or_undef ( TARGET_CRC32 , "__ARM_FEATURE_CRC32" , pfile ) ; aarch64_def_or_undef ( TARGET_DOTPROD , "__ARM_FEATURE_DOTPROD" , pfile ) ; aarch64_def_or_undef ( TARGET_COMPLEX , "__ARM_FEATURE_COMPLEX" , pfile ) ; cpp_undef ( pfile , "__AARCH64_CMODEL_TINY__" ) ; cpp_undef ( pfile , "__AARCH64_CMODEL_SMALL__" ) ; cpp_undef ( pfile , "__AARCH64_CMODEL_LARGE__" ) ; switch ( aarch64_cmodel ) { case AARCH64_CMODEL_TINY : case AARCH64_CMODEL_TINY_PIC : builtin_define ( "__AARCH64_CMODEL_TINY__" ) ; break ; case AARCH64_CMODEL_SMALL : case AARCH64_CMODEL_SMALL_PIC : builtin_define ( "__AARCH64_CMODEL_SMALL__" ) ; break ; case AARCH64_CMODEL_LARGE : builtin_define ( "__AARCH64_CMODEL_LARGE__" ) ; break ; default : break ; } aarch64_def_or_undef ( TARGET_ILP32 , "_ILP32" , pfile ) ; aarch64_def_or_undef ( TARGET_ILP32 , "__ILP32__" , pfile ) ; aarch64_def_or_undef ( TARGET_CRYPTO , "__ARM_FEATURE_CRYPTO" , pfile ) ; aarch64_def_or_undef ( TARGET_SIMD_RDMA , "__ARM_FEATURE_QRDMX" , pfile ) ; aarch64_def_or_undef ( TARGET_SVE , "__ARM_FEATURE_SVE" , pfile ) ; cpp_undef ( pfile , "__ARM_FEATURE_SVE_BITS" ) ; if ( TARGET_SVE ) { int bits ; if ( ! BITS_PER_SVE_VECTOR . is_constant ( & bits ) ) bits = 0 ; builtin_define_with_int_value ( "__ARM_FEATURE_SVE_BITS" , bits ) ; } aarch64_def_or_undef ( TARGET_LSE , "__ARM_FEATURE_ATOMICS" , pfile ) ; aarch64_def_or_undef ( TARGET_AES , "__ARM_FEATURE_AES" , pfile ) ; aarch64_def_or_undef ( TARGET_SHA2 , "__ARM_FEATURE_SHA2" , pfile ) ; aarch64_def_or_undef ( TARGET_SHA3 , "__ARM_FEATURE_SHA3" , pfile ) ; aarch64_def_or_undef ( TARGET_SHA3 , "__ARM_FEATURE_SHA512" , pfile ) ; aarch64_def_or_undef ( TARGET_SM4 , "__ARM_FEATURE_SM3" , pfile ) ; aarch64_def_or_undef ( TARGET_SM4 , "__ARM_FEATURE_SM4" , pfile ) ; aarch64_def_or_undef ( TARGET_F16FML , "__ARM_FEATURE_FP16_FML" , pfile ) ; cpp_undef ( pfile , "__FLT_EVAL_METHOD__" ) ; builtin_define_with_int_value ( "__FLT_EVAL_METHOD__" , c_flt_eval_method ( true ) ) ; cpp_undef ( pfile , "__FLT_EVAL_METHOD_C99__" ) ; builtin_define_with_int_value ( "__FLT_EVAL_METHOD_C99__" , c_flt_eval_method ( false ) ) ; } </s>

Undefine/redefine macros that depend on the current backend state and may need to change when a target pragma modifies the backend state .


"va_start: words = %d, n_gpr = %d, n_fpr = %d\n"


<s> rtx mcore_function_arg ( CUMULATIVE_ARGS cum , enum machine_mode mode , tree type , int named ) { int arg_reg ; if ( ! named || mode == VOIDmode ) return 0 ; if ( targetm . calls . must_pass_in_stack ( mode , type ) ) return 0 ; arg_reg = ROUND_REG ( cum , mode ) ; if ( arg_reg < NPARM_REGS ) return handle_structs_in_regs ( mode , type , FIRST_PARM_REG + arg_reg ) ; return 0 ; } </s>

Define where to put the arguments to a function . Value is zero to push the argument on the stack , or a hard register in which to store the argument . MODE is the argument 's machine mode . TYPE is the data type of the argument ( as a tree ) . This is null for libcalls where that information may not be available . CUM is a variable of type CUMULATIVE_ARGS which gives info about the preceding args and about the function being called . NAMED is nonzero if this argument is a named parameter ( otherwise it is an extra parameter matching an ellipsis ) . On MCore the first args are normally in registers and the rest are pushed . Any arg that starts within the first NPARM_REGS words is at least partially passed in a register unless its data type forbids .


<s> unsigned getSize ( ) const { return CurType . Size ; } </s>

Return the number of bytes in the encoding of this instruction , or zero if the encoding size can not be known from the opcode .


<s> bool ARM64TargetLowering :: isTruncateFree ( EVT VT1 , EVT VT2 ) const { if ( ! VT1 . isInteger ( ) || ! VT2 . isInteger ( ) ) return false ; unsigned NumBits1 = VT1 . getSizeInBits ( ) ; unsigned NumBits2 = VT2 . getSizeInBits ( ) ; if ( NumBits1 <= NumBits2 ) return false ; return true ; } </s>

Return true if it 's free to truncate a value of type Ty1 to type Ty2 .


<s> static bool arc_symbol_binds_local_p ( const_rtx x ) { return ( SYMBOL_REF_DECL ( x ) ? targetm . binds_local_p ( SYMBOL_REF_DECL ( x ) ) : SYMBOL_REF_LOCAL_P ( x ) ) ; } </s>

Return true if SYMBOL_REF X binds locally .


<s> void SIInstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , unsigned SrcReg , bool isKill , int FrameIndex , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { MachineFunction * MF = MBB . getParent ( ) ; SIMachineFunctionInfo * MFI = MF -> getInfo < SIMachineFunctionInfo > ( ) ; MachineFrameInfo & FrameInfo = MF -> getFrameInfo ( ) ; const DebugLoc & DL = MBB . findDebugLoc ( MI ) ; unsigned Size = FrameInfo . getObjectSize ( FrameIndex ) ; unsigned Align = FrameInfo . getObjectAlignment ( FrameIndex ) ; MachinePointerInfo PtrInfo = MachinePointerInfo :: getFixedStack ( * MF , FrameIndex ) ; MachineMemOperand * MMO = MF -> getMachineMemOperand ( PtrInfo , MachineMemOperand :: MOStore , Size , Align ) ; unsigned SpillSize = TRI -> getSpillSize ( * RC ) ; if ( RI . isSGPRClass ( RC ) ) { MFI -> setHasSpilledSGPRs ( ) ; const MCInstrDesc & OpDesc = get ( getSGPRSpillSaveOpcode ( SpillSize ) ) ; if ( Register :: isVirtualRegister ( SrcReg ) && SpillSize == 4 ) { MachineRegisterInfo & MRI = MF -> getRegInfo ( ) ; MRI . constrainRegClass ( SrcReg , & AMDGPU :: SReg_32_XM0RegClass ) ; } MachineInstrBuilder Spill = BuildMI ( MBB , MI , DL , OpDesc ) . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FrameIndex ) . addMemOperand ( MMO ) . addReg ( MFI -> getScratchRSrcReg ( ) , RegState :: Implicit ) . addReg ( MFI -> getStackPtrOffsetReg ( ) , RegState :: Implicit ) ; if ( RI . spillSGPRToVGPR ( ) ) FrameInfo . setStackID ( FrameIndex , TargetStackID :: SGPRSpill ) ; if ( ST . hasScalarStores ( ) ) { Spill . addReg ( AMDGPU :: M0 , RegState :: ImplicitDefine | RegState :: Dead ) ; } return ; } unsigned Opcode = RI . hasAGPRs ( RC ) ? getAGPRSpillSaveOpcode ( SpillSize ) : getVGPRSpillSaveOpcode ( SpillSize ) ; MFI -> setHasSpilledVGPRs ( ) ; auto MIB = BuildMI ( MBB , MI , DL , get ( Opcode ) ) ; if ( RI . hasAGPRs ( RC ) ) { MachineRegisterInfo & MRI = MF -> getRegInfo ( ) ; Register Tmp = MRI . createVirtualRegister ( & AMDGPU :: VGPR_32RegClass ) ; MIB . addReg ( Tmp , RegState :: Define ) ; } MIB . addReg ( SrcReg , getKillRegState ( isKill ) ) . addFrameIndex ( FrameIndex ) . addReg ( MFI -> getScratchRSrcReg ( ) ) . addReg ( MFI -> getStackPtrOffsetReg ( ) ) . addImm ( 0 ) . addMemOperand ( MMO ) ; } </s>

Store the specified register of the given register class to the specified stack frame index .


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlotPostFE ( const MachineInstr & MI , int & FrameIndex ) const { const MachineMemOperand * Dummy ; return MI . mayStore ( ) && hasStoreToStackSlot ( MI , Dummy , FrameIndex ) ; } </s>

isStoreToStackSlotPostFE - Check for post-frame ptr elimination stack locations as well .


<s> static bool mips_call_may_need_jalx_p ( tree decl ) { if ( mips_get_compress_mode ( decl ) != TARGET_COMPRESSION ) return true ; if ( ! DECL_EXTERNAL ( decl ) && targetm . binds_local_p ( decl ) ) return false ; if ( TARGET_INTERLINK_COMPRESSED ) { if ( ! TARGET_COMPRESSION && mips_get_compress_off_flags ( DECL_ATTRIBUTES ( decl ) ) == 0 ) return true ; if ( TARGET_COMPRESSION && mips_get_compress_on_flags ( DECL_ATTRIBUTES ( decl ) ) == 0 ) return true ; } return false ; } </s>

Return true if a call to DECL may need to use JALX .


"%qE attribute only applies to functions"

Handle a `` longcall '' attribute ; arguments as in struct attribute_spec.handler .


<s> std :: pair < unsigned , const TargetRegisterClass * > MSP430TargetLowering :: getRegForInlineAsmConstraint ( const std :: string & Constraint , EVT VT ) const { if ( Constraint . size ( ) == 1 ) { switch ( Constraint [ 0 ] ) { default : break ; case 'r' : if ( VT == MVT :: i8 ) return std :: make_pair ( 0U , MSP430 :: GR8RegisterClass ) ; return std :: make_pair ( 0U , MSP430 :: GR16RegisterClass ) ; } } return TargetLowering :: getRegForInlineAsmConstraint ( Constraint , VT ) ; } </s>

Given a physical register constraint ( e.g .


<s> static bool indirect_call_p ( rtx pat ) { if ( GET_CODE ( pat ) == PARALLEL ) pat = XVECEXP ( pat , 0 , 0 ) ; if ( GET_CODE ( pat ) == SET ) pat = SET_SRC ( pat ) ; gcc_assert ( GET_CODE ( pat ) == CALL ) ; pat = XEXP ( pat , 0 ) ; gcc_assert ( GET_CODE ( pat ) == MEM ) ; pat = XEXP ( pat , 0 ) ; return REG_P ( pat ) ; } </s>

Determine whether PAT is an indirect call pattern .


<s> EVT X86TargetLowering :: getOptimalMemOpType ( uint64_t Size , unsigned Align , bool isSrcConst , bool isSrcStr , SelectionDAG & DAG ) const { const Function * F = DAG . getMachineFunction ( ) . getFunction ( ) ; bool NoImplicitFloatOps = F -> hasFnAttr ( Attribute :: NoImplicitFloat ) ; if ( ! NoImplicitFloatOps && Subtarget -> getStackAlignment ( ) >= 16 ) { if ( ( isSrcConst || isSrcStr ) && Subtarget -> hasSSE2 ( ) && Size >= 16 ) return MVT :: v4i32 ; if ( ( isSrcConst || isSrcStr ) && Subtarget -> hasSSE1 ( ) && Size >= 16 ) return MVT :: v4f32 ; } if ( Subtarget -> is64Bit ( ) && Size >= 8 ) return MVT :: i64 ; return MVT :: i32 ; } </s>

It returns EVT : :Other if the type should be determined using generic target-independent logic .


<s> static rtx alignment_mask ( rtx_insn * insn ) { rtx body = PATTERN ( insn ) ; if ( GET_CODE ( body ) != SET || GET_CODE ( SET_SRC ( body ) ) != AND || ! REG_P ( XEXP ( SET_SRC ( body ) , 0 ) ) ) return 0 ; rtx mask = XEXP ( SET_SRC ( body ) , 1 ) ; if ( GET_CODE ( mask ) == CONST_INT ) { if ( INTVAL ( mask ) == - 16 ) return alignment_with_canonical_addr ( SET_SRC ( body ) ) ; else return 0 ; } if ( ! REG_P ( mask ) ) return 0 ; struct df_insn_info * insn_info = DF_INSN_INFO_GET ( insn ) ; df_ref use ; rtx real_mask = 0 ; FOR_EACH_INSN_INFO_USE ( use , insn_info ) { if ( ! rtx_equal_p ( DF_REF_REG ( use ) , mask ) ) continue ; struct df_link * def_link = DF_REF_CHAIN ( use ) ; if ( ! def_link || def_link -> next ) return 0 ; rtx_insn * const_insn = DF_REF_INSN ( def_link -> ref ) ; rtx const_body = PATTERN ( const_insn ) ; if ( GET_CODE ( const_body ) != SET ) return 0 ; real_mask = SET_SRC ( const_body ) ; if ( GET_CODE ( real_mask ) != CONST_INT || INTVAL ( real_mask ) != - 16 ) return 0 ; } if ( real_mask == 0 ) return 0 ; return alignment_with_canonical_addr ( SET_SRC ( body ) ) ; } </s>

Check whether an rtx is an alignment mask , and if so , return a fully-expanded rtx for the masking operation .


<s> void PPCRegisterInfo :: lowerQuadwordSpilling ( MachineBasicBlock :: iterator II , unsigned FrameIndex ) const { MachineInstr & MI = * II ; MachineBasicBlock & MBB = * MI . getParent ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const PPCSubtarget & Subtarget = MF . getSubtarget < PPCSubtarget > ( ) ; const TargetInstrInfo & TII = * Subtarget . getInstrInfo ( ) ; DebugLoc DL = MI . getDebugLoc ( ) ; Register SrcReg = MI . getOperand ( 0 ) . getReg ( ) ; bool IsKilled = MI . getOperand ( 0 ) . isKill ( ) ; Register Reg = PPC :: X0 + ( SrcReg - PPC :: G8p0 ) * 2 ; bool IsLittleEndian = Subtarget . isLittleEndian ( ) ; addFrameReference ( BuildMI ( MBB , II , DL , TII . get ( PPC :: STD ) ) . addReg ( Reg , getKillRegState ( IsKilled ) ) , FrameIndex , IsLittleEndian ? 8 : 0 ) ; addFrameReference ( BuildMI ( MBB , II , DL , TII . get ( PPC :: STD ) ) . addReg ( Reg + 1 , getKillRegState ( IsKilled ) ) , FrameIndex , IsLittleEndian ? 0 : 8 ) ; MBB . erase ( II ) ; } </s>

lowerQuadwordSpilling - Generate code to spill paired general register .


<s> bool AArch64Subtarget :: enableEarlyIfConversion ( ) const { return EnableEarlyIfConvert ; } </s>

Enable the use of the early if conversion pass .


<s> TargetPassConfig * MBlazeTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new MBlazePassConfig ( this , PM ) ; } </s>

Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of CodeGen passes .


<s>
static
bool
pdp11_assemble_integer
(
rtx
x
,
unsigned
int
size
,
int
aligned_p
)
{
if
(
aligned_p
)
switch
(
size
)
{
case
1
:
fprintf
(
asm_out_file
,
"\t.byte\t"
)
;
output_addr_const_pdp11
(
asm_out_file
,
GEN_INT
(
INTVAL
(
x
)
&
0xff
)
)
;
;
fprintf
(
asm_out_file
,
" /* char */\n"
)
;
return
true
;
case
2
:
fprintf
(
asm_out_file
,
TARGET_UNIX_ASM
"\t"
:
"\t.word\t"
)
;
output_addr_const_pdp11
(
asm_out_file
,
x
)
;
fprintf
(
asm_out_file
,
" /* short */\n"
)
;
return
true
;
}
return
default_assemble_integer
(
x
,
size
,
aligned_p
)
;
}
</s>

Target hook to assemble integer objects . We need to use the pdp-specific version of output_addr_const .


<s> static rtx safe_vector_operand ( rtx x , machine_mode mode ) { if ( x == const0_rtx ) x = CONST0_RTX ( mode ) ; return x ; } </s>

Errors in the source file can cause expand_expr to return const0_rtx where we expect a vector . To avoid crashing , use one of the vector clear instructions .


<s> bool TPCPassConfig :: addInstSelector ( ) { addPass ( createTPCISelDag ( getTPCTargetMachine ( ) , getOptLevel ( ) ) ) ; addPass ( createTPCMemorySize ( ) ) ; return false ; } </s>

addInstSelector - This method should install an instruction selector pass , which converts from LLVM code to machine instructions .


<s> void arm_poke_function_name ( FILE * stream , const char * name ) { unsigned long alignlength ; unsigned long length ; rtx x ; length = strlen ( name ) + 1 ; alignlength = ROUND_UP_WORD ( length ) ; ASM_OUTPUT_ASCII ( stream , name , length ) ; ASM_OUTPUT_ALIGN ( stream , 2 ) ; x = GEN_INT ( ( unsigned HOST_WIDE_INT ) 0xff000000 + alignlength ) ; assemble_aligned_integer ( UNITS_PER_WORD , x ) ; } </s>

Write the function name into the code section , directly preceding the function prologue . Code will be output similar to this : t0 .ascii `` arm_poke_function_name '' , 0 .align t1 .word 0xff000000 + ( t1 - t0 ) arm_poke_function_name mov ip , sp stmfd sp ! , { fp , ip , lr , pc } sub fp , ip , # 4 When performing a stack backtrace , code can inspect the value of 'pc ' stored at 'fp ' + 0 . If the trace function then looks at location pc - 12 and the top 8 bits are set , then we know that there is a function name embedded immediately preceding this location and has length ( ( pc [ -3 ] ) & 0xff000000 ) . We assume that pc is declared as a pointer to an unsigned long . It is of no benefit to output the function name if we are assembling a leaf function . These function types will not contain a stack backtrace structure , therefore it is not possible to determine the function name .


<s> bool NVPTXDAGToDAGISel :: SelectInlineAsmMemoryOperand ( const SDValue & Op , char ConstraintCode , std :: vector < SDValue > & OutOps ) { SDValue Op0 , Op1 ; switch ( ConstraintCode ) { default : return true ; case 'm' : if ( SelectDirectAddr ( Op , Op0 ) ) { OutOps . push_back ( Op0 ) ; OutOps . push_back ( CurDAG -> getTargetConstant ( 0 , MVT :: i32 ) ) ; return false ; } if ( SelectADDRri ( Op . getNode ( ) , Op , Op0 , Op1 ) ) { OutOps . push_back ( Op0 ) ; OutOps . push_back ( Op1 ) ; return false ; } break ; } return true ; } </s>

SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode , according to the specified constraint .


<s> bool mips_const_vector_bitimm_set_p ( rtx op , machine_mode mode ) { if ( GET_CODE ( op ) == CONST_VECTOR && op != CONST0_RTX ( mode ) ) { unsigned HOST_WIDE_INT val = UINTVAL ( CONST_VECTOR_ELT ( op , 0 ) ) ; int vlog2 = exact_log2 ( val & GET_MODE_MASK ( GET_MODE_INNER ( mode ) ) ) ; if ( vlog2 != - 1 ) { gcc_assert ( GET_MODE_CLASS ( mode ) == MODE_VECTOR_INT ) ; gcc_assert ( vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE ( mode ) - 1 ) ; return mips_const_vector_same_val_p ( op , mode ) ; } } return false ; } </s>

Return true if OP is a constant vector with the number of units in MODE , and each unit has the same bit set .


<s> void SystemZInstrInfo :: storeRegToStackSlot ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MBBI , unsigned SrcReg , bool isKill , int FrameIdx , const TargetRegisterClass * RC , const TargetRegisterInfo * TRI ) const { DebugLoc DL = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned LoadOpcode , StoreOpcode ; getLoadStoreOpcodes ( RC , LoadOpcode , StoreOpcode ) ; addFrameReference ( BuildMI ( MBB , MBBI , DL , get ( StoreOpcode ) ) . addReg ( SrcReg , getKillRegState ( isKill ) ) , FrameIdx ) ; } </s>

Store the specified register of the given register class to the specified stack frame index .


<s> bool HexagonAsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & OS ) { if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; switch ( ExtraCode [ 0 ] ) { default : return true ; case 'c' : printOperand ( MI , OpNo , OS ) ; return false ; case 'L' : if ( ! MI -> getOperand ( OpNo ) . isReg ( ) || OpNo + 1 == MI -> getNumOperands ( ) || ! MI -> getOperand ( OpNo + 1 ) . isReg ( ) ) return true ; ++ OpNo ; break ; case 'I' : if ( MI -> getOperand ( OpNo ) . isImm ( ) ) OS << "i" ; return false ; } } printOperand ( MI , OpNo , OS ) ; return false ; } </s>

PrintAsmOperand - Print out an operand for an inline asm expression .


<s>
static
bool
arm_rtx_costs
(
rtx
x
,
int
code
,
int
outer_code
,
int
opno
ATTRIBUTE_UNUSED
,
int
*
total
,
bool
speed
)
{
bool
result
;
if
(
TARGET_OLD_RTX_COSTS
||
(
!
current_tune
->
insn_extra_cost
&&
!
TARGET_NEW_GENERIC_COSTS
)
)
{
if
(
!
speed
)
result
=
arm_size_rtx_costs
(
x
,
(
enum
rtx_code
)
code
,
(
enum
rtx_code
)
outer_code
,
total
)
;
else
result
=
current_tune
->
rtx_costs
(
x
,
(
enum
rtx_code
)
code
,
(
enum
rtx_code
)
outer_code
,
total
,
speed
)
;
}
else
{
if
(
current_tune
->
insn_extra_cost
)
result
=
arm_new_rtx_costs
(
x
,
(
enum
rtx_code
)
code
,
(
enum
rtx_code
)
outer_code
,
current_tune
->
insn_extra_cost
,
total
,
speed
)
;
else
result
=
arm_new_rtx_costs
(
x
,
(
enum
rtx_code
)
code
,
(
enum
rtx_code
)
outer_code
,
&
generic_extra_costs
,
total
,
speed
)
;
}
if
(
dump_file
&&
(
dump_flags
&
TDF_DETAILS
)
)
{
print_rtl_single
(
dump_file
,
x
)
;
fprintf
(
dump_file
,
"\n%s cost: %d (%s)\n"
,
speed
"Hot"
:
"Cold"
,
*
total
,
result
"final"
:
"partial"
)
;
}
return
result
;
}
</s>

arm
"\n%s cost: %d (%s)\n"
"Hot"
"Cold"
"final"
"partial"


<s> static bool aarch64_takes_arguments_in_sve_regs_p ( const_tree fntype ) { CUMULATIVE_ARGS args_so_far_v ; aarch64_init_cumulative_args ( & args_so_far_v , NULL_TREE , NULL_RTX , NULL_TREE , 0 , true ) ; cumulative_args_t args_so_far = pack_cumulative_args ( & args_so_far_v ) ; for ( tree chain = TYPE_ARG_TYPES ( fntype ) ; chain && chain != void_list_node ; chain = TREE_CHAIN ( chain ) ) { tree arg_type = TREE_VALUE ( chain ) ; if ( arg_type == error_mark_node ) return false ; function_arg_info arg ( arg_type , true ) ; apply_pass_by_reference_rules ( & args_so_far_v , arg ) ; pure_scalable_type_info pst_info ; if ( pst_info . analyze_registers ( arg . type ) ) { unsigned int end_zr = args_so_far_v . aapcs_nvrn + pst_info . num_zr ( ) ; unsigned int end_pr = args_so_far_v . aapcs_nprn + pst_info . num_pr ( ) ; gcc_assert ( end_zr <= NUM_FP_ARG_REGS && end_pr <= NUM_PR_ARG_REGS ) ; return true ; } targetm . calls . function_arg_advance ( args_so_far , arg ) ; } return false ; } </s>

Return true if a function with type FNTYPE takes arguments in SVE vector or predicate registers .


<s> TargetPassConfig * WebAssemblyTargetMachine :: createPassConfig ( PassManagerBase & PM ) { return new WebAssemblyPassConfig ( * this , PM ) ; } </s>


<s> void OR1KAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { auto I = MI -> getIterator ( ) ; auto E = MI -> getParent ( ) -> instr_end ( ) ; do { customEmitInstruction ( & * I ++ ) ; } while ( ( I != E ) && I -> isInsideBundle ( ) ) ; } </s>

EmitInstruction - This callback is invoked when an instruction is emitted , to advance the hazard state .


<s> static struct machine_function * mmix_init_machine_status ( void ) { return ggc_alloc_cleared ( sizeof ( struct machine_function ) ) ; } </s>


<s> void P2AsmPrinter :: emitFunctionEntryLabel ( ) { OutStreamer -> emitLabel ( CurrentFnSym ) ; } </s>

EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function .


<s> void Cpu0MCInstLower :: Initialize ( MCContext * C ) { Ctx = C ; } </s>

This method must be called before any actual lowering is done .


<s> static void verify_neutering_labels ( basic_block to , rtx_insn * vector_label , rtx_insn * worker_label ) { basic_block bb = to ; rtx_insn * insn = BB_END ( bb ) ; bool seen_worker_label = false ; bool seen_vector_label = false ; while ( true ) { if ( insn == worker_label ) { seen_worker_label = true ; gcc_assert ( ! seen_vector_label ) ; } else if ( insn == vector_label ) seen_vector_label = true ; else if ( INSN_P ( insn ) ) switch ( recog_memoized ( insn ) ) { case CODE_FOR_nvptx_barsync : gcc_assert ( ! seen_vector_label && ! seen_worker_label ) ; break ; } if ( insn != BB_HEAD ( bb ) ) insn = PREV_INSN ( insn ) ; else break ; } gcc_assert ( ! ( vector_label && ! seen_vector_label ) ) ; gcc_assert ( ! ( worker_label && ! seen_worker_label ) ) ; } </s>

Verify position of VECTOR_LABEL and WORKER_LABEL in TO .


<s> bool AArch64PassConfig :: addInstSelector ( ) { addPass ( createAArch64ISelDag ( getAArch64TargetMachine ( ) , getOptLevel ( ) ) ) ; if ( TM -> getTargetTriple ( ) . isOSBinFormatELF ( ) && getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createAArch64CleanupLocalDynamicTLSPass ( ) ) ; return false ; } </s>


<s> bool HexagonAsmPrinter :: PrintAsmMemoryOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & O ) { if ( ExtraCode && ExtraCode [ 0 ] ) return true ; const MachineOperand & Base = MI -> getOperand ( OpNo ) ; const MachineOperand & Offset = MI -> getOperand ( OpNo + 1 ) ; if ( Base . isReg ( ) ) printOperand ( MI , OpNo , O ) ; else llvm_unreachable ( "Unimplemented" ) ; if ( Offset . isImm ( ) ) { if ( Offset . getImm ( ) ) O << "+#" << Offset . getImm ( ) ; } else { llvm_unreachable ( "Unimplemented" ) ; } return false ; } </s>

Print the specified operand of MI , an INLINEASM instruction , using the specified assembler variant as an address .

Hexagon Hexagon 0 1 "Unimplemented" "+#" "Unimplemented"


<s> bool LanaiTargetObjectFile :: isGlobalInSmallSection ( const GlobalValue * GV , const TargetMachine & TM , SectionKind Kind ) const { return ( isGlobalInSmallSectionImpl ( GV , TM ) && ( Kind . isData ( ) || Kind . isBSS ( ) || Kind . isCommon ( ) ) ) ; } </s>

Return true if this global address should be placed into small data/bss section .


<s>
void
ARMTTIImpl
::
getUnrollingPreferences
(
Loop
*
L
,
ScalarEvolution
&
SE
,
TTI
::
UnrollingPreferences
&
UP
)
{
if
(
!
ST
->
isMClass
(
)
)
return
BasicTTIImplBase
::
getUnrollingPreferences
(
L
,
SE
,
UP
)
;
UP
.
OptSizeThreshold
=
0
;
UP
.
PartialOptSizeThreshold
=
0
;
if
(
L
->
getHeader
(
)
->
getParent
(
)
->
optForSize
(
)
)
return
;
if
(
!
ST
->
isThumb2
(
)
)
return
;
SmallVector
<
BasicBlock
*
,
4
>
ExitingBlocks
;
L
->
getExitingBlocks
(
ExitingBlocks
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Loop has:\n"
<<
"Blocks: "
<<
L
->
getNumBlocks
(
)
<<
"\n"
<<
"Exit blocks: "
<<
ExitingBlocks
.
size
(
)
<<
"\n"
)
;
if
(
ExitingBlocks
.
size
(
)
>
2
)
return
;
if
(
ST
->
hasBranchPredictor
(
)
&&
L
->
getNumBlocks
(
)
>
4
)
return
;
unsigned
Cost
=
0
;
for
(
auto
*
BB
:
L
->
getBlocks
(
)
)
{
for
(
auto
&
I
:
*
BB
)
{
if
(
isa
<
CallInst
>
(
I
)
||
isa
<
InvokeInst
>
(
I
)
)
{
ImmutableCallSite
CS
(
&
I
)
;
if
(
const
Function
*
F
=
CS
.
getCalledFunction
(
)
)
{
if
(
!
isLoweredToCall
(
F
)
)
continue
;
}
return
;
}
SmallVector
<
const
Value
*
,
4
>
Operands
(
I
.
value_op_begin
(
)
,
I
.
value_op_end
(
)
)
;
Cost
+=
getUserCost
(
&
I
,
Operands
)
;
}
}
LLVM_DEBUG
(
dbgs
(
)
<<
"Cost of loop: "
<<
Cost
<<
"\n"
)
;
UP
.
Partial
=
true
;
UP
.
Runtime
=
true
;
UP
.
UnrollRemainder
=
true
;
UP
.
DefaultUnrollRuntimeCount
=
4
;
if
(
Cost
<
12
)
UP
.
Force
=
true
;
}
</s>

Get target-customized preferences for the generic loop unrolling transformation .


<s> bool X86InstrInfo :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc DL = MBB . findDebugLoc ( MI ) ; bool is64Bit = TM . getSubtarget < X86Subtarget > ( ) . is64Bit ( ) ; bool isWin64 = TM . getSubtarget < X86Subtarget > ( ) . isTargetWin64 ( ) ; unsigned SlotSize = is64Bit ? 8 : 4 ; MachineFunction & MF = * MBB . getParent ( ) ; unsigned FPReg = RI . getFrameRegister ( MF ) ; X86MachineFunctionInfo * X86FI = MF . getInfo < X86MachineFunctionInfo > ( ) ; unsigned CalleeFrameSize = 0 ; unsigned Opc = is64Bit ? X86 :: PUSH64r : X86 :: PUSH32r ; for ( unsigned i = CSI . size ( ) ; i != 0 ; -- i ) { unsigned Reg = CSI [ i - 1 ] . getReg ( ) ; const TargetRegisterClass * RegClass = CSI [ i - 1 ] . getRegClass ( ) ; MBB . addLiveIn ( Reg ) ; if ( Reg == FPReg ) continue ; if ( RegClass != & X86 :: VR128RegClass && ! isWin64 ) { CalleeFrameSize += SlotSize ; BuildMI ( MBB , MI , DL , get ( Opc ) ) . addReg ( Reg , RegState :: Kill ) ; } else { storeRegToStackSlot ( MBB , MI , Reg , true , CSI [ i - 1 ] . getFrameIdx ( ) , RegClass ) ; } } X86FI -> setCalleeSavedFrameSize ( CalleeFrameSize ) ; return true ; } </s>

spillCalleeSavedRegisters - Issues instruction ( s ) to spill all callee saved registers and returns true if it is n't possible / profitable to do so by issuing a series of store instructions via storeRegToStackSlot ( ) .


<s> static void mcore_mark_dllexport ( tree decl ) { const char * oldname ; char * newname ; rtx rtlname ; tree idp ; rtlname = XEXP ( DECL_RTL ( decl ) , 0 ) ; if ( GET_CODE ( rtlname ) == MEM ) rtlname = XEXP ( rtlname , 0 ) ; gcc_assert ( GET_CODE ( rtlname ) == SYMBOL_REF ) ; oldname = XSTR ( rtlname , 0 ) ; if ( mcore_dllexport_name_p ( oldname ) ) return ; newname = XALLOCAVEC ( char , strlen ( oldname ) + 4 ) ; sprintf ( newname , "@e.%s" , oldname ) ; idp = get_identifier ( newname ) ; XEXP ( DECL_RTL ( decl ) , 0 ) = gen_rtx_SYMBOL_REF ( Pmode , IDENTIFIER_POINTER ( idp ) ) ; } </s>


<s>
LLVM_DUMP_METHOD
void
SDWADstPreserveOperand
::
print
(
raw_ostream
&
OS
)
const
{
OS
<<
"SDWA preserve dst: "
<<
*
getTargetOperand
(
)
<<
" dst_sel:"
<<
getDstSel
(
)
<<
" preserve:"
<<
*
getPreservedOperand
(
)
<<
'\n'
;
}
</s>

print - Print a debug representation of the operand to the given stream .

AMDGPU
"SDWA preserve dst: "
" dst_sel:"
" preserve:"


<s> const Nios2MCExpr * Nios2MCExpr :: create ( const MCSymbol * Symbol , Nios2MCExpr :: Nios2ExprKind Kind , MCContext & Ctx ) { const MCSymbolRefExpr * MCSym = MCSymbolRefExpr :: create ( Symbol , MCSymbolRefExpr :: VK_None , Ctx ) ; return new ( Ctx ) Nios2MCExpr ( Kind , MCSym ) ; } </s>


This pass may be implemented by targets that want to run passes immediately before machine code is emitted .


<s>
static
unsigned
getHashValue
(
const
MemOpKey
&
Val
)
{
assert
(
Val
.
Disp
!=
PtrInfo
::
getEmptyKey
(
)
&&
"Cannot hash the empty key"
)
;
assert
(
Val
.
Disp
!=
PtrInfo
::
getTombstoneKey
(
)
&&
"Cannot hash the tombstone key"
)
;
hash_code
Hash
=
hash_combine
(
*
Val
.
Operands
[
0
]
,
*
Val
.
Operands
[
1
]
,
*
Val
.
Operands
[
2
]
,
*
Val
.
Operands
[
3
]
)
;
switch
(
Val
.
Disp
->
getType
(
)
)
{
case
MachineOperand
::
MO_Immediate
:
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
case
MachineOperand
::
MO_JumpTableIndex
:
Hash
=
hash_combine
(
Hash
,
Val
.
Disp
->
getIndex
(
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
Hash
=
hash_combine
(
Hash
,
Val
.
Disp
->
getSymbolName
(
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
Hash
=
hash_combine
(
Hash
,
Val
.
Disp
->
getGlobal
(
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
Hash
=
hash_combine
(
Hash
,
Val
.
Disp
->
getBlockAddress
(
)
)
;
break
;
case
MachineOperand
::
MO_MCSymbol
:
Hash
=
hash_combine
(
Hash
,
Val
.
Disp
->
getMCSymbol
(
)
)
;
break
;
default
:
llvm_unreachable
(
"Invalid address displacement operand"
)
;
}
return
(
unsigned
)
Hash
;
}
</s>

Using name and line to get hash value . It should already be mostly unique .


<s> MachineInstr * HexagonInstrInfo :: findLoopInstr ( MachineBasicBlock * BB , unsigned EndLoopOp , MachineBasicBlock * TargetBB , SmallPtrSet < MachineBasicBlock * , 8 > & Visited ) const { unsigned LOOPi ; unsigned LOOPr ; if ( EndLoopOp == Hexagon :: ENDLOOP0 ) { LOOPi = Hexagon :: J2_loop0i ; LOOPr = Hexagon :: J2_loop0r ; } else { LOOPi = Hexagon :: J2_loop1i ; LOOPr = Hexagon :: J2_loop1r ; } for ( MachineBasicBlock * PB : BB -> predecessors ( ) ) { if ( ! Visited . insert ( PB ) . second ) continue ; if ( PB == BB ) continue ; for ( auto I = PB -> instr_rbegin ( ) , E = PB -> instr_rend ( ) ; I != E ; ++ I ) { unsigned Opc = I -> getOpcode ( ) ; if ( Opc == LOOPi || Opc == LOOPr ) return & * I ; if ( Opc == EndLoopOp && I -> getOperand ( 0 ) . getMBB ( ) != TargetBB ) return nullptr ; } if ( MachineInstr * Loop = findLoopInstr ( PB , EndLoopOp , TargetBB , Visited ) ) return Loop ; } return nullptr ; } </s>

Find the hardware loop instruction used to set-up the specified loop .


<s> static void mips_output_mi_thunk ( FILE * file , tree thunk_fndecl ATTRIBUTE_UNUSED , HOST_WIDE_INT delta , HOST_WIDE_INT vcall_offset , tree function ) { const char * fnname = IDENTIFIER_POINTER ( DECL_ASSEMBLER_NAME ( thunk_fndecl ) ) ; rtx this_rtx , temp1 , temp2 , fnaddr ; rtx_insn * insn ; bool use_sibcall_p ; reload_completed = 1 ; emit_note ( NOTE_INSN_PROLOGUE_END ) ; fnaddr = XEXP ( DECL_RTL ( function ) , 0 ) ; use_sibcall_p = ( mips_function_ok_for_sibcall ( function , NULL ) && const_call_insn_operand ( fnaddr , Pmode ) ) ; if ( ! use_sibcall_p && ( mips_got_symbol_type_p ( mips_classify_symbol ( fnaddr , SYMBOL_CONTEXT_LEA ) ) ) ) { cfun -> machine -> global_pointer = TARGET_CALL_SAVED_GP ? 15 : GLOBAL_POINTER_REGNUM ; cfun -> machine -> must_initialize_gp_p = true ; SET_REGNO ( pic_offset_table_rtx , cfun -> machine -> global_pointer ) ; mips_emit_loadgp ( ) ; } temp1 = gen_rtx_REG ( Pmode , 2 ) ; temp2 = gen_rtx_REG ( Pmode , 3 ) ; if ( aggregate_value_p ( TREE_TYPE ( TREE_TYPE ( function ) ) , function ) ) this_rtx = gen_rtx_REG ( Pmode , GP_ARG_FIRST + 1 ) ; else this_rtx = gen_rtx_REG ( Pmode , GP_ARG_FIRST ) ; if ( delta != 0 ) { rtx offset = GEN_INT ( delta ) ; if ( ! SMALL_OPERAND ( delta ) ) { mips_emit_move ( temp1 , offset ) ; offset = temp1 ; } emit_insn ( gen_add3_insn ( this_rtx , this_rtx , offset ) ) ; } if ( vcall_offset != 0 ) { rtx addr ; mips_emit_move ( temp1 , gen_rtx_MEM ( Pmode , this_rtx ) ) ; addr = mips_add_offset ( temp2 , temp1 , vcall_offset ) ; mips_emit_move ( temp1 , gen_rtx_MEM ( Pmode , addr ) ) ; emit_insn ( gen_add3_insn ( this_rtx , this_rtx , temp1 ) ) ; } if ( use_sibcall_p ) { insn = emit_call_insn ( gen_sibcall_internal ( fnaddr , const0_rtx ) ) ; SIBLING_CALL_P ( insn ) = 1 ; } else { if ( TARGET_USE_PIC_FN_ADDR_REG && ! TARGET_MIPS16 && ! mips_dangerous_for_la25_p ( fnaddr ) ) temp1 = gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) ; mips_load_call_address ( MIPS_CALL_SIBCALL , temp1 , fnaddr ) ; if ( TARGET_USE_PIC_FN_ADDR_REG && REGNO ( temp1 ) != PIC_FUNCTION_ADDR_REGNUM ) mips_emit_move ( gen_rtx_REG ( Pmode , PIC_FUNCTION_ADDR_REGNUM ) , temp1 ) ; emit_jump_insn ( gen_indirect_jump ( temp1 ) ) ; } insn = get_insns ( ) ; split_all_insns_noflow ( ) ; mips16_lay_out_constants ( true ) ; shorten_branches ( insn ) ; assemble_start_function ( thunk_fndecl , fnname ) ; final_start_function ( insn , file , 1 ) ; final ( insn , file , 1 ) ; final_end_function ( ) ; assemble_end_function ( thunk_fndecl , fnname ) ; reload_completed = 0 ; } </s>

Implement TARGET_ASM_OUTPUT_MI_THUNK . Generate rtl rather than asm text in order to avoid duplicating too much logic from elsewhere .


<s>
unsigned
MipsCodeEmitter
::
getMachineOpValue
(
const
MachineInstr
&
MI
,
const
MachineOperand
&
MO
)
const
{
if
(
MO
.
isReg
(
)
)
return
getMipsRegisterNumbering
(
MO
.
getReg
(
)
)
;
else
if
(
MO
.
isImm
(
)
)
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
else
if
(
MO
.
isGlobal
(
)
)
{
if
(
MI
.
getOpcode
(
)
==
Mips
::
ULW
||
MI
.
getOpcode
(
)
==
Mips
::
USW
||
MI
.
getOpcode
(
)
==
Mips
::
ULH
||
MI
.
getOpcode
(
)
==
Mips
::
ULHu
)
emitGlobalAddressUnaligned
(
MO
.
getGlobal
(
)
,
getRelocation
(
MI
,
MO
)
,
4
)
;
else
if
(
MI
.
getOpcode
(
)
==
Mips
::
USH
)
emitGlobalAddressUnaligned
(
MO
.
getGlobal
(
)
,
getRelocation
(
MI
,
MO
)
,
8
)
;
else
emitGlobalAddress
(
MO
.
getGlobal
(
)
,
getRelocation
(
MI
,
MO
)
,
true
)
;
}
else
if
(
MO
.
isSymbol
(
)
)
emitExternalSymbolAddress
(
MO
.
getSymbolName
(
)
,
getRelocation
(
MI
,
MO
)
)
;
else
if
(
MO
.
isCPI
(
)
)
emitConstPoolAddress
(
MO
.
getIndex
(
)
,
getRelocation
(
MI
,
MO
)
)
;
else
if
(
MO
.
isJTI
(
)
)
emitJumpTableAddress
(
MO
.
getIndex
(
)
,
getRelocation
(
MI
,
MO
)
)
;
else
if
(
MO
.
isMBB
(
)
)
emitMachineBasicBlock
(
MO
.
getMBB
(
)
,
getRelocation
(
MI
,
MO
)
)
;
else
llvm_unreachable
(
"Unable to encode MachineOperand!"
)
;
return
0
;
}
</s>

getMachineOpValue - Return binary encoding of operand .

Mips
Mips
Mips
Mips::ULW
Mips::USW
Mips::ULH
Mips::ULHu
4
Mips::USH
8
"Unable to encode MachineOperand!"
0


<s> bool ARM64FrameLowering :: canUseRedZone ( const MachineFunction & MF ) const { if ( ! EnableRedZone ) return false ; if ( MF . getFunction ( ) -> getAttributes ( ) . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: NoRedZone ) ) return false ; const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const ARM64FunctionInfo * AFI = MF . getInfo < ARM64FunctionInfo > ( ) ; unsigned NumBytes = AFI -> getLocalStackSize ( ) ; if ( MFI -> hasCalls ( ) || hasFP ( MF ) || NumBytes > 128 ) return false ; return true ; } </s>

Can this function use the red zone for local allocations .


<s> bool runOnMachineFunction ( MachineFunction & MF ) override { return SelectionDAGISel :: runOnMachineFunction ( MF ) ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool X86TTIImpl :: isLegalMaskedScatter ( Type * DataType , Align Alignment ) { if ( ! ST -> hasAVX512 ( ) ) return false ; return isLegalMaskedGather ( DataType , Alignment ) ; } </s>

Return true if the target supports masked scatter .


<s> bool TLCS900FrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc DL ; if ( MI != MBB . end ( ) ) DL = MI -> getDebugLoc ( ) ; MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getTarget ( ) . getInstrInfo ( ) ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) BuildMI ( MBB , MI , DL , TII . get ( TLCS900 :: POP16r ) , CSI [ i ] . getReg ( ) ) ; return true ; } </s>

restoreCalleeSavedRegisters - Issues instruction ( s ) to restore all callee saved registers and returns true if it is n't possible / profitable to do so by issuing a series of load instructions via loadRegToStackSlot ( ) .


<s> void loongarch_split_move_insn ( rtx dest , rtx src , rtx insn ) { loongarch_split_move ( dest , src , insn ) ; } </s>

Split a move from SRC to DEST in INSN , given that loongarch_split_move_insn_p holds .


<s> int mips_split_const_insns ( rtx x ) { unsigned int low , high ; low = mips_const_insns ( mips_subword ( x , false ) ) ; high = mips_const_insns ( mips_subword ( x , true ) ) ; gcc_assert ( low > 0 && high > 0 ) ; return low + high ; } </s>

X is a doubleword constant that can be handled by splitting it into two words and loading each word separately . Return the number of instructions required to do this , assuming that BASE_INSN_LENGTH is the length of one instruction .


<s> static bool aarch64_simd_decl_p ( tree fndecl ) { tree fntype ; if ( fndecl == NULL ) return false ; fntype = TREE_TYPE ( fndecl ) ; if ( fntype == NULL ) return false ; if ( lookup_attribute ( "aarch64_vector_pcs" , TYPE_ATTRIBUTES ( fntype ) ) != NULL ) return true ; return false ; } </s>

Return true if this is a definition of a vectorized simd function .


<s> static void block_move_sequence ( rtx dst_mem , rtx src_mem , int size , int align ) { rtx temp [ 2 ] ; enum machine_mode mode [ 2 ] ; int amount [ 2 ] ; bool active [ 2 ] ; int phase = 0 ; int next ; int offset_ld = 0 ; int offset_st = 0 ; rtx x ; x = XEXP ( dst_mem , 0 ) ; if ( ! REG_P ( x ) ) { x = force_reg ( Pmode , x ) ; dst_mem = replace_equiv_address ( dst_mem , x ) ; } x = XEXP ( src_mem , 0 ) ; if ( ! REG_P ( x ) ) { x = force_reg ( Pmode , x ) ; src_mem = replace_equiv_address ( src_mem , x ) ; } active [ 0 ] = active [ 1 ] = false ; do { next = phase ; phase ^= 1 ; if ( size > 0 ) { int next_amount ; next_amount = ( size >= 4 ? 4 : ( size >= 2 ? 2 : 1 ) ) ; next_amount = MIN ( next_amount , align ) ; amount [ next ] = next_amount ; mode [ next ] = mode_from_align [ next_amount ] ; temp [ next ] = gen_reg_rtx ( mode [ next ] ) ; x = adjust_address ( src_mem , mode [ next ] , offset_ld ) ; emit_insn ( gen_rtx_SET ( VOIDmode , temp [ next ] , x ) ) ; offset_ld += next_amount ; size -= next_amount ; active [ next ] = true ; } if ( active [ phase ] ) { active [ phase ] = false ; x = adjust_address ( dst_mem , mode [ phase ] , offset_st ) ; emit_insn ( gen_rtx_SET ( VOIDmode , x , temp [ phase ] ) ) ; offset_st += amount [ phase ] ; } } while ( active [ next ] ) ; } </s>

Emit code to perform a block move with an offset sequence of ld/st instructions ( ... , ld 0 , st 1 , ld 1 , st 0 , ... ) . SIZE and ALIGN are known constants . DEST and SRC are registers . OFFSET is the known starting point for the output pattern .


<s> static bool riscv_slow_unaligned_access ( machine_mode , unsigned int ) { return riscv_slow_unaligned_access_p ; } </s>


"insertBranch must not be told to insert a fallthrough"

"X86 branch conditions have one component!"

"Unconditional branch with multiple successors!"

"MBB cannot be the last block in function when the false "

Insert branch code into the end of the specified MachineBasicBlock .


<s>
virtual
void
print
(
raw_ostream
&
OS
)
const
{
switch
(
Kind
)
{
case
k_Immediate
:
OS
<<
"Imm<"
;
Imm
.
Val
->
print
(
OS
)
;
OS
<<
">"
;
break
;
case
k_Memory
:
OS
<<
"Mem<"
;
Mem
.
Base
->
print
(
OS
)
;
OS
<<
", "
;
Mem
.
Off
->
print
(
OS
)
;
OS
<<
">"
;
break
;
case
k_PhysRegister
:
OS
<<
"PhysReg<"
<<
PhysReg
.
Num
<<
">"
;
break
;
case
k_RegisterIndex
:
OS
<<
"RegIdx<"
<<
RegIdx
.
Index
<<
":"
<<
RegIdx
.
Kind
<<
">"
;
break
;
case
k_Token
:
OS
<<
Tok
.
Data
;
break
;
}
}
</s>


<s> CUMULATIVE_ARGS xstormy16_function_arg_advance ( CUMULATIVE_ARGS cum , enum machine_mode mode , tree type , int named ATTRIBUTE_UNUSED ) { if ( cum < NUM_ARGUMENT_REGISTERS && cum + XSTORMY16_WORD_SIZE ( type , mode ) > NUM_ARGUMENT_REGISTERS ) cum = NUM_ARGUMENT_REGISTERS ; cum += XSTORMY16_WORD_SIZE ( type , mode ) ; return cum ; } </s>

Update CUM to advance past an argument in the argument list . The values MODE , TYPE and NAMED describe that argument . Once this is done , the variable CUM is suitable for analyzing the * following * argument with ` TARGET_FUNCTION_ARG ' , etc . This function need not do anything if the argument in question was passed on the stack . The compiler knows how to track the amount of stack space used for arguments without any special help . However , it makes life easier for xstormy16_build_va_list if it does update the word count .


This constructor initializes the data members to match that of the specified triple .


<s> void nds32_expand_prologue_v3push ( void ) { int fp_adjust ; int sp_adjust ; int fpr_space = 0 ; unsigned Rb , Re ; nds32_compute_stack_frame ( ) ; if ( cfun -> machine -> callee_saved_gpr_regs_size > 0 ) df_set_regs_ever_live ( FP_REGNUM , 1 ) ; if ( cfun -> machine -> naked_p ) return ; Rb = cfun -> machine -> callee_saved_first_gpr_regno ; Re = cfun -> machine -> callee_saved_last_gpr_regno ; sp_adjust = cfun -> machine -> local_size + cfun -> machine -> out_args_size + cfun -> machine -> callee_saved_area_gpr_padding_bytes + cfun -> machine -> callee_saved_fpr_regs_size ; if ( satisfies_constraint_Iu08 ( GEN_INT ( sp_adjust ) ) && NDS32_DOUBLE_WORD_ALIGN_P ( sp_adjust ) ) { nds32_emit_stack_v3push ( Rb , Re , sp_adjust ) ; if ( cfun -> machine -> callee_saved_first_fpr_regno != SP_REGNUM ) { int fpr_position = cfun -> machine -> local_size + cfun -> machine -> out_args_size ; nds32_emit_push_fpr_callee_saved ( fpr_position ) ; } if ( frame_pointer_needed ) { fp_adjust = cfun -> machine -> fp_size + cfun -> machine -> gp_size + cfun -> machine -> lp_size + cfun -> machine -> callee_saved_gpr_regs_size + sp_adjust ; nds32_emit_adjust_frame ( hard_frame_pointer_rtx , stack_pointer_rtx , fp_adjust ) ; } } else { if ( cfun -> machine -> callee_saved_first_fpr_regno != SP_REGNUM ) { fpr_space = cfun -> machine -> callee_saved_area_gpr_padding_bytes + cfun -> machine -> callee_saved_fpr_regs_size ; nds32_emit_stack_v3push ( Rb , Re , fpr_space ) ; nds32_emit_push_fpr_callee_saved ( 0 ) ; } else { nds32_emit_stack_v3push ( Rb , Re , 0 ) ; } if ( frame_pointer_needed ) { fp_adjust = cfun -> machine -> fp_size + cfun -> machine -> gp_size + cfun -> machine -> lp_size + cfun -> machine -> callee_saved_gpr_regs_size ; if ( cfun -> machine -> callee_saved_first_fpr_regno != SP_REGNUM ) { fp_adjust = fp_adjust + fpr_space ; } nds32_emit_adjust_frame ( hard_frame_pointer_rtx , stack_pointer_rtx , fp_adjust ) ; } if ( cfun -> machine -> callee_saved_first_fpr_regno != SP_REGNUM ) { sp_adjust = sp_adjust - fpr_space ; } nds32_emit_adjust_frame ( stack_pointer_rtx , stack_pointer_rtx , - 1 * sp_adjust ) ; } emit_insn ( gen_blockage ( ) ) ; } </s>


<s> SDValue SystemZTargetLowering :: LowerCallResult ( SDValue Chain , SDValue InFlag , CallingConv :: ID CallConv , bool isVarArg , const SmallVectorImpl < ISD :: InputArg > & Ins , DebugLoc dl , SelectionDAG & DAG , SmallVectorImpl < SDValue > & InVals ) const { SmallVector < CCValAssign , 16 > RVLocs ; CCState CCInfo ( CallConv , isVarArg , getTargetMachine ( ) , RVLocs , * DAG . getContext ( ) ) ; CCInfo . AnalyzeCallResult ( Ins , RetCC_SystemZ ) ; for ( unsigned i = 0 ; i != RVLocs . size ( ) ; ++ i ) { CCValAssign & VA = RVLocs [ i ] ; Chain = DAG . getCopyFromReg ( Chain , dl , VA . getLocReg ( ) , VA . getLocVT ( ) , InFlag ) . getValue ( 1 ) ; SDValue RetValue = Chain . getValue ( 0 ) ; InFlag = Chain . getValue ( 2 ) ; if ( VA . getLocInfo ( ) == CCValAssign :: SExt ) RetValue = DAG . getNode ( ISD :: AssertSext , dl , VA . getLocVT ( ) , RetValue , DAG . getValueType ( VA . getValVT ( ) ) ) ; else if ( VA . getLocInfo ( ) == CCValAssign :: ZExt ) RetValue = DAG . getNode ( ISD :: AssertZext , dl , VA . getLocVT ( ) , RetValue , DAG . getValueType ( VA . getValVT ( ) ) ) ; if ( VA . getLocInfo ( ) != CCValAssign :: Full ) RetValue = DAG . getNode ( ISD :: TRUNCATE , dl , VA . getValVT ( ) , RetValue ) ; InVals . push_back ( RetValue ) ; } return Chain ; } </s>

LowerCallResult - Lower the result values of an ISD : :CALL into the appropriate copies out of appropriate physical registers .


<s> int TL45FrameLowering :: getFrameIndexReference ( const MachineFunction & MF , int FI , unsigned & FrameReg ) const { const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const TargetRegisterInfo * RI = MF . getSubtarget ( ) . getRegisterInfo ( ) ; int Offset = MFI . getObjectOffset ( FI ) - getOffsetOfLocalArea ( ) + MFI . getOffsetAdjustment ( ) ; FrameReg = RI -> getFrameRegister ( MF ) ; if ( hasFP ( MF ) ) Offset += 0 ; else Offset += MF . getFrameInfo ( ) . getStackSize ( ) ; return Offset ; } </s>

getFrameIndexReference - This method should return the base register and offset used to reference a frame index location .


<s> static int mcore_ior_cost ( rtx x ) { HOST_WIDE_INT val ; if ( GET_CODE ( XEXP ( x , 1 ) ) != CONST_INT ) return 2 ; val = INTVAL ( XEXP ( x , 1 ) ) ; if ( CONST_OK_FOR_M ( val ) ) return 2 ; else if ( const_ok_for_mcore ( val ) ) return 3 ; else if ( TARGET_HARDLIT && mcore_const_ok_for_inline ( val ) ) return 4 ; return 5 ; } </s>

What does an or cost - see and_cost ( ) .


<s> static int ck801_legitimate_index_p ( machine_mode mode , rtx index , int strict_p ATTRIBUTE_UNUSED ) { enum rtx_code code = GET_CODE ( index ) ; if ( GET_MODE_SIZE ( mode ) >= 8 ) return ( code == CONST_INT && INTVAL ( index ) < CSKY_LD16_MAX_OFFSET ( SImode ) && INTVAL ( index ) >= 0 && ( INTVAL ( index ) & 3 ) == 0 ) ; if ( code == CONST_INT && GET_MODE_SIZE ( mode ) > 0 && INTVAL ( index ) <= CSKY_LD16_MAX_OFFSET ( mode ) && INTVAL ( index ) >= 0 ) return ( ( INTVAL ( index ) % GET_MODE_SIZE ( mode ) ) == 0 ) ; return 0 ; } </s>

Return nonzero if INDEX is valid for an address index operand . ck801 use 16 bits ld ck802 use 16 and 32 bits ld others use ld and ldr .


<s> unsigned int pass_vsetvl :: execute ( function * ) { if ( n_basic_blocks_for_fn ( cfun ) <= 0 ) return 0 ; split_all_insns ( ) ; if ( ! has_vector_insn ( cfun ) ) return 0 ; init ( ) ; if ( ! optimize ) simple_vsetvl ( ) ; else lazy_vsetvl ( ) ; done ( ) ; return 0 ; } </s>


<s> static bool ix86_return_in_memory ( const_tree type , const_tree fntype ATTRIBUTE_UNUSED ) { return SUBTARGET_RETURN_IN_MEMORY ( type , fntype ) ; const machine_mode mode = type_natural_mode ( type , NULL , true ) ; HOST_WIDE_INT size ; if ( POINTER_BOUNDS_TYPE_P ( type ) ) return false ; if ( TARGET_64BIT ) { if ( ix86_function_type_abi ( fntype ) == MS_ABI ) { size = int_size_in_bytes ( type ) ; if ( ( ! type || VECTOR_INTEGER_TYPE_P ( type ) || INTEGRAL_TYPE_P ( type ) || VECTOR_FLOAT_TYPE_P ( type ) ) && ( SCALAR_INT_MODE_P ( mode ) || VECTOR_MODE_P ( mode ) ) && ! COMPLEX_MODE_P ( mode ) && ( GET_MODE_SIZE ( mode ) == 16 || size == 16 ) ) return false ; return size != 1 && size != 2 && size != 4 && size != 8 ; } else { int needed_intregs , needed_sseregs ; return examine_argument ( mode , type , 1 , & needed_intregs , & needed_sseregs ) ; } } else { if ( mode == BLKmode ) return true ; size = int_size_in_bytes ( type ) ; if ( MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P ( type ) && size <= 8 ) return false ; if ( VECTOR_MODE_P ( mode ) || mode == TImode ) { if ( size < 8 ) return false ; if ( size == 8 ) return TARGET_VECT8_RETURNS || ! TARGET_MMX ; if ( size == 16 ) return ! TARGET_SSE ; if ( size == 32 ) return ! TARGET_AVX ; if ( size == 64 ) return ! TARGET_AVX512F ; } if ( mode == XFmode ) return false ; if ( size > 12 ) return true ; gcc_assert ( mode != OImode ) ; return false ; } } </s>

Return false iff type is returned in memory .


<s> static bool ix86_ifunc_ref_local_ok ( void ) { return ! flag_pic || ( TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC ) ; } </s>

Implement TARGET_IFUNC_REF_LOCAL_OK . If this hook returns true , the PLT entry will be used as the function address for local IFUNC functions . When the PIC register is needed for PLT call , indirect call via the PLT entry will fail since the PIC register may not be set up properly for indirect call . In this case , we should return false .


<s> SMLoc getStartLoc ( ) const override { return StartLoc ; } </s>

getStartLoc - Get the location of the first token of this operand .


<s> BitVector AArch64RegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const AArch64FrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; markSuperRegs ( Reserved , AArch64 :: SP ) ; markSuperRegs ( Reserved , AArch64 :: XZR ) ; markSuperRegs ( Reserved , AArch64 :: WSP ) ; markSuperRegs ( Reserved , AArch64 :: WZR ) ; if ( TFI -> hasFP ( MF ) || TT . isOSDarwin ( ) ) { markSuperRegs ( Reserved , AArch64 :: FP ) ; markSuperRegs ( Reserved , AArch64 :: W29 ) ; } if ( MF . getSubtarget < AArch64Subtarget > ( ) . isX18Reserved ( ) ) { markSuperRegs ( Reserved , AArch64 :: X18 ) ; markSuperRegs ( Reserved , AArch64 :: W18 ) ; } if ( hasBasePointer ( MF ) ) { markSuperRegs ( Reserved , AArch64 :: X19 ) ; markSuperRegs ( Reserved , AArch64 :: W19 ) ; } assert ( checkAllSuperRegsMarked ( Reserved ) ) ; return Reserved ; } </s>

getReservedRegs - Returns a bitset indexed by physical register number indicating if a register is a special register that has particular uses and should be considered unavailable at all times , e.g .


<s> void m32c_expand_neg_mulpsi3 ( rtx * operands ) { rtx temp1 ; rtx scale ; rtx temp2 ; temp1 = gen_reg_rtx ( SImode ) ; temp2 = gen_reg_rtx ( SImode ) ; if ( GET_CODE ( operands [ 2 ] ) != CONST_INT ) { scale = gen_reg_rtx ( SImode ) ; emit_insn ( gen_zero_extendpsisi2 ( scale , operands [ 2 ] ) ) ; } else scale = copy_to_mode_reg ( SImode , operands [ 2 ] ) ; emit_insn ( gen_zero_extendpsisi2 ( temp1 , operands [ 1 ] ) ) ; temp2 = expand_simple_binop ( SImode , MULT , temp1 , scale , temp2 , 1 , OPTAB_LIB ) ; emit_insn ( gen_truncsipsi2 ( operands [ 0 ] , temp2 ) ) ; } </s>

The m32c has a limited range of operations that work on PSImode values ; we have to expand to SI , do the math , and truncate back to PSI . Yes , this is expensive , but hopefully gcc will learn to avoid those cases .


<s> bool AArch64CallLowering :: lowerCall ( MachineIRBuilder & MIRBuilder , const MachineOperand & Callee , const ArgInfo & OrigRet , ArrayRef < ArgInfo > OrigArgs ) const { MachineFunction & MF = MIRBuilder . getMF ( ) ; const Function & F = * MF . getFunction ( ) ; MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; auto & DL = F . getParent ( ) -> getDataLayout ( ) ; SmallVector < ArgInfo , 8 > SplitArgs ; for ( auto & OrigArg : OrigArgs ) { splitToValueTypes ( OrigArg , SplitArgs , DL , MRI , [ & ] ( ArrayRef < unsigned > Regs , ArrayRef < uint64_t > Offsets ) { MIRBuilder . buildExtract ( Regs , Offsets , OrigArg . Reg ) ; } ) ; } const AArch64TargetLowering & TLI = * getTLI < AArch64TargetLowering > ( ) ; CCAssignFn * CallAssignFn = TLI . CCAssignFnForCall ( F . getCallingConv ( ) , false ) ; auto MIB = MIRBuilder . buildInstrNoInsert ( Callee . isReg ( ) ? AArch64 :: BLR : AArch64 :: BL ) ; MIB . addOperand ( Callee ) ; auto TRI = MF . getSubtarget ( ) . getRegisterInfo ( ) ; MIB . addRegMask ( TRI -> getCallPreservedMask ( MF , F . getCallingConv ( ) ) ) ; SmallVector < unsigned , 8 > PhysRegs ; OutgoingArgHandler Handler ( MIRBuilder , MRI , MIB ) ; if ( ! handleAssignments ( MIRBuilder , CallAssignFn , SplitArgs , Handler ) ) return false ; MIRBuilder . insertInstr ( MIB ) ; if ( Callee . isReg ( ) ) MIB -> getOperand ( 0 ) . setReg ( constrainOperandRegClass ( MF , * TRI , MRI , * MF . getSubtarget ( ) . getInstrInfo ( ) , * MF . getSubtarget ( ) . getRegBankInfo ( ) , * MIB , MIB -> getDesc ( ) , Callee . getReg ( ) , 0 ) ) ; CCAssignFn * RetAssignFn = TLI . CCAssignFnForReturn ( F . getCallingConv ( ) ) ; if ( OrigRet . Reg ) { SplitArgs . clear ( ) ; SmallVector < uint64_t , 8 > RegOffsets ; SmallVector < unsigned , 8 > SplitRegs ; splitToValueTypes ( OrigRet , SplitArgs , DL , MRI , [ & ] ( ArrayRef < unsigned > Regs , ArrayRef < uint64_t > Offsets ) { std :: copy ( Offsets . begin ( ) , Offsets . end ( ) , std :: back_inserter ( RegOffsets ) ) ; std :: copy ( Regs . begin ( ) , Regs . end ( ) , std :: back_inserter ( SplitRegs ) ) ; } ) ; CallReturnHandler Handler ( MIRBuilder , MRI , MIB ) ; if ( ! handleAssignments ( MIRBuilder , RetAssignFn , SplitArgs , Handler ) ) return false ; if ( ! RegOffsets . empty ( ) ) MIRBuilder . buildSequence ( OrigRet . Reg , SplitRegs , RegOffsets ) ; } return true ; } </s>

This hook must be implemented to lower the given call instruction , including argument and return value marshalling .


<s> void R600SchedStrategy :: initialize ( ScheduleDAGMI * dag ) { DAG = dag ; TII = static_cast < const R600InstrInfo * > ( DAG -> TII ) ; TRI = static_cast < const R600RegisterInfo * > ( DAG -> TRI ) ; MRI = & DAG -> MRI ; Available [ IDAlu ] -> clear ( ) ; Available [ IDFetch ] -> clear ( ) ; Available [ IDOther ] -> clear ( ) ; CurInstKind = IDOther ; CurEmitted = 0 ; OccupedSlotsMask = 15 ; InstKindLimit [ IDAlu ] = TII -> getMaxAlusPerClause ( ) ; const AMDGPUSubtarget & ST = DAG -> TM . getSubtarget < AMDGPUSubtarget > ( ) ; if ( ST . device ( ) -> getGeneration ( ) <= AMDGPUDeviceInfo :: HD5XXX ) { InstKindLimit [ IDFetch ] = 7 ; } else { InstKindLimit [ IDFetch ] = 15 ; } } </s>

Initialize the strategy after building the DAG for a new region .


<s> MCSection * X86ELFMCAsmInfo :: getNonexecutableStackSection ( MCContext & Ctx ) const { return MCSectionELF :: Create ( ".note.GNU-stack" , MCSectionELF :: SHT_PROGBITS , 0 , SectionKind :: getMetadata ( ) , false , Ctx ) ; } </s>

Targets can implement this method to specify a section to switch to if the translation unit does n't have any trampolines that require an executable stack .


<s> static rtx sh_delegitimize_address ( rtx orig_x ) { rtx x , y ; orig_x = delegitimize_mem_from_attrs ( orig_x ) ; x = orig_x ; if ( MEM_P ( x ) ) x = XEXP ( x , 0 ) ; if ( GET_CODE ( x ) == CONST ) { y = XEXP ( x , 0 ) ; if ( GET_CODE ( y ) == UNSPEC ) { if ( XINT ( y , 1 ) == UNSPEC_GOT || XINT ( y , 1 ) == UNSPEC_GOTOFF || XINT ( y , 1 ) == UNSPEC_SYMOFF ) return XVECEXP ( y , 0 , 0 ) ; else if ( XINT ( y , 1 ) == UNSPEC_PCREL_SYMOFF ) { if ( GET_CODE ( XVECEXP ( y , 0 , 0 ) ) == CONST ) { rtx symplt = XEXP ( XVECEXP ( y , 0 , 0 ) , 0 ) ; if ( GET_CODE ( symplt ) == UNSPEC && XINT ( symplt , 1 ) == UNSPEC_PLT ) return XVECEXP ( symplt , 0 , 0 ) ; } } else if ( TARGET_SHMEDIA && ( XINT ( y , 1 ) == UNSPEC_EXTRACT_S16 || XINT ( y , 1 ) == UNSPEC_EXTRACT_U16 ) ) { rtx offset = XVECEXP ( y , 0 , 1 ) ; x = gen_rtx_PLUS ( Pmode , XVECEXP ( y , 0 , 0 ) , offset ) ; if ( MEM_P ( orig_x ) ) x = replace_equiv_address_nv ( orig_x , x ) ; return x ; } } } return orig_x ; } </s>

In the name of slightly smaller debug output , and to cater to general assembler lossage , recognize various UNSPEC sequences and turn them back into a direct symbol reference .


<s> unsigned M68kInstrInfo :: getGlobalBaseReg ( MachineFunction * MF ) const { M68kMachineFunctionInfo * MxFI = MF -> getInfo < M68kMachineFunctionInfo > ( ) ; unsigned GlobalBaseReg = MxFI -> getGlobalBaseReg ( ) ; if ( GlobalBaseReg != 0 ) return GlobalBaseReg ; MachineRegisterInfo & RegInfo = MF -> getRegInfo ( ) ; GlobalBaseReg = RegInfo . createVirtualRegister ( & M68k :: AR32_NOSPRegClass ) ; MxFI -> setGlobalBaseReg ( GlobalBaseReg ) ; return GlobalBaseReg ; } </s>

getGlobalBaseReg - Return a virtual register initialized with the the global base register value .


<s> static rtx tilepro_emit_cc_test ( enum rtx_code code , rtx op0 , rtx op1 , machine_mode cmp_mode , bool eq_ne_only ) { enum rtx_code branch_code ; rtx temp ; if ( cmp_mode != DImode && op1 == const0_rtx && ( code == EQ || code == NE || ( ! eq_ne_only && signed_compare_p ( code ) ) ) ) { op0 = force_reg ( SImode , op0 ) ; return gen_rtx_fmt_ee ( code , VOIDmode , op0 , const0_rtx ) ; } switch ( code ) { case EQ : case LE : case LT : case LEU : case LTU : branch_code = NE ; break ; case NE : case GE : case GT : case GEU : case GTU : code = reverse_condition ( code ) ; branch_code = EQ ; break ; default : gcc_unreachable ( ) ; } if ( cmp_mode != DImode && CONST_INT_P ( op1 ) && ( ! satisfies_constraint_I ( op1 ) || code == LEU ) ) { HOST_WIDE_INT n = trunc_int_for_mode ( INTVAL ( op1 ) , SImode ) ; switch ( code ) { case EQ : if ( ! ( symbolic_operand ( op0 , VOIDmode ) || ( REG_P ( op0 ) && REG_POINTER ( op0 ) ) ) ) { HOST_WIDE_INT add ; if ( n != - 2147483647 - 1 ) add = - n ; else add = n ; op0 = force_reg ( SImode , op0 ) ; temp = gen_reg_rtx ( SImode ) ; emit_insn ( gen_addsi3 ( temp , op0 , gen_int_si ( add ) ) ) ; return gen_rtx_fmt_ee ( reverse_condition ( branch_code ) , VOIDmode , temp , const0_rtx ) ; } break ; case LEU : if ( n == - 1 ) break ; case LTU : { int first = exact_log2 ( code == LTU ? n : n + 1 ) ; if ( first != - 1 ) { op0 = force_reg ( SImode , op0 ) ; temp = gen_reg_rtx ( SImode ) ; emit_move_insn ( temp , gen_rtx_LSHIFTRT ( SImode , op0 , gen_int_si ( first ) ) ) ; return gen_rtx_fmt_ee ( reverse_condition ( branch_code ) , VOIDmode , temp , const0_rtx ) ; } } break ; default : break ; } } temp = gen_reg_rtx ( SImode ) ; tilepro_emit_setcc_internal ( temp , code , op0 , op1 , cmp_mode ) ; return gen_rtx_fmt_ee ( branch_code , VOIDmode , temp , const0_rtx ) ; } </s>

Generate the comparison for an SImode conditional branch .


<s>
const
char
*
output_call
(
rtx
*
operands
)
{
gcc_assert
(
!
arm_arch5
)
;
if
(
REGNO
(
operands
[
0
]
)
==
LR_REGNUM
)
{
operands
[
0
]
=
gen_rtx_REG
(
SImode
,
IP_REGNUM
)
;
output_asm_insn
(
"mov%?\t%0, %|lr"
,
operands
)
;
}
output_asm_insn
(
"mov%?\t%|lr, %|pc"
,
operands
)
;
if
(
TARGET_INTERWORK
||
arm_arch4t
)
output_asm_insn
(
"bx%?\t%0"
,
operands
)
;
else
output_asm_insn
(
"mov%?\t%|pc, %0"
,
operands
)
;
return
""
;
}
</s>

INSN is either a function call or a millicode call . It may have an unconditional jump in its delay slot . CALL_DEST is the routine we are calling .


runOnMachineFunction - Emit the function body .


"WebAssembly hasn't implemented computed gotos"

"WebAssembly hasn't implemented __builtin_return_address"

LowerOperation - Provide custom lowering hooks for some operations .


"Unknown regclass in loadRegFromStackSlot!"

Load the specified register of the given register class from the specified stack frame index .


<s>
const
char
*
output_adjust_stack_and_probe
(
rtx
reg
)
{
static
int
labelno
=
0
;
char
loop_lab
[
32
]
,
end_lab
[
32
]
;
rtx
xops
[
2
]
;
ASM_GENERATE_INTERNAL_LABEL
(
loop_lab
,
"LPSRL"
,
labelno
)
;
ASM_GENERATE_INTERNAL_LABEL
(
end_lab
,
"LPSRE"
,
labelno
++
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
loop_lab
)
;
xops
[
0
]
=
stack_pointer_rtx
;
xops
[
1
]
=
reg
;
output_asm_insn
(
"cmp%z0\t{%1, %0|%0, %1}"
,
xops
)
;
fputs
(
"\tje\t"
,
asm_out_file
)
;
assemble_name_raw
(
asm_out_file
,
end_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
xops
[
1
]
=
GEN_INT
(
PROBE_INTERVAL
)
;
output_asm_insn
(
"sub%z0\t{%1, %0|%0, %1}"
,
xops
)
;
xops
[
1
]
=
const0_rtx
;
output_asm_insn
(
"or%z0\t{%1, (%0)|DWORD PTR [%0], %1}"
,
xops
)
;
fprintf
(
asm_out_file
,
"\tjmp\t"
)
;
assemble_name_raw
(
asm_out_file
,
loop_lab
)
;
fputc
(
'\n'
,
asm_out_file
)
;
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
end_lab
)
;
return
""
;
}
</s>

Adjust the stack pointer up to REG while probing it .


<s>
void
VideoCore4InstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
DebugLoc
DL
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
if
(
VideoCore4
::
FR32RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
VideoCore4
::
MOV_F
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
else
if
(
VideoCore4
::
GR32RegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
BuildMI
(
MBB
,
I
,
DL
,
get
(
VideoCore4
::
MOV_R
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
return
;
}
llvm_unreachable
(
"Cannot emit physreg copy instruction"
)
;
}
</s>


<s> static rtx generate_set_vrsave ( rtx reg , rs6000_stack_t * info , int epiloguep ) { int nclobs , i ; rtx insn , clobs [ TOTAL_ALTIVEC_REGS + 1 ] ; rtx vrsave = gen_rtx_REG ( SImode , VRSAVE_REGNO ) ; clobs [ 0 ] = gen_rtx_SET ( vrsave , gen_rtx_UNSPEC_VOLATILE ( SImode , gen_rtvec ( 2 , reg , vrsave ) , UNSPECV_SET_VRSAVE ) ) ; nclobs = 1 ; for ( i = FIRST_ALTIVEC_REGNO ; i <= LAST_ALTIVEC_REGNO ; ++ i ) if ( info -> vrsave_mask & ALTIVEC_REG_BIT ( i ) ) { if ( ! epiloguep || call_used_regs [ i ] ) clobs [ nclobs ++ ] = gen_rtx_CLOBBER ( VOIDmode , gen_rtx_REG ( V4SImode , i ) ) ; else { rtx reg = gen_rtx_REG ( V4SImode , i ) ; clobs [ nclobs ++ ] = gen_rtx_SET ( reg , gen_rtx_UNSPEC ( V4SImode , gen_rtvec ( 1 , reg ) , 27 ) ) ; } } insn = gen_rtx_PARALLEL ( VOIDmode , rtvec_alloc ( nclobs ) ) ; for ( i = 0 ; i < nclobs ; ++ i ) XVECEXP ( insn , 0 , i ) = clobs [ i ] ; return insn ; } </s>

Returns an insn that has a vrsave set operation with the appropriate CLOBBERs .


<s> void LanaiFrameLowering :: determineFrameLayout ( MachineFunction & MF ) const { MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; const LanaiRegisterInfo * LRI = STI . getRegisterInfo ( ) ; unsigned FrameSize = MFI . getStackSize ( ) ; unsigned StackAlign = LRI -> needsStackRealignment ( MF ) ? MFI . getMaxAlignment ( ) : getStackAlignment ( ) ; unsigned MaxCallFrameSize = MFI . getMaxCallFrameSize ( ) ; if ( MFI . hasVarSizedObjects ( ) ) MaxCallFrameSize = alignTo ( MaxCallFrameSize , StackAlign ) ; MFI . setMaxCallFrameSize ( MaxCallFrameSize ) ; if ( ! ( hasReservedCallFrame ( MF ) && MFI . adjustsStack ( ) ) ) FrameSize += MaxCallFrameSize ; FrameSize = alignTo ( FrameSize , StackAlign ) ; MFI . setStackSize ( FrameSize ) ; } </s>

Determine the frame layout but do not update the machine function .


<s>
void
s390_asm_declare_function_size
(
FILE
*
asm_out_file
,
const
char
*
fnname
,
tree
decl
)
{
if
(
!
flag_inhibit_size_directive
)
ASM_OUTPUT_MEASURED_SIZE
(
asm_out_file
,
fnname
)
;
if
(
DECL_FUNCTION_SPECIFIC_TARGET
(
decl
)
==
)
return
;
fprintf
(
asm_out_file
,
"\t.machine pop\n"
)
;
fprintf
(
asm_out_file
,
"\t.machinemode pop\n"
)
;
}
</s>

Write an extra function footer after the very end of the function .

s390
"\t.machine pop\n"
"\t.machinemode pop\n"


<s> static cpp_hashnode * spu_macro_to_expand ( cpp_reader * pfile , const cpp_token * tok ) { cpp_hashnode * expand_this = tok -> val . node . node ; cpp_hashnode * ident ; ident = spu_categorize_keyword ( tok ) ; if ( ident == C_CPP_HASHNODE ( __vector_keyword ) ) { tok = cpp_peek_token ( pfile , 0 ) ; ident = spu_categorize_keyword ( tok ) ; if ( ident ) { enum rid rid_code = ( enum rid ) ( ident -> rid_code ) ; if ( cpp_macro_p ( ident ) ) { ( void ) cpp_get_token ( pfile ) ; tok = cpp_peek_token ( pfile , 0 ) ; ident = spu_categorize_keyword ( tok ) ; if ( ident ) rid_code = ( enum rid ) ( ident -> rid_code ) ; } if ( rid_code == RID_UNSIGNED || rid_code == RID_LONG || rid_code == RID_SHORT || rid_code == RID_SIGNED || rid_code == RID_INT || rid_code == RID_CHAR || rid_code == RID_FLOAT || rid_code == RID_DOUBLE ) expand_this = C_CPP_HASHNODE ( __vector_keyword ) ; } } return expand_this ; } </s>

Called to decide whether a conditional macro should be expanded . Since we have exactly one such macro ( i.e , 'vector ' ) , we do not need to examine the 'tok ' parameter .


<s>
void
X86InstPrinterCommon
::
printPCRelImm
(
const
MCInst
*
MI
,
uint64_t
Address
,
unsigned
OpNo
,
raw_ostream
&
O
)
{
const
MCOperand
&
Op
=
MI
->
getOperand
(
OpNo
)
;
if
(
Op
.
isImm
(
)
)
{
if
(
PrintBranchImmAsAddress
)
{
uint64_t
Target
=
Address
+
Op
.
getImm
(
)
;
if
(
MAI
.
getCodePointerSize
(
)
==
4
)
Target
&=
0xffffffff
;
O
<<
formatHex
(
Target
)
;
}
else
O
<<
formatImm
(
Op
.
getImm
(
)
)
;
}
else
{
assert
(
Op
.
isExpr
(
)
&&
"unknown pcrel immediate operand"
)
;
const
MCConstantExpr
*
BranchTarget
=
dyn_cast
<
MCConstantExpr
>
(
Op
.
getExpr
(
)
)
;
int64_t
Address
;
if
(
BranchTarget
&&
BranchTarget
->
evaluateAsAbsolute
(
Address
)
)
{
O
<<
formatHex
(
(
uint64_t
)
Address
)
;
}
else
{
Op
.
getExpr
(
)
->
print
(
O
,
&
MAI
)
;
}
}
}
</s>


<s> static bool aarch64_legitimize_address_displacement ( rtx * offset1 , rtx * offset2 , poly_int64 orig_offset , machine_mode mode ) { HOST_WIDE_INT size ; if ( GET_MODE_SIZE ( mode ) . is_constant ( & size ) ) { HOST_WIDE_INT const_offset , second_offset ; const_offset = orig_offset . coeffs [ 0 ] - orig_offset . coeffs [ 1 ] ; if ( mode == TImode || mode == TFmode ) second_offset = ( ( const_offset + 0x100 ) & 0x1f8 ) - 0x100 ; else if ( ( const_offset & ( size - 1 ) ) != 0 ) second_offset = ( ( const_offset + 0x100 ) & 0x1ff ) - 0x100 ; else second_offset = const_offset & ( size < 4 ? 0xfff : 0x3ffc ) ; if ( second_offset == 0 || known_eq ( orig_offset , second_offset ) ) return false ; * offset1 = gen_int_mode ( orig_offset - second_offset , Pmode ) ; * offset2 = gen_int_mode ( second_offset , Pmode ) ; return true ; } else { unsigned int vec_flags = aarch64_classify_vector_mode ( mode ) ; machine_mode step_mode = ( vec_flags & VEC_STRUCT ) != 0 ? SVE_BYTE_MODE : mode ; HOST_WIDE_INT factor = GET_MODE_SIZE ( step_mode ) . coeffs [ 1 ] ; HOST_WIDE_INT vnum = orig_offset . coeffs [ 1 ] / factor ; if ( vec_flags & VEC_SVE_DATA ) vnum = ( ( vnum + 128 ) & 255 ) - 128 ; else vnum = ( ( vnum + 256 ) & 511 ) - 256 ; if ( vnum == 0 ) return false ; poly_int64 second_offset = GET_MODE_SIZE ( step_mode ) * vnum ; if ( known_eq ( second_offset , orig_offset ) ) return false ; * offset1 = gen_int_mode ( orig_offset - second_offset , Pmode ) ; * offset2 = gen_int_mode ( second_offset , Pmode ) ; return true ; } } </s>

Split an out-of-range address displacement into a base and offset . Use 4KB range for 1- and 2-byte accesses and a 16KB range otherwise to increase opportunities for sharing the base address of different sizes . For unaligned accesses and TI/TF mode use the signed 9-bit range .


<s>
SDValue
AArch64TargetLowering
::
LowerReturn
(
SDValue
Chain
,
CallingConv
::
ID
CallConv
,
bool
isVarArg
,
const
SmallVectorImpl
<
ISD
::
OutputArg
>
&
Outs
,
const
SmallVectorImpl
<
SDValue
>
&
OutVals
,
SDLoc
DL
,
SelectionDAG
&
DAG
)
const
{
CCAssignFn
*
RetCC
=
CallConv
==
CallingConv
::
WebKit_JS
RetCC_AArch64_WebKit_JS
:
RetCC_AArch64_AAPCS
;
SmallVector
<
CCValAssign
,
16
>
RVLocs
;
CCState
CCInfo
(
CallConv
,
isVarArg
,
DAG
.
getMachineFunction
(
)
,
RVLocs
,
*
DAG
.
getContext
(
)
)
;
CCInfo
.
AnalyzeReturn
(
Outs
,
RetCC
)
;
SDValue
Flag
;
SmallVector
<
SDValue
,
4
>
RetOps
(
1
,
Chain
)
;
for
(
unsigned
i
=
0
,
realRVLocIdx
=
0
;
i
!=
RVLocs
.
size
(
)
;
++
i
,
++
realRVLocIdx
)
{
CCValAssign
&
VA
=
RVLocs
[
i
]
;
assert
(
VA
.
isRegLoc
(
)
&&
"Can only return in registers!"
)
;
SDValue
Arg
=
OutVals
[
realRVLocIdx
]
;
switch
(
VA
.
getLocInfo
(
)
)
{
default
:
llvm_unreachable
(
"Unknown loc info!"
)
;
case
CCValAssign
::
Full
:
if
(
Outs
[
i
]
.
ArgVT
==
MVT
::
i1
)
{
Arg
=
DAG
.
getNode
(
ISD
::
TRUNCATE
,
DL
,
MVT
::
i1
,
Arg
)
;
Arg
=
DAG
.
getNode
(
ISD
::
ZERO_EXTEND
,
DL
,
VA
.
getLocVT
(
)
,
Arg
)
;
}
break
;
case
CCValAssign
::
BCvt
:
Arg
=
DAG
.
getNode
(
ISD
::
BITCAST
,
DL
,
VA
.
getLocVT
(
)
,
Arg
)
;
break
;
}
Chain
=
DAG
.
getCopyToReg
(
Chain
,
DL
,
VA
.
getLocReg
(
)
,
Arg
,
Flag
)
;
Flag
=
Chain
.
getValue
(
1
)
;
RetOps
.
push_back
(
DAG
.
getRegister
(
VA
.
getLocReg
(
)
,
VA
.
getLocVT
(
)
)
)
;
}
RetOps
[
0
]
=
Chain
;
if
(
Flag
.
getNode
(
)
)
RetOps
.
push_back
(
Flag
)
;
return
DAG
.
getNode
(
AArch64ISD
::
RET_FLAG
,
DL
,
MVT
::
Other
,
RetOps
)
;
}
</s>

This hook must be implemented to lower outgoing return values , described by the Outs array , into the specified DAG .


<s> const TargetFrameLowering :: SpillSlot * ARMFrameLowering :: getCalleeSavedSpillSlots ( unsigned & NumEntries ) const { static const SpillSlot FixedSpillOffsets [ ] = { { ARM :: FPCXTNS , - 4 } } ; NumEntries = array_lengthof ( FixedSpillOffsets ) ; return FixedSpillOffsets ; } </s>

getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs , that contains an entry for each callee saved register that must be spilled to a particular stack location if it is spilled .


<s> virtual const PTXSubtarget * getSubtargetImpl ( ) const { return & Subtarget ; } </s>

Virtual method implemented by subclasses that returns a reference to that target 's TargetSubtargetInfo-derived member variable .


<s> void AArch64PassConfig :: addPreEmitPass ( ) { if ( TM -> getOptLevel ( ) >= CodeGenOpt :: Aggressive && EnableLoadStoreOpt ) addPass ( createAArch64LoadStoreOptimizationPass ( ) ) ; if ( EnableA53Fix835769 ) addPass ( createAArch64A53Fix835769 ( ) ) ; if ( BranchRelaxation ) addPass ( & BranchRelaxationPassID ) ; if ( EnableBranchTargets ) addPass ( createAArch64BranchTargetsPass ( ) ) ; if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableCompressJumpTables ) addPass ( createAArch64CompressJumpTablesPass ( ) ) ; if ( TM -> getOptLevel ( ) != CodeGenOpt :: None && EnableCollectLOH && TM -> getTargetTriple ( ) . isOSBinFormatMachO ( ) ) addPass ( createAArch64CollectLOHPass ( ) ) ; } </s>

This pass may be implemented by targets that want to run passes immediately before machine code is emitted .