<s> static bool chain_contains_only_swaps ( swap_web_entry * insn_entry , struct df_link * link , enum chain_purpose purpose ) { if ( ! link ) return false ; for ( ; link ; link = link -> next ) { if ( ! VECTOR_MODE_P ( GET_MODE ( DF_REF_REG ( link -> ref ) ) ) ) continue ; if ( DF_REF_IS_ARTIFICIAL ( link -> ref ) ) return false ; rtx reached_insn = DF_REF_INSN ( link -> ref ) ; unsigned uid = INSN_UID ( reached_insn ) ; struct df_insn_info * insn_info = DF_INSN_INFO_GET ( reached_insn ) ; if ( ! insn_entry [ uid ] . is_swap || insn_entry [ uid ] . is_load || insn_entry [ uid ] . is_store ) return false ; if ( purpose == FOR_LOADS ) { df_ref use ; FOR_EACH_INSN_INFO_USE ( use , insn_info ) { struct df_link * swap_link = DF_REF_CHAIN ( use ) ; while ( swap_link ) { if ( DF_REF_IS_ARTIFICIAL ( link -> ref ) ) return false ; rtx swap_def_insn = DF_REF_INSN ( swap_link -> ref ) ; unsigned uid2 = INSN_UID ( swap_def_insn ) ; if ( ! insn_entry [ uid2 ] . is_swap || ! insn_entry [ uid2 ] . is_load ) return false ; swap_link = swap_link -> next ; } } } else if ( purpose == FOR_STORES ) { df_ref def ; FOR_EACH_INSN_INFO_DEF ( def , insn_info ) { struct df_link * swap_link = DF_REF_CHAIN ( def ) ; while ( swap_link ) { if ( DF_REF_IS_ARTIFICIAL ( link -> ref ) ) return false ; rtx swap_use_insn = DF_REF_INSN ( swap_link -> ref ) ; unsigned uid2 = INSN_UID ( swap_use_insn ) ; if ( ! insn_entry [ uid2 ] . is_swap || insn_entry [ uid2 ] . is_load ) return false ; swap_link = swap_link -> next ; } } } } return true ; } </s>

Return true if the UD or DU chain headed by LINK is non-empty , and every entry on the chain references an insn that is a register swap . Furthermore , if PURPOSE is FOR_LOADS , each such register swap must have only permuting loads as reaching defs . If PURPOSE is FOR_STORES , each such register swap must have only register swaps or permuting stores as reached uses .


"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> bool X86FrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc DL = MBB . findDebugLoc ( MI ) ; MachineFunction & MF = * MBB . getParent ( ) ; unsigned SlotSize = STI . is64Bit ( ) ? 8 : 4 ; unsigned FPReg = TRI -> getFrameRegister ( MF ) ; unsigned CalleeFrameSize = 0 ; const TargetInstrInfo & TII = * MF . getTarget ( ) . getInstrInfo ( ) ; X86MachineFunctionInfo * X86FI = MF . getInfo < X86MachineFunctionInfo > ( ) ; unsigned Opc = STI . is64Bit ( ) ? X86 :: PUSH64r : X86 :: PUSH32r ; for ( unsigned i = CSI . size ( ) ; i != 0 ; -- i ) { unsigned Reg = CSI [ i - 1 ] . getReg ( ) ; if ( ! X86 :: GR64RegClass . contains ( Reg ) && ! X86 :: GR32RegClass . contains ( Reg ) ) continue ; MBB . addLiveIn ( Reg ) ; if ( Reg == FPReg ) continue ; CalleeFrameSize += SlotSize ; BuildMI ( MBB , MI , DL , TII . get ( Opc ) ) . addReg ( Reg , RegState :: Kill ) ; } X86FI -> setCalleeSavedFrameSize ( CalleeFrameSize ) ; for ( unsigned i = CSI . size ( ) ; i != 0 ; -- i ) { unsigned Reg = CSI [ i - 1 ] . getReg ( ) ; if ( X86 :: GR64RegClass . contains ( Reg ) || X86 :: GR32RegClass . contains ( Reg ) ) continue ; MBB . addLiveIn ( Reg ) ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; TII . storeRegToStackSlot ( MBB , MI , Reg , true , CSI [ i - 1 ] . getFrameIdx ( ) , RC , TRI ) ; } 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 ( ) .


"sorry, I don't know how to store this sort of reg in the stack\n"

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


<s> static rtx rs6000_emit_vector_compare_inner ( enum rtx_code code , rtx op0 , rtx op1 ) { rtx mask ; machine_mode mode = GET_MODE ( op0 ) ; switch ( code ) { default : break ; case GE : if ( GET_MODE_CLASS ( mode ) == MODE_VECTOR_INT ) return NULL_RTX ; case EQ : case GT : case GTU : case ORDERED : case UNORDERED : case UNEQ : case LTGT : mask = gen_reg_rtx ( mode ) ; emit_insn ( gen_rtx_SET ( mask , gen_rtx_fmt_ee ( code , mode , op0 , op1 ) ) ) ; return mask ; } return NULL_RTX ; } </s>

Return insn for VSX or Altivec comparisons .


<s> bool PPCLoopPreIncPrep :: runOnFunction ( Function & F ) { LI = & getAnalysis < LoopInfoWrapperPass > ( ) . getLoopInfo ( ) ; SE = & getAnalysis < ScalarEvolution > ( ) ; DataLayoutPass * DLP = getAnalysisIfAvailable < DataLayoutPass > ( ) ; DL = DLP ? & DLP -> getDataLayout ( ) : 0 ; bool MadeChange = false ; for ( LoopInfo :: iterator I = LI -> begin ( ) , E = LI -> end ( ) ; I != E ; ++ I ) { Loop * L = * I ; MadeChange |= runOnLoop ( L ) ; } return MadeChange ; } </s>

runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass .


<s> static bool rs6000_real_tls_symbol_ref_p ( rtx x ) { return ( SYMBOL_REF_P ( x ) && SYMBOL_REF_TLS_MODEL ( x ) >= TLS_MODEL_REAL ) ; } </s>

Return true if X is a symbol that refers to real ( rather than emulated ) TLS .


<s> bool X86AsmBackend :: mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const { if ( getRelaxedOpcodeBranch ( Inst , false ) != Inst . getOpcode ( ) ) return true ; if ( getRelaxedOpcodeArith ( Inst ) == Inst . getOpcode ( ) ) return false ; unsigned RelaxableOp = Inst . getNumOperands ( ) - 1 ; if ( Inst . getOperand ( RelaxableOp ) . isExpr ( ) ) return true ; return false ; } </s>

Check whether the given instruction may need relaxation .


<s> unsigned MipsInstrInfo :: isLoadFromStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { unsigned Opc = MI -> getOpcode ( ) ; if ( ( Opc == Mips :: LW ) || ( Opc == Mips :: LW_P8 ) || ( Opc == Mips :: LD ) || ( Opc == Mips :: LD_P8 ) || ( Opc == Mips :: LWC1 ) || ( Opc == Mips :: LWC1_P8 ) || ( Opc == Mips :: LDC1 ) || ( Opc == Mips :: LDC164 ) || ( Opc == Mips :: LDC164_P8 ) ) { if ( ( MI -> getOperand ( 1 ) . isFI ( ) ) && ( MI -> getOperand ( 2 ) . isImm ( ) ) && ( isZeroImm ( MI -> getOperand ( 2 ) ) ) ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } } return 0 ; } </s>

isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot , return the virtual or physical register number of the destination along with the FrameIndex of the loaded stack slot .


<s> static tree mips_builtin_vector_type ( tree type , machine_mode mode ) { static tree types [ 2 * ( int ) MAX_MACHINE_MODE ] ; int mode_index ; mode_index = ( int ) mode ; if ( TREE_CODE ( type ) == INTEGER_TYPE && TYPE_UNSIGNED ( type ) ) mode_index += MAX_MACHINE_MODE ; if ( types [ mode_index ] == NULL_TREE ) types [ mode_index ] = build_vector_type_for_mode ( type , mode ) ; return types [ mode_index ] ; } </s>

MODE is a vector mode whose elements have type TYPE . Return the type of the vector itself .


<s> gimple * gimple_folder :: redirect_call ( const function_instance & instance ) { registered_function * rfn = function_table -> find_with_hash ( instance , instance . hash ( ) ) ; if ( ! rfn ) return NULL ; gimple_call_set_fndecl ( call , rfn -> decl ) ; return call ; } </s>

Fold the call to a call to INSTANCE , with the same arguments .


<s> bool X86AsmPrinter :: PrintAsmOperand ( const MachineInstr * MI , unsigned OpNo , unsigned AsmVariant , const char * ExtraCode , raw_ostream & O ) { if ( ExtraCode && ExtraCode [ 0 ] ) { if ( ExtraCode [ 1 ] != 0 ) return true ; const MachineOperand & MO = MI -> getOperand ( OpNo ) ; switch ( ExtraCode [ 0 ] ) { default : return AsmPrinter :: PrintAsmOperand ( MI , OpNo , AsmVariant , ExtraCode , O ) ; case 'a' : if ( MO . isImm ( ) ) { O << MO . getImm ( ) ; return false ; } if ( MO . isGlobal ( ) || MO . isCPI ( ) || MO . isJTI ( ) || MO . isSymbol ( ) ) { printSymbolOperand ( MO , O ) ; if ( Subtarget -> isPICStyleRIPRel ( ) ) O << "(%rip)" ; return false ; } if ( MO . isReg ( ) ) { O << '(' ; printOperand ( MI , OpNo , O ) ; O << ')' ; return false ; } return true ; case 'c' : if ( MO . isImm ( ) ) O << MO . getImm ( ) ; else if ( MO . isGlobal ( ) || MO . isCPI ( ) || MO . isJTI ( ) || MO . isSymbol ( ) ) printSymbolOperand ( MO , O ) ; else printOperand ( MI , OpNo , O ) ; return false ; case 'A' : if ( MO . isReg ( ) ) { O << '*' ; printOperand ( MI , OpNo , O ) ; return false ; } return true ; case 'b' : case 'h' : case 'w' : case 'k' : case 'q' : if ( MO . isReg ( ) ) return printAsmMRegister ( MO , ExtraCode [ 0 ] , O ) ; printOperand ( MI , OpNo , O ) ; return false ; case 'P' : print_pcrel_imm ( MI , OpNo , O ) ; return false ; case 'n' : if ( MO . isImm ( ) ) { O << - MO . getImm ( ) ; return false ; } O << '-' ; } } printOperand ( MI , OpNo , O ) ; return false ; } </s>

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


"Only support MVT::i32 register passing"

"Can only pass arguments as either registers or via the stack"

This hook must be implemented to lower the incoming ( formal ) arguments , described by the Ins array , into the specified DAG .


<s> bool runOnMachineFunction ( MachineFunction & F ) { bool Changed = false ; for ( MachineFunction :: iterator FI = F . begin ( ) , FE = F . end ( ) ; FI != FE ; ++ FI ) Changed |= runOnMachineBasicBlock ( * FI ) ; return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool LoongArchRegisterInfo :: isConstantPhysReg ( MCRegister PhysReg ) const { return PhysReg == LoongArch :: R0 ; } </s>

Returns true if PhysReg is unallocatable and constant throughout the function .


<s> AArch64Subtarget :: AArch64Subtarget ( const Triple & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM , bool LittleEndian ) : AArch64GenSubtargetInfo ( TT , CPU , FS ) , ARMProcFamily ( Others ) , HasV8_1aOps ( false ) , HasV8_2aOps ( false ) , HasFPARMv8 ( false ) , HasNEON ( false ) , HasCrypto ( false ) , HasCRC ( false ) , HasPerfMon ( false ) , HasFullFP16 ( false ) , HasZeroCycleRegMove ( false ) , HasZeroCycleZeroing ( false ) , StrictAlign ( false ) , ReserveX18 ( TT . isOSDarwin ( ) ) , IsLittle ( LittleEndian ) , CPUString ( CPU ) , TargetTriple ( TT ) , FrameLowering ( ) , InstrInfo ( initializeSubtargetDependencies ( FS ) ) , TSInfo ( ) , TLInfo ( TM , * this ) , CallLoweringInfo ( nullptr ) { } </s>

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


Copy one MODE sized block from SRC to DST , then progress SRC and DST by MODE bytes .


"internal error: builtin function %s already processed"

Add a SPARC builtin function with NAME , ICODE , CODE and TYPE . Return the function decl or NULL_TREE if the builtin was not added .


<s> bool MipsAsmPrinter :: runOnMachineFunction ( MachineFunction & MF ) { this -> MF = & MF ; SetupMachineFunction ( MF ) ; EmitConstantPool ( MF . getConstantPool ( ) ) ; EmitJumpTableInfo ( MF . getJumpTableInfo ( ) , MF ) ; O << "\n\n" ; emitFunctionStart ( MF ) ; for ( MachineFunction :: const_iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) { if ( I != MF . begin ( ) ) { printBasicBlockLabel ( I , true , true ) ; O << '\n' ; } for ( MachineBasicBlock :: const_iterator II = I -> begin ( ) , E = I -> end ( ) ; II != E ; ++ II ) { printInstruction ( II ) ; ++ EmittedInsts ; } O << '\n' ; } emitFunctionEnd ( MF ) ; return false ; } </s>


<s> std :: pair < const TargetRegisterClass * , uint8_t > X86TargetLowering :: findRepresentativeClass ( EVT VT ) const { const TargetRegisterClass * RRC = 0 ; uint8_t Cost = 1 ; switch ( VT . getSimpleVT ( ) . SimpleTy ) { default : return TargetLowering :: findRepresentativeClass ( VT ) ; case MVT :: i8 : case MVT :: i16 : case MVT :: i32 : case MVT :: i64 : RRC = ( Subtarget -> is64Bit ( ) ? X86 :: GR64RegisterClass : X86 :: GR32RegisterClass ) ; break ; case MVT :: v8i8 : case MVT :: v4i16 : case MVT :: v2i32 : case MVT :: v1i64 : RRC = X86 :: VR64RegisterClass ; break ; case MVT :: f32 : case MVT :: f64 : case MVT :: v16i8 : case MVT :: v8i16 : case MVT :: v4i32 : case MVT :: v2i64 : case MVT :: v4f32 : case MVT :: v2f64 : case MVT :: v32i8 : case MVT :: v8i32 : case MVT :: v4i64 : case MVT :: v8f32 : case MVT :: v4f64 : RRC = X86 :: VR128RegisterClass ; break ; } return std :: make_pair ( RRC , Cost ) ; } </s>

Return the largest legal super-reg register class of the register class for the specified type and its associated `` cost '' .


<s> static void rs6000_emit_dot_insn ( rtx dst , rtx src , int dot , rtx ccreg ) { if ( dot == 0 ) { emit_move_insn ( dst , src ) ; return ; } if ( cc_reg_not_cr0_operand ( ccreg , CCmode ) ) { emit_move_insn ( dst , src ) ; emit_move_insn ( ccreg , gen_rtx_COMPARE ( CCmode , dst , const0_rtx ) ) ; return ; } rtx ccset = gen_rtx_SET ( ccreg , gen_rtx_COMPARE ( CCmode , src , const0_rtx ) ) ; if ( dot == 1 ) { rtx clobber = gen_rtx_CLOBBER ( VOIDmode , dst ) ; emit_insn ( gen_rtx_PARALLEL ( VOIDmode , gen_rtvec ( 2 , ccset , clobber ) ) ) ; } else { rtx set = gen_rtx_SET ( dst , src ) ; emit_insn ( gen_rtx_PARALLEL ( VOIDmode , gen_rtvec ( 2 , ccset , set ) ) ) ; } } </s>

Emit a potentially record-form instruction , setting DST from SRC . If DOT is 0 , that is all ; otherwise , set CCREG to the result of the signed comparison of DST with zero . If DOT is 1 , the generated RTL does n't care about the DST result ; if DOT is 2 , it does . If CCREG is CR0 do a single dot insn ( as a PARALLEL ) ; otherwise , do a SET and a separate COMPARE .


<s> bool ix86_save_reg ( unsigned int regno , bool maybe_eh_return , bool ignore_outlined ) { if ( cfun -> machine -> no_caller_saved_registers ) { rtx reg = crtl -> return_rtx ; if ( reg ) { unsigned int i = REGNO ( reg ) ; unsigned int nregs = REG_NREGS ( reg ) ; while ( nregs -- > 0 ) if ( ( i + nregs ) == regno ) return false ; } return ( df_regs_ever_live_p ( regno ) && ! fixed_regs [ regno ] && ! STACK_REGNO_P ( regno ) && ! MMX_REGNO_P ( regno ) && ( regno != HARD_FRAME_POINTER_REGNUM || ! frame_pointer_needed ) ) ; } if ( regno == REAL_PIC_OFFSET_TABLE_REGNUM && pic_offset_table_rtx ) { if ( ix86_use_pseudo_pic_reg ( ) ) { if ( ! TARGET_64BIT && flag_pic && crtl -> profile ) return true ; } else if ( df_regs_ever_live_p ( REAL_PIC_OFFSET_TABLE_REGNUM ) || crtl -> profile || crtl -> calls_eh_return || crtl -> uses_const_pool || cfun -> has_nonlocal_label ) return ix86_select_alt_pic_regnum ( ) == INVALID_REGNUM ; } if ( crtl -> calls_eh_return && maybe_eh_return ) { unsigned i ; for ( i = 0 ; ; i ++ ) { unsigned test = EH_RETURN_DATA_REGNO ( i ) ; if ( test == INVALID_REGNUM ) break ; if ( test == regno ) return true ; } } if ( ignore_outlined && cfun -> machine -> call_ms2sysv ) { unsigned count = cfun -> machine -> call_ms2sysv_extra_regs + xlogue_layout :: MIN_REGS ; if ( xlogue_layout :: is_stub_managed_reg ( regno , count ) ) return false ; } if ( crtl -> drap_reg && regno == REGNO ( crtl -> drap_reg ) && ! cfun -> machine -> no_drap_save_restore ) return true ; return ( df_regs_ever_live_p ( regno ) && ! call_used_or_fixed_reg_p ( regno ) && ( regno != HARD_FRAME_POINTER_REGNUM || ! frame_pointer_needed ) ) ; } </s>


<s> bool ARMTargetLowering :: allowsMisalignedMemoryAccesses ( EVT VT , unsigned , unsigned Alignment , MachineMemOperand :: Flags , bool * Fast ) const { if ( ! VT . isSimple ( ) ) return false ; bool AllowsUnaligned = Subtarget -> allowsUnalignedMem ( ) ; auto Ty = VT . getSimpleVT ( ) . SimpleTy ; if ( Ty == MVT :: i8 || Ty == MVT :: i16 || Ty == MVT :: i32 ) { if ( AllowsUnaligned ) { if ( Fast ) * Fast = Subtarget -> hasV7Ops ( ) ; return true ; } } if ( Ty == MVT :: f64 || Ty == MVT :: v2f64 ) { if ( Subtarget -> hasNEON ( ) && ( AllowsUnaligned || Subtarget -> isLittle ( ) ) ) { if ( Fast ) * Fast = true ; return true ; } } if ( ! Subtarget -> hasMVEIntegerOps ( ) ) return false ; if ( Ty != MVT :: v16i8 && Ty != MVT :: v8i16 && Ty != MVT :: v8f16 && Ty != MVT :: v4i32 && Ty != MVT :: v4f32 && Ty != MVT :: v2i64 && Ty != MVT :: v2f64 && Ty != MVT :: v4i8 && Ty != MVT :: v8i8 && Ty != MVT :: v4i16 ) return false ; if ( Subtarget -> isLittle ( ) ) { if ( Fast ) * Fast = true ; return true ; } else { if ( Ty == MVT :: v16i8 || ( ( Ty == MVT :: v8i16 || Ty == MVT :: v8f16 ) && Alignment >= 2 ) || ( ( Ty == MVT :: v4i32 || Ty == MVT :: v4f32 ) && Alignment >= 4 ) ) { if ( Fast ) * Fast = true ; return true ; } } return false ; } </s>

Returns true if the target allows unaligned memory accesses of the specified type .


<s> static bool aarch64_pac_insn_p ( rtx x ) { if ( ! INSN_P ( x ) ) return false ; subrtx_var_iterator :: array_type array ; FOR_EACH_SUBRTX_VAR ( iter , array , PATTERN ( x ) , ALL ) { rtx sub = * iter ; if ( sub && GET_CODE ( sub ) == UNSPEC ) { int unspec_val = XINT ( sub , 1 ) ; switch ( unspec_val ) { case UNSPEC_PACIASP : case UNSPEC_PACIBSP : return true ; default : return false ; } iter . skip_subrtxes ( ) ; } } return false ; } </s>

Check if X ( or any sub-rtx of X ) is a PACIASP/PACIBSP instruction .


<s> static void vr4130_align_insns ( void ) { struct mips_sim state ; rtx_insn * insn , * subinsn , * last , * last2 , * next ; bool aligned_p ; dfa_start ( ) ; last = 0 ; last2 = 0 ; aligned_p = true ; mips_sim_init ( & state , alloca ( state_size ( ) ) ) ; for ( insn = get_insns ( ) ; insn != 0 ; insn = next ) { unsigned int length ; next = NEXT_INSN ( insn ) ; vr4130_avoid_branch_rt_conflict ( insn ) ; length = get_attr_length ( insn ) ; if ( length > 0 && USEFUL_INSN_P ( insn ) ) FOR_EACH_SUBINSN ( subinsn , insn ) { mips_sim_wait_insn ( & state , subinsn ) ; if ( state . insns_left != state . issue_rate && ! CALL_P ( subinsn ) ) { if ( subinsn == SEQ_BEGIN ( insn ) && aligned_p ) { gcc_assert ( last2 ) ; emit_insn_after ( gen_nop ( ) , last2 ) ; aligned_p = false ; } else if ( subinsn != SEQ_BEGIN ( insn ) && ! aligned_p ) { gcc_assert ( last ) ; emit_insn_after ( gen_nop ( ) , last ) ; aligned_p = true ; } } mips_sim_issue_insn ( & state , subinsn ) ; } mips_sim_finish_insn ( & state , insn ) ; length = get_attr_length ( insn ) ; if ( length > 0 ) { if ( NONJUMP_INSN_P ( SEQ_BEGIN ( insn ) ) && ( recog_memoized ( insn ) < 0 || length >= 8 ) ) { next = emit_insn_after ( gen_align ( GEN_INT ( 3 ) ) , insn ) ; next = NEXT_INSN ( next ) ; mips_sim_next_cycle ( & state ) ; aligned_p = true ; } else if ( length & 4 ) aligned_p = ! aligned_p ; last2 = last ; last = insn ; } if ( LABEL_P ( insn ) && label_to_alignment ( insn ) >= 3 ) aligned_p = true ; } dfa_finish ( ) ; } </s>

Implement -mvr4130-align . Go through each basic block and simulate the processor pipeline . If we find that a pair of instructions could execute in parallel , and the first of those instruction is not 8-byte aligned , insert a nop to make it aligned .


<s> static void rs6000_output_dwarf_dtprel ( FILE * file , int size , rtx x ) { switch ( size ) { case 4 : fputs ( "\t.long\t" , file ) ; break ; case 8 : fputs ( DOUBLE_INT_ASM_OP , file ) ; break ; default : gcc_unreachable ( ) ; } output_addr_const ( file , x ) ; if ( TARGET_ELF ) fputs ( "@dtprel+0x8000" , file ) ; else if ( TARGET_XCOFF && GET_CODE ( x ) == SYMBOL_REF ) { switch ( SYMBOL_REF_TLS_MODEL ( x ) ) { case 0 : break ; case TLS_MODEL_LOCAL_EXEC : fputs ( "@le" , file ) ; break ; case TLS_MODEL_INITIAL_EXEC : fputs ( "@ie" , file ) ; break ; case TLS_MODEL_GLOBAL_DYNAMIC : case TLS_MODEL_LOCAL_DYNAMIC : fputs ( "@m" , file ) ; break ; default : gcc_unreachable ( ) ; } } } </s>

This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL . We need to emit DTP-relative relocations .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { TargetTransformInfo :: getAnalysisUsage ( AU ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> static void mips_set_architecture ( const struct mips_cpu_info * info ) { if ( info != 0 ) { mips_arch_info = info ; mips_arch = info -> cpu ; mips_isa = info -> isa ; } } </s>

Set up globals to generate code for the ISA or processor described by INFO .


<s> bool function_checker :: require_immediate_range ( unsigned int rel_argno , HOST_WIDE_INT min , HOST_WIDE_INT max ) { unsigned int argno = m_base_arg + rel_argno ; if ( ! argument_exists_p ( argno ) ) return true ; gcc_assert ( min >= 0 && min <= max ) ; HOST_WIDE_INT actual ; if ( ! require_immediate ( argno , actual ) ) return false ; if ( ! IN_RANGE ( actual , min , max ) ) { report_out_of_range ( location , fndecl , argno , actual , min , max ) ; return false ; } return true ; } </s>

Check that argument REL_ARGNO is an integer constant expression in the range [ MIN , MAX ] . REL_ARGNO counts from the end of the predication arguments .


<s> void sh_set_return_address ( rtx ra , rtx tmp ) { HARD_REG_SET live_regs_mask ; int d ; int pr_reg = TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG ; int pr_offset ; d = calc_live_regs ( & live_regs_mask ) ; if ( ! TEST_HARD_REG_BIT ( live_regs_mask , pr_reg ) ) { rtx rr ; if ( TARGET_SHMEDIA ) { int rr_regno = sh_media_register_for_return ( ) ; if ( rr_regno < 0 ) rr_regno = pr_reg ; rr = gen_rtx_REG ( DImode , rr_regno ) ; } else rr = gen_rtx_REG ( SImode , pr_reg ) ; emit_insn ( GEN_MOV ( rr , ra ) ) ; emit_use ( rr ) ; return ; } if ( TARGET_SH5 ) { int offset ; save_schedule schedule ; save_entry * entry ; entry = sh5_schedule_saves ( & live_regs_mask , & schedule , 0 ) ; offset = entry [ 1 ] . offset ; for ( ; entry -> mode != VOIDmode ; entry -- ) if ( entry -> reg == pr_reg ) goto found ; gcc_unreachable ( ) ; found : offset = entry -> offset - offset ; pr_offset = ( rounded_frame_size ( d ) + offset + SHMEDIA_REGS_STACK_ADJUST ( ) ) ; } else pr_offset = rounded_frame_size ( d ) ; emit_insn ( GEN_MOV ( tmp , GEN_INT ( pr_offset ) ) ) ; if ( frame_pointer_needed ) emit_insn ( GEN_ADD3 ( tmp , tmp , hard_frame_pointer_rtx ) ) ; else emit_insn ( GEN_ADD3 ( tmp , tmp , stack_pointer_rtx ) ) ; tmp = gen_frame_mem ( Pmode , tmp ) ; emit_insn ( GEN_MOV ( tmp , ra ) ) ; emit_use ( tmp ) ; } </s>

Emit code to change the current function 's return address to RA . TEMP is available as a scratch register , if needed .


<s> bool X86TargetLowering :: isIntDivCheap ( EVT VT , AttributeList Attr ) const { bool OptSize = Attr . hasAttribute ( AttributeList :: FunctionIndex , Attribute :: MinSize ) ; return OptSize && ! VT . isVector ( ) ; } </s>

Return true if integer divide is usually cheaper than a sequence of several shifts , adds , and multiplies for this target .


<s> void rs6000_split_stack_space_check ( rtx size , rtx label ) { rtx sp = gen_rtx_REG ( Pmode , STACK_POINTER_REGNUM ) ; rtx limit = gen_reg_rtx ( Pmode ) ; rtx requested = gen_reg_rtx ( Pmode ) ; rtx cmp = gen_reg_rtx ( CCUNSmode ) ; rtx jump ; emit_insn ( gen_load_split_stack_limit ( limit ) ) ; if ( CONST_INT_P ( size ) ) emit_insn ( gen_add3_insn ( requested , sp , GEN_INT ( - INTVAL ( size ) ) ) ) ; else { size = force_reg ( Pmode , size ) ; emit_move_insn ( requested , gen_rtx_MINUS ( Pmode , sp , size ) ) ; } emit_insn ( gen_rtx_SET ( cmp , gen_rtx_COMPARE ( CCUNSmode , requested , limit ) ) ) ; jump = gen_rtx_IF_THEN_ELSE ( VOIDmode , gen_rtx_GEU ( VOIDmode , cmp , const0_rtx ) , gen_rtx_LABEL_REF ( VOIDmode , label ) , pc_rtx ) ; jump = emit_jump_insn ( gen_rtx_SET ( pc_rtx , jump ) ) ; JUMP_LABEL ( jump ) = label ; } </s>

Emit -fsplit-stack dynamic stack allocation space check .


<s> bool MipsHazardSchedule :: runOnMachineFunction ( MachineFunction & MF ) { const MipsSubtarget * STI = & static_cast < const MipsSubtarget & > ( MF . getSubtarget ( ) ) ; if ( ! STI -> hasMips32r6 ( ) || STI -> inMicroMipsMode ( ) ) return false ; bool Changed = false ; const MipsInstrInfo * TII = STI -> getInstrInfo ( ) ; for ( MachineFunction :: iterator FI = MF . begin ( ) ; FI != MF . end ( ) ; ++ FI ) { for ( Iter I = FI -> begin ( ) ; I != FI -> end ( ) ; ++ I ) { if ( ! TII -> HasForbiddenSlot ( * I ) ) continue ; bool InsertNop = false ; if ( std :: next ( I ) != FI -> end ( ) && ! TII -> SafeInForbiddenSlot ( * getNextMachineInstr ( std :: next ( I ) ) ) ) { InsertNop = true ; } else { for ( auto * Succ : FI -> successors ( ) ) { if ( FI -> isLayoutSuccessor ( Succ ) && getNextMachineInstr ( Succ -> begin ( ) ) != Succ -> end ( ) && ! TII -> SafeInForbiddenSlot ( * getNextMachineInstr ( Succ -> begin ( ) ) ) ) { InsertNop = true ; break ; } } } if ( InsertNop ) { Changed = true ; MIBundleBuilder ( & * I ) . append ( BuildMI ( MF , I -> getDebugLoc ( ) , TII -> get ( Mips :: NOP ) ) ) ; NumInsertedNops ++ ; } } } return Changed ; } </s>

runOnMachineFunction - Emit the function body .

Mips Mips Mips Mips Mips Mips Mips Mips::NOP


<s>
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
FISCTargetLowering
::
getRegForInlineAsmConstraint
(
const
TargetRegisterInfo
*
TRI
,
StringRef
Constraint
,
MVT
VT
)
const
{
if
(
Constraint
.
size
(
)
==
1
)
{
switch
(
Constraint
[
0
]
)
{
case
'r'
:
if
(
VT
==
MVT
::
i8
||
VT
==
MVT
::
i16
||
VT
==
MVT
::
i32
||
VT
==
MVT
::
i64
)
return
std
::
make_pair
(
0U
,
&
FISC
::
GRRegsRegClass
)
;
return
std
::
make_pair
(
0u
,
static_cast
<
const
TargetRegisterClass
*
>
(
0
)
)
;
case
'c'
:
if
(
VT
==
MVT
::
i64
)
return
std
::
make_pair
(
(
unsigned
)
FISC
::
X19
,
&
FISC
::
GRRegsRegClass
)
;
assert
(
"Unexpected type."
)
;
}
}
std
::
pair
<
unsigned
,
const
TargetRegisterClass
*
>
R
;
R
=
parseRegForInlineAsmConstraint
(
Constraint
,
VT
)
;
if
(
R
.
second
)
return
R
;
return
TargetLowering
::
getRegForInlineAsmConstraint
(
TRI
,
Constraint
,
VT
)
;
}
</s>

Given a physical register constraint ( e.g .


<s> bool X86TargetLowering :: combineRepeatedFPDivisors ( unsigned NumUsers ) const { return NumUsers > 1 ; } </s>

Indicate whether this target prefers to combine FDIVs with the same divisor .


<s> void rs6000_emit_le_vsx_load ( rtx dest , rtx source , machine_mode mode ) { rtx tmp , permute_mem , permute_reg ; if ( mode == TImode || mode == V1TImode ) { mode = V2DImode ; dest = gen_lowpart ( V2DImode , dest ) ; source = adjust_address ( source , V2DImode , 0 ) ; } tmp = can_create_pseudo_p ( ) ? gen_reg_rtx_and_attrs ( dest ) : dest ; permute_mem = rs6000_gen_le_vsx_permute ( source , mode ) ; permute_reg = rs6000_gen_le_vsx_permute ( tmp , mode ) ; emit_insn ( gen_rtx_SET ( tmp , permute_mem ) ) ; emit_insn ( gen_rtx_SET ( dest , permute_reg ) ) ; } </s>

Emit a little-endian load from vector memory location SOURCE to VSX register DEST in mode MODE . The load is done with two permuting insn 's that represent an lxvd2x and xxpermdi .


"SystemZ DAG preprocessing replacing:\nOld:    "

PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts .


<s>
unsigned
Mips16InstrInfo
::
getInlineAsmLength
(
const
char
*
Str
,
const
MCAsmInfo
&
MAI
)
const
{
bool
atInsnStart
=
true
;
unsigned
Length
=
0
;
for
(
;
*
Str
;
++
Str
)
{
if
(
*
Str
==
'\n'
||
strncmp
(
Str
,
MAI
.
getSeparatorString
(
)
,
strlen
(
MAI
.
getSeparatorString
(
)
)
)
==
0
)
atInsnStart
=
true
;
if
(
atInsnStart
&&
!
std
::
isspace
(
static_cast
<
unsigned
char
>
(
*
Str
)
)
)
{
if
(
strncmp
(
Str
,
".space"
,
6
)
==
0
)
{
char
*
EStr
;
int
Sz
;
Sz
=
strtol
(
Str
+
6
,
&
EStr
,
10
)
;
while
(
isspace
(
*
EStr
)
)
++
EStr
;
if
(
*
EStr
==
'\0'
)
{
DEBUG
(
dbgs
(
)
<<
"parsed .space "
<<
Sz
<<
'\n'
)
;
return
Sz
;
}
}
Length
+=
MAI
.
getMaxInstLength
(
)
;
atInsnStart
=
false
;
}
if
(
atInsnStart
&&
strncmp
(
Str
,
MAI
.
getCommentString
(
)
.
data
(
)
,
MAI
.
getCommentString
(
)
.
size
(
)
)
==
0
)
atInsnStart
=
false
;
}
return
Length
;
}
</s>

Measure the specified inline asm to determine an approximation of its length .


<s> static const char * sparc_mangle_type ( const_tree type ) { if ( ! TARGET_64BIT && TYPE_MAIN_VARIANT ( type ) == long_double_type_node && TARGET_LONG_DOUBLE_128 ) return "g" ; return NULL ; } </s>


"flag setting instruction only valid outside IT block"

"instruction only valid inside IT block"

"instruction variant requires ARMv6 or later"

"immediate operand must be in the range [0,15]"

MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specified MCStreamer .


<s> bool MLxExpansion :: runOnMachineFunction ( MachineFunction & Fn ) { if ( skipFunction ( * Fn . getFunction ( ) ) ) return false ; TII = static_cast < const ARMBaseInstrInfo * > ( Fn . getSubtarget ( ) . getInstrInfo ( ) ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; const ARMSubtarget * STI = & Fn . getSubtarget < ARMSubtarget > ( ) ; if ( ! STI -> isCortexA9 ( ) ) return false ; isLikeA9 = STI -> isLikeA9 ( ) || STI -> isSwift ( ) ; isSwift = STI -> isSwift ( ) ; bool Modified = false ; for ( MachineBasicBlock & MBB : Fn ) Modified |= ExpandFPMLxInstructions ( MBB ) ; return Modified ; } </s>


<s> static const char * rs6000_mangle_fundamental_type ( tree type ) { if ( type == bool_char_type_node ) return "U6__boolc" ; if ( type == bool_short_type_node ) return "U6__bools" ; if ( type == pixel_type_node ) return "u7__pixel" ; if ( type == bool_int_type_node ) return "U6__booli" ; if ( TYPE_MAIN_VARIANT ( type ) == long_double_type_node && TARGET_ELF && TARGET_LONG_DOUBLE_128 && ! TARGET_IEEEQUAD ) return "g" ; return NULL ; } </s>

AltiVec defines four built-in scalar types that serve as vector elements ; we must teach the compiler how to mangle them .


<s> static void ix86_emit_restore_sse_regs_using_mov ( HOST_WIDE_INT cfa_offset , bool maybe_eh_return ) { unsigned int regno ; for ( regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno ++ ) if ( SSE_REGNO_P ( regno ) && ix86_save_reg ( regno , maybe_eh_return ) ) { rtx reg = gen_rtx_REG ( V4SFmode , regno ) ; rtx mem ; mem = choose_baseaddr ( cfa_offset ) ; mem = gen_rtx_MEM ( V4SFmode , mem ) ; set_mem_align ( mem , 128 ) ; emit_move_insn ( reg , mem ) ; ix86_add_cfa_restore_note ( NULL_RTX , reg , cfa_offset ) ; cfa_offset -= 16 ; } } </s>

Emit code to restore saved registers using MOV insns . First register is restored from CFA - CFA_OFFSET .


<s>
bool
AArch64InstrInfo
::
shouldClusterMemOps
(
MachineInstr
&
FirstLdSt
,
unsigned
BaseReg1
,
MachineInstr
&
SecondLdSt
,
unsigned
BaseReg2
,
unsigned
NumLoads
)
const
{
if
(
BaseReg1
!=
BaseReg2
)
return
false
;
if
(
NumLoads
>
1
)
return
false
;
if
(
!
isPairableLdStInst
(
FirstLdSt
)
||
!
isPairableLdStInst
(
SecondLdSt
)
)
return
false
;
unsigned
FirstOpc
=
FirstLdSt
.
getOpcode
(
)
;
unsigned
SecondOpc
=
SecondLdSt
.
getOpcode
(
)
;
if
(
!
canPairLdStOpc
(
FirstOpc
,
SecondOpc
)
)
return
false
;
if
(
!
isCandidateToMergeOrPair
(
FirstLdSt
)
||
!
isCandidateToMergeOrPair
(
SecondLdSt
)
)
return
false
;
int64_t
Offset1
=
FirstLdSt
.
getOperand
(
2
)
.
getImm
(
)
;
if
(
isUnscaledLdSt
(
FirstOpc
)
&&
!
scaleOffset
(
FirstOpc
,
Offset1
)
)
return
false
;
int64_t
Offset2
=
SecondLdSt
.
getOperand
(
2
)
.
getImm
(
)
;
if
(
isUnscaledLdSt
(
SecondOpc
)
&&
!
scaleOffset
(
SecondOpc
,
Offset2
)
)
return
false
;
if
(
Offset1
>
63
||
Offset1
<
64
)
return
false
;
assert
(
Offset1
<=
Offset2
&&
"Caller should have ordered offsets."
)
;
return
Offset1
+
1
==
Offset2
;
}
</s>

Returns true if the two given memory operations should be scheduled adjacent .


<s> unsigned ARM64RegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; return TFI -> hasFP ( MF ) ? ARM64 :: FP : ARM64 :: SP ; } </s>


<s> rtx neon_make_constant ( rtx vals , bool generate ) { machine_mode mode = GET_MODE ( vals ) ; rtx target ; rtx const_vec = NULL_RTX ; int n_elts = GET_MODE_NUNITS ( mode ) ; int n_const = 0 ; int i ; if ( GET_CODE ( vals ) == CONST_VECTOR ) const_vec = vals ; else if ( GET_CODE ( vals ) == PARALLEL ) { for ( i = 0 ; i < n_elts ; ++ i ) { rtx x = XVECEXP ( vals , 0 , i ) ; if ( CONST_INT_P ( x ) || CONST_DOUBLE_P ( x ) ) n_const ++ ; } if ( n_const == n_elts ) const_vec = gen_rtx_CONST_VECTOR ( mode , XVEC ( vals , 0 ) ) ; } else gcc_unreachable ( ) ; if ( const_vec != NULL && simd_immediate_valid_for_move ( const_vec , mode , NULL , NULL ) ) return const_vec ; else if ( TARGET_HAVE_MVE && VALID_MVE_PRED_MODE ( mode ) ) return mve_bool_vec_to_const ( const_vec ) ; else if ( ( target = neon_vdup_constant ( vals , generate ) ) != NULL_RTX ) return target ; else if ( const_vec != NULL_RTX ) return arm_disable_literal_pool ? NULL_RTX : const_vec ; else return NULL_RTX ; } </s>

Generate code to load VALS , which is a PARALLEL containing only constants ( for vec_init ) or CONST_VECTOR , efficiently into a register . Returns an RTX to copy into the register , or NULL_RTX for a PARALLEL that can not be converted into a CONST_VECTOR .


<s> unsigned X86FrameLowering :: getWinEHFuncletFrameSize ( const MachineFunction & MF ) const { const X86MachineFunctionInfo * X86FI = MF . getInfo < X86MachineFunctionInfo > ( ) ; unsigned CSSize = X86FI -> getCalleeSavedFrameSize ( ) ; const auto & WinEHXMMSlotInfo = X86FI -> getWinEHXMMSlotInfo ( ) ; unsigned XMMSize = WinEHXMMSlotInfo . size ( ) * TRI -> getSpillSize ( X86 :: VR128RegClass ) ; unsigned UsedSize ; EHPersonality Personality = classifyEHPersonality ( MF . getFunction ( ) . getPersonalityFn ( ) ) ; if ( Personality == EHPersonality :: CoreCLR ) { UsedSize = getPSPSlotOffsetFromSP ( MF ) + SlotSize ; } else { UsedSize = MF . getFrameInfo ( ) . getMaxCallFrameSize ( ) ; } unsigned FrameSizeMinusRBP = alignTo ( CSSize + UsedSize , getStackAlignment ( ) ) ; return FrameSizeMinusRBP + XMMSize - CSSize ; } </s>

Funclets only need to account for space for the callee saved registers , as the locals are accounted for in the parent 's stack frame .


<s> static int min_insn_size ( rtx_insn * insn ) { int l = 0 , len ; if ( ! INSN_P ( insn ) || ! active_insn_p ( insn ) ) return 0 ; if ( GET_CODE ( PATTERN ( insn ) ) == UNSPEC_VOLATILE && XINT ( PATTERN ( insn ) , 1 ) == UNSPECV_ALIGN ) return 0 ; if ( CALL_P ( insn ) && symbolic_reference_mentioned_p ( PATTERN ( insn ) ) && ! SIBLING_CALL_P ( insn ) ) return 5 ; len = get_attr_length ( insn ) ; if ( len <= 1 ) return 1 ; if ( ! JUMP_P ( insn ) ) { enum attr_type type = get_attr_type ( insn ) ; switch ( type ) { case TYPE_MULTI : if ( GET_CODE ( PATTERN ( insn ) ) == ASM_INPUT || asm_noperands ( PATTERN ( insn ) ) >= 0 ) return 0 ; break ; case TYPE_OTHER : case TYPE_FCMP : break ; default : return len ; } l = get_attr_length_address ( insn ) ; if ( l < 4 && symbolic_reference_mentioned_p ( PATTERN ( insn ) ) ) l = 4 ; } if ( l ) return 1 + l ; else return 2 ; } </s>

We do n't have exact information about the insn sizes , but we may assume quite safely that we are informed about all 1 byte insns and memory address sizes . This is enough to eliminate unnecessary padding in 99 % of cases .


<s> bool X86FrameLowering :: restoreCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; if ( isFuncletReturnInstr ( MI ) && STI . is32Bit ( ) && STI . isOSWindows ( ) ) return true ; DebugLoc DL = MBB . findDebugLoc ( MI ) ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; if ( X86 :: GR64RegClass . contains ( Reg ) || X86 :: GR32RegClass . contains ( Reg ) ) continue ; const TargetRegisterClass * RC = TRI -> getMinimalPhysRegClass ( Reg ) ; TII . loadRegFromStackSlot ( MBB , MI , Reg , CSI [ i ] . getFrameIdx ( ) , RC , TRI ) ; } unsigned Opc = STI . is64Bit ( ) ? X86 :: POP64r : X86 :: POP32r ; for ( unsigned i = 0 , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; if ( ! X86 :: GR64RegClass . contains ( Reg ) && ! X86 :: GR32RegClass . contains ( Reg ) ) continue ; BuildMI ( MBB , MI , DL , TII . get ( Opc ) , Reg ) ; } 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> bool isToken ( ) const { return Kind == k_Token ; } </s>


<s> const X86RegisterInfo * getRegisterInfo ( ) const override { return & getInstrInfo ( ) -> getRegisterInfo ( ) ; } </s>

getRegisterInfo - TargetInstrInfo is a superset of MRegister info .


<s> static arm_stack_offsets * arm_get_frame_offsets ( void ) { struct arm_stack_offsets * offsets ; unsigned long func_type ; int leaf ; int saved ; HOST_WIDE_INT frame_size ; offsets = & cfun -> machine -> stack_offsets ; if ( reload_completed ) return offsets ; frame_size = ROUND_UP_WORD ( get_frame_size ( ) ) ; leaf = leaf_function_p ( ) ; offsets -> saved_args = current_function_pretend_args_size ; offsets -> frame = offsets -> saved_args + ( frame_pointer_needed ? 4 : 0 ) ; if ( TARGET_ARM ) { unsigned int regno ; saved = bit_count ( arm_compute_save_reg_mask ( ) ) * 4 ; if ( TARGET_REALLY_IWMMXT ) { for ( regno = FIRST_IWMMXT_REGNUM ; regno <= LAST_IWMMXT_REGNUM ; regno ++ ) if ( regs_ever_live [ regno ] && ! call_used_regs [ regno ] ) saved += 8 ; } func_type = arm_current_func_type ( ) ; if ( ! IS_VOLATILE ( func_type ) ) { for ( regno = FIRST_FPA_REGNUM ; regno <= LAST_FPA_REGNUM ; regno ++ ) if ( regs_ever_live [ regno ] && ! call_used_regs [ regno ] ) saved += 12 ; if ( TARGET_HARD_FLOAT && TARGET_VFP ) saved += arm_get_vfp_saved_size ( ) ; } } else { saved = bit_count ( thumb_compute_save_reg_mask ( ) ) * 4 ; if ( TARGET_BACKTRACE ) saved += 16 ; } offsets -> saved_regs = offsets -> saved_args + saved ; offsets -> soft_frame = offsets -> saved_regs + CALLER_INTERWORKING_SLOT_SIZE ; if ( leaf && frame_size == 0 ) { offsets -> outgoing_args = offsets -> soft_frame ; return offsets ; } if ( ARM_DOUBLEWORD_ALIGN && ( offsets -> soft_frame & 7 ) ) offsets -> soft_frame += 4 ; offsets -> locals_base = offsets -> soft_frame + frame_size ; offsets -> outgoing_args = ( offsets -> locals_base + current_function_outgoing_args_size ) ; if ( ARM_DOUBLEWORD_ALIGN ) { if ( offsets -> outgoing_args & 7 ) offsets -> outgoing_args += 4 ; gcc_assert ( ! ( offsets -> outgoing_args & 7 ) ) ; } return offsets ; } </s>

Calculate stack offsets . These are used to calculate register elimination offsets and in prologue/epilogue code . Also calculates which registers should be saved .


<s> static unsigned int loongarch_hard_regno_nregs ( unsigned int regno , machine_mode mode ) { if ( FCC_REG_P ( regno ) ) return ( GET_MODE_SIZE ( mode ) + 3 ) / 4 ; if ( FP_REG_P ( regno ) ) return ( GET_MODE_SIZE ( mode ) + UNITS_PER_FPREG - 1 ) / UNITS_PER_FPREG ; return ( GET_MODE_SIZE ( mode ) + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD ; } </s>


<s> bool X86FastISel :: tryToFoldLoadIntoMI ( MachineInstr * MI , unsigned OpNo , const LoadInst * LI ) { X86AddressMode AM ; if ( ! X86SelectAddress ( LI -> getOperand ( 0 ) , AM ) ) return false ; const X86InstrInfo & XII = ( const X86InstrInfo & ) TII ; unsigned Size = TD . getTypeAllocSize ( LI -> getType ( ) ) ; unsigned Alignment = LI -> getAlignment ( ) ; SmallVector < MachineOperand , 8 > AddrOps ; AM . getFullAddress ( AddrOps ) ; MachineInstr * Result = XII . foldMemoryOperandImpl ( * FuncInfo . MF , MI , OpNo , AddrOps , Size , Alignment ) ; if ( Result == 0 ) return false ; FuncInfo . MBB -> insert ( FuncInfo . InsertPt , Result ) ; MI -> eraseFromParent ( ) ; return true ; } </s>

The specified machine instr operand is a vreg , and that vreg is being provided by the specified load instruction .


<s> static unsigned getReg ( const MCDisassembler * D , unsigned RC , unsigned RegNo ) { const MCRegisterInfo * RegInfo = D -> getContext ( ) . getRegisterInfo ( ) ; return * ( RegInfo -> getRegClass ( RC ) . begin ( ) + RegNo ) ; } </s>

Returns the register associated with this edge .


<s> static int rs6000_reassociation_width ( unsigned int opc ATTRIBUTE_UNUSED , enum machine_mode mode ) { switch ( rs6000_cpu ) { case PROCESSOR_POWER8 : case PROCESSOR_POWER9 : if ( DECIMAL_FLOAT_MODE_P ( mode ) ) return 1 ; if ( VECTOR_MODE_P ( mode ) ) return 4 ; if ( INTEGRAL_MODE_P ( mode ) ) return opc == MULT_EXPR ? 4 : 6 ; if ( FLOAT_MODE_P ( mode ) ) return 4 ; break ; default : break ; } return 1 ; } </s>

Determine the reassociation width to be used in reassociate_bb . This takes into account how many parallel operations we can actually do of a given type , and also the latency . P8 : int add/sub 6/cycle mul 2/cycle vect add/sub/mul 2/cycle fp add/sub/mul 2/cycle dfp 1/cycle


<s> LoadInst * X86TargetLowering :: lowerIdempotentRMWIntoFencedLoad ( AtomicRMWInst * AI ) const { unsigned NativeWidth = Subtarget . is64Bit ( ) ? 64 : 32 ; Type * MemType = AI -> getType ( ) ; if ( MemType -> getPrimitiveSizeInBits ( ) > NativeWidth ) return nullptr ; if ( auto * C = dyn_cast < ConstantInt > ( AI -> getValOperand ( ) ) ) if ( AI -> getOperation ( ) == AtomicRMWInst :: Or && C -> isZero ( ) && AI -> use_empty ( ) ) return nullptr ; auto Builder = IRBuilder < > ( AI ) ; Module * M = Builder . GetInsertBlock ( ) -> getParent ( ) -> getParent ( ) ; auto SSID = AI -> getSyncScopeID ( ) ; auto Order = AtomicCmpXchgInst :: getStrongestFailureOrdering ( AI -> getOrdering ( ) ) ; if ( SSID == SyncScope :: SingleThread ) return nullptr ; if ( ! Subtarget . hasMFence ( ) ) return nullptr ; Function * MFence = llvm :: Intrinsic :: getDeclaration ( M , Intrinsic :: x86_sse2_mfence ) ; Builder . CreateCall ( MFence , { } ) ; LoadInst * Loaded = Builder . CreateAlignedLoad ( AI -> getType ( ) , AI -> getPointerOperand ( ) , AI -> getType ( ) -> getPrimitiveSizeInBits ( ) ) ; Loaded -> setAtomic ( Order , SSID ) ; AI -> replaceAllUsesWith ( Loaded ) ; AI -> eraseFromParent ( ) ; return Loaded ; } </s>

On some platforms , an AtomicRMW that never actually modifies the value ( such as fetch_add of 0 ) can be turned into a fence followed by an atomic load .


"  Skipping pass: no machine model present.\n"

runOnMachineFunction - Emit the function body .


<s> bool AArch64TargetLowering :: shouldExpandAtomicRMWInIR ( AtomicRMWInst * AI ) const { unsigned Size = AI -> getType ( ) -> getPrimitiveSizeInBits ( ) ; return Size <= 128 ; } </s>

Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW , if at all .


<s>
bool
X86CmovConverterPass
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
if
(
!
EnableCmovConverter
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"********** "
<<
getPassName
(
)
<<
" : "
<<
MF
.
getName
(
)
<<
"**********\n"
)
;
bool
Changed
=
false
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
const
TargetSubtargetInfo
&
STI
=
MF
.
getSubtarget
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
TII
=
STI
.
getInstrInfo
(
)
;
TRI
=
STI
.
getRegisterInfo
(
)
;
TSchedModel
.
init
(
&
STI
)
;
if
(
ForceMemOperand
||
ForceAll
)
{
CmovGroups
AllCmovGroups
;
SmallVector
<
MachineBasicBlock
*
,
4
>
Blocks
;
for
(
auto
&
MBB
:
MF
)
Blocks
.
push_back
(
&
MBB
)
;
if
(
collectCmovCandidates
(
Blocks
,
AllCmovGroups
,
true
)
)
{
for
(
auto
&
Group
:
AllCmovGroups
)
{
if
(
ForceMemOperand
&&
!
ForceAll
&&
llvm
::
none_of
(
Group
,
[
&
]
(
MachineInstr
*
I
)
{
return
I
->
mayLoad
(
)
;
}
)
)
continue
;
Changed
=
true
;
convertCmovInstsToBranches
(
Group
)
;
}
}
if
(
ForceAll
)
return
Changed
;
}
SmallVector
<
MachineLoop
*
,
4
>
Loops
(
MLI
->
begin
(
)
,
MLI
->
end
(
)
)
;
for
(
int
i
=
0
;
i
<
(
int
)
Loops
.
size
(
)
;
++
i
)
for
(
MachineLoop
*
Child
:
Loops
[
i
]
->
getSubLoops
(
)
)
Loops
.
push_back
(
Child
)
;
for
(
MachineLoop
*
CurrLoop
:
Loops
)
{
if
(
!
CurrLoop
->
getSubLoops
(
)
.
empty
(
)
)
continue
;
CmovGroups
CmovInstGroups
;
if
(
!
collectCmovCandidates
(
CurrLoop
->
getBlocks
(
)
,
CmovInstGroups
)
)
continue
;
if
(
!
checkForProfitableCmovCandidates
(
CurrLoop
->
getBlocks
(
)
,
CmovInstGroups
)
)
continue
;
Changed
=
true
;
for
(
auto
&
Group
:
CmovInstGroups
)
convertCmovInstsToBranches
(
Group
)
;
}
return
Changed
;
}
</s>


<s>
static
void
recombine_stvx_pattern
(
rtx_insn
*
insn
,
del_info
*
to_delete
)
{
rtx
body
=
PATTERN
(
insn
)
;
gcc_assert
(
GET_CODE
(
body
)
==
SET
&&
GET_CODE
(
SET_DEST
(
body
)
)
==
MEM
&&
GET_CODE
(
SET_SRC
(
body
)
)
==
VEC_SELECT
)
;
rtx
mem
=
SET_DEST
(
body
)
;
rtx
base_reg
=
XEXP
(
mem
,
0
)
;
rtx
and_operation
=
find_alignment_op
(
insn
,
base_reg
)
;
if
(
and_operation
!=
0
)
{
rtx
src_reg
=
XEXP
(
SET_SRC
(
body
)
,
0
)
;
df_ref
src_use
;
struct
df_insn_info
*
insn_info
=
DF_INSN_INFO_GET
(
insn
)
;
FOR_EACH_INSN_INFO_USE
(
src_use
,
insn_info
)
{
if
(
!
rtx_equal_p
(
DF_REF_REG
(
src_use
)
,
src_reg
)
)
continue
;
struct
df_link
*
link
=
DF_REF_CHAIN
(
src_use
)
;
if
(
!
link
||
link
->
next
)
break
;
rtx_insn
*
swap_insn
=
DF_REF_INSN
(
link
->
ref
)
;
if
(
!
insn_is_swap_p
(
swap_insn
)
||
insn_is_load_p
(
swap_insn
)
||
insn_is_store_p
(
swap_insn
)
)
break
;
to_delete
[
INSN_UID
(
swap_insn
)
]
.
replace
=
true
;
to_delete
[
INSN_UID
(
swap_insn
)
]
.
replace_insn
=
swap_insn
;
XEXP
(
mem
,
0
)
=
and_operation
;
SET_SRC
(
body
)
=
src_reg
;
INSN_CODE
(
insn
)
=
1
;
df_insn_rescan
(
insn
)
;
if
(
dump_file
)
fprintf
(
dump_file
,
"stvx opportunity found at %d\n"
,
INSN_UID
(
insn
)
)
;
}
}
}
</s>

If INSN is the store for an stvx pattern , put it in canonical form .


"LOAD_STACK_GUARD currently supported only for MachO."

This function is called for all pseudo instructions that remain after register allocation .


<s> bool X86InstrInfo :: isHighLatencyDef ( int opc ) const { switch ( opc ) { default : return false ; case X86 :: DIVSDrm : case X86 :: DIVSDrm_Int : case X86 :: DIVSDrr : case X86 :: DIVSDrr_Int : case X86 :: DIVSSrm : case X86 :: DIVSSrm_Int : case X86 :: DIVSSrr : case X86 :: DIVSSrr_Int : case X86 :: SQRTPDm : case X86 :: SQRTPDr : case X86 :: SQRTPSm : case X86 :: SQRTPSr : case X86 :: SQRTSDm : case X86 :: SQRTSDm_Int : case X86 :: SQRTSDr : case X86 :: SQRTSDr_Int : case X86 :: SQRTSSm : case X86 :: SQRTSSm_Int : case X86 :: SQRTSSr : case X86 :: SQRTSSr_Int : case X86 :: VDIVSDrm : case X86 :: VDIVSDrm_Int : case X86 :: VDIVSDrr : case X86 :: VDIVSDrr_Int : case X86 :: VDIVSSrm : case X86 :: VDIVSSrm_Int : case X86 :: VDIVSSrr : case X86 :: VDIVSSrr_Int : case X86 :: VSQRTPDm : case X86 :: VSQRTPDr : case X86 :: VSQRTPSm : case X86 :: VSQRTPSr : case X86 :: VSQRTSDm : case X86 :: VSQRTSDm_Int : case X86 :: VSQRTSDr : case X86 :: VSQRTSSm : case X86 :: VSQRTSSm_Int : case X86 :: VSQRTSSr : return true ; } } </s>

Return true if this opcode has high latency to its result .


<s> static void or1k_option_override ( void ) { init_machine_status = or1k_init_machine_status ; } </s>

Worker for TARGET_OPTION_OVERRIDE . We currently only use this to setup init_machine_status .


<s>
static
uint8_t
name
(
struct
InternalInstruction
*
insn
,
\
OperandType
type
,
\
uint8_t
index
,
\
uint8_t
*
valid
)
{
\
*
valid
=
1
;
\
switch
(
type
)
{
\
default
:
\
debug
(
"Unhandled register type"
)
;
\
*
valid
=
0
;
\
return
0
;
\
case
TYPE_Rv
:
\
return
base
+
index
;
\
case
TYPE_R8
:
\
if
(
insn
->
rexPrefix
&&
\
index
>=
4
&&
index
<=
7
)
{
\
return
prefix
##
_SPL
+
(
index
4
)
;
\
}
else
{
\
return
prefix
##
_AL
+
index
;
\
}
\
case
TYPE_R16
:
\
return
prefix
##
_AX
+
index
;
\
case
TYPE_R32
:
\
return
prefix
##
_EAX
+
index
;
\
case
TYPE_R64
:
\
return
prefix
##
_RAX
+
index
;
\
case
TYPE_XMM512
:
\
return
prefix
##
_ZMM0
+
index
;
\
case
TYPE_XMM256
:
\
return
prefix
##
_YMM0
+
index
;
\
case
TYPE_XMM128
:
\
case
TYPE_XMM64
:
\
case
TYPE_XMM32
:
\
case
TYPE_XMM
:
\
return
prefix
##
_XMM0
+
index
;
\
case
TYPE_VK1
:
\
case
TYPE_VK8
:
\
case
TYPE_VK16
:
\
if
(
index
>
7
)
\
*
valid
=
0
;
\
return
prefix
##
_K0
+
index
;
\
case
TYPE_MM64
:
\
return
prefix
##
_MM0
+
(
index
&
0x7
)
;
\
case
TYPE_SEGMENTREG
:
\
if
(
index
>
5
)
\
*
valid
=
0
;
\
return
prefix
##
_ES
+
index
;
\
case
TYPE_DEBUGREG
:
\
return
prefix
##
_DR0
+
index
;
\
case
TYPE_CONTROLREG
:
\
return
prefix
##
_CR0
+
index
;
\
}
\
}
</s>

Gets the name of the pass we are mixed into .


"getMemOperandWithOffset only supports base "

Get the base operand and byte offset of an instruction that reads/writes memory .


<s> bool rx_match_ccmode ( rtx insn , machine_mode cc_mode ) { rtx op1 , flags ; machine_mode flags_mode ; gcc_checking_assert ( XVECLEN ( PATTERN ( insn ) , 0 ) == 2 ) ; op1 = XVECEXP ( PATTERN ( insn ) , 0 , 0 ) ; gcc_checking_assert ( GET_CODE ( SET_SRC ( op1 ) ) == COMPARE ) ; flags = SET_DEST ( op1 ) ; flags_mode = GET_MODE ( flags ) ; if ( GET_MODE ( SET_SRC ( op1 ) ) != flags_mode ) return false ; if ( GET_MODE_CLASS ( flags_mode ) != MODE_CC ) return false ; if ( flags_from_mode ( flags_mode ) & ~ flags_from_mode ( cc_mode ) ) return false ; return true ; } </s>

A helper function for matching parallels that set the flags .


<s> static Mnode * add_csky_minipool_forward_ref ( Mfix * fix ) { Mnode * max_mp = NULL ; HOST_WIDE_INT max_address = fix -> address + fix -> forwards ; Mnode * mp ; if ( minipool_vector_head && ( fix -> address + get_attr_length ( fix -> insn ) >= minipool_vector_head -> max_address - fix -> fix_size ) ) return NULL ; for ( mp = minipool_vector_head ; mp != NULL ; mp = mp -> next ) { if ( GET_CODE ( fix -> value ) == GET_CODE ( mp -> value ) && fix -> mode == mp -> mode && ( GET_CODE ( fix -> value ) != CODE_LABEL || ( CODE_LABEL_NUMBER ( fix -> value ) == CODE_LABEL_NUMBER ( mp -> value ) ) ) && rtx_equal_p ( fix -> value , mp -> value ) ) { mp -> refcount ++ ; return mp ; } if ( max_mp == NULL && mp -> max_address > max_address ) max_mp = mp ; } mp = XNEW ( Mnode ) ; mp -> fix_size = fix -> fix_size ; mp -> mode = fix -> mode ; mp -> value = fix -> value ; mp -> refcount = 1 ; mp -> min_address = - 65536 ; if ( max_mp == NULL ) { mp -> max_address = max_address ; mp -> next = NULL ; mp -> prev = minipool_vector_tail ; if ( mp -> prev == NULL ) { minipool_vector_head = mp ; minipool_vector_label = gen_csky_constpool_label ( gen_rtx_CONST_INT ( VOIDmode , constpool_label_no ++ ) ) ; } else mp -> prev -> next = mp ; minipool_vector_tail = mp ; } else { if ( max_address > max_mp -> max_address - mp -> fix_size ) mp -> max_address = max_mp -> max_address - mp -> fix_size ; else mp -> max_address = max_address ; mp -> next = max_mp ; mp -> prev = max_mp -> prev ; max_mp -> prev = mp ; if ( mp -> prev != NULL ) mp -> prev -> next = mp ; else minipool_vector_head = mp ; } max_mp = mp ; while ( mp -> prev != NULL && mp -> prev -> max_address > mp -> max_address - mp -> prev -> fix_size ) { mp -> prev -> max_address = mp -> max_address - mp -> prev -> fix_size ; mp = mp -> prev ; } return max_mp ; } </s>

Add a constant to the minipool for a forward reference . Returns the node added or NULL if the constant will not fit in this pool .


<s> EVT X86TargetLowering :: getOptimalMemOpType ( uint64_t Size , unsigned DstAlign , unsigned SrcAlign , bool IsMemset , bool ZeroMemset , bool MemcpyStrSrc , MachineFunction & MF ) const { const Function * F = MF . getFunction ( ) ; if ( ( ! IsMemset || ZeroMemset ) && ! F -> hasFnAttribute ( Attribute :: NoImplicitFloat ) ) { if ( Size >= 16 && ( ! Subtarget . isUnalignedMem16Slow ( ) || ( ( DstAlign == 0 || DstAlign >= 16 ) && ( SrcAlign == 0 || SrcAlign >= 16 ) ) ) ) { if ( Size >= 32 ) { if ( Subtarget . hasInt256 ( ) ) return MVT :: v8i32 ; if ( Subtarget . hasFp256 ( ) ) return MVT :: v8f32 ; } if ( Subtarget . hasSSE2 ( ) ) return MVT :: v4i32 ; if ( Subtarget . hasSSE1 ( ) ) return MVT :: v4f32 ; } else if ( ! MemcpyStrSrc && Size >= 8 && ! Subtarget . is64Bit ( ) && Subtarget . hasSSE2 ( ) ) { return MVT :: f64 ; } } 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 void nds32_emit_stack_v3push ( rtx Rb , rtx Re , rtx En4 ATTRIBUTE_UNUSED , rtx imm8u ) { int regno ; int num_use_regs ; int par_index ; int offset ; rtx reg ; rtx mem ; rtx push_rtx ; rtx adjust_sp_rtx ; rtx parallel_insn ; num_use_regs = REGNO ( Re ) - REGNO ( Rb ) + 1 + 3 ; parallel_insn = gen_rtx_PARALLEL ( VOIDmode , rtvec_alloc ( num_use_regs + 1 ) ) ; par_index = 0 ; offset = - ( num_use_regs * 4 ) ; for ( regno = REGNO ( Rb ) ; regno <= ( int ) REGNO ( Re ) ; regno ++ ) { reg = gen_rtx_REG ( SImode , regno ) ; mem = gen_frame_mem ( SImode , plus_constant ( Pmode , stack_pointer_rtx , offset ) ) ; push_rtx = gen_rtx_SET ( mem , reg ) ; XVECEXP ( parallel_insn , 0 , par_index ) = push_rtx ; RTX_FRAME_RELATED_P ( push_rtx ) = 1 ; offset = offset + 4 ; par_index ++ ; } reg = gen_rtx_REG ( SImode , FP_REGNUM ) ; mem = gen_frame_mem ( SImode , plus_constant ( Pmode , stack_pointer_rtx , offset ) ) ; push_rtx = gen_rtx_SET ( mem , reg ) ; XVECEXP ( parallel_insn , 0 , par_index ) = push_rtx ; RTX_FRAME_RELATED_P ( push_rtx ) = 1 ; offset = offset + 4 ; par_index ++ ; reg = gen_rtx_REG ( SImode , GP_REGNUM ) ; mem = gen_frame_mem ( SImode , plus_constant ( Pmode , stack_pointer_rtx , offset ) ) ; push_rtx = gen_rtx_SET ( mem , reg ) ; XVECEXP ( parallel_insn , 0 , par_index ) = push_rtx ; RTX_FRAME_RELATED_P ( push_rtx ) = 1 ; offset = offset + 4 ; par_index ++ ; reg = gen_rtx_REG ( SImode , LP_REGNUM ) ; mem = gen_frame_mem ( SImode , plus_constant ( Pmode , stack_pointer_rtx , offset ) ) ; push_rtx = gen_rtx_SET ( mem , reg ) ; XVECEXP ( parallel_insn , 0 , par_index ) = push_rtx ; RTX_FRAME_RELATED_P ( push_rtx ) = 1 ; offset = offset + 4 ; par_index ++ ; offset = - ( num_use_regs * 4 ) ; adjust_sp_rtx = gen_rtx_SET ( stack_pointer_rtx , plus_constant ( Pmode , stack_pointer_rtx , offset - INTVAL ( imm8u ) ) ) ; XVECEXP ( parallel_insn , 0 , par_index ) = adjust_sp_rtx ; RTX_FRAME_RELATED_P ( adjust_sp_rtx ) = 1 ; parallel_insn = emit_insn ( parallel_insn ) ; RTX_FRAME_RELATED_P ( parallel_insn ) = 1 ; } </s>

Function to create a parallel rtx pattern which presents stack v3push behavior . The overall concept are : `` push registers to memory '' , `` adjust stack pointer '' .


<s> void SparcAsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { switch ( MI -> getOpcode ( ) ) { default : break ; case TargetOpcode :: DBG_VALUE : return ; case SP :: GETPCX : LowerGETPCXAndEmitMCInsts ( MI , getSubtargetInfo ( ) ) ; return ; } MachineBasicBlock :: const_instr_iterator I = MI ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; do { MCInst TmpInst ; LowerSparcMachineInstrToMCInst ( I , TmpInst , * this ) ; EmitToStreamer ( * OutStreamer , TmpInst ) ; } while ( ( ++ I != E ) && I -> isInsideBundle ( ) ) ; } </s>

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


"selector must be an integer constant in the range [0, %wi]"

Return the integer constant in ARG . Constrain it to be in the range of the subparts of VEC_TYPE ; issue an error if not .


<s>
void
ARMTargetLowering
::
ReplaceNodeResults
(
SDNode
*
N
,
SmallVectorImpl
<
SDValue
>
&
Results
,
SelectionDAG
&
DAG
)
const
{
SDValue
Res
;
switch
(
N
->
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Don't know how to custom expand this!"
)
;
case
ISD
::
READ_REGISTER
:
ExpandREAD_REGISTER
(
N
,
Results
,
DAG
)
;
break
;
case
ISD
::
BITCAST
:
Res
=
ExpandBITCAST
(
N
,
DAG
)
;
break
;
case
ISD
::
SRL
:
case
ISD
::
SRA
:
Res
=
Expand64BitShift
(
N
,
DAG
,
Subtarget
)
;
break
;
case
ISD
::
READCYCLECOUNTER
:
ReplaceREADCYCLECOUNTER
(
N
,
Results
,
DAG
,
Subtarget
)
;
return
;
}
if
(
Res
.
getNode
(
)
)
Results
.
push_back
(
Res
)
;
}
</s>

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built out of custom code .

ARM
ARM
"Don't know how to custom expand this!"
ISD::READ_REGISTER
ISD::BITCAST
ISD::SRL
ISD::SRA
ISD::READCYCLECOUNTER


<s> static HOST_WIDE_INT aarch64_simd_vector_alignment ( const_tree type ) { if ( TREE_CODE ( TYPE_SIZE ( type ) ) != INTEGER_CST ) return GET_MODE_CLASS ( TYPE_MODE ( type ) ) == MODE_VECTOR_BOOL ? 16 : 128 ; HOST_WIDE_INT align = tree_to_shwi ( TYPE_SIZE ( type ) ) ; return MIN ( align , 128 ) ; } </s>

Implement target hook TARGET_VECTOR_ALIGNMENT . The AAPCS64 sets the maximum alignment of a vector to 128 bits .


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

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


<s> bool n9_3r2w_consumed_by_ex_dep_p ( rtx_insn * consumer , rtx def_reg ) { rtx use_rtx ; switch ( get_attr_type ( consumer ) ) { case TYPE_ALU : case TYPE_PBSAD : case TYPE_MUL : use_rtx = SET_SRC ( PATTERN ( consumer ) ) ; break ; case TYPE_ALU_SHIFT : use_rtx = extract_shift_reg ( consumer ) ; break ; case TYPE_PBSADA : return pbsada_insn_ra_rb_dep_reg_p ( consumer , def_reg ) ; case TYPE_MAC : use_rtx = extract_mac_non_acc_rtx ( consumer ) ; break ; case TYPE_DIV : if ( INSN_CODE ( consumer ) == CODE_FOR_divmodsi4 || INSN_CODE ( consumer ) == CODE_FOR_udivmodsi4 ) use_rtx = SET_SRC ( parallel_element ( consumer , 0 ) ) ; else use_rtx = SET_SRC ( PATTERN ( consumer ) ) ; break ; case TYPE_MMU : if ( GET_CODE ( PATTERN ( consumer ) ) == SET ) use_rtx = SET_SRC ( PATTERN ( consumer ) ) ; else return true ; break ; case TYPE_LOAD : case TYPE_STORE : use_rtx = extract_mem_rtx ( consumer ) ; break ; case TYPE_LOAD_MULTIPLE : case TYPE_STORE_MULTIPLE : use_rtx = extract_base_reg ( consumer ) ; break ; case TYPE_BRANCH : use_rtx = PATTERN ( consumer ) ; break ; default : gcc_unreachable ( ) ; } if ( reg_overlap_p ( def_reg , use_rtx ) ) return true ; return false ; } </s>

Check the dependency between the producer defining DEF_REG and CONSUMER requiring input operand at EX .


<s> MINA32Subtarget & MINA32Subtarget :: initializeSubtargetDependencies ( StringRef CPU , StringRef FS , const TargetMachine & TM ) { ParseSubtargetFeatures ( CPU , FS ) ; return * this ; } </s>

initializeSubtargetDependencies - Initializes using a CPU , a TuneCPU , and feature string so that we can use initializer lists for subtarget initialization .


"  Preloading operand for insn %d into r%d\n"

Convert operand OP in INSN . We should handle memory operands and uninitialized registers . All other register uses are converted during registers conversion .


<s> bool aarch64_reinterpret_float_as_int ( rtx value , unsigned HOST_WIDE_INT * intval ) { if ( aarch64_float_const_zero_rtx_p ( value ) ) { * intval = 0 ; return true ; } scalar_float_mode mode ; if ( GET_CODE ( value ) != CONST_DOUBLE || ! is_a < scalar_float_mode > ( GET_MODE ( value ) , & mode ) || GET_MODE_BITSIZE ( mode ) > HOST_BITS_PER_WIDE_INT || GET_MODE_BITSIZE ( mode ) > GET_MODE_BITSIZE ( DFmode ) ) return false ; unsigned HOST_WIDE_INT ival = 0 ; long res [ 2 ] ; real_to_target ( res , CONST_DOUBLE_REAL_VALUE ( value ) , REAL_MODE_FORMAT ( mode ) ) ; if ( mode == DFmode ) { int order = BYTES_BIG_ENDIAN ? 1 : 0 ; ival = zext_hwi ( res [ order ] , 32 ) ; ival |= ( zext_hwi ( res [ 1 - order ] , 32 ) << 32 ) ; } else ival = zext_hwi ( res [ 0 ] , 32 ) ; * intval = ival ; return true ; } </s>

Return the binary representation of floating point constant VALUE in INTVAL . If the value can not be converted , return false without setting INTVAL . The conversion is done in the given MODE .


<s> SDValue AArch64SelectionDAGInfo :: EmitTargetCodeForMemcpy ( SelectionDAG & DAG , const SDLoc & DL , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , bool AlwaysInline , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { const AArch64Subtarget & STI = DAG . getMachineFunction ( ) . getSubtarget < AArch64Subtarget > ( ) ; if ( STI . hasMOPS ( ) ) return EmitMOPS ( AArch64ISD :: MOPS_MEMCOPY , DAG , DL , Chain , Dst , Src , Size , Alignment , isVolatile , DstPtrInfo , SrcPtrInfo ) ; return SDValue ( ) ; } </s>

Emit target-specific code that performs a memcpy .


<s> StringRef getPassName ( ) const override { return "AArch64PostLegalizerLowering" ; } </s>

getPassName - Return a nice clean name for a pass .


<s>
MachineBasicBlock
*
CSKYTargetLowering
::
EmitInstrWithCustomInserter
(
MachineInstr
&
MI
,
MachineBasicBlock
*
BB
)
const
{
switch
(
MI
.
getOpcode
(
)
)
{
default
:
llvm_unreachable
(
"Unexpected instr type to insert"
)
;
case
CSKY
::
ISEL32
:
return
emitSelectPseudo
(
MI
,
BB
,
CSKY
::
BT32
)
;
case
CSKY
::
ISEL16
:
return
emitSelectPseudo
(
MI
,
BB
,
CSKY
::
BT16
)
;
}
}
</s>

This method should be implemented by targets that mark instructions with the 'usesCustomInserter ' flag .


<s>
bool
FixupLEAPass
::
runOnMachineFunction
(
MachineFunction
&
Func
)
{
if
(
skipFunction
(
*
Func
.
getFunction
(
)
)
)
return
false
;
MF
=
&
Func
;
const
X86Subtarget
&
ST
=
Func
.
getSubtarget
<
X86Subtarget
>
(
)
;
OptIncDec
=
!
ST
.
slowIncDec
(
)
||
Func
.
getFunction
(
)
->
optForMinSize
(
)
;
OptLEA
=
ST
.
LEAusesAG
(
)
||
ST
.
slowLEA
(
)
;
if
(
!
OptLEA
&&
!
OptIncDec
)
return
false
;
TII
=
ST
.
getInstrInfo
(
)
;
DEBUG
(
dbgs
(
)
<<
"Start X86FixupLEAs\n"
;
)
;
for
(
MachineFunction
::
iterator
I
=
Func
.
begin
(
)
,
E
=
Func
.
end
(
)
;
I
!=
E
;
++
I
)
processBasicBlock
(
Func
,
I
)
;
DEBUG
(
dbgs
(
)
<<
"End X86FixupLEAs\n"
;
)
;
return
true
;
}
</s>

runOnMachineFunction - Emit the function body .


<s> AArch64Subtarget :: AArch64Subtarget ( const std :: string & TT , const std :: string & CPU , const std :: string & FS , const TargetMachine & TM , bool LittleEndian ) : AArch64GenSubtargetInfo ( TT , CPU , FS ) , ARMProcFamily ( Others ) , HasFPARMv8 ( false ) , HasNEON ( false ) , HasCrypto ( false ) , HasCRC ( false ) , HasZeroCycleRegMove ( false ) , HasZeroCycleZeroing ( false ) , CPUString ( CPU ) , TargetTriple ( TT ) , DL ( isTargetMachO ( ) ? "e-m:o-i64:64-i128:128-n32:64-S128" : ( LittleEndian ? "e-m:e-i64:64-i128:128-n32:64-S128" : "E-m:e-i64:64-i128:128-n32:64-S128" ) ) , FrameLowering ( ) , InstrInfo ( initializeSubtargetDependencies ( FS ) ) , TSInfo ( & DL ) , TLInfo ( TM ) { } </s>

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


<s> enum calling_abi ix86_cfun_abi ( void ) { if ( ! cfun ) return ix86_abi ; return cfun -> machine -> call_abi ; } </s>

Returns value SYSV_ABI , MS_ABI dependent on cfun , specifying the call abi used .


<s> uint64_t VESubtarget :: getAdjustedFrameSize ( uint64_t FrameSize ) const { const VEFrameLowering * TFL = getFrameLowering ( ) ; FrameSize += getRsaSize ( ) ; FrameSize = alignTo ( FrameSize , TFL -> getStackAlign ( ) ) ; return FrameSize ; } </s>

Given a actual stack size as determined by FrameInfo , this function returns adjusted framesize which includes space for RSA , return address , and frame poitner .


"CPRESTORE's operand must be an immediate."


<s> static void function_arg_record_value_1 ( tree type , HOST_WIDE_INT startbitpos , struct function_arg_record_value_parms * parms , bool packed_p ) { tree field ; if ( ! packed_p ) for ( field = TYPE_FIELDS ( type ) ; field ; field = TREE_CHAIN ( field ) ) { if ( TREE_CODE ( field ) == FIELD_DECL && DECL_PACKED ( field ) ) { packed_p = true ; break ; } } for ( field = TYPE_FIELDS ( type ) ; field ; field = TREE_CHAIN ( field ) ) { if ( TREE_CODE ( field ) == FIELD_DECL ) { HOST_WIDE_INT bitpos = startbitpos ; if ( DECL_SIZE ( field ) != 0 ) { if ( integer_zerop ( DECL_SIZE ( field ) ) ) continue ; if ( host_integerp ( bit_position ( field ) , 1 ) ) bitpos += int_bit_position ( field ) ; } if ( TREE_CODE ( TREE_TYPE ( field ) ) == RECORD_TYPE ) function_arg_record_value_1 ( TREE_TYPE ( field ) , bitpos , parms , packed_p ) ; else if ( ( FLOAT_TYPE_P ( TREE_TYPE ( field ) ) || TREE_CODE ( TREE_TYPE ( field ) ) == VECTOR_TYPE ) && TARGET_FPU && parms -> named && ! packed_p ) { if ( parms -> intoffset != - 1 ) { unsigned int startbit , endbit ; int intslots , this_slotno ; startbit = parms -> intoffset & - BITS_PER_WORD ; endbit = ( bitpos + BITS_PER_WORD - 1 ) & - BITS_PER_WORD ; intslots = ( endbit - startbit ) / BITS_PER_WORD ; this_slotno = parms -> slotno + parms -> intoffset / BITS_PER_WORD ; if ( intslots > 0 && intslots > SPARC_INT_ARG_MAX - this_slotno ) { intslots = MAX ( 0 , SPARC_INT_ARG_MAX - this_slotno ) ; parms -> stack = 1 ; } parms -> nregs += intslots ; parms -> intoffset = - 1 ; } if ( TREE_CODE ( TREE_TYPE ( field ) ) == VECTOR_TYPE && DECL_MODE ( field ) == BLKmode ) parms -> nregs += TYPE_VECTOR_SUBPARTS ( TREE_TYPE ( field ) ) ; else if ( TREE_CODE ( TREE_TYPE ( field ) ) == COMPLEX_TYPE ) parms -> nregs += 2 ; else parms -> nregs += 1 ; } else { if ( parms -> intoffset == - 1 ) parms -> intoffset = bitpos ; } } } } </s>

A subroutine of function_arg_record_value . Traverse the structure recursively and determine how many registers will be required .


<s>
void
SystemZPostRASchedStrategy
::
enterMBB
(
MachineBasicBlock
*
NextMBB
)
{
assert
(
(
SchedStates
.
find
(
NextMBB
)
==
SchedStates
.
end
(
)
)
&&
"Entering MBB twice?"
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
"** Entering "
<<
printMBBReference
(
*
NextMBB
)
)
;
MBB
=
NextMBB
;
HazardRec
=
SchedStates
[
MBB
]
=
new
SystemZHazardRecognizer
(
TII
,
&
SchedModel
)
;
LLVM_DEBUG
(
const
MachineLoop
*
Loop
=
MLI
->
getLoopFor
(
MBB
)
;
if
(
Loop
&&
Loop
->
getHeader
(
)
==
MBB
)
dbgs
(
)
<<
" (Loop header)"
;
dbgs
(
)
<<
":\n"
;
)
;
MachineBasicBlock
*
SinglePredMBB
=
getSingleSchedPred
(
MBB
,
MLI
->
getLoopFor
(
MBB
)
)
;
if
(
SinglePredMBB
==
nullptr
||
SchedStates
.
find
(
SinglePredMBB
)
==
SchedStates
.
end
(
)
)
return
;
LLVM_DEBUG
(
dbgs
(
)
<<
"** Continued scheduling from "
<<
printMBBReference
(
*
SinglePredMBB
)
<<
"\n"
;
)
;
HazardRec
->
copyState
(
SchedStates
[
SinglePredMBB
]
)
;
LLVM_DEBUG
(
HazardRec
->
dumpState
(
)
;
)
;
for
(
MachineInstr
&
MI
:
SinglePredMBB
->
terminators
(
)
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"** Emitting incoming branch: "
;
MI
.
dump
(
)
;
)
;
bool
TakenBranch
=
(
MI
.
isBranch
(
)
&&
(
TII
->
getBranchInfo
(
MI
)
.
isIndirect
(
)
||
TII
->
getBranchInfo
(
MI
)
.
getMBBTarget
(
)
==
MBB
)
)
;
HazardRec
->
emitInstruction
(
&
MI
,
TakenBranch
)
;
if
(
TakenBranch
)
break
;
}
}
</s>

Tell the strategy that MBB is about to be processed .

SystemZ
SystemZ
"Entering MBB twice?"
"** Entering "
SystemZ
" (Loop header)"
":\n"
"** Continued scheduling from "
"\n"
"** Emitting incoming branch: "


<s> bool shouldBuildRelLookupTables ( ) const { return false ; } </s>

Return true if lookup tables should be turned into relative lookup tables .


<s> bool TOYPassConfig :: addPreEmitPass ( ) { addPass ( createTOYPreEmit ( ) ) ; return true ; } </s>

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


<s> const MCRegisterInfo * getRegInfo ( ) const { return RegInfo ; } </s>

getRegInfo - Return information about the registers currently in use .


<s>
const
char
*
arm_output_shift
(
rtx
*
operands
,
int
set_flags
)
{
char
pattern
[
100
]
;
static
const
char
flag_chars
[
3
]
=
{
'?'
,
'.'
,
'!'
}
;
const
char
*
shift
;
HOST_WIDE_INT
val
;
char
c
;
c
=
flag_chars
[
set_flags
]
;
shift
=
shift_op
(
operands
[
3
]
,
&
val
)
;
if
(
shift
)
{
if
(
val
!=
1
)
operands
[
2
]
=
GEN_INT
(
val
)
;
sprintf
(
pattern
,
"%s%%%c\t%%0, %%1, %%2"
,
shift
,
c
)
;
}
else
sprintf
(
pattern
,
"mov%%%c\t%%0, %%1"
,
c
)
;
output_asm_insn
(
pattern
,
operands
)
;
return
""
;
}
</s>

Output assembly for a shift instruction . SET_FLAGS determines how the instruction modifies the condition codes . 0 - Do not set condition codes . 1 - Set condition codes . 2 - Use smallest instruction .


<s> static type_suffix_index find_type_suffix_for_scalar_type ( const_tree type ) { for ( unsigned int suffix_i = 0 ; suffix_i < NUM_TYPE_SUFFIXES ; ++ suffix_i ) if ( ! type_suffixes [ suffix_i ] . bool_p ) { vector_type_index vector_i = type_suffixes [ suffix_i ] . vector_type ; if ( matches_type_p ( scalar_types [ vector_i ] , type ) ) return type_suffix_index ( suffix_i ) ; } return NUM_TYPE_SUFFIXES ; } </s>

If TYPE is a valid SVE element type , return the corresponding type suffix , otherwise return NUM_TYPE_SUFFIXES .


<s> void DLXInstPrinter :: printRegName ( raw_ostream & OS , unsigned RegNo ) const { OS << StringRef ( getRegisterName ( RegNo ) ) . lower ( ) ; } </s>


<s> static rtx mips_unspec_call ( rtx reg , rtx symbol ) { rtvec vec ; vec = gen_rtvec ( 3 , reg , symbol , gen_rtx_REG ( SImode , GOT_VERSION_REGNUM ) ) ; return gen_rtx_UNSPEC ( Pmode , vec , UNSPEC_LOAD_CALL ) ; } </s>

Return the RHS of a load_call < mode > insn .


<s> void MipsTargetLowering :: ReplaceNodeResults ( SDNode * N , SmallVectorImpl < SDValue > & Results , SelectionDAG & DAG ) const { return LowerOperationWrapper ( N , Results , DAG ) ; } </s>

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built out of custom code .


<s> bool ARMFastISel :: fastLowerArguments ( ) { if ( ! FuncInfo . CanLowerReturn ) return false ; const Function * F = FuncInfo . Fn ; if ( F -> isVarArg ( ) ) return false ; CallingConv :: ID CC = F -> getCallingConv ( ) ; switch ( CC ) { default : return false ; case CallingConv :: Fast : case CallingConv :: C : case CallingConv :: ARM_AAPCS_VFP : case CallingConv :: ARM_AAPCS : case CallingConv :: ARM_APCS : break ; } unsigned Idx = 1 ; for ( Function :: const_arg_iterator I = F -> arg_begin ( ) , E = F -> arg_end ( ) ; I != E ; ++ I , ++ Idx ) { if ( Idx > 4 ) return false ; if ( F -> getAttributes ( ) . hasAttribute ( Idx , Attribute :: InReg ) || F -> getAttributes ( ) . hasAttribute ( Idx , Attribute :: StructRet ) || F -> getAttributes ( ) . hasAttribute ( Idx , Attribute :: ByVal ) ) return false ; Type * ArgTy = I -> getType ( ) ; if ( ArgTy -> isStructTy ( ) || ArgTy -> isArrayTy ( ) || ArgTy -> isVectorTy ( ) ) return false ; EVT ArgVT = TLI . getValueType ( DL , ArgTy ) ; if ( ! ArgVT . isSimple ( ) ) return false ; switch ( ArgVT . getSimpleVT ( ) . SimpleTy ) { case MVT :: i8 : case MVT :: i16 : case MVT :: i32 : break ; default : return false ; } } static const uint16_t GPRArgRegs [ ] = { ARM :: R0 , ARM :: R1 , ARM :: R2 , ARM :: R3 } ; const TargetRegisterClass * RC = & ARM :: rGPRRegClass ; Idx = 0 ; for ( Function :: const_arg_iterator I = F -> arg_begin ( ) , E = F -> arg_end ( ) ; I != E ; ++ I , ++ Idx ) { unsigned SrcReg = GPRArgRegs [ Idx ] ; unsigned DstReg = FuncInfo . MF -> addLiveIn ( SrcReg , RC ) ; unsigned ResultReg = createResultReg ( RC ) ; BuildMI ( * FuncInfo . MBB , FuncInfo . InsertPt , DbgLoc , TII . get ( TargetOpcode :: COPY ) , ResultReg ) . addReg ( DstReg , getKillRegState ( true ) ) ; updateValueMap ( & * I , ResultReg ) ; } return true ; } </s>

This method is called by target-independent code to do target- specific argument lowering .


<s> static bool hasReassociableSibling ( const MachineInstr & Inst , bool & Commuted ) { const MachineBasicBlock * MBB = Inst . getParent ( ) ; const MachineRegisterInfo & MRI = MBB -> getParent ( ) -> getRegInfo ( ) ; MachineInstr * MI1 = MRI . getUniqueVRegDef ( Inst . getOperand ( 1 ) . getReg ( ) ) ; MachineInstr * MI2 = MRI . getUniqueVRegDef ( Inst . getOperand ( 2 ) . getReg ( ) ) ; unsigned AssocOpcode = Inst . getOpcode ( ) ; Commuted = MI1 -> getOpcode ( ) != AssocOpcode && MI2 -> getOpcode ( ) == AssocOpcode ; if ( Commuted ) std :: swap ( MI1 , MI2 ) ; if ( MI1 -> getOpcode ( ) == AssocOpcode && hasReassociableOperands ( * MI1 , MBB ) && MRI . hasOneNonDBGUse ( MI1 -> getOperand ( 0 ) . getReg ( ) ) ) return true ; return false ; } </s>

Return true when \P Inst has reassociable sibling .


<s> const TargetRegisterClass * X86RegisterInfo :: getMatchingSuperRegClass ( const TargetRegisterClass * A , const TargetRegisterClass * B , unsigned SubIdx ) const { if ( ! Is64Bit && SubIdx == X86 :: sub_8bit ) { A = X86GenRegisterInfo :: getSubClassWithSubReg ( A , X86 :: sub_8bit_hi ) ; if ( ! A ) return nullptr ; } return X86GenRegisterInfo :: getMatchingSuperRegClass ( A , B , SubIdx ) ; } </s>

getMatchingSuperRegClass - Return a subclass of the specified register class A so that each register in it has a sub-register of the specified sub-register index which is in the specified register class B .


"without AVX512F enabled changes the ABI"

Return the `` natural '' mode for TYPE . In most cases , this is just TYPE_MODE . But in the case of vector types , it is some vector mode . When we have only some of our vector isa extensions enabled , then there are some modes for which vector_mode_supported_p is false . For these modes , the generic vector support in gcc will choose some non-vector mode in order to implement the type . By computing the natural mode , we 'll select the proper ABI location for the operand and not depend on whatever the middle-end decides to do with these vector types .


<s>
static
void
write_type_node
(
char
*
tok
,
bool
indent
)
{
if
(
indent
)
fprintf
(
init_file
,
"  "
)
;
typemap
*
entry
=
(
typemap
*
)
bsearch
(
tok
,
type_map
,
sizeof
type_map
/
sizeof
type_map
[
0
]
,
sizeof
(
typemap
)
,
typemap_cmp
)
;
if
(
!
entry
)
fatal
(
"Type map is inconsistent."
)
;
fprintf
(
init_file
,
"%s_type_node"
,
entry
->
value
)
;
}
</s>

Write the type node corresponding to TOK .


<s> static bool arm_can_change_mode_class ( machine_mode from , machine_mode to , reg_class_t rclass ) { if ( TARGET_BIG_END && ! ( GET_MODE_SIZE ( from ) == 16 && GET_MODE_SIZE ( to ) == 8 ) && ( GET_MODE_SIZE ( from ) > UNITS_PER_WORD || GET_MODE_SIZE ( to ) > UNITS_PER_WORD ) && reg_classes_intersect_p ( VFP_REGS , rclass ) ) return false ; return true ; } </s>

Implement TARGET_CAN_CHANGE_MODE_CLASS . In VFPv1 , VFP registers could only be accessed in the mode they were set , so subregs would be invalid there . However , we do n't support VFPv1 at the moment , and the restriction was lifted in VFPv2 . In big-endian mode , modes greater than word size ( i.e . DFmode ) are stored in VFP registers in little-endian order . We ca n't describe that accurately to GCC , so avoid taking subregs of such values . The only exception is going from a 128-bit to a 64-bit type . In that case the data layout happens to be consistent for big-endian , so we explicitly allow that case .


<s> int mips_register_move_cost ( enum machine_mode mode ATTRIBUTE_UNUSED , enum reg_class to , enum reg_class from ) { if ( from == M16_REGS && GR_REG_CLASS_P ( to ) ) return 2 ; else if ( from == M16_NA_REGS && GR_REG_CLASS_P ( to ) ) return 2 ; else if ( GR_REG_CLASS_P ( from ) ) { if ( to == M16_REGS ) return 2 ; else if ( to == M16_NA_REGS ) return 2 ; else if ( GR_REG_CLASS_P ( to ) ) { if ( TARGET_MIPS16 ) return 4 ; else return 2 ; } else if ( to == FP_REGS ) return 4 ; else if ( reg_class_subset_p ( to , ACC_REGS ) ) { if ( TARGET_MIPS16 ) return 12 ; else return 6 ; } else if ( COP_REG_CLASS_P ( to ) ) { return 5 ; } } else if ( from == FP_REGS ) { if ( GR_REG_CLASS_P ( to ) ) return 4 ; else if ( to == FP_REGS ) return 2 ; else if ( to == ST_REGS ) return 8 ; } else if ( reg_class_subset_p ( from , ACC_REGS ) ) { if ( GR_REG_CLASS_P ( to ) ) { if ( TARGET_MIPS16 ) return 12 ; else return 6 ; } } else if ( from == ST_REGS && GR_REG_CLASS_P ( to ) ) return 4 ; else if ( COP_REG_CLASS_P ( from ) ) { return 5 ; } return 12 ; } </s>

Implement TARGET_REGISTER_MOVE_COST . Return 0 for classes that are the maximum of the move costs for subclasses ; regclass will work out the maximum for us .


<s> void ia64_expand_call ( rtx retval , rtx addr , rtx nextarg ATTRIBUTE_UNUSED , int sibcall_p ) { rtx insn , b0 ; addr = XEXP ( addr , 0 ) ; addr = convert_memory_address ( DImode , addr ) ; b0 = gen_rtx_REG ( DImode , R_BR ( 0 ) ) ; if ( TARGET_NO_PIC || TARGET_AUTO_PIC ) { if ( sibcall_p ) insn = gen_sibcall_nogp ( addr ) ; else if ( ! retval ) insn = gen_call_nogp ( addr , b0 ) ; else insn = gen_call_value_nogp ( retval , addr , b0 ) ; insn = emit_call_insn ( insn ) ; } else { if ( sibcall_p ) insn = gen_sibcall_gp ( addr ) ; else if ( ! retval ) insn = gen_call_gp ( addr , b0 ) ; else insn = gen_call_value_gp ( retval , addr , b0 ) ; insn = emit_call_insn ( insn ) ; use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , pic_offset_table_rtx ) ; } if ( sibcall_p ) use_reg ( & CALL_INSN_FUNCTION_USAGE ( insn ) , b0 ) ; } </s>

Emit the appropriate sequence for a call .


<s> static bool ix86_compat_aligned_value_p ( const_tree type ) { machine_mode mode = TYPE_MODE ( type ) ; if ( ( ( TARGET_SSE && SSE_REG_MODE_P ( mode ) ) || mode == TDmode || mode == TFmode || mode == TCmode ) && ( ! TYPE_USER_ALIGN ( type ) || TYPE_ALIGN ( type ) > 128 ) ) return true ; if ( TYPE_ALIGN ( type ) < 128 ) return false ; if ( AGGREGATE_TYPE_P ( type ) ) { switch ( TREE_CODE ( type ) ) { case RECORD_TYPE : case UNION_TYPE : case QUAL_UNION_TYPE : { tree field ; for ( field = TYPE_FIELDS ( type ) ; field ; field = DECL_CHAIN ( field ) ) { if ( TREE_CODE ( field ) == FIELD_DECL && ix86_compat_aligned_value_p ( TREE_TYPE ( field ) ) ) return true ; } break ; } case ARRAY_TYPE : if ( ix86_compat_aligned_value_p ( TREE_TYPE ( type ) ) ) return true ; break ; default : gcc_unreachable ( ) ; } } return false ; } </s>

Return true when TYPE should be 128bit aligned for 32bit argument passing ABI . XXX : This function is obsolete and is only used for checking psABI compatibility with previous versions of GCC .


<s> const MipsSubtarget * MipsTargetMachine :: getSubtargetImpl ( const Function & F ) const { Attribute CPUAttr = F . getFnAttribute ( "target-cpu" ) ; Attribute FSAttr = F . getFnAttribute ( "target-features" ) ; std :: string CPU = ! CPUAttr . hasAttribute ( Attribute :: None ) ? CPUAttr . getValueAsString ( ) . str ( ) : TargetCPU ; std :: string FS = ! FSAttr . hasAttribute ( Attribute :: None ) ? FSAttr . getValueAsString ( ) . str ( ) : TargetFS ; bool hasMips16Attr = ! F . getFnAttribute ( "mips16" ) . hasAttribute ( Attribute :: None ) ; bool hasNoMips16Attr = ! F . getFnAttribute ( "nomips16" ) . hasAttribute ( Attribute :: None ) ; bool softFloat = F . hasFnAttribute ( "use-soft-float" ) && F . getFnAttribute ( "use-soft-float" ) . getValueAsString ( ) == "true" ; if ( hasMips16Attr ) FS += FS . empty ( ) ? "+mips16" : ",+mips16" ; else if ( hasNoMips16Attr ) FS += FS . empty ( ) ? "-mips16" : ",-mips16" ; if ( softFloat ) FS += FS . empty ( ) ? "+soft-float" : ",+soft-float" ; auto & I = SubtargetMap [ CPU + FS ] ; if ( ! I ) { resetTargetOptions ( F ) ; I = llvm :: make_unique < MipsSubtarget > ( TargetTriple , CPU , FS , isLittle , * this ) ; } return I . get ( ) ; } </s>

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

Mips Mips Mips "target-cpu" "target-features" Mips "mips16" Mips "nomips16" "use-soft-float" "use-soft-float" "true" Mips "+mips16" ",+mips16" Mips "-mips16" ",-mips16" "+soft-float" ",+soft-float" Mips


<s> bool sh_split_movrt_negc_to_movt_xor ( rtx_insn * curr_insn , rtx operands [ ] ) { if ( ! can_create_pseudo_p ( ) ) return false ; set_of_reg t_before_negc = sh_find_set_of_reg ( get_t_reg_rtx ( ) , curr_insn , prev_nonnote_nondebug_insn_bb ) ; set_of_reg t_after_negc = sh_find_set_of_reg ( get_t_reg_rtx ( ) , curr_insn , next_nonnote_nondebug_insn_bb ) ; if ( t_before_negc . set_rtx != NULL_RTX && t_after_negc . set_rtx != NULL_RTX && rtx_equal_p ( t_before_negc . set_rtx , t_after_negc . set_rtx ) && ! reg_used_between_p ( get_t_reg_rtx ( ) , curr_insn , t_after_negc . insn ) && ! sh_insn_operands_modified_between_p ( t_before_negc . insn , t_before_negc . insn , t_after_negc . insn ) && ! modified_between_p ( get_t_reg_rtx ( ) , curr_insn , t_after_negc . insn ) && ! sh_unspec_insn_p ( t_after_negc . insn ) && ! volatile_insn_p ( PATTERN ( t_after_negc . insn ) ) && ! side_effects_p ( PATTERN ( t_after_negc . insn ) ) && ! may_trap_or_fault_p ( PATTERN ( t_after_negc . insn ) ) ) { emit_insn ( gen_movrt_xor ( operands [ 0 ] , get_t_reg_rtx ( ) ) ) ; set_insn_deleted ( t_after_negc . insn ) ; return true ; } else return false ; } </s>

Given the current insn , which is assumed to be a movrt_negc insn , try to figure out whether it should be converted into a movt-xor sequence in the movrt_negc splitter . Returns true if insns have been modified and the splitter has succeeded .


"64-bit code requested on a subtarget that doesn't support it!"

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


<s> void sparc_split_reg_mem ( rtx dest , rtx src , machine_mode mode ) { rtx high_part = gen_highpart ( mode , dest ) ; rtx low_part = gen_lowpart ( mode , dest ) ; rtx word0 = adjust_address ( src , mode , 0 ) ; rtx word1 = adjust_address ( src , mode , 4 ) ; if ( reg_overlap_mentioned_p ( high_part , word1 ) ) { emit_move_insn_1 ( low_part , word1 ) ; emit_move_insn_1 ( high_part , word0 ) ; } else { emit_move_insn_1 ( high_part , word0 ) ; emit_move_insn_1 ( low_part , word1 ) ; } } </s>

Split a REG < -- MEM move into a pair of moves in MODE .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


This is just a placeholder to make linking work without having to add this to the generic Darwin EXTRA_SECTIONS . If -mcall-aix is ever needed for Darwin ( not too likely ! ) this would have to get a real definition .


<s> static bool sh_use_by_pieces_infrastructure_p ( unsigned HOST_WIDE_INT size , unsigned int align , enum by_pieces_operation op , bool speed_p ) { switch ( op ) { case MOVE_BY_PIECES : return by_pieces_ninsns ( size , align , MOVE_MAX_PIECES + 1 , op ) < ( ! speed_p ? 2 : ( align >= 32 ) ? 16 : 2 ) ; case STORE_BY_PIECES : case SET_BY_PIECES : return by_pieces_ninsns ( size , align , STORE_MAX_PIECES + 1 , op ) < ( ! speed_p ? 2 : ( align >= 32 ) ? 16 : 2 ) ; default : return default_use_by_pieces_infrastructure_p ( size , align , op , speed_p ) ; } } </s>


<s> bool DLXMemAluCombiner :: runOnMachineFunction ( MachineFunction & MF ) { if ( DisableMemAluCombiner ) return false ; TII = MF . getSubtarget < DLXSubtarget > ( ) . getInstrInfo ( ) ; bool Modified = false ; for ( MfIterator MFI = MF . begin ( ) ; MFI != MF . end ( ) ; ++ MFI ) { Modified |= combineMemAluInBasicBlock ( & * MFI ) ; } return Modified ; } </s>

runOnMachineFunction - Emit the function body .


"Instr doesn't have FrameIndex operand!"

Determine whether a given base register plus offset immediate is encodable to resolve a frame index .


"CFProtection used on invalid architecture!"

This virtual method can be overridden by targets that want to emit something at the start of their file .


<s> static unsigned int aarch64_add_offset_1_temporaries ( HOST_WIDE_INT offset ) { return abs_hwi ( offset ) < 0x1000000 ? 0 : 1 ; } </s>

Return the number of temporary registers that aarch64_add_offset_1 would need to add OFFSET to a register .


<s> int mmix_reversible_cc_mode ( machine_mode mode ) { return mode != CC_FPmode ; } </s>


<s> static bool aarch64_vector_data_mode_p ( machine_mode mode ) { return aarch64_classify_vector_mode ( mode ) & VEC_ANY_DATA ; } </s>

Return true if MODE is any of the data vector modes , including structure modes .


<s> ScheduleDAGInstrs * createMachineScheduler ( MachineSchedContext * C ) const override { ScheduleDAGMILive * DAG = createGenericSchedLive ( C ) ; DAG -> addMutation ( createMacroFusionDAGMutation ( DAG -> TII ) ) ; return DAG ; } </s>

Create an instance of ScheduleDAGInstrs to be run within the standard MachineScheduler pass for this function and target at the current optimization level .


<s> void ARMPassConfig :: addPreEmitPass ( ) { addPass ( createThumb2SizeReductionPass ( ) ) ; addPass ( createUnpackMachineBundles ( [ this ] ( const Function & F ) { return this -> TM -> getSubtarget < ARMSubtarget > ( F ) . isThumb2 ( ) ; } ) ) ; if ( getOptLevel ( ) != CodeGenOpt :: None ) addPass ( createARMOptimizeBarriersPass ( ) ) ; addPass ( createARMConstantIslandPass ( ) ) ; } </s>

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


<s> bool X86TargetLowering :: isLegalAddressingMode ( const DataLayout & DL , const AddrMode & AM , Type * Ty , unsigned AS , Instruction * I ) const { CodeModel :: Model M = getTargetMachine ( ) . getCodeModel ( ) ; if ( ! X86 :: isOffsetSuitableForCodeModel ( AM . BaseOffs , M , AM . BaseGV != nullptr ) ) return false ; if ( AM . BaseGV ) { unsigned GVFlags = Subtarget . classifyGlobalReference ( AM . BaseGV ) ; if ( isGlobalStubReference ( GVFlags ) ) return false ; if ( AM . HasBaseReg && isGlobalRelativeToPICBase ( GVFlags ) ) return false ; if ( ( M != CodeModel :: Small || isPositionIndependent ( ) ) && Subtarget . is64Bit ( ) && ( AM . BaseOffs || AM . Scale > 1 ) ) return false ; } switch ( AM . Scale ) { case 0 : case 1 : case 2 : case 4 : case 8 : break ; case 3 : case 5 : case 9 : if ( AM . HasBaseReg ) return false ; break ; default : return false ; } return true ; } </s>

isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target , for a load/store of the specified type .


<s> void MipsPreLegalizerCombiner :: getAnalysisUsage ( AnalysisUsage & AU ) const { AU . addRequired < TargetPassConfig > ( ) ; AU . setPreservesCFG ( ) ; getSelectionDAGFallbackAnalysisUsage ( AU ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>


<s> unsigned aarch64_dbx_register_number ( unsigned regno ) { if ( GP_REGNUM_P ( regno ) ) return AARCH64_DWARF_R0 + regno - R0_REGNUM ; else if ( regno == SP_REGNUM ) return AARCH64_DWARF_SP ; else if ( FP_REGNUM_P ( regno ) ) return AARCH64_DWARF_V0 + regno - V0_REGNUM ; return DWARF_FRAME_REGISTERS ; } </s>

Provide a mapping from gcc register numbers to dwarf register numbers .


<s> bool X86InstrInfo :: canInsertSelect ( const MachineBasicBlock & MBB , const SmallVectorImpl < MachineOperand > & Cond , unsigned TrueReg , unsigned FalseReg , int & CondCycles , int & TrueCycles , int & FalseCycles ) const { if ( ! TM . getSubtarget < X86Subtarget > ( ) . hasCMov ( ) ) return false ; if ( Cond . size ( ) != 1 ) return false ; if ( ( X86 :: CondCode ) Cond [ 0 ] . getImm ( ) > X86 :: COND_S ) return false ; const MachineRegisterInfo & MRI = MBB . getParent ( ) -> getRegInfo ( ) ; const TargetRegisterClass * RC = RI . getCommonSubClass ( MRI . getRegClass ( TrueReg ) , MRI . getRegClass ( FalseReg ) ) ; if ( ! RC ) return false ; if ( X86 :: GR16RegClass . hasSubClassEq ( RC ) || X86 :: GR32RegClass . hasSubClassEq ( RC ) || X86 :: GR64RegClass . hasSubClassEq ( RC ) ) { CondCycles = 2 ; TrueCycles = 2 ; FalseCycles = 2 ; return true ; } return false ; } </s>

Return true if it is possible to insert a select instruction that chooses between TrueReg and FalseReg based on the condition code in Cond .


<s> unsigned MipsAsmParser :: checkTargetMatchPredicate ( MCInst & Inst ) { switch ( Inst . getOpcode ( ) ) { case Mips :: JALR_HB : case Mips :: JALRC_HB_MMR6 : case Mips :: JALRC_MMR6 : if ( Inst . getOperand ( 0 ) . getReg ( ) == Inst . getOperand ( 1 ) . getReg ( ) ) return Match_RequiresDifferentSrcAndDst ; return Match_Success ; case Mips :: LWP_MM : case Mips :: LWP_MMR6 : if ( Inst . getOperand ( 0 ) . getReg ( ) == Inst . getOperand ( 2 ) . getReg ( ) ) return Match_RequiresDifferentSrcAndDst ; return Match_Success ; case Mips :: BLEZC : case Mips :: BGEZC : case Mips :: BGTZC : case Mips :: BLTZC : case Mips :: BEQZC : case Mips :: BNEZC : if ( Inst . getOperand ( 0 ) . getReg ( ) == Mips :: ZERO ) return Match_RequiresNoZeroRegister ; return Match_Success ; case Mips :: BGEC : case Mips :: BLTC : case Mips :: BGEUC : case Mips :: BLTUC : case Mips :: BEQC : case Mips :: BNEC : if ( Inst . getOperand ( 0 ) . getReg ( ) == Mips :: ZERO ) return Match_RequiresNoZeroRegister ; if ( Inst . getOperand ( 1 ) . getReg ( ) == Mips :: ZERO ) return Match_RequiresNoZeroRegister ; if ( Inst . getOperand ( 0 ) . getReg ( ) == Inst . getOperand ( 1 ) . getReg ( ) ) return Match_RequiresDifferentOperands ; return Match_Success ; default : return Match_Success ; } } </s>

checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not expressible via match classes .


"calling %qD with SSE calling convention without "

"this is a GCC bug that can be worked around by adding "

Define how to find the value returned by a function . VALTYPE is the data type of the value ( as a tree ) . If the precise function being called is known , FUNC is its FUNCTION_DECL ; otherwise , FUNC is 0 .


<s> virtual const Cpu0InstrInfo * getInstrInfo ( ) const { return & InstrInfo ; } </s>


<s> bool AArch64TTIImpl :: shouldConsiderAddressTypePromotion ( const Instruction & I , bool & AllowPromotionWithoutCommonHeader ) { bool Considerable = false ; AllowPromotionWithoutCommonHeader = false ; if ( ! isa < SExtInst > ( & I ) ) return false ; Type * ConsideredSExtType = Type :: getInt64Ty ( I . getParent ( ) -> getParent ( ) -> getContext ( ) ) ; if ( I . getType ( ) != ConsideredSExtType ) return false ; for ( const User * U : I . users ( ) ) { if ( const GetElementPtrInst * GEPInst = dyn_cast < GetElementPtrInst > ( U ) ) { Considerable = true ; if ( GEPInst -> getNumOperands ( ) > 2 ) { AllowPromotionWithoutCommonHeader = true ; break ; } } } return Considerable ; } </s>

See if I should be considered for address type promotion .


<s> unsigned CSKYAsmParser :: validateTargetOperandClass ( MCParsedAsmOperand & AsmOp , unsigned Kind ) { CSKYOperand & Op = static_cast < CSKYOperand & > ( AsmOp ) ; if ( ! Op . isReg ( ) ) return Match_InvalidOperand ; MCRegister Reg = Op . getReg ( ) ; if ( CSKYMCRegisterClasses [ CSKY :: FPR32RegClassID ] . contains ( Reg ) ) { if ( Kind == MCK_FPR64 || Kind == MCK_sFPR64_V ) { Op . Reg . RegNum = convertFPR32ToFPR64 ( Reg ) ; if ( Kind == MCK_sFPR64_V && ( Op . Reg . RegNum < CSKY :: F0_64 || Op . Reg . RegNum > CSKY :: F15_64 ) ) return Match_InvalidRegOutOfRange ; if ( Kind == MCK_FPR64 && ( Op . Reg . RegNum < CSKY :: F0_64 || Op . Reg . RegNum > CSKY :: F31_64 ) ) return Match_InvalidRegOutOfRange ; return Match_Success ; } } if ( CSKYMCRegisterClasses [ CSKY :: GPRRegClassID ] . contains ( Reg ) ) { if ( Kind == MCK_GPRPair ) { Op . Reg . RegNum = MRI -> getEncodingValue ( Reg ) + CSKY :: R0_R1 ; return Match_Success ; } } return Match_InvalidOperand ; } </s>

Allow a target to add special case operand matching for things that tblgen doesn't/ca n't handle effectively .


<s> MachineBasicBlock :: iterator X86FrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { bool reserveCallFrame = hasReservedCallFrame ( MF ) ; unsigned Opcode = I -> getOpcode ( ) ; bool isDestroy = Opcode == TII . getCallFrameDestroyOpcode ( ) ; DebugLoc DL = I -> getDebugLoc ( ) ; uint64_t Amount = ! reserveCallFrame ? TII . getFrameSize ( * I ) : 0 ; uint64_t InternalAmt = ( isDestroy || Amount ) ? TII . getFrameAdjustment ( * I ) : 0 ; I = MBB . erase ( I ) ; auto InsertPos = skipDebugInstructionsForward ( I , MBB . end ( ) ) ; if ( ! reserveCallFrame ) { unsigned StackAlign = getStackAlignment ( ) ; Amount = alignTo ( Amount , StackAlign ) ; MachineModuleInfo & MMI = MF . getMMI ( ) ; const Function & F = MF . getFunction ( ) ; bool WindowsCFI = MF . getTarget ( ) . getMCAsmInfo ( ) -> usesWindowsCFI ( ) ; bool DwarfCFI = ! WindowsCFI && ( MMI . hasDebugInfo ( ) || F . needsUnwindTableEntry ( ) ) ; bool HasDwarfEHHandlers = ! WindowsCFI && ! MF . getLandingPads ( ) . empty ( ) ; if ( HasDwarfEHHandlers && ! isDestroy && MF . getInfo < X86MachineFunctionInfo > ( ) -> getHasPushSequences ( ) ) BuildCFI ( MBB , InsertPos , DL , MCCFIInstruction :: createGnuArgsSize ( nullptr , Amount ) ) ; if ( Amount == 0 ) return I ; Amount -= InternalAmt ; if ( isDestroy && InternalAmt && DwarfCFI && ! hasFP ( MF ) ) BuildCFI ( MBB , InsertPos , DL , MCCFIInstruction :: createAdjustCfaOffset ( nullptr , - InternalAmt ) ) ; int64_t StackAdjustment = isDestroy ? Amount : - Amount ; if ( StackAdjustment ) { StackAdjustment += mergeSPUpdates ( MBB , InsertPos , true ) ; StackAdjustment += mergeSPUpdates ( MBB , InsertPos , false ) ; if ( StackAdjustment ) { if ( ! ( F . hasMinSize ( ) && adjustStackWithPops ( MBB , InsertPos , DL , StackAdjustment ) ) ) BuildStackAdjustment ( MBB , InsertPos , DL , StackAdjustment , false ) ; } } if ( DwarfCFI && ! hasFP ( MF ) ) { int64_t CfaAdjustment = - StackAdjustment ; if ( CfaAdjustment ) { BuildCFI ( MBB , InsertPos , DL , MCCFIInstruction :: createAdjustCfaOffset ( nullptr , CfaAdjustment ) ) ; } } return I ; } if ( isDestroy && InternalAmt ) { MachineBasicBlock :: iterator CI = I ; MachineBasicBlock :: iterator B = MBB . begin ( ) ; while ( CI != B && ! std :: prev ( CI ) -> isCall ( ) ) -- CI ; BuildStackAdjustment ( MBB , CI , DL , - InternalAmt , false ) ; } return I ; } </s>

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy pseudo instructions ( but only if the Target is using them ) .


<s> bool PPCInstrInfo :: getMachineCombinerPatterns ( MachineInstr & Root , SmallVectorImpl < MachineCombinerPattern > & Patterns ) const { if ( Subtarget . getTargetMachine ( ) . getOptLevel ( ) != CodeGenOpt :: Aggressive ) return false ; if ( getFMAPatterns ( Root , Patterns ) ) return true ; return TargetInstrInfo :: getMachineCombinerPatterns ( Root , Patterns ) ; } </s>

Return true when there is potentially a faster code sequence for an instruction chain ending in Root .


<s> void AnalyzeReturn ( const SmallVectorImpl < ISD :: OutputArg > & Outs , CCAssignFn Fn ) { PreAnalyzeReturnForF128 ( Outs ) ; PreAnalyzeReturnForVectorFloat ( Outs ) ; CCState :: AnalyzeReturn ( Outs , Fn ) ; OriginalArgWasFloat . clear ( ) ; OriginalArgWasF128 . clear ( ) ; OriginalArgWasFloatVector . clear ( ) ; } </s>

AnalyzeReturn - Analyze the returned values of a return , incorporating info about the result values into this state .


<s> unsigned char X86Subtarget :: classifyGlobalFunctionReference ( const GlobalValue * GV , const Module & M ) const { if ( TM . shouldAssumeDSOLocal ( M , GV ) ) return X86II :: MO_NO_FLAG ; if ( isTargetCOFF ( ) ) { if ( ! GV ) return X86II :: MO_NO_FLAG ; if ( GV -> hasDLLImportStorageClass ( ) ) return X86II :: MO_DLLIMPORT ; return X86II :: MO_COFFSTUB ; } const Function * F = dyn_cast_or_null < Function > ( GV ) ; if ( isTargetELF ( ) ) { if ( is64Bit ( ) && F && ( CallingConv :: X86_RegCall == F -> getCallingConv ( ) ) ) return X86II :: MO_GOTPCREL ; if ( ( ( F && F -> hasFnAttribute ( Attribute :: NonLazyBind ) ) || ( ! F && M . getRtLibUseGOT ( ) ) ) && is64Bit ( ) ) return X86II :: MO_GOTPCREL ; if ( ! is64Bit ( ) && ! GV && TM . getRelocationModel ( ) == Reloc :: Static ) return X86II :: MO_NO_FLAG ; return X86II :: MO_PLT ; } if ( is64Bit ( ) ) { if ( F && F -> hasFnAttribute ( Attribute :: NonLazyBind ) ) return X86II :: MO_GOTPCREL ; return X86II :: MO_NO_FLAG ; } return X86II :: MO_NO_FLAG ; } </s>

Classify a global function reference for the current subtarget .


"Constant Island pass failed to converge!"

"Branch Fix Up pass failed to converge!"

runOnMachineFunction - Emit the function body .


<s> void xstormy16_expand_epilogue ( ) { struct xstormy16_stack_layout layout ; rtx mem_pop_rtx ; int regno ; const int ifun = xstormy16_interrupt_function_p ( ) ; mem_pop_rtx = gen_rtx_PRE_DEC ( Pmode , stack_pointer_rtx ) ; mem_pop_rtx = gen_rtx_MEM ( HImode , mem_pop_rtx ) ; layout = xstormy16_compute_stack_layout ( ) ; if ( layout . locals_size ) { if ( frame_pointer_needed && layout . sp_minus_fp == layout . locals_size ) emit_move_insn ( stack_pointer_rtx , hard_frame_pointer_rtx ) ; else emit_addhi3_postreload ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - layout . locals_size ) ) ; } for ( regno = FIRST_PSEUDO_REGISTER - 1 ; regno >= 0 ; regno -- ) if ( REG_NEEDS_SAVE ( regno , ifun ) ) emit_move_insn ( gen_rtx_REG ( HImode , regno ) , mem_pop_rtx ) ; if ( layout . stdarg_save_size ) emit_addhi3_postreload ( stack_pointer_rtx , stack_pointer_rtx , GEN_INT ( - layout . stdarg_save_size ) ) ; if ( ifun ) emit_jump_insn ( gen_return_internal_interrupt ( ) ) ; else emit_jump_insn ( gen_return_internal ( ) ) ; } </s>

Called after register allocation to add any instructions needed for the epilogue . Using an epilogue insn is favored compared to putting all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro , since it allows the scheduler to intermix instructions with the saves of the caller saved registers . In some cases , it might be necessary to emit a barrier instruction as the last insn to prevent such scheduling .


<s> bool ARMTargetLowering :: isFMAFasterThanFMulAndFAdd ( const MachineFunction & MF , EVT VT ) const { if ( ! Subtarget -> hasMVEFloatOps ( ) ) return false ; if ( ! VT . isSimple ( ) ) return false ; switch ( VT . getSimpleVT ( ) . SimpleTy ) { case MVT :: v4f32 : case MVT :: v8f16 : return true ; default : break ; } return false ; } </s>

Return true if an FMA operation is faster than a pair of fmul and fadd instructions .


<s> void AArch64AsmPrinter :: EmitInstruction ( const MachineInstr * MI ) { if ( emitPseudoExpansionLowering ( OutStreamer , MI ) ) return ; switch ( MI -> getOpcode ( ) ) { case AArch64 :: DBG_VALUE : { if ( isVerbose ( ) && OutStreamer . hasRawTextSupport ( ) ) { SmallString < 128 > TmpStr ; raw_svector_ostream OS ( TmpStr ) ; PrintDebugValueComment ( MI , OS ) ; OutStreamer . EmitRawText ( StringRef ( OS . str ( ) ) ) ; } return ; } } MCInst TmpInst ; LowerAArch64MachineInstrToMCInst ( MI , TmpInst , * this ) ; OutStreamer . EmitInstruction ( TmpInst ) ; } </s>

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