<s> ProgInfo . NumSGPR = std :: max ( ProgInfo . NumSGPR , WaveDispatchNumSGPR ) ; ProgInfo . NumVGPR = std :: max ( ProgInfo . NumVGPR , WaveDispatchNumVGPR ) ; ProgInfo . NumSGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumSGPR , <NUM_LIT> ) , STM . getMinNumSGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; ProgInfo . NumVGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumVGPR , <NUM_LIT> ) , STM . getMinNumVGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; if ( STM . getGeneration ( ) <= <ISA_LIT>Subtarget :: SEA_ISLANDS || STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , DS_Error , DK_ResourceLimit , MaxAddressableNumSGPRs ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs ; ProgInfo . NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs ; } } if ( STM . hasSGPRInitBug ( ) ) { ProgInfo . NumSGPR = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; ProgInfo . NumSGPRsForWavesPerEU = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; } if ( MFI -> getNumUserSGPRs ( ) > STM . getMaxNumUserSGPRs ( ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getNumUserSGPRs ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } if ( MFI -> getLDSSize ( ) > static_cast < unsigned > ( STM . getLocalMemorySize ( ) ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getLDSSize ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } ProgInfo . SGPRBlocks = IsaInfo :: getNumSGPRBlocks ( & STM , ProgInfo . NumSGPRsForWavesPerEU ) ; ProgInfo . VGPRBlocks = IsaInfo :: getNumVGPRBlocks ( & STM , ProgInfo . NumVGPRsForWavesPerEU ) ; const <ISA_LIT>ModeRegisterDefaults Mode = MFI -> getMode ( ) ; ProgInfo . FloatMode = getFPMode ( Mode ) ; ProgInfo . IEEEMode = Mode . IEEE ; ProgInfo . DX10Clamp = Mode . DX10Clamp ; unsigned LDSAlignShift ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: SEA_ISLANDS ) { LDSAlignShift = <NUM_LIT> ; } else { LDSAlignShift = <NUM_LIT> ; } unsigned LDSSpillSize = MFI -> getLDSWaveSpillSize ( ) * MFI -> getMaxFlatWorkGroupSize ( ) ; ProgInfo . LDSSize = MFI -> getLDSSize ( ) + LDSSpillSize ; ProgInfo . LDSBlocks = alignTo ( ProgInfo . LDSSize , <NUM_LIT> << LDSAlignShift ) >> LDSAlignShift ; unsigned ScratchAlignShift = <NUM_LIT> ;

ProgInfo . ScratchBlocks = alignTo ( ProgInfo . ScratchSize * STM . getWavefrontSize ( ) , <NUM_LIT> << ScratchAlignShift ) >> ScratchAlignShift ;


<s> ProgInfo . IEEEMode = Mode . IEEE ; ProgInfo . DX10Clamp = Mode . DX10Clamp ; unsigned LDSAlignShift ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: SEA_ISLANDS ) { LDSAlignShift = <NUM_LIT> ; } else { LDSAlignShift = <NUM_LIT> ; } unsigned LDSSpillSize = MFI -> getLDSWaveSpillSize ( ) * MFI -> getMaxFlatWorkGroupSize ( ) ; ProgInfo . LDSSize = MFI -> getLDSSize ( ) + LDSSpillSize ; ProgInfo . LDSBlocks = alignTo ( ProgInfo . LDSSize , <NUM_LIT> << LDSAlignShift ) >> LDSAlignShift ; unsigned ScratchAlignShift = <NUM_LIT> ; ProgInfo . ScratchBlocks = alignTo ( ProgInfo . ScratchSize * STM . getWavefrontSize ( ) , <NUM_LIT> << ScratchAlignShift ) >> ScratchAlignShift ; if ( getIsaVersion ( getGlobalSTI ( ) -> getCPU ( ) ) . Major >= <NUM_LIT> ) { ProgInfo . WgpMode = STM . isCuModeEnabled ( ) ? <NUM_LIT> : <NUM_LIT> ; ProgInfo . MemOrdered = <NUM_LIT> ; } ProgInfo . ComputePGMRSrc1 = S_00B848_VGPRS ( ProgInfo . VGPRBlocks ) | S_00B848_SGPRS ( ProgInfo . SGPRBlocks ) | S_00B848_PRIORITY ( ProgInfo . Priority ) | S_00B848_FLOAT_MODE ( ProgInfo . FloatMode ) | S_00B848_PRIV ( ProgInfo . Priv ) | S_00B848_DX10_CLAMP ( ProgInfo . DX10Clamp ) | S_00B848_DEBUG_MODE ( ProgInfo . DebugMode ) | S_00B848_IEEE_MODE ( ProgInfo . IEEEMode ) | S_00B848_WGP_MODE ( ProgInfo . WgpMode ) | S_00B848_MEM_ORDERED ( ProgInfo . MemOrdered ) ; unsigned TIDIGCompCnt = <NUM_LIT> ; if ( MFI -> hasWorkItemIDZ ( ) ) TIDIGCompCnt = <NUM_LIT> ; else if ( MFI -> hasWorkItemIDY ( ) ) TIDIGCompCnt = <NUM_LIT> ; ProgInfo . ComputePGMRSrc2 = S_00B84C_SCRATCH_EN ( ProgInfo . ScratchBlocks > <NUM_LIT> ) | S_00B84C_USER_SGPR ( MFI -> getNumUserSGPRs ( ) ) | S_00B84C_TRAP_HANDLER ( STM . isAmdHsaOS ( ) ? <NUM_LIT> : STM . isTrapHandlerEnabled ( ) ) | S_00B84C_TGID_X_EN ( MFI -> hasWorkGroupIDX ( ) ) | S_00B84C_TGID_Y_EN ( MFI -> hasWorkGroupIDY ( ) ) | S_00B84C_TGID_Z_EN ( MFI -> hasWorkGroupIDZ ( ) ) | S_00B84C_TG_<ISA_LIT>ZE_EN ( MFI -> hasWorkGroupInfo ( ) ) | S_00B84C_TIDIG_COMP_CNT ( TIDIGCompCnt ) | S_00B84C_EXCP_EN_MSB ( <NUM_LIT> ) | S_00B84C_LDS_<ISA_LIT>ZE ( STM . isAmdHsaOS ( ) ? <NUM_LIT> : ProgInfo . LDSBlocks ) | S_00B84C_EXCP_EN ( <NUM_LIT> ) ;

ProgInfo . Occupancy = STM . computeOccupancy ( MF . getFunction ( ) , ProgInfo . LDSSize , ProgInfo . NumSGPRsForWavesPerEU , ProgInfo . NumVGPRsForWavesPerEU ) ;


<s> } } } unsigned RsrcReg ; if ( STM . getGeneration ( ) >= <ISA_LIT>Subtarget :: EVERGREEN ) { switch ( MF . getFunction ( ) -> getCallingConv ( ) ) { default : case CallingConv :: <ISA_LIT>_CS : RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS ; break ; case CallingConv :: <ISA_LIT>_GS : RsrcReg = R_028878_SQ_PGM_RESOURCES_GS ; break ; case CallingConv :: <ISA_LIT>_PS : RsrcReg = R_028844_SQ_PGM_RESOURCES_PS ; break ; case CallingConv :: <ISA_LIT>_VS : RsrcReg = R_028860_SQ_PGM_RESOURCES_VS ; break ; } } else { switch ( MF . getFunction ( ) -> getCallingConv ( ) ) { default : case CallingConv :: <ISA_LIT>_GS : case CallingConv :: <ISA_LIT>_CS : case CallingConv :: <ISA_LIT>_VS : RsrcReg = R_028868_SQ_PGM_RESOURCES_VS ; break ; case CallingConv :: <ISA_LIT>_PS : RsrcReg = R_028850_SQ_PGM_RESOURCES_PS ; break ; } } OutStreamer -> EmitIntValue ( RsrcReg , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_NUM_GPRS ( MaxGPR + <NUM_LIT> ) | S_STACK_<ISA_LIT>ZE ( MFI -> StackSize ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_02880C_DB_SHADER_CONTROL , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_02880C_KILL_ENABLE ( killPixel ) , <NUM_LIT> ) ; if ( <STR_LIT> ( MF . getFunction ( ) -> getCallingConv ( ) ) ) { OutStreamer -> EmitIntValue ( R_0288E8_SQ_LDS_ALLOC , <NUM_LIT> ) ;

OutStreamer -> EmitIntValue ( alignTo ( MFI -> LDSSize , <NUM_LIT> ) >> <NUM_LIT> , <NUM_LIT> ) ;


<s> void <ISA_LIT>AsmPrinter :: EmitProgramInfo<ISA_LIT> ( const MachineFunction & MF , const <ISA_LIT>ProgramInfo & KernelInfo ) { const <ISA_LIT>Subtarget & STM = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; const <ISA_LIT>MachineFunctionInfo * MFI = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; unsigned RsrcReg = getRsrcReg ( MF . getFunction ( ) -> getCallingConv ( ) ) ; if ( <STR_LIT> ( MF . getFunction ( ) -> getCallingConv ( ) ) ) { OutStreamer -> EmitIntValue ( R_00B848_COMPUTE_PGM_RSRC1 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( KernelInfo . ComputePGMRSrc1 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_00B84C_COMPUTE_PGM_RSRC2 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( KernelInfo . ComputePGMRSrc2 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_00B860_COMPUTE_TMPRING_<ISA_LIT>ZE , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B860_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } else { OutStreamer -> EmitIntValue ( RsrcReg , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B028_VGPRS ( KernelInfo . VGPRBlocks ) | S_00B028_SGPRS ( KernelInfo . SGPRBlocks ) , <NUM_LIT> ) ; if ( STM . isVGPRSpillingEnabled ( * MF . getFunction ( ) ) ) { OutStreamer -> EmitIntValue ( R_0286E8_SPI_TMPRING_<ISA_LIT>ZE , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_0286E8_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } } if ( MF . getFunction ( ) -> getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { OutStreamer -> EmitIntValue ( R_00B02C_SPI_SHADER_PGM_RSRC2_PS , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( KernelInfo . LDSBlocks ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_0286CC_SPI_PS_INPUT_ENA , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( MFI -> P<ISA_LIT>nputEna , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_0286D0_SPI_PS_INPUT_ADDR , <NUM_LIT> ) ;

OutStreamer -> EmitIntValue ( MFI -> getP<ISA_LIT>nputAddr ( ) , <NUM_LIT> ) ;


<s> width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else { llvm_unreachable ( <STR_LIT> ) ; } unsigned hwReg = RI -> getEncodingValue ( reg ) & <NUM_LIT> ; unsigned maxUsed = hwReg + width - <NUM_LIT> ; if ( isSGPR ) { MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR ; } else { MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR ; } } } } unsigned ExtraSGPRs = <NUM_LIT> ; if ( VCCUsed ) ExtraSGPRs = <NUM_LIT> ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS ) { if ( FlatUsed ) ExtraSGPRs = <NUM_LIT> ; } else { if ( STM . isXNACKEnabled ( ) ) ExtraSGPRs = <NUM_LIT> ; if ( FlatUsed ) ExtraSGPRs = <NUM_LIT> ; } MaxSGPR += ExtraSGPRs ; if ( STM . debuggerReserveRegs ( ) ) { ProgInfo . ReservedVGPRFirst = MaxVGPR + <NUM_LIT> ; ProgInfo . ReservedVGPRCount = MFI -> getDebuggerReservedVGPRCount ( ) ; MaxVGPR += MFI -> getDebuggerReservedVGPRCount ( ) ; } ProgInfo . NumVGPR = MaxVGPR + <NUM_LIT> ; ProgInfo . NumSGPR = MaxSGPR + <NUM_LIT> ; if ( STM . hasSGPRInitBug ( ) ) { if ( ProgInfo . NumSGPR > <ISA_LIT>Subtarget :: FIXED_SGPR_COUNT_FOR_INIT_BUG ) { LLVMContext & Ctx = MF . getFunction ( ) -> getContext ( ) ; Ctx . emitError ( <STR_LIT> ) ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : VCCUsed = true ; continue ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FlatUsed = true ; continue ; default : break ; } if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = true ; width = <NUM_LIT> ; } else if ( <STR_LIT> . contains ( reg ) ) { isSGPR = false ; width = <NUM_LIT> ; } else { llvm_unreachable ( <STR_LIT> ) ; } unsigned hwReg = RI -> getEncodingValue ( reg ) & <NUM_LIT> ; unsigned maxUsed = hwReg + width - <NUM_LIT> ; if ( isSGPR ) { MaxSGPR = maxUsed > MaxSGPR ? maxUsed : MaxSGPR ; } else { MaxVGPR = maxUsed > MaxVGPR ? maxUsed : MaxVGPR ; } } } } unsigned ExtraSGPRs = <NUM_LIT> ; if ( VCCUsed ) ExtraSGPRs = <NUM_LIT> ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS ) { if ( FlatUsed ) ExtraSGPRs = <NUM_LIT> ;


<s> static void emitRuntimeMDIntValue ( std :: unique_ptr < MCStreamer > & Streamer , RuntimeMD :: Key K , uint64_t V , unsigned Size ) {

Streamer -> EmitIntValue ( K , <NUM_LIT> ) ;


<s> Streamer -> EmitIntValue ( S . size ( ) , <NUM_LIT> ) ; Streamer -> EmitBytes ( S ) ;


<s> Streamer -> EmitIntValue ( mdconst :: extract < ConstantInt > ( Node -> getOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) , Size ) ; Streamer -> EmitIntValue ( mdconst :: extract < ConstantInt > ( Node -> getOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) , Size ) ;


<s> OutStreamer -> EmitIntValue ( RuntimeMD :: KeyKernelBegin , <NUM_LIT> ) ; emitRuntimeMDStringValue ( OutStreamer , RuntimeMD :: KeyKernelName , F . getName ( ) ) ; for ( auto & Arg : F . args ( ) ) { unsigned I = Arg . getArgNo ( ) ; OutStreamer -> EmitIntValue ( RuntimeMD :: KeyArgBegin , <NUM_LIT> ) ; auto T = Arg . getType ( ) ; auto DL = F . getParent ( ) -> getDataLayout ( ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgSize , DL . getTypeAllocSize ( T ) , <NUM_LIT> ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgAlign , DL . getABITypeAlignment ( T ) , <NUM_LIT> ) ; auto TypeName = dyn_cast < MDString > ( F . getMetadata ( <STR_LIT> ) -> getOperand ( I ) ) -> getString ( ) ; emitRuntimeMDStringValue ( OutStreamer , RuntimeMD :: KeyArgTypeName , TypeName ) ; if ( auto ArgNameMD = F . getMetadata ( <STR_LIT> ) ) { auto ArgName = cast < MDString > ( ArgNameMD -> getOperand ( I ) ) -> getString ( ) ; emitRuntimeMDStringValue ( OutStreamer , RuntimeMD :: KeyArgName , ArgName ) ; } auto TypeQual = cast < MDString > ( F . getMetadata ( <STR_LIT> ) -> getOperand ( I ) ) -> getString ( ) ; SmallVector < StringRef , <NUM_LIT> > SplitQ ; TypeQual . split ( SplitQ , <STR_LIT> , - <NUM_LIT> , false ) ; for ( auto & I : SplitQ ) { auto Key = StringSwitch < RuntimeMD :: Key > ( I ) . Case ( <STR_LIT> , RuntimeMD :: KeyArgIsVolatile ) . Case ( <STR_LIT> , RuntimeMD :: KeyArgIsRestrict ) . Case ( <STR_LIT> , RuntimeMD :: KeyArgIsConst ) . Case ( <STR_LIT> , RuntimeMD :: KeyArgIsPipe ) . Default ( RuntimeMD :: KeyNull ) ; OutStreamer -> EmitIntValue ( Key , <NUM_LIT> ) ; } auto BaseTypeName = cast < MDString > ( F . getMetadata ( <STR_LIT> ) -> getOperand ( I ) ) -> getString ( ) ; auto TypeKind = StringSwitch < RuntimeMD :: KernelArg :: TypeKind > ( BaseTypeName ) . Case ( <STR_LIT> , RuntimeMD :: KernelArg :: Sampler ) . Case ( <STR_LIT> , RuntimeMD :: KernelArg :: Queue ) . Cases ( <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , RuntimeMD :: KernelArg :: Image ) . Cases ( <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , RuntimeMD :: KernelArg :: Image ) . Cases ( <STR_LIT> , <STR_LIT> , RuntimeMD :: KernelArg :: Image ) . Default ( isa < PointerType > ( T ) ? RuntimeMD :: KernelArg :: Pointer :


<s> RuntimeMD :: KernelArg :: Value ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgTypeKind , TypeKind , <NUM_LIT> ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgValueType , getRuntimeMDValueType ( T , BaseTypeName ) , <NUM_LIT> ) ; auto AccQual = cast < MDString > ( F . getMetadata ( <STR_LIT> ) -> getOperand ( I ) ) -> getString ( ) ; auto AQ = StringSwitch < RuntimeMD :: KernelArg :: AccessQualifer > ( AccQual ) . Case ( <STR_LIT> , RuntimeMD :: KernelArg :: ReadOnly ) . Case ( <STR_LIT> , RuntimeMD :: KernelArg :: WriteOnly ) . Case ( <STR_LIT> , RuntimeMD :: KernelArg :: ReadWrite ) . Default ( RuntimeMD :: KernelArg :: None ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgAccQual , AQ , <NUM_LIT> ) ; if ( isa < PointerType > ( T ) ) emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyArgAddrQual , T -> getPointerAddressSpace ( ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( RuntimeMD :: KeyArgEnd , <NUM_LIT> ) ; } if ( auto RWGS = F . getMetadata ( <STR_LIT> ) ) emitRuntimeMDThreeIntValues ( OutStreamer , RuntimeMD :: KeyReqdWorkGroupSize , RWGS , <NUM_LIT> ) ; if ( auto WGSH = F . getMetadata ( <STR_LIT> ) ) emitRuntimeMDThreeIntValues ( OutStreamer , RuntimeMD :: KeyWorkGroupSizeHint , WGSH , <NUM_LIT> ) ; if ( auto VTH = F . getMetadata ( <STR_LIT> ) ) { auto TypeName = getOCLTypeName ( cast < ValueAsMetadata > ( VTH -> getOperand ( <NUM_LIT> ) ) -> getType ( ) , mdconst :: extract < ConstantInt > ( VTH -> getOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) ) ; emitRuntimeMDStringValue ( OutStreamer , RuntimeMD :: KeyVecTypeHint , TypeName ) ; }

OutStreamer -> EmitIntValue ( RuntimeMD :: KeyKernelEnd , <NUM_LIT> ) ;


<s> if ( MD -> getNumOperands ( ) ) { auto Node = MD -> getOperand ( <NUM_LIT> ) ; if ( Node -> getNumOperands ( ) > <NUM_LIT> ) { emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyLanguage , RuntimeMD :: OpenCL_C , <NUM_LIT> ) ; uint16_t Major = mdconst :: extract < ConstantInt > ( Node -> getOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) ; uint16_t Minor = mdconst :: extract < ConstantInt > ( Node -> getOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) ; emitRuntimeMDIntValue ( OutStreamer , RuntimeMD :: KeyLanguageVersion , Major * <NUM_LIT> + Minor * <NUM_LIT> , <NUM_LIT> ) ; }


<s> Type * EleTy = VecTy -> getElementType ( ) ; unsigned Size = VecTy -> getVectorNumElements ( ) ; return ( Twine ( getOCLTypeName ( EleTy , isSigned ) ) + Twine ( Size ) ) . str ( ) ; } switch ( Ty -> getTypeID ( ) ) { case Type :: HalfTyID : return <STR_LIT> ; case Type :: FloatTyID : return <STR_LIT> ; case Type :: DoubleTyID : return <STR_LIT> ; case Type :: IntegerTyID : { if ( ! isSigned ) return ( Twine ( 'u' ) + Twine ( getOCLTypeName ( Ty , true ) ) ) . str ( ) ; auto IntTy = cast < IntegerType > ( Ty ) ; auto BW = IntTy -> getIntegerBitWidth ( ) ; switch ( BW ) { case <NUM_LIT> : return <STR_LIT> ; case <NUM_LIT> : return <STR_LIT> ; case <NUM_LIT> : return <STR_LIT> ; case <NUM_LIT> : return <STR_LIT> ; default : return ( Twine ( 'i' ) + Twine ( BW ) ) . str ( ) ;


<s> if ( <STR_LIT> ( * getGlobalSTI ( ) ) ) { OutStreamer -> SwitchSection ( getObjFileLowering ( ) . getTextSection ( ) ) ;

getTargetStreamer ( ) -> EmitCodeEnd ( ) ;


<s> } if ( STM . isAmdHsaOS ( ) ) HSAMetadataStream -> emitKernel ( * MF , CurrentProgramInfo ) ; DumpCodeInstEmitter = nullptr ; if ( STM . dumpCode ( ) ) { bool SaveFlag = OutStreamer -> getUseAssemblerInfoForParsing ( ) ; OutStreamer -> setUseAssemblerInfoForParsing ( true ) ; MCAssembler * Assembler = OutStreamer -> getAssemblerPtr ( ) ; OutStreamer -> setUseAssemblerInfoForParsing ( SaveFlag ) ; if ( Assembler ) DumpCodeInstEmitter = Assembler -> getEmitterPtr ( ) ;


<s> const <ISA_LIT>MachineFunctionInfo * MFI = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; auto CC = MF . getFunction ( ) . getCallingConv ( ) ; auto MD = getTargetStreamer ( ) -> getPALMetadata ( ) ; MD -> setEntryPoint ( CC , MF . getFunction ( ) . getName ( ) ) ; MD -> setNumUsedVgprs ( CC , CurrentProgramInfo . NumVGPRsForWavesPerEU ) ; MD -> setNumUsedSgprs ( CC , CurrentProgramInfo . NumSGPRsForWavesPerEU ) ; if ( <STR_LIT> ( MF . getFunction ( ) . getCallingConv ( ) ) ) { MD -> setRsrc1 ( CC , CurrentProgramInfo . ComputePGMRSrc1 ) ; MD -> setRsrc2 ( CC , CurrentProgramInfo . ComputePGMRSrc2 ) ; } else { MD -> setRsrc1 ( CC , S_00B028_VGPRS ( CurrentProgramInfo . VGPRBlocks ) | S_00B028_SGPRS ( CurrentProgramInfo . SGPRBlocks ) ) ; if ( CurrentProgramInfo . ScratchBlocks > <NUM_LIT> ) MD -> setRsrc2 ( CC , S_00B84C_SCRATCH_EN ( <NUM_LIT> ) ) ; } MD -> setScratchSize ( CC , alignTo ( CurrentProgramInfo . ScratchSize , <NUM_LIT> ) ) ; if ( MF . getFunction ( ) . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { MD -> setRsrc2 ( CC , S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( CurrentProgramInfo . LDSBlocks ) ) ; MD -> setSpiPsInputEna ( MFI -> getP<ISA_LIT>nputEnable ( ) ) ; MD -> setSpiPsInputAddr ( MFI -> getP<ISA_LIT>nputAddr ( ) ) ; }


Out . kernarg_segment_alignment = std :: max ( ( size_t ) <NUM_LIT> , countTrailingZeros ( MaxKernArgAlign ) ) ;


<s>
}
OutStreamer
->
emitRawComment
(
<STR_LIT>
,
false
)
;
emitCommonFunctionComments
(
CurrentProgramInfo
.
NumVGPR
,
CurrentProgramInfo
.
NumSGPR
,
CurrentProgramInfo
.
ScratchSize
,
getFunctionCodeSize
(
MF
)
,
MFI
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
FloatMode
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
IEEEMode
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
LDSSize
)
+
<STR_LIT>
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
SGPRBlocks
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
VGPRBlocks
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumSGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumVGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
MFI
->
needsWaveLimiter
(
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_USER_SGPR
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TRAP_HANDLER
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_X_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Y_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Z_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TIDIG_COMP_CNT
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
}
if
(
DumpCodeInstEmitter
)
{
OutStreamer
->
SwitchSection
(
Context
.
getELFSection
(
<STR_LIT>
,
ELF
::
SHT_NOTE
,
<NUM_LIT>
)
)
;
for
(
size_t
i
=
<NUM_LIT>
;
i
<
DisasmLines
.
size
(
)
;
++
i
)
{
std
::
string
Comment
=
<STR_LIT>
;
if
(
!
HexLines
[
i
]
.
empty
(
)
)
{
Comment
=
std
::
string
(
DisasmLineMaxLen
DisasmLines
[
i
]
.
size
(
)
,
' '
)
;

Comment += <STR_LIT> + HexLines [ i ] + <STR_LIT> ;


<s> if ( STM . isAmdPalOS ( ) ) EmitPALMetadata ( MF , CurrentProgramInfo ) ; else if ( ! STM . isAmdHsaOS ( ) ) { EmitProgramInfo<ISA_LIT> ( MF , CurrentProgramInfo ) ; } DisasmLines . clear ( ) ; HexLines . clear ( ) ; DisasmLineMaxLen = <NUM_LIT> ; EmitFunctionBody ( ) ; if ( isVerbose ( ) ) { MCSectionELF * CommentSection = Context . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; OutStreamer -> SwitchSection ( CommentSection ) ; if ( ! MFI -> isEntryFunction ( ) ) { OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; <ISA_LIT>FunctionResourceInfo & Info = CallGraphResourceInfo [ & MF . getFunction ( ) ] ; emitCommonFunctionComments ( Info . NumVGPR , Info . getTotalNumSGPRs ( MF . getSubtarget < GCNSubtarget > ( ) ) , Info . PrivateSegmentSize , getFunctionCodeSize ( MF ) , MFI ) ; return false ; } OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; emitCommonFunctionComments ( CurrentProgramInfo . NumVGPR , CurrentProgramInfo . NumSGPR , CurrentProgramInfo . ScratchSize , getFunctionCodeSize ( MF ) , MFI ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . FloatMode ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . IEEEMode ) , false ) ;

OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . LDSSize ) + <STR_LIT> , false ) ;


<s> getTargetStreamer ( ) -> EmitAMDKernelCodeT ( KernelCode ) ; } if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA ) return ;

HSAMetadataStream . emitKernel ( MF -> getFunction ( ) , getHSACodeProps ( * MF , CurrentProgramInfo ) , getHSADebugProps ( * MF , CurrentProgramInfo ) ) ;


<s> const <ISA_LIT>Subtarget & STI = MF -> getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( STI . dumpCode ( ) ) { DisasmLines . push_back ( MF -> getName ( ) . str ( ) + <STR_LIT> ) ; DisasmLineMaxLen = std :: max ( DisasmLineMaxLen , DisasmLines . back ( ) . size ( ) ) ; HexLines . push_back ( <STR_LIT> ) ;


<s> const Function & F = MF . getFunction ( ) ; if ( F . getCallingConv ( ) != CallingConv :: <ISA_LIT>_KERNEL ) return HSACodeProps ; HSACodeProps . mKernargSegmentSize = STM . getKernArgSegmentSize ( F ) ; HSACodeProps . mGroupSegmentFixedSize = ProgramInfo . LDSSize ; HSACodeProps . mPrivateSegmentFixedSize = ProgramInfo . ScratchSize ; HSACodeProps . mKernargSegmentAlign = std :: max ( uint32_t ( <NUM_LIT> ) , MFI . getMaxKernArgAlign ( ) ) ; HSACodeProps . mWavefrontSize = STM . getWavefrontSize ( ) ; HSACodeProps . mNumSGPRs = CurrentProgramInfo . NumSGPR ; HSACodeProps . mNumVGPRs = CurrentProgramInfo . NumVGPR ; HSACodeProps . mMaxFlatWorkGroupSize = MFI . getMaxFlatWorkGroupSize ( ) ;

HSACodeProps . mIsDynamicCallStack = ProgramInfo . DynamicCallStack ;


OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TGID_Y_EN ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ;


<s> CurrentProgramInfo = <ISA_LIT>ProgramInfo ( ) ; const <ISA_LIT>MachineFunction * MFI = MF . getInfo < <ISA_LIT>MachineFunction > ( ) ; MF . setAlignment ( MFI -> isEntryFunction ( ) ? <NUM_LIT> : <NUM_LIT> ) ; SetupMachineFunction ( MF ) ; const <ISA_LIT>Subtarget & STM = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; MCContext & Context = getObjFileLowering ( ) . getContext ( ) ; if ( ! STM . isAmdHsaOS ( ) && ! STM . isAmdPalOS ( ) ) { MCSectionELF * ConfigSection = Context . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; OutStreamer -> SwitchSection ( ConfigSection ) ; } if ( MFI -> isEntryFunction ( ) ) { get<ISA_LIT>ProgramInfo ( CurrentProgramInfo , MF ) ; } else { auto I = CallGraphResourceInfo . insert ( std :: make_pair ( & MF . getFunction ( ) , <ISA_LIT>FunctionResourceInfo ( ) ) ) ; <ISA_LIT>FunctionResourceInfo & Info = I . first -> second ; assert ( I . second && <STR_LIT> ) ; Info = analyzeResourceUsage ( MF ) ; } if ( STM . isAmdPalOS ( ) ) EmitPALMetadata ( MF , CurrentProgramInfo ) ; else if ( ! STM . isAmdHsaOS ( ) ) { EmitProgramInfo<ISA_LIT> ( MF , CurrentProgramInfo ) ; } DisasmLines . clear ( ) ; HexLines . clear ( ) ; DisasmLineMaxLen = <NUM_LIT> ; EmitFunctionBody ( ) ; if ( isVerbose ( ) ) { MCSectionELF * CommentSection = Context . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; OutStreamer -> SwitchSection ( CommentSection ) ; if ( ! MFI -> isEntryFunction ( ) ) { OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; <ISA_LIT>FunctionResourceInfo & Info = CallGraphResourceInfo [ & MF . getFunction ( ) ] ; emitCommonFunctionComments ( Info . NumVGPR , Info . getTotalNumSGPRs ( MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ) , Info . PrivateSegmentSize , getFunctionCodeSize ( MF ) , MFI ) ; return false ; } OutStreamer -> emitRawComment ( <STR_LIT> , false ) ;

emitCommonFunctionComments ( CurrentProgramInfo . NumVGPR , CurrentProgramInfo . NumSGPR , CurrentProgramInfo . ScratchSize , getFunctionCodeSize ( MF ) , MFI ) ;


<s> return <STR_LIT> ; case Type :: FloatTyID : return <STR_LIT> ; case Type :: DoubleTyID : return <STR_LIT> ; case Type :: IntegerTyID : { if ( ! Signed ) return ( Twine ( 'u' ) + getOCLTypeName ( Ty , true ) ) . str ( ) ; unsigned BW = Ty -> getIntegerBitWidth ( ) ; switch ( BW ) { case <NUM_LIT> : return <STR_LIT> ; case <NUM_LIT> : return <STR_LIT> ; case <NUM_LIT> :


<s>
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumSGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumVGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
Occupancy
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
MFI
->
needsWaveLimiter
(
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_USER_SGPR
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TRAP_HANDLER
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_X_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Y_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Z_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TIDIG_COMP_CNT
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
}
if
(
DumpCodeInstEmitter
)
{
OutStreamer
->
SwitchSection
(
Context
.
getELFSection
(
<STR_LIT>
,
ELF
::
SHT_NOTE
,
<NUM_LIT>
)
)
;
for
(
size_t
i
=
<NUM_LIT>
;
i
<
DisasmLines
.
size
(
)
;
++
i
)
{
std
::
string
Comment
=
<STR_LIT>
;
if
(
!
HexLines
[
i
]
.
empty
(
)
)
{
Comment
=
std
::
string
(
DisasmLineMaxLen
DisasmLines
[
i
]
.
size
(
)
,
' '
)
;
Comment
+=
<STR_LIT>
+
HexLines
[
i
]
+
<STR_LIT>
;


<s> const <ISA_LIT>MachineFunction * MFI = MF -> getInfo < <ISA_LIT>MachineFunction > ( ) ; if ( ! MFI -> isEntryFunction ( ) ) return ; const <ISA_LIT>Subtarget & STM = MF -> getSubtarget < <ISA_LIT>Subtarget > ( ) ; <ISA_LIT>ProgramInfo KernelInfo ; amd_kernel_code_t KernelCode ; if ( STM . isAmdCodeObjectV2 ( * MF ) ) {

get<ISA_LIT>ProgramInfo ( KernelInfo , * MF ) ;


<s> const <ISA_LIT>Subtarget & STM = MF -> getSubtarget < <ISA_LIT>Subtarget > ( ) ; <ISA_LIT>ProgramInfo KernelInfo ; amd_kernel_code_t KernelCode ; if ( STM . isAmdCodeObjectV2 ( * MF ) ) { get<ISA_LIT>ProgramInfo ( KernelInfo , * MF ) ; getAmdKernelCode ( KernelCode , KernelInfo , * MF ) ; OutStreamer -> SwitchSection ( getObjFileLowering ( ) . getTextSection ( ) ) ;

getTargetStreamer ( ) . EmitAMDKernelCodeT ( KernelCode ) ;


<s> OutStreamer -> EmitIntValue ( S_00B860_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } else { OutStreamer -> EmitIntValue ( RsrcReg , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B028_VGPRS ( KernelInfo . VGPRBlocks ) | S_00B028_SGPRS ( KernelInfo . SGPRBlocks ) , <NUM_LIT> ) ; if ( STM . isVGPRSpillingEnabled ( * MF . getFunction ( ) ) ) { OutStreamer -> EmitIntValue ( R_0286E8_SPI_TMPRING_<ISA_LIT>ZE , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_0286E8_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } } if ( MF . getFunction ( ) -> getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { OutStreamer -> EmitIntValue ( R_00B02C_SPI_SHADER_PGM_RSRC2_PS , <NUM_LIT> ) ;

OutStreamer -> EmitIntValue ( S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( KernelInfo . LDSBlocks ) , <NUM_LIT> ) ;


<s> void <ISA_LIT>AsmPrinter :: EmitProgramInfo<ISA_LIT> ( const MachineFunction & MF , const <ISA_LIT>ProgramInfo & KernelInfo ) { const <ISA_LIT>Subtarget & STM = MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; const <ISA_LIT>MachineFunctionInfo * MFI = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; unsigned RsrcReg = getRsrcReg ( MF . getFunction ( ) -> getCallingConv ( ) ) ; if ( <STR_LIT> ( MF . getFunction ( ) -> getCallingConv ( ) ) ) { OutStreamer -> EmitIntValue ( R_00B848_COMPUTE_PGM_RSRC1 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( KernelInfo . ComputePGMRSrc1 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_00B84C_COMPUTE_PGM_RSRC2 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( KernelInfo . ComputePGMRSrc2 , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_00B860_COMPUTE_TMPRING_<ISA_LIT>ZE , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B860_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } else { OutStreamer -> EmitIntValue ( RsrcReg , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B028_VGPRS ( KernelInfo . VGPRBlocks ) | S_00B028_SGPRS ( KernelInfo . SGPRBlocks ) , <NUM_LIT> ) ; if ( STM . isVGPRSpillingEnabled ( * MF . getFunction ( ) ) ) { OutStreamer -> EmitIntValue ( R_0286E8_SPI_TMPRING_<ISA_LIT>ZE , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_0286E8_WAVE<ISA_LIT>ZE ( KernelInfo . ScratchBlocks ) , <NUM_LIT> ) ; } } if ( MF . getFunction ( ) -> getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { OutStreamer -> EmitIntValue ( R_00B02C_SPI_SHADER_PGM_RSRC2_PS , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( KernelInfo . LDSBlocks ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_0286CC_SPI_PS_INPUT_ENA , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( MFI -> getP<ISA_LIT>nputEnable ( ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_0286D0_SPI_PS_INPUT_ADDR , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( MFI -> getP<ISA_LIT>nputAddr ( ) , <NUM_LIT> ) ; } OutStreamer -> EmitIntValue ( R_SPILLED_SGPRS , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( MFI -> getNumSpilledSGPRs ( ) , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( R_SPILLED_VGPRS , <NUM_LIT> ) ; OutStreamer -> EmitIntValue ( MFI -> getNumSpilledVGPRs ( ) , <NUM_LIT> ) ;


<s> break ; } } MCPhysReg NumSGPRReg = <STR_LIT> ; for ( MCPhysReg Reg : reverse ( <STR_LIT> . getRegisters ( ) ) ) { if ( MRI . isPhysRegUsed ( Reg ) ) { NumSGPRReg = Reg ; break ; } } ProgInfo . NumVGPR = NumVGPRReg == <STR_LIT> ? <NUM_LIT> : RI -> getHWRegIndex ( NumVGPRReg ) + <NUM_LIT> ; ProgInfo . NumSGPR = NumSGPRReg == <STR_LIT> ? <NUM_LIT> : RI -> getHWRegIndex ( NumSGPRReg ) + <NUM_LIT> ; unsigned ExtraSGPRs = <NUM_LIT> ; ProgInfo . VCCUsed = MRI . isPhysRegUsed ( <STR_LIT> ) || MRI . isPhysRegUsed ( <STR_LIT> ) ; if ( ProgInfo . VCCUsed ) ExtraSGPRs = <NUM_LIT> ; ProgInfo . FlatUsed = MRI . isPhysRegUsed ( <STR_LIT> ) || MRI . isPhysRegUsed ( <STR_LIT> ) ; if ( ProgInfo . FlatUsed && ! MFI -> hasFlatScratchInit ( ) && ( ! hasAnyNonFlatUseOfReg ( MRI , * TII , <STR_LIT> ) && ! hasAnyNonFlatUseOfReg ( MRI , * TII , <STR_LIT> ) && ! hasAnyNonFlatUseOfReg ( MRI , * TII , <STR_LIT> ) ) ) { ProgInfo . FlatUsed = false ; } if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS ) { if ( ProgInfo . FlatUsed ) ExtraSGPRs = <NUM_LIT> ; } else { if ( STM . isXNACKEnabled ( ) ) ExtraSGPRs = <NUM_LIT> ; if ( ProgInfo . FlatUsed ) ExtraSGPRs = <NUM_LIT> ; } unsigned ExtraVGPRs = STM . getReservedNumVGPRs ( MF ) ; if ( STM . getGeneration ( ) >= <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS && ! STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) -> getContext ( ) ; DiagnosticInfoResourceLimit Diag ( * MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , DS_Error , DK_ResourceLimit , MaxAddressableNumSGPRs ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs - <NUM_LIT> ; } } ProgInfo . NumSGPR += ExtraSGPRs ; ProgInfo . NumVGPR += ExtraVGPRs ; ProgInfo . NumSGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumSGPR , <NUM_LIT> ) , STM . getMinNumSGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; ProgInfo . NumVGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumVGPR , <NUM_LIT> ) , STM . getMinNumVGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; if ( STM . getGeneration ( ) <= <ISA_LIT>Subtarget :: SEA_ISLANDS || STM . hasSGPRInitBug ( ) ) {


<s> get<ISA_LIT>ProgramInfo ( KernelInfo , * MF ) ; getAmdKernelCode ( KernelCode , KernelInfo , * MF ) ; OutStreamer -> SwitchSection ( getObjFileLowering ( ) . getTextSection ( ) ) ; getTargetStreamer ( ) . EmitAMDKernelCodeT ( KernelCode ) ; } if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA ) return ;

getTargetStreamer ( ) . EmitKernelCodeObjectMetadata ( * MF -> getFunction ( ) , KernelCode ) ;


Out . kernarg_segment_byte_size = STM . getKernArgSegmentSize ( F , MaxKernArgAlign ) ;


<s> ProgInfo . NumSGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumSGPR , <NUM_LIT> ) , STM . getMinNumSGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; ProgInfo . NumVGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumVGPR , <NUM_LIT> ) , STM . getMinNumVGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; if ( STM . getGeneration ( ) <= <ISA_LIT>Subtarget :: SEA_ISLANDS || STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , DS_Error , DK_ResourceLimit , MaxAddressableNumSGPRs ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs ; ProgInfo . NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs ; } } if ( STM . hasSGPRInitBug ( ) ) { ProgInfo . NumSGPR = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; ProgInfo . NumSGPRsForWavesPerEU = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; } if ( MFI -> getNumUserSGPRs ( ) > STM . getMaxNumUserSGPRs ( ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getNumUserSGPRs ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } if ( MFI -> getLDSSize ( ) > static_cast < unsigned > ( STM . getLocalMemorySize ( ) ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getLDSSize ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } ProgInfo . SGPRBlocks = IsaInfo :: getNumSGPRBlocks ( & STM , ProgInfo . NumSGPRsForWavesPerEU ) ; ProgInfo . VGPRBlocks = IsaInfo :: getNumVGPRBlocks ( & STM , ProgInfo . NumVGPRsForWavesPerEU ) ; ProgInfo . FloatMode = getFPMode ( MF ) ; const <ISA_LIT>ModeRegisterDefaults Mode = MFI -> getMode ( ) ; ProgInfo . IEEEMode = Mode . IEEE ;

ProgInfo . DX10Clamp = Mode . DX10Clamp ;


<s> ProgInfo . ScratchSize = Info . PrivateSegmentSize ; ProgInfo . VCCUsed = Info . UsesVCC ; ProgInfo . FlatUsed = Info . UsesFlatScratch ; ProgInfo . DynamicCallStack = Info . HasDynamicallySizedStack || Info . HasRecursion ; if ( ! isUInt < <NUM_LIT> > ( ProgInfo . ScratchSize ) ) { DiagnosticInfoStackSize DiagStackSize ( MF . getFunction ( ) , ProgInfo . ScratchSize , DS_Error ) ; MF . getFunction ( ) . getContext ( ) . diagnose ( DiagStackSize ) ; } const GCNSubtarget & STM = MF . getSubtarget < GCNSubtarget > ( ) ; const <ISA_LIT>MachineFunctionInfo * MFI = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; unsigned ExtraSGPRs = IsaInfo :: getNumExtraSGPRs ( & STM , ProgInfo . VCCUsed , ProgInfo . FlatUsed ) ; if ( STM . getGeneration ( ) >= <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS && ! STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , DS_Error , DK_ResourceLimit , MaxAddressableNumSGPRs ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs - <NUM_LIT> ; } } ProgInfo . NumSGPR += ExtraSGPRs ; unsigned WaveDispatchNumSGPR = <NUM_LIT> , WaveDispatchNumVGPR = <NUM_LIT> ; for ( auto & Arg : MF . getFunction ( ) . args ( ) ) { unsigned NumRegs = ( Arg . getType ( ) -> getPrimitiveSizeInBits ( ) + <NUM_LIT> ) / <NUM_LIT> ; if ( Arg . hasAttribute ( Attribute :: InReg ) ) WaveDispatchNumSGPR += NumRegs ; else WaveDispatchNumVGPR += NumRegs ; } ProgInfo . NumSGPR = std :: max ( ProgInfo . NumSGPR , WaveDispatchNumSGPR ) ; ProgInfo . NumVGPR = std :: max ( ProgInfo . NumVGPR , WaveDispatchNumVGPR ) ; ProgInfo . NumSGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumSGPR , <NUM_LIT> ) , STM . getMinNumSGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; ProgInfo . NumVGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumVGPR , <NUM_LIT> ) , STM . getMinNumVGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ;

if ( STM . getGeneration ( ) <= <ISA_LIT>Subtarget :: SEA_ISLANDS || STM . hasSGPRInitBug ( ) ) {


<s>
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
SGPRBlocks
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
VGPRBlocks
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumSGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
CurrentProgramInfo
.
NumVGPRsForWavesPerEU
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
MFI
->
needsWaveLimiter
(
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_USER_SGPR
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TRAP_HANDLER
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_X_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Y_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Z_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TIDIG_COMP_CNT
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
}
if
(
STM
.
dumpCode
(
)
)
{
OutStreamer
->
SwitchSection
(
Context
.
getELFSection
(
<STR_LIT>
,
ELF
::
SHT_NOTE
,
<NUM_LIT>
)
)
;
for
(
size_t
i
=
<NUM_LIT>
;
i
<
DisasmLines
.
size
(
)
;
++
i
)
{
std
::
string
Comment
=
<STR_LIT>
;
if
(
!
HexLines
[
i
]
.
empty
(
)
)
{
Comment
=
std
::
string
(
DisasmLineMaxLen
DisasmLines
[
i
]
.
size
(
)
,
' '
)
;
Comment
+=
<STR_LIT>
+
HexLines
[
i
]
+
<STR_LIT>
;


<s> auto I = CallGraphResourceInfo . insert ( std :: make_pair ( & MF . getFunction ( ) , <ISA_LIT>FunctionResourceInfo ( ) ) ) ; <ISA_LIT>FunctionResourceInfo & Info = I . first -> second ; assert ( I . second && <STR_LIT> ) ; Info = analyzeResourceUsage ( MF ) ; } if ( STM . isAmdPalOS ( ) ) EmitPALMetadata ( MF , CurrentProgramInfo ) ; else if ( ! STM . isAmdHsaOS ( ) ) { EmitProgramInfo<ISA_LIT> ( MF , CurrentProgramInfo ) ; } DumpCodeInstEmitter = nullptr ; if ( STM . dumpCode ( ) ) { bool SaveFlag = OutStreamer -> getUseAssemblerInfoForParsing ( ) ; OutStreamer -> setUseAssemblerInfoForParsing ( true ) ; MCAssembler * Assembler = OutStreamer -> getAssemblerPtr ( ) ; OutStreamer -> setUseAssemblerInfoForParsing ( SaveFlag ) ; if ( Assembler ) DumpCodeInstEmitter = Assembler -> getEmitterPtr ( ) ; } DisasmLines . clear ( ) ; HexLines . clear ( ) ; DisasmLineMaxLen = <NUM_LIT> ; EmitFunctionBody ( ) ; if ( isVerbose ( ) ) { MCSectionELF * CommentSection = Context . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; OutStreamer -> SwitchSection ( CommentSection ) ; if ( ! MFI -> isEntryFunction ( ) ) { OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; <ISA_LIT>FunctionResourceInfo & Info = CallGraphResourceInfo [ & MF . getFunction ( ) ] ; emitCommonFunctionComments ( Info . NumVGPR , Info . getTotalNumSGPRs ( MF . getSubtarget < GCNSubtarget > ( ) ) , Info . PrivateSegmentSize , getFunctionCodeSize ( MF ) , MFI ) ; return false ; } OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; emitCommonFunctionComments ( CurrentProgramInfo . NumVGPR , CurrentProgramInfo . NumSGPR , CurrentProgramInfo . ScratchSize , getFunctionCodeSize ( MF ) , MFI ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . FloatMode ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . IEEEMode ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . LDSSize ) + <STR_LIT> , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . SGPRBlocks ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . VGPRBlocks ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . NumSGPRsForWavesPerEU ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . NumVGPRsForWavesPerEU ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . Occupancy ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( MFI -> needsWaveLimiter ( ) ) , false ) ;

OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_USER_SGPR ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ;


<s> EmitFunctionBody ( ) ; if ( isVerbose ( ) ) { MCSectionELF * CommentSection = Context . getELFSection ( <STR_LIT> , ELF :: SHT_PROGBITS , <NUM_LIT> ) ; OutStreamer -> SwitchSection ( CommentSection ) ; if ( ! MFI -> isEntryFunction ( ) ) { OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; <ISA_LIT>FunctionResourceInfo & Info = CallGraphResourceInfo [ & MF . getFunction ( ) ] ; emitCommonFunctionComments ( Info . NumVGPR , Info . getTotalNumSGPRs ( MF . getSubtarget < GCNSubtarget > ( ) ) , Info . PrivateSegmentSize , getFunctionCodeSize ( MF ) , MFI ) ; return false ; } OutStreamer -> emitRawComment ( <STR_LIT> , false ) ; emitCommonFunctionComments ( CurrentProgramInfo . NumVGPR , CurrentProgramInfo . NumSGPR , CurrentProgramInfo . ScratchSize , getFunctionCodeSize ( MF ) , MFI ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . FloatMode ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . IEEEMode ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . LDSSize ) + <STR_LIT> , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . SGPRBlocks ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . VGPRBlocks ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . NumSGPRsForWavesPerEU ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . NumVGPRsForWavesPerEU ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CurrentProgramInfo . Occupancy ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( MFI -> needsWaveLimiter ( ) ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_USER_SGPR ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TRAP_HANDLER ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TGID_X_EN ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TGID_Y_EN ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TGID_Z_EN ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ;

OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( G_00B84C_TIDIG_COMP_CNT ( CurrentProgramInfo . ComputePGMRSrc2 ) ) , false ) ;


<s> getAmdKernelCode ( KernelCode , CurrentProgramInfo , * MF ) ; getTargetStreamer ( ) -> EmitAMDKernelCodeT ( KernelCode ) ; } if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA ) return ; if ( ! STM . hasCodeObjectV3 ( ) && STM . isAmdHsaOS ( ) ) HSAMetadataStream . emitKernel ( * MF , CurrentProgramInfo ) ;


<s> const <ISA_LIT>MachineFunctionInfo & MFI = * MF -> getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; if ( ! MFI . isEntryFunction ( ) ) return ; const GCNSubtarget & STM = MF -> getSubtarget < GCNSubtarget > ( ) ; const Function & F = MF -> getFunction ( ) ; if ( ! STM . hasCodeObjectV3 ( ) && STM . isAmdHsaOrMesa ( F ) && ( F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_KERNEL || F . getCallingConv ( ) == CallingConv :: SPIR_KERNEL ) ) { amd_kernel_code_t KernelCode ; getAmdKernelCode ( KernelCode , CurrentProgramInfo , * MF ) ; getTargetStreamer ( ) -> EmitAMDKernelCodeT ( KernelCode ) ;


<s> getTargetStreamer ( ) -> EmitDirectiveAMDGCNTarget ( ExpectedTarget ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) return ; } if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA && TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDPAL ) return ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) HSAMetadataStream . begin ( M ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDPAL ) readPALMetadata ( M ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectVersion ( <NUM_LIT> , <NUM_LIT> ) ; IsaVersion Version = getIsaVersion ( getSTI ( ) -> getCPU ( ) ) ; getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectISA ( Version . Major , Version . Minor , Version . Stepping , <STR_LIT> , <STR_LIT> ) ;


<s> if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA && TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDPAL ) return ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) HSAMetadataStream . begin ( M ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDPAL ) readPALMetadata ( M ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectVersion ( <NUM_LIT> , <NUM_LIT> ) ;

IsaVersion Version = getIsaVersion ( getSTI ( ) -> getCPU ( ) ) ;


Out . wavefront_sgpr_count = CurrentProgramInfo . NumSGPR ;


Out . workgroup_group_segment_byte_size = CurrentProgramInfo . LDSSize ;


<s> Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs ; ProgInfo . NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs ; } } if ( STM . hasSGPRInitBug ( ) ) { ProgInfo . NumSGPR = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; ProgInfo . NumSGPRsForWavesPerEU = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; } if ( MFI -> getNumUserSGPRs ( ) > STM . getMaxNumUserSGPRs ( ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getNumUserSGPRs ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } if ( MFI -> getLDSSize ( ) > static_cast < unsigned > ( STM . getLocalMemorySize ( ) ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getLDSSize ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } ProgInfo . SGPRBlocks = IsaInfo :: getNumSGPRBlocks ( & STM , ProgInfo . NumSGPRsForWavesPerEU ) ; ProgInfo . VGPRBlocks = IsaInfo :: getNumVGPRBlocks ( & STM , ProgInfo . NumVGPRsForWavesPerEU ) ; const <ISA_LIT>ModeRegisterDefaults Mode = MFI -> getMode ( ) ; ProgInfo . FloatMode = getFPMode ( Mode ) ; ProgInfo . IEEEMode = Mode . IEEE ; ProgInfo . DX10Clamp = Mode . DX10Clamp ; unsigned LDSAlignShift ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: SEA_ISLANDS ) { LDSAlignShift = <NUM_LIT> ; } else { LDSAlignShift = <NUM_LIT> ; } unsigned LDSSpillSize = MFI -> getLDSWaveSpillSize ( ) * MFI -> getMaxFlatWorkGroupSize ( ) ; ProgInfo . LDSSize = MFI -> getLDSSize ( ) + LDSSpillSize ; ProgInfo . LDSBlocks = alignTo ( ProgInfo . LDSSize , <NUM_LIT> << LDSAlignShift ) >> LDSAlignShift ; unsigned ScratchAlignShift = <NUM_LIT> ; ProgInfo . ScratchBlocks = alignTo ( ProgInfo . ScratchSize * STM . getWavefrontSize ( ) , <NUM_LIT> << ScratchAlignShift ) >> ScratchAlignShift ; if ( getIsaVersion ( getGlobalSTI ( ) -> getCPU ( ) ) . Major >= <NUM_LIT> ) { ProgInfo . WgpMode = STM . isCuModeEnabled ( ) ? <NUM_LIT> : <NUM_LIT> ; ProgInfo . MemOrdered = <NUM_LIT> ; } unsigned TIDIGCompCnt = <NUM_LIT> ;

if ( MFI -> hasWorkItemIDZ ( ) ) TIDIGCompCnt = <NUM_LIT> ;


<s> <ISA_LIT>AsmPrinter :: <ISA_LIT>AsmPrinter ( TargetMachine & TM , std :: unique_ptr < MCStreamer > Streamer ) : AsmPrinter ( TM , std :: move ( Streamer ) ) {

if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) {


<s> OutStreamer -> SwitchSection ( getObjFileLowering ( ) . getTextSection ( ) ) ; getTargetStreamer ( ) -> EmitCodeEnd ( STI ) ; } return AsmPrinter :: doFinalization ( M ) ;


<s> if ( ( <STR_LIT> ( STI ) || <STR_LIT> ( STI ) ) && ( STI . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA || STI . getTargetTriple ( ) . getOS ( ) == Triple :: AMDPAL ) ) { OutStreamer -> SwitchSection ( getObjFileLowering ( ) . getTextSection ( ) ) ; getTargetStreamer ( ) -> EmitCodeEnd ( STI ) ; } return AsmPrinter :: doFinalization ( M ) ;


<s> void <ISA_LIT>AsmPrinter :: emitBasicBlockStart ( const MachineBasicBlock & MBB ) { if ( DumpCodeInstEmitter && ! isBlockOnlyReachableByFallthrough ( & MBB ) ) { DisasmLines . push_back ( ( Twine ( <STR_LIT> ) + Twine ( getFunctionNumber ( ) ) + <STR_LIT> + Twine ( MBB . getNumber ( ) ) + <STR_LIT> ) . str ( ) ) ; DisasmLineMaxLen = std :: max ( DisasmLineMaxLen , DisasmLines . back ( ) . size ( ) ) ; HexLines . push_back ( <STR_LIT> ) ; } AsmPrinter :: emitBasicBlockStart ( MBB ) ;


<s> DisasmLineMaxLen = std :: max ( DisasmLineMaxLen , DisasmLines . back ( ) . size ( ) ) ; HexLines . push_back ( <STR_LIT> ) ; }

AsmPrinter :: emitBasicBlockStart ( MBB ) ;


<s> void <ISA_LIT>AsmPrinter :: emitCommonFunctionComments ( uint32_t NumVGPR , Optional < uint32_t > NumAGPR , uint32_t TotalNumVGPR , uint32_t NumSGPR , uint64_t ScratchSize , uint64_t CodeSize , const <ISA_LIT>MachineFunction * MFI ) { OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( CodeSize ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( NumSGPR ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( NumVGPR ) , false ) ; if ( NumAGPR ) { OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( * NumAGPR ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( TotalNumVGPR ) , false ) ;


<s> OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( * NumAGPR ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( TotalNumVGPR ) , false ) ; } OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( ScratchSize ) , false ) ; OutStreamer -> emitRawComment ( <STR_LIT> + Twine ( MFI -> isMemoryBound ( ) ) , false ) ;


<s> SmallString < <NUM_LIT> > KernelName ; getNameWithPrefix ( KernelName , & MF -> getFunction ( ) ) ; getTargetStreamer ( ) -> EmitAmdhsaKernelDescriptor ( STM , KernelName , getAmdhsaKernelDescriptor ( * MF , CurrentProgramInfo ) , CurrentProgramInfo . NumVGPRsForWavesPerEU , CurrentProgramInfo . NumSGPRsForWavesPerEU - IsaInfo :: getNumExtraSGPRs ( & STM , CurrentProgramInfo . VCCUsed , CurrentProgramInfo . FlatUsed ) , CurrentProgramInfo . VCCUsed , CurrentProgramInfo . FlatUsed ) ; Streamer . PopSection ( ) ;


<s> Streamer . emitValueToAlignment ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ) ; if ( ReadOnlySection . getAlignment ( ) < <NUM_LIT> ) ReadOnlySection . setAlignment ( Align ( <NUM_LIT> ) ) ; const GCNSubtarget & STM = MF -> getSubtarget < GCNSubtarget > ( ) ; SmallString < <NUM_LIT> > KernelName ; getNameWithPrefix ( KernelName , & MF -> getFunction ( ) ) ; getTargetStreamer ( ) -> EmitAmdhsaKernelDescriptor ( STM , KernelName , getAmdhsaKernelDescriptor ( * MF , CurrentProgramInfo ) , CurrentProgramInfo . NumVGPRsForWavesPerEU , CurrentProgramInfo . NumSGPRsForWavesPerEU - IsaInfo :: getNumExtraSGPRs ( & STM , CurrentProgramInfo . VCCUsed , CurrentProgramInfo . FlatUsed ) , CurrentProgramInfo . VCCUsed , CurrentProgramInfo . FlatUsed ) ;


<s> if ( ! MFI . isEntryFunction ( ) ) return ; if ( ( STM . isMesaKernel ( F ) || isHsaAbiVersion2 ( getGlobalSTI ( ) ) ) && ( F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_KERNEL || F . getCallingConv ( ) == CallingConv :: SPIR_KERNEL ) ) { amd_kernel_code_t KernelCode ; getAmdKernelCode ( KernelCode , CurrentProgramInfo , * MF ) ; getTargetStreamer ( ) -> EmitAMDKernelCodeT ( KernelCode ) ; }

if ( STM . isAmdHsaOS ( ) ) HSAMetadataStream -> emitKernel ( * MF , CurrentProgramInfo ) ;


<s> } if ( FunctionTargetID . isSramEccSupported ( ) && FunctionTargetID . getSramEccSetting ( ) != IsaInfo :: TargetIDSetting :: Any && FunctionTargetID . getSramEccSetting ( ) != getTargetStreamer ( ) -> getTargetID ( ) -> getSramEccSetting ( ) ) { OutContext . reportError ( { } , <STR_LIT> + Twine ( MF -> getName ( ) ) + <STR_LIT> ) ; return ; } if ( ! MFI . isEntryFunction ( ) ) return ; if ( ( STM . isMesaKernel ( F ) || isHsaAbiVersion2 ( getGlobalSTI ( ) ) ) && ( F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_KERNEL || F . getCallingConv ( ) == CallingConv :: SPIR_KERNEL ) ) {


<s> AsmPrinter :: emitFunctionEntryLabel ( ) ; return ; } const <ISA_LIT>MachineFunctionInfo * MFI = MF -> getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; const GCNSubtarget & STM = MF -> getSubtarget < GCNSubtarget > ( ) ;

if ( MFI -> isEntryFunction ( ) && STM . isAmdHsaOrMesa ( MF -> getFunction ( ) ) ) {


<s> const Triple :: OSType OS = TM . getTargetTriple ( ) . getOS ( ) ; if ( OS == Triple :: AMDHSA || OS == Triple :: AMDPAL ) return ; MCSymbol * GVSym = getSymbol ( GV ) ; GVSym -> redefineIfPossible ( ) ; if ( GVSym -> isDefined ( ) || GVSym -> isVariable ( ) ) report_fatal_error ( <STR_LIT> + Twine ( GVSym -> getName ( ) ) + <STR_LIT> ) ; const DataLayout & DL = GV -> getParent ( ) -> getDataLayout ( ) ; uint64_t Size = DL . getTypeAllocSize ( GV -> getValueType ( ) ) ; Align Alignment = GV -> getAlign ( ) . getValueOr ( Align ( <NUM_LIT> ) ) ;

emitVisibility ( GVSym , GV -> getVisibility ( ) , ! GV -> isDeclaration ( ) ) ;


<s> MD -> setRsrc2 ( CallingConv :: <ISA_LIT>_CS , CurrentProgramInfo . ComputePGMRSrc2 ) ; MD -> setFunctionLdsSize ( MF , CurrentProgramInfo . LDSSize ) ; MD -> setFunctionNumUsedVgprs ( MF , CurrentProgramInfo . NumVGPRsForWavesPerEU ) ; MD -> setFunctionNumUsedSgprs ( MF , CurrentProgramInfo . NumSGPRsForWavesPerEU ) ;


<s> const MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; MD -> setFunctionScratchSize ( MF , MFI . getStackSize ( ) ) ; MD -> setRsrc1 ( CallingConv :: <ISA_LIT>_CS , CurrentProgramInfo . getPGMRSrc1 ( CallingConv :: <ISA_LIT>_CS ) ) ; MD -> setRsrc2 ( CallingConv :: <ISA_LIT>_CS , CurrentProgramInfo . ComputePGMRSrc2 ) ; MD -> setFunctionLdsSize ( MF , CurrentProgramInfo . LDSSize ) ;

MD -> setFunctionNumUsedVgprs ( MF , CurrentProgramInfo . NumVGPRsForWavesPerEU ) ;


<s> MD -> setScratchSize ( CC , alignTo ( CurrentProgramInfo . ScratchSize , <NUM_LIT> ) ) ; if ( MF . getFunction ( ) . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { MD -> setRsrc2 ( CC , S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( CurrentProgramInfo . LDSBlocks ) ) ; MD -> setSpiPsInputEna ( MFI -> getP<ISA_LIT>nputEnable ( ) ) ; MD -> setSpiPsInputAddr ( MFI -> getP<ISA_LIT>nputAddr ( ) ) ; }

const GCNSubtarget & STM = MF . getSubtarget < GCNSubtarget > ( ) ;


<s> if ( MF . getFunction ( ) . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ) { OutStreamer -> emitInt32 ( R_00B02C_SPI_SHADER_PGM_RSRC2_PS ) ; OutStreamer -> emitInt32 ( S_00B02C_EXTRA_LDS_<ISA_LIT>ZE ( CurrentProgramInfo . LDSBlocks ) ) ; OutStreamer -> emitInt32 ( R_0286CC_SPI_PS_INPUT_ENA ) ; OutStreamer -> emitInt32 ( MFI -> getP<ISA_LIT>nputEnable ( ) ) ; OutStreamer -> emitInt32 ( R_0286D0_SPI_PS_INPUT_ADDR ) ; OutStreamer -> emitInt32 ( MFI -> getP<ISA_LIT>nputAddr ( ) ) ; } OutStreamer -> emitInt32 ( R_SPILLED_SGPRS ) ;

OutStreamer -> emitInt32 ( MFI -> getNumSpilledSGPRs ( ) ) ;


<s> if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDPAL ) getTargetStreamer ( ) -> getPALMetadata ( ) -> readFromIR ( M ) ; if ( isHsaAbiVersion3Or4 ( getGlobalSTI ( ) ) ) return ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectVersion ( <NUM_LIT> , <NUM_LIT> ) ;

IsaVersion Version = getIsaVersion ( getGlobalSTI ( ) -> getCPU ( ) ) ;


<s> void <ISA_LIT>AsmPrinter :: emitStartOfAsmFile ( Module & M ) { if ( getTargetStreamer ( ) && ! getTargetStreamer ( ) -> getTargetID ( ) ) initializeTargetID ( M ) ; if ( TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDHSA && TM . getTargetTriple ( ) . getOS ( ) != Triple :: AMDPAL ) return ; if ( isHsaAbiVersion3Or4 ( getGlobalSTI ( ) ) ) getTargetStreamer ( ) -> EmitDirectiveAMDGCNTarget ( ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) HSAMetadataStream -> begin ( M , * getTargetStreamer ( ) -> getTargetID ( ) ) ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDPAL ) getTargetStreamer ( ) -> getPALMetadata ( ) -> readFromIR ( M ) ; if ( isHsaAbiVersion3Or4 ( getGlobalSTI ( ) ) ) return ; if ( TM . getTargetTriple ( ) . getOS ( ) == Triple :: AMDHSA ) getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectVersion ( <NUM_LIT> , <NUM_LIT> ) ; IsaVersion Version = getIsaVersion ( getGlobalSTI ( ) -> getCPU ( ) ) ; getTargetStreamer ( ) -> EmitDirectiveHSACodeObjectISAV2 ( Version . Major , Version . Minor , Version . Stepping , <STR_LIT> , <STR_LIT> ) ;


<s> memset ( & KernelDescriptor , <NUM_LIT> , sizeof ( KernelDescriptor ) ) ; assert ( isUInt < <NUM_LIT> > ( PI . ScratchSize ) ) ; assert ( isUInt < <NUM_LIT> > ( PI . getComputePGMRSrc1 ( ) ) ) ; assert ( isUInt < <NUM_LIT> > ( PI . ComputePGMRSrc2 ) ) ; KernelDescriptor . group_segment_fixed_size = PI . LDSSize ; KernelDescriptor . private_segment_fixed_size = PI . ScratchSize ; Align MaxKernArgAlign ; KernelDescriptor . kernarg_size = STM . getKernArgSegmentSize ( F , MaxKernArgAlign ) ; KernelDescriptor . compute_pgm_rsrc1 = PI . getComputePGMRSrc1 ( ) ; KernelDescriptor . compute_pgm_rsrc2 = PI . ComputePGMRSrc2 ; KernelDescriptor . kernel_code_properties = getAmdhsaKernelCodeProperties ( MF ) ; assert ( STM . hasGFX90AInsts ( ) || CurrentProgramInfo . ComputePGMRSrc3GFX90A == <NUM_LIT> ) ;

if ( STM . hasGFX90AInsts ( ) ) KernelDescriptor . compute_pgm_rsrc3 = CurrentProgramInfo . ComputePGMRSrc3GFX90A ;


<s> void <ISA_LIT>AsmPrinter :: getAnalysisUsage ( AnalysisUsage & AU ) const { AU . addRequired < <ISA_LIT>ResourceUsageAnalysis > ( ) ; AU . addPreserved < <ISA_LIT>ResourceUsageAnalysis > ( ) ; AsmPrinter :: getAnalysisUsage ( AU ) ;


<s> AU . addRequired < <ISA_LIT>ResourceUsageAnalysis > ( ) ;

AU . addPreserved < <ISA_LIT>ResourceUsageAnalysis > ( ) ;


<s> static amd_element_byte_size_t getElementByteSizeValue ( unsigned Size ) { switch ( Size ) {


<s> return FP_ROUND_MODE_SP ( FP_ROUND_ROUND_TO_NEAREST ) | FP_ROUND_MODE_DP ( FP_ROUND_ROUND_TO_NEAREST ) | FP_DENORM_MODE_SP ( Mode . fpDenormModeSPValue ( ) ) | FP_DENORM_MODE_DP ( Mode . fpDenormModeDPValue ( ) ) ;


<s> static uint32_t getFPMode ( <STR_LIT> Mode ) { return FP_ROUND_MODE_SP ( FP_ROUND_ROUND_TO_NEAREST ) | FP_ROUND_MODE_DP ( FP_ROUND_ROUND_TO_NEAREST ) | FP_DENORM_MODE_SP ( Mode . fpDenormModeSPValue ( ) ) | FP_DENORM_MODE_DP ( Mode . fpDenormModeDPValue ( ) ) ;


<s> uint64_t <ISA_LIT>AsmPrinter :: getFunctionCodeSize ( const MachineFunction & MF ) const { const GCNSubtarget & STM = MF . getSubtarget < GCNSubtarget > ( ) ; const <ISA_LIT>InstrInfo * TII = STM . getInstrInfo ( ) ; uint64_t CodeSize = <NUM_LIT> ; for ( const MachineBasicBlock & MBB : MF ) { for ( const MachineInstr & MI : MBB ) { if ( MI . isDebugInstr ( ) ) continue ; CodeSize += TII -> getInstSizeInBytes ( MI ) ; } }


<s> StringRef <ISA_LIT>AsmPrinter :: getPassName ( ) const {


<s> default : LLVM_FALLTHROUGH ; case CallingConv :: <ISA_LIT>_CS : return R_00B848_COMPUTE_PGM_RSRC1 ; case CallingConv :: <ISA_LIT>_LS : return R_00B528_SPI_SHADER_PGM_RSRC1_LS ; case CallingConv :: <ISA_LIT>_HS : return R_00B428_SPI_SHADER_PGM_RSRC1_HS ;

case CallingConv :: <ISA_LIT>_ES : return R_00B328_SPI_SHADER_PGM_RSRC1_ES ;


<s> case CallingConv :: <ISA_LIT>_CS : return R_00B848_COMPUTE_PGM_RSRC1 ; case CallingConv :: <ISA_LIT>_LS : return R_00B528_SPI_SHADER_PGM_RSRC1_LS ; case CallingConv :: <ISA_LIT>_HS : return R_00B428_SPI_SHADER_PGM_RSRC1_HS ; case CallingConv :: <ISA_LIT>_ES : return R_00B328_SPI_SHADER_PGM_RSRC1_ES ; case CallingConv :: <ISA_LIT>_GS : return R_00B228_SPI_SHADER_PGM_RSRC1_GS ; case CallingConv :: <ISA_LIT>_VS : return R_00B128_SPI_SHADER_PGM_RSRC1_VS ;

case CallingConv :: <ISA_LIT>_PS : return R_00B028_SPI_SHADER_PGM_RSRC1_PS ;


<s> ProgInfo . NumSGPR = Info . NumExplicitSGPR ; ProgInfo . ScratchSize = Info . PrivateSegmentSize ; ProgInfo . VCCUsed = Info . UsesVCC ; ProgInfo . FlatUsed = Info . UsesFlatScratch ; ProgInfo . DynamicCallStack = Info . HasDynamicallySizedStack || Info . HasRecursion ; const uint64_t MaxScratchPerWorkitem = GCNSubtarget :: MaxWaveScratchSize / STM . getWavefrontSize ( ) ; if ( ProgInfo . ScratchSize > MaxScratchPerWorkitem ) { DiagnosticInfoStackSize DiagStackSize ( MF . getFunction ( ) , ProgInfo . ScratchSize , MaxScratchPerWorkitem , DS_Error ) ; MF . getFunction ( ) . getContext ( ) . diagnose ( DiagStackSize ) ; } const <ISA_LIT>MachineFunctionInfo * MFI = MF . getInfo < <ISA_LIT>MachineFunctionInfo > ( ) ; unsigned ExtraSGPRs = IsaInfo :: getNumExtraSGPRs ( & STM , ProgInfo . VCCUsed , ProgInfo . FlatUsed ) ; if ( STM . getGeneration ( ) >= <ISA_LIT>Subtarget :: VOLCANIC_ISLANDS && ! STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , MaxAddressableNumSGPRs , DS_Error , DK_ResourceLimit ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs - <NUM_LIT> ; } } ProgInfo . NumSGPR += ExtraSGPRs ; const Function & F = MF . getFunction ( ) ; unsigned WaveDispatchNumSGPR = <NUM_LIT> , WaveDispatchNumVGPR = <NUM_LIT> ; if ( isShader ( F . getCallingConv ( ) ) ) { bool IsPixelShader = F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS && ! STM . isAmdHsaOS ( ) ; uint32_t InputEna = <NUM_LIT> ; uint32_t InputAddr = <NUM_LIT> ; unsigned LastEna = <NUM_LIT> ; if ( IsPixelShader ) { InputEna = MFI -> getP<ISA_LIT>nputEnable ( ) ; InputAddr = MFI -> getP<ISA_LIT>nputAddr ( ) ; assert ( ( InputEna || InputAddr ) && <STR_LIT> <STR_LIT> ) ; LastEna = InputEna ? findLastSet ( InputEna ) + <NUM_LIT> : <NUM_LIT> ; } const DataLayout & DL = F . getParent ( ) -> getDataLayout ( ) ; unsigned PSArgCount = <NUM_LIT> ; unsigned IntermediateVGPR = <NUM_LIT> ; for ( auto & Arg : F . args ( ) ) { unsigned NumRegs = ( DL . getTypeSizeInBits ( Arg . getType ( ) ) + <NUM_LIT> ) / <NUM_LIT> ; if ( Arg . hasAttribute ( Attribute :: InReg ) ) { WaveDispatchNumSGPR += NumRegs ; } else {

if ( IsPixelShader && PSArgCount < <NUM_LIT> ) {


<s> } } ProgInfo . NumSGPR = std :: max ( ProgInfo . NumSGPR , WaveDispatchNumSGPR ) ; ProgInfo . NumArchVGPR = std :: max ( ProgInfo . NumVGPR , WaveDispatchNumVGPR ) ; ProgInfo . NumVGPR = Info . getTotalNumVGPRs ( STM , Info . NumAGPR , ProgInfo . NumArchVGPR ) ; } ProgInfo . NumSGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumSGPR , <NUM_LIT> ) , STM . getMinNumSGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; ProgInfo . NumVGPRsForWavesPerEU = std :: max ( std :: max ( ProgInfo . NumVGPR , <NUM_LIT> ) , STM . getMinNumVGPRs ( MFI -> getMaxWavesPerEU ( ) ) ) ; if ( STM . getGeneration ( ) <= <ISA_LIT>Subtarget :: SEA_ISLANDS || STM . hasSGPRInitBug ( ) ) { unsigned MaxAddressableNumSGPRs = STM . getAddressableNumSGPRs ( ) ; if ( ProgInfo . NumSGPR > MaxAddressableNumSGPRs ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , ProgInfo . NumSGPR , MaxAddressableNumSGPRs , DS_Error , DK_ResourceLimit ) ; Ctx . diagnose ( Diag ) ; ProgInfo . NumSGPR = MaxAddressableNumSGPRs ; ProgInfo . NumSGPRsForWavesPerEU = MaxAddressableNumSGPRs ; } } if ( STM . hasSGPRInitBug ( ) ) { ProgInfo . NumSGPR = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; ProgInfo . NumSGPRsForWavesPerEU = <STR_LIT> :: FIXED_NUM_SGPRS_FOR_INIT_BUG ; } if ( MFI -> getNumUserSGPRs ( ) > STM . getMaxNumUserSGPRs ( ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getNumUserSGPRs ( ) , STM . getMaxNumUserSGPRs ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } if ( MFI -> getLDSSize ( ) > static_cast < unsigned > ( STM . getLocalMemorySize ( ) ) ) { LLVMContext & Ctx = MF . getFunction ( ) . getContext ( ) ; DiagnosticInfoResourceLimit Diag ( MF . getFunction ( ) , <STR_LIT> , MFI -> getLDSSize ( ) , STM . getLocalMemorySize ( ) , DS_Error ) ; Ctx . diagnose ( Diag ) ; } ProgInfo . SGPRBlocks = IsaInfo :: getNumSGPRBlocks ( & STM , ProgInfo . NumSGPRsForWavesPerEU ) ; ProgInfo . VGPRBlocks = IsaInfo :: getNumVGPRBlocks ( & STM , ProgInfo . NumVGPRsForWavesPerEU ) ; const <ISA_LIT>ModeRegisterDefaults Mode = MFI -> getMode ( ) ; ProgInfo . FloatMode = getFPMode ( Mode ) ; ProgInfo . IEEEMode = Mode . IEEE ; ProgInfo . DX10Clamp = Mode . DX10Clamp ; unsigned LDSAlignShift ; if ( STM . getGeneration ( ) < <ISA_LIT>Subtarget :: SEA_ISLANDS ) { LDSAlignShift = <NUM_LIT> ; } else { LDSAlignShift = <NUM_LIT> ; }

unsigned LDSSpillSize = MFI -> getLDSWaveSpillSize ( ) * MFI -> getMaxFlatWorkGroupSize ( ) ;


<s> return static_cast < <ISA_LIT>TargetStreamer * > ( OutStreamer -> getTargetStreamer ( ) ) ;


<s> auto & TSTargetID = getTargetStreamer ( ) -> getTargetID ( ) ; if ( ( ! TSTargetID -> isXnackSupported ( ) || TSTargetID -> isXnackOnOrOff ( ) ) && ( ! TSTargetID -> isSramEccSupported ( ) || TSTargetID -> isSramEccOnOrOff ( ) ) ) break ; const GCNSubtarget & STM = TM . getSubtarget < GCNSubtarget > ( F ) ; const IsaInfo :: <ISA_LIT>TargetID & STMTargetID = STM . getTargetID ( ) ;

if ( TSTargetID -> isXnackSupported ( ) ) if ( TSTargetID -> getXnackSetting ( ) == IsaInfo :: TargetIDSetting :: Any ) TSTargetID -> setXnackSetting ( STMTargetID . getXnackSetting ( ) ) ;


<s> if ( ! AsmPrinter :: isBlockOnlyReachableByFallthrough ( MBB ) ) return false ; if ( MBB -> empty ( ) ) return true ;

return ( MBB -> back ( ) . getOpcode ( ) != <STR_LIT> ) ;


<s> TargetRegistry :: RegisterAsmPrinter ( getThe<ISA_LIT>Target ( ) , llvm :: create<ISA_LIT>AsmPrinterPass ) ; TargetRegistry :: RegisterAsmPrinter ( getTheGCNTarget ( ) , create<ISA_LIT>AsmPrinterPass ) ;


<s> void LLVM_EXTERNAL_VI<ISA_LIT>BILITY LLVMInitialize<ISA_LIT>AsmPrinter ( ) { TargetRegistry :: RegisterAsmPrinter ( getThe<ISA_LIT>Target ( ) , llvm :: create<ISA_LIT>AsmPrinterPass ) ;

TargetRegistry :: RegisterAsmPrinter ( getTheGCNTarget ( ) , create<ISA_LIT>AsmPrinterPass ) ;


<s> break ; default : return true ; } } const MachineOperand & MO = MI -> getOperand ( OpNo ) ; if ( MO . isReg ( ) ) { <ISA_LIT>InstPrinter :: printRegOperand ( MO . getReg ( ) , O , * MF -> getSubtarget ( ) . getRegisterInfo ( ) ) ; return false ; } else if ( MO . isImm ( ) ) { int64_t Val = MO . getImm ( ) ; if ( <STR_LIT> ( Val ) ) { O << Val ; } else if ( isUInt < <NUM_LIT> > ( Val ) ) { O << format ( <STR_LIT> PRIx16 , static_cast < uint16_t > ( Val ) ) ; } else if ( isUInt < <NUM_LIT> > ( Val ) ) {

O << format ( <STR_LIT> PRIx32 , static_cast < uint32_t > ( Val ) ) ;


<s> return true ; } } const MachineOperand & MO = MI -> getOperand ( OpNo ) ; if ( MO . isReg ( ) ) { <ISA_LIT>InstPrinter :: printRegOperand ( MO . getReg ( ) , O , * MF -> getSubtarget ( ) . getRegisterInfo ( ) ) ; return false ; } else if ( MO . isImm ( ) ) { int64_t Val = MO . getImm ( ) ;


<s>
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
MFI
->
needsWaveLimiter
(
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_SCRATCH_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_USER_SGPR
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TRAP_HANDLER
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_X_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Y_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TGID_Z_EN
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
G_00B84C_TIDIG_COMP_CNT
(
CurrentProgramInfo
.
ComputePGMRSrc2
)
)
,
false
)
;
assert
(
STM
.
hasGFX90AInsts
(
)
||
CurrentProgramInfo
.
ComputePGMRSrc3GFX90A
==
<NUM_LIT>
)
;
if
(
STM
.
hasGFX90AInsts
(
)
)
{
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
(
AMDHSA_BITS_GET
(
CurrentProgramInfo
.
ComputePGMRSrc3GFX90A
,
amdhsa
::
COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET
)
)
)
,
false
)
;
OutStreamer
->
emitRawComment
(
<STR_LIT>
+
Twine
(
(
AMDHSA_BITS_GET
(
CurrentProgramInfo
.
ComputePGMRSrc3GFX90A
,
amdhsa
::
COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT
)
)
)
,
false
)
;
}
}
if
(
DumpCodeInstEmitter
)
{
OutStreamer
->
SwitchSection
(
Context
.
getELFSection
(
<STR_LIT>
,
ELF
::
SHT_PROGBITS
,
<NUM_LIT>
)
)
;
for
(
size_t
i
=
<NUM_LIT>
;
i
<
DisasmLines
.
size
(
)
;
++
i
)
{
std
::
string
Comment
=
<STR_LIT>
;
if
(
!
HexLines
[
i
]
.
empty
(
)
)
{
Comment
=
std
::
string
(
DisasmLineMaxLen
DisasmLines
[
i
]
.
size
(
)
,
' '
)
;
Comment
+=
<STR_LIT>
+
HexLines
[
i
]
+
<STR_LIT>
;
}
OutStreamer
->
emitBytes
(
StringRef
(
DisasmLines
[
i
]
)
)
;
OutStreamer
->
emitBytes
(
StringRef
(
Comment
)
)
;
}
}
return
false
;


<s> unsigned decode ( unsigned Code ) const {


<s> unsigned decode ( unsigned Code ) const { return ( Code >> Shift ) & Mask ;


<s> unsigned encode ( unsigned Val ) const {


<s> bool isSupported ( const MCSubtargetInfo & STI ) const { return ! Cond || Cond ( STI ) ;


<s> Function * UpdateDPP = <STR_LIT> ( M , <STR_LIT> , Ty ) ; Function * PermLaneX16 = <STR_LIT> ( M , <STR_LIT> , { } ) ; Function * ReadLane = <STR_LIT> ( M , <STR_LIT> , { } ) ; for ( unsigned Idx = <NUM_LIT> ; Idx < <NUM_LIT> ; Idx ++ ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 | <NUM_LIT> << Idx ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } if ( ST -> hasDPPBroadcasts ( ) ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST15 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST31 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } else { Value * const PermX = B . CreateCall ( PermLaneX16 , { V , V , B . getInt32 ( - <NUM_LIT> ) , B . getInt32 ( - <NUM_LIT> ) , B . getFalse ( ) , B . getFalse ( ) } ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , PermX , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ;


<s> Value * <ISA_LIT>AtomicOptimizer :: buildScan ( IRBuilder < > & B , AtomicRMWInst :: BinOp Op , Value * V , Value * const Identity ) const { Type * const Ty = V -> getType ( ) ; Module * M = B . GetInsertBlock ( ) -> getModule ( ) ; Function * UpdateDPP = <STR_LIT> ( M , <STR_LIT> , Ty ) ; Function * PermLaneX16 = <STR_LIT> ( M , <STR_LIT> , { } ) ; Function * ReadLane = <STR_LIT> ( M , <STR_LIT> , { } ) ; for ( unsigned Idx = <NUM_LIT> ; Idx < <NUM_LIT> ; Idx ++ ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 | <NUM_LIT> << Idx ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } if ( ST -> hasDPPBroadcasts ( ) ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST15 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST31 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } else { Value * const PermX = B . CreateCall ( PermLaneX16 , { V , V , B . getInt32 ( - <NUM_LIT> ) , B . getInt32 ( - <NUM_LIT> ) , B . getFalse ( ) , B . getFalse ( ) } ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , PermX , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; if ( ! ST -> isWave32 ( ) ) { Value * const Lane31 = B . CreateCall ( ReadLane , { V , B . getInt32 ( <NUM_LIT> ) } ) ;

V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , Lane31 , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ;


<s> Value * Old = V ; V = B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 + <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ; V = B . CreateCall ( WriteLane , { B . CreateCall ( ReadLane , { Old , B . getInt32 ( <NUM_LIT> ) } ) , B . getInt32 ( <NUM_LIT> ) , V } ) ; if ( ! ST -> isWave32 ( ) ) {


<s> DominatorTreeWrapperPass * const DTW = getAnalysisIfAvailable < DominatorTreeWrapperPass > ( ) ; DT = DTW ? & DTW -> getDomTree ( ) : nullptr ; const TargetPassConfig & TPC = getAnalysis < TargetPassConfig > ( ) ; const TargetMachine & TM = TPC . getTM < TargetMachine > ( ) ; ST = & TM . getSubtarget < GCNSubtarget > ( F ) ; IsPixelShader = F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ;


<s> const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! ST -> hasDPP ( ) || DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) { return ; } const ReplacementInfo Info = { & I , Op , ValIdx , ValDivergent } ;


<s> break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ; if ( DA -> isDivergentUse ( & I . getOperandUse ( PtrIdx ) ) ) { return ; } const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! ST -> hasDPP ( ) || DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) { return ; } const ReplacementInfo Info = { & I , Op , ValIdx , ValDivergent } ;


<s> switch ( I . getIntrinsicID ( ) ) { default : return ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Add ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Sub ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: And ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Or ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Xor ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Min ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMin ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Max ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMax ; break ; } const unsigned ValIdx = <NUM_LIT> ; const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! ST -> hasDPP ( ) || DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) { return ; } for ( unsigned Idx = <NUM_LIT> ; Idx < I . getNumOperands ( ) ; Idx ++ ) { if ( DA -> isDivergentUse ( & I . getOperandUse ( Idx ) ) ) { return ; } }

const ReplacementInfo Info = { & I , Op , ValIdx , ValDivergent } ;


<s> break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMax ; break ; } const unsigned ValIdx = <NUM_LIT> ; const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! ST -> hasDPP ( ) || DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) { return ; } for ( unsigned Idx = <NUM_LIT> ; Idx < I . getNumOperands ( ) ; Idx ++ ) { if ( DA -> isDivergentUse ( & I . getOperandUse ( Idx ) ) ) { return ;


<s> void <ISA_LIT>AtomicOptimizer :: setConvergent ( CallInst * const CI ) const {

CI -> addAttribute ( AttributeList :: FunctionIndex , Attribute :: Convergent ) ;


<s> void <ISA_LIT>AtomicOptimizer :: setConvergent ( CallInst * const CI ) const { CI -> addAttribute ( AttributeList :: FunctionIndex , Attribute :: Convergent ) ;


<s> break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ; if ( DA -> isDivergent ( I . getOperand ( PtrIdx ) ) ) { return ; } const bool ValDivergent = DA -> isDivergent ( I . getOperand ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ;


<s> break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ; if ( DA -> isDivergent ( I . getOperand ( PtrIdx ) ) ) { return ; } const bool ValDivergent = DA -> isDivergent ( I . getOperand ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ; } const ReplacementInfo Info = { & I , Op , ValIdx , ValDivergent } ; ToReplace . push_back ( Info ) ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = Instruction :: Add ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = Instruction :: Sub ; break ; } const unsigned ValIdx = <NUM_LIT> ; const bool ValDivergent = DA -> isDivergent ( I . getOperand ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ; } for ( unsigned Idx = <NUM_LIT> ; Idx < I . getNumOperands ( ) ; Idx ++ ) {

if ( DA -> isDivergent ( I . getOperand ( Idx ) ) ) {


<s> static Value * buildMul ( IRBuilder < > & B , Value * LHS , Value * RHS ) {

const ConstantInt * CI = dyn_cast < ConstantInt > ( LHS ) ;


<s> V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 | <NUM_LIT> << Idx ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } if ( ST -> hasDPPBroadcasts ( ) ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST15 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST31 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } else { assert ( ST -> hasPermLaneX16 ( ) ) ; Value * const PermX = B . CreateIntrinsic ( <STR_LIT> , { } , { V , V , B . getInt32 ( - <NUM_LIT> ) , B . getInt32 ( - <NUM_LIT> ) , B . getFalse ( ) , B . getFalse ( ) } ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , PermX , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; if ( ! ST -> isWave32 ( ) ) { Value * const Lane31 = B . CreateIntrinsic ( <STR_LIT> , { } , { V , B . getInt32 ( <NUM_LIT> ) } ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , Lane31 , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; }


<s> Type * const Ty = V -> getType ( ) ; Module * M = B . GetInsertBlock ( ) -> getModule ( ) ; Function * UpdateDPP = <STR_LIT> ( M , <STR_LIT> , Ty ) ; for ( unsigned Idx = <NUM_LIT> ; Idx < <NUM_LIT> ; Idx ++ ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 | <NUM_LIT> << Idx ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } if ( ST -> hasDPPBroadcasts ( ) ) { V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST15 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: BCAST31 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ; } else { assert ( ST -> hasPermLaneX16 ( ) ) ; Value * const PermX = B . CreateIntrinsic ( <STR_LIT> , { } , { V , V , B . getInt32 ( - <NUM_LIT> ) , B . getInt32 ( - <NUM_LIT> ) , B . getFalse ( ) , B . getFalse ( ) } ) ;

V = buildNonAtomicBinOp ( B , Op , V , B . CreateCall ( UpdateDPP , { Identity , PermX , B . getInt32 ( DPP :: QUAD_PERM_ID ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ) ;


<s> Function * WriteLane = <STR_LIT> ( M , <STR_LIT> , { } ) ; Value * Old = V ; V = B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 + <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ; V = B . CreateCall ( WriteLane , { B . CreateCall ( ReadLane , { Old , B . getInt32 ( <NUM_LIT> ) } ) , B . getInt32 ( <NUM_LIT> ) , V } ) ;


<s> Value * <ISA_LIT>AtomicOptimizer :: buildShiftRight ( IRBuilder < > & B , Value * V , Value * const Identity ) const { Type * const Ty = V -> getType ( ) ; Module * M = B . GetInsertBlock ( ) -> getModule ( ) ; Function * UpdateDPP = <STR_LIT> ( M , <STR_LIT> , Ty ) ; if ( ST -> hasDPPWavefrontShifts ( ) ) { V = B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: WAVE_SHR1 ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ; } else { Function * ReadLane = <STR_LIT> ( M , <STR_LIT> , { } ) ; Function * WriteLane = <STR_LIT> ( M , <STR_LIT> , { } ) ; Value * Old = V ; V = B . CreateCall ( UpdateDPP , { Identity , V , B . getInt32 ( DPP :: ROW_SHR0 + <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getInt32 ( <NUM_LIT> ) , B . getFalse ( ) } ) ; V = B . CreateCall ( WriteLane , { B . CreateCall ( ReadLane , { Old , B . getInt32 ( <NUM_LIT> ) } ) , B . getInt32 ( <NUM_LIT> ) , V } ) ; if ( ! ST -> isWave32 ( ) ) { V = B . CreateCall ( WriteLane , { B . CreateCall ( ReadLane , { Old , B . getInt32 ( <NUM_LIT> ) } ) , B . getInt32 ( <NUM_LIT> ) , V } ) ; V = B . CreateCall ( WriteLane , { B . CreateCall ( ReadLane , { Old , B . getInt32 ( <NUM_LIT> ) } ) , B . getInt32 ( <NUM_LIT> ) , V } ) ;


<s> CmpInst :: Predicate Pred ; switch ( Op ) { default : llvm_unreachable ( <STR_LIT> ) ; case AtomicRMWInst :: Add : return B . CreateBinOp ( Instruction :: Add , LHS , RHS ) ; case AtomicRMWInst :: Sub : return B . CreateBinOp ( Instruction :: Sub , LHS , RHS ) ; case AtomicRMWInst :: Max :


<s> static APInt getIdentityValueForAtomicOp ( AtomicRMWInst :: BinOp Op , unsigned BitWidth ) { switch ( Op ) { default : llvm_unreachable ( <STR_LIT> ) ; case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub :


<s> llvm_unreachable ( <STR_LIT> ) ; case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub : case AtomicRMWInst :: UMax : return APInt :: getMinValue ( BitWidth ) ; case AtomicRMWInst :: UMin : return APInt :: getMaxValue ( BitWidth ) ; case AtomicRMWInst :: Max : return APInt :: getSignedMinValue ( BitWidth ) ; case AtomicRMWInst :: Min :

return APInt :: getSignedMaxValue ( BitWidth ) ;


<s> AtomicRMWInst :: BinOp Op = I . getOperation ( ) ; switch ( Op ) { default : return ; case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub : case AtomicRMWInst :: Max : case AtomicRMWInst :: Min : case AtomicRMWInst :: UMax : case AtomicRMWInst :: UMin : break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ; if ( DA -> isDivergent ( I . getOperand ( PtrIdx ) ) ) { return ; } const bool ValDivergent = DA -> isDivergent ( I . getOperand ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ; } const ReplacementInfo Info = { & I , Op , ValIdx , ValDivergent } ;


<s> case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMin ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Max ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMax ; break ; } const unsigned ValIdx = <NUM_LIT> ; const bool ValDivergent = DA -> isDivergent ( I . getOperand ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ; } for ( unsigned Idx = <NUM_LIT> ; Idx < I . getNumOperands ( ) ; Idx ++ ) { if ( DA -> isDivergent ( I . getOperand ( Idx ) ) ) { return ; }


<s> void <ISA_LIT>AtomicOptimizer :: visitAtomicRMWInst ( AtomicRMWInst & I ) { switch ( I . getPointerAddressSpace ( ) ) { default : return ; case <ISA_LIT>AS :: GLOBAL_ADDRESS : case <ISA_LIT>AS :: LOCAL_ADDRESS : break ; } AtomicRMWInst :: BinOp Op = I . getOperation ( ) ; switch ( Op ) { default : return ; case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub : case AtomicRMWInst :: And : case AtomicRMWInst :: Or : case AtomicRMWInst :: Xor : case AtomicRMWInst :: Max : case AtomicRMWInst :: Min : case AtomicRMWInst :: UMax : case AtomicRMWInst :: UMin : break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ;

if ( DA -> isDivergent ( I . getOperand ( PtrIdx ) ) ) {


<s> void <ISA_LIT>AtomicOptimizer :: visitAtomicRMWInst ( AtomicRMWInst & I ) { switch ( I . getPointerAddressSpace ( ) ) { default : return ; case <ISA_LIT>AS :: GLOBAL_ADDRESS : case <ISA_LIT>AS :: LOCAL_ADDRESS : break ; } AtomicRMWInst :: BinOp Op = I . getOperation ( ) ; switch ( Op ) { default : return ; case AtomicRMWInst :: Add :


<s> break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Sub ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: And ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Or ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Xor ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Min ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMin ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Max ; break ;


<s> DT = DTW ? & DTW -> getDomTree ( ) : nullptr ; const TargetPassConfig & TPC = getAnalysis < TargetPassConfig > ( ) ; const TargetMachine & TM = TPC . getTM < TargetMachine > ( ) ; const GCNSubtarget & ST = TM . getSubtarget < GCNSubtarget > ( F ) ; HasDPP = ST . hasDPP ( ) ; visit ( F ) ;

const bool Changed = ! ToReplace . empty ( ) ;


<s> DL = & F . getParent ( ) -> getDataLayout ( ) ; DominatorTreeWrapperPass * const DTW = getAnalysisIfAvailable < DominatorTreeWrapperPass > ( ) ; DT = DTW ? & DTW -> getDomTree ( ) : nullptr ; const TargetPassConfig & TPC = getAnalysis < TargetPassConfig > ( ) ; const TargetMachine & TM = TPC . getTM < TargetMachine > ( ) ; const GCNSubtarget & ST = TM . getSubtarget < GCNSubtarget > ( F ) ;


<s> Instruction * const Ctpop = B . CreateUnaryIntrinsic ( <STR_LIT> , Ballot ) ; Value * const CtpopCast = B . CreateIntCast ( Ctpop , Ty , false ) ; NewV = B . CreateMul ( V , CtpopCast ) ; LaneOffset = B . CreateMul ( V , MbcntCast ) ; } Value * const Cond = B . CreateICmpEQ ( MbcntCast , B . getIntN ( TyBitWidth , <NUM_LIT> ) ) ; BasicBlock * const EntryBB = I . getParent ( ) ; Instruction * const SingleLaneTerminator = SplitBlockAndInsertIfThen ( Cond , & I , false , nullptr , DT , nullptr ) ; B . SetInsertPoint ( SingleLaneTerminator ) ; Instruction * const NewI = I . clone ( ) ; B . Insert ( NewI ) ; NewI -> setOperand ( ValIdx , NewV ) ; B . SetInsertPoint ( & I ) ; PHINode * const PHI = B . CreatePHI ( Ty , <NUM_LIT> ) ; PHI -> addIncoming ( UndefValue :: get ( Ty ) , EntryBB ) ; PHI -> addIncoming ( NewI , SingleLaneTerminator -> getParent ( ) ) ; Value * BroadcastI = nullptr ; if ( TyBitWidth == <NUM_LIT> ) { Value * const ExtractLo = B . CreateTrunc ( PHI , B . getInt32Ty ( ) ) ; Value * const ExtractHi = B . CreateTrunc ( B . CreateLShr ( PHI , B . getInt64 ( <NUM_LIT> ) ) , B . getInt32Ty ( ) ) ; CallInst * const ReadFirstLaneLo = B . CreateIntrinsic ( <STR_LIT> , { } , ExtractLo ) ; CallInst * const ReadFirstLaneHi = B . CreateIntrinsic ( <STR_LIT> , { } , ExtractHi ) ; Value * const PartialInsert = B . CreateInsertElement ( UndefValue :: get ( VecTy ) , ReadFirstLaneLo , B . getInt32 ( <NUM_LIT> ) ) ; Value * const Insert = B . CreateInsertElement ( PartialInsert , ReadFirstLaneHi , B . getInt32 ( <NUM_LIT> ) ) ; BroadcastI = B . CreateBitCast ( Insert , Ty ) ; } else if ( TyBitWidth == <NUM_LIT> ) { BroadcastI = B . CreateIntrinsic ( <STR_LIT> , { } , PHI ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } Value * const Result = B . CreateBinOp ( Op , BroadcastI , LaneOffset ) ; if ( IsPixelShader ) { B . SetInsertPoint ( PixelExitBB -> getFirstNonPHI ( ) ) ;


<s> const unsigned RowMask [ Iters ] = { <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; const unsigned BankMask [ Iters ] = { <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; for ( unsigned Idx = <NUM_LIT> ; Idx < Iters ; Idx ++ ) { Value * const UpdateValue = Idx < <NUM_LIT> ? FirstDPP : NewV ; CallInst * const DPP = B . CreateIntrinsic ( <STR_LIT> , Ty , { Identity , UpdateValue , B . getInt32 ( DPPCtrl [ Idx ] ) , B . getInt32 ( RowMask [ Idx ] ) , B . getInt32 ( BankMask [ Idx ] ) , B . getFalse ( ) } ) ; NewV = B . CreateBinOp ( Op , NewV , DPP ) ; } LaneOffset = B . CreateIntrinsic ( <STR_LIT> , Ty , NewV ) ; NewV = B . CreateBinOp ( Op , SetInactive , NewV ) ; if ( TyBitWidth == <NUM_LIT> ) { Value * const ExtractLo = B . CreateTrunc ( NewV , B . getInt32Ty ( ) ) ; Value * const ExtractHi = B . CreateTrunc ( B . CreateLShr ( NewV , B . getInt64 ( <NUM_LIT> ) ) , B . getInt32Ty ( ) ) ; CallInst * const ReadLaneLo = B . CreateIntrinsic ( <STR_LIT> , { } , { ExtractLo , B . getInt32 ( <NUM_LIT> ) } ) ; CallInst * const ReadLaneHi = B . CreateIntrinsic ( <STR_LIT> , { } , { ExtractHi , B . getInt32 ( <NUM_LIT> ) } ) ; Value * const PartialInsert = B . CreateInsertElement ( UndefValue :: get ( VecTy ) , ReadLaneLo , B . getInt32 ( <NUM_LIT> ) ) ; Value * const Insert = B . CreateInsertElement ( PartialInsert , ReadLaneHi , B . getInt32 ( <NUM_LIT> ) ) ; NewV = B . CreateBitCast ( Insert , Ty ) ; } else if ( TyBitWidth == <NUM_LIT> ) { CallInst * const ReadLane = B . CreateIntrinsic ( <STR_LIT> , { } , { NewV , B . getInt32 ( <NUM_LIT> ) } ) ; NewV = ReadLane ; } else { llvm_unreachable ( <STR_LIT> ) ; } NewV = B . CreateIntrinsic ( <STR_LIT> , Ty , NewV ) ; } else { Instruction * const Ctpop = B . CreateUnaryIntrinsic ( <STR_LIT> , Ballot ) ; Value * const CtpopCast = B . CreateIntCast ( Ctpop , Ty , false ) ; NewV = B . CreateMul ( V , CtpopCast ) ; LaneOffset = B . CreateMul ( V , MbcntCast ) ; }

Value * const Cond = B . CreateICmpEQ ( MbcntCast , B . getIntN ( TyBitWidth , <NUM_LIT> ) ) ;


<s> <ISA_LIT>AtomicOptimizer ( ) : FunctionPass ( ID ) {


<s> static Value * buildNonAtomicBinOp ( IRBuilder < > & B , AtomicRMWInst :: BinOp Op , Value * LHS , Value * RHS ) { CmpInst :: Predicate Pred ; switch ( Op ) { default : llvm_unreachable ( <STR_LIT> ) ; case AtomicRMWInst :: Add : return B . CreateBinOp ( Instruction :: Add , LHS , RHS ) ; case AtomicRMWInst :: Sub : return B . CreateBinOp ( Instruction :: Sub , LHS , RHS ) ; case AtomicRMWInst :: And : return B . CreateBinOp ( Instruction :: And , LHS , RHS ) ; case AtomicRMWInst :: Or : return B . CreateBinOp ( Instruction :: Or , LHS , RHS ) ; case AtomicRMWInst :: Xor : return B . CreateBinOp ( Instruction :: Xor , LHS , RHS ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>AtomicOptimizerPass ( ) { return new <ISA_LIT>AtomicOptimizer ( ) ;


<s> return new <ISA_LIT>AtomicOptimizer ( ) ;


<s> AU . addPreserved < DominatorTreeWrapperPass > ( ) ; AU . addRequired < LegacyDivergenceAnalysis > ( ) ;

AU . addRequired < TargetPassConfig > ( ) ;


<s> llvm_unreachable ( <STR_LIT> ) ; case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub : case AtomicRMWInst :: Or : case AtomicRMWInst :: Xor : case AtomicRMWInst :: UMax : return APInt :: getMinValue ( BitWidth ) ; case AtomicRMWInst :: And : case AtomicRMWInst :: UMin : return APInt :: getMaxValue ( BitWidth ) ; case AtomicRMWInst :: Max : return APInt :: getSignedMinValue ( BitWidth ) ;


<s> const TargetMachine & TM = TPC . getTM < TargetMachine > ( ) ; const GCNSubtarget & ST = TM . getSubtarget < GCNSubtarget > ( F ) ; HasDPP = ST . hasDPP ( ) ; IsPixelShader = F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ; visit ( F ) ; const bool Changed = ! ToReplace . empty ( ) ; for ( ReplacementInfo & Info : ToReplace ) { optimizeAtomic ( * Info . I , Info . Op , Info . ValIdx , Info . ValDivergent ) ; } ToReplace . clear ( ) ; return Changed ;


<s> return false ; } DA = & getAnalysis < LegacyDivergenceAnalysis > ( ) ; DL = & F . getParent ( ) -> getDataLayout ( ) ; DominatorTreeWrapperPass * const DTW = getAnalysisIfAvailable < DominatorTreeWrapperPass > ( ) ; DT = DTW ? & DTW -> getDomTree ( ) : nullptr ; const TargetPassConfig & TPC = getAnalysis < TargetPassConfig > ( ) ; const TargetMachine & TM = TPC . getTM < TargetMachine > ( ) ; const GCNSubtarget & ST = TM . getSubtarget < GCNSubtarget > ( F ) ; HasDPP = ST . hasDPP ( ) ; IsPixelShader = F . getCallingConv ( ) == CallingConv :: <ISA_LIT>_PS ; visit ( F ) ; const bool Changed = ! ToReplace . empty ( ) ; for ( ReplacementInfo & Info : ToReplace ) { optimizeAtomic ( * Info . I , Info . Op , Info . ValIdx , Info . ValDivergent ) ; }


<s> case AtomicRMWInst :: Add : case AtomicRMWInst :: Sub : case AtomicRMWInst :: And : case AtomicRMWInst :: Or : case AtomicRMWInst :: Xor : case AtomicRMWInst :: Max : case AtomicRMWInst :: Min : case AtomicRMWInst :: UMax : case AtomicRMWInst :: UMin : break ; } const unsigned PtrIdx = <NUM_LIT> ; const unsigned ValIdx = <NUM_LIT> ; if ( DA -> isDivergentUse ( & I . getOperandUse ( PtrIdx ) ) ) { return ; } const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ;


<s> case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Min ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMin ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: Max ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Op = AtomicRMWInst :: UMax ; break ; } const unsigned ValIdx = <NUM_LIT> ; const bool ValDivergent = DA -> isDivergentUse ( & I . getOperandUse ( ValIdx ) ) ; if ( ValDivergent && ( ! HasDPP || ( DL -> getTypeSizeInBits ( I . getType ( ) ) != <NUM_LIT> ) ) ) { return ; } for ( unsigned Idx = <NUM_LIT> ; Idx < I . getNumOperands ( ) ; Idx ++ ) {

if ( DA -> isDivergentUse ( & I . getOperandUse ( Idx ) ) ) {


<s> bool IsNonEntryFunc = ! <STR_LIT> ( F -> getCallingConv ( ) ) ; auto & InfoCache = static_cast < <ISA_LIT>InformationCache & > ( A . getInfoCache ( ) ) ; bool NeedsQueuePtr = false ; auto CheckAddrSpaceCasts = [ & ] ( Instruction & I ) { unsigned SrcAS = static_cast < AddrSpaceCastInst & > ( I ) . getSrcAddressSpace ( ) ; if ( castRequiresQueuePtr ( SrcAS ) ) { NeedsQueuePtr = true ; return false ; } return true ; } ; bool HasApertureRegs = InfoCache . hasApertureRegs ( * F ) ; if ( ! HasApertureRegs ) { bool UsedAssumedInformation = false ; A . checkForAllInstructions ( CheckAddrSpaceCasts , * this , { Instruction :: AddrSpaceCast } , UsedAssumedInformation ) ; } if ( NeedsQueuePtr ) return true ;

if ( ! IsNonEntryFunc && HasApertureRegs ) return false ;


<s> static bool funcRequiresHostcallPtr ( const Function & F ) {

return F . hasFnAttribute ( Attribute :: SanitizeAddress ) || F . hasFnAttribute ( Attribute :: SanitizeThread ) || F . hasFnAttribute ( Attribute :: SanitizeMemory ) || F . hasFnAttribute ( Attribute :: SanitizeHWAddress ) || F . hasFnAttribute ( Attribute :: SanitizeMemTag ) ;


<s> bool funcRetrievesHostcallPtr ( Attributor & A ) { auto Pos = llvm :: <STR_LIT> ( ) ;

AAPointerInfo :: OffsetAndSize OAS ( Pos , <NUM_LIT> ) ;


<s> AAPointerInfo :: OffsetAndSize OAS ( Pos , <NUM_LIT> ) ; return funcRetrievesImplicitKernelArg ( A , OAS ) ;


<s> return PointerInfoAA . forallInterferingAccesses ( OAS , [ ] ( const AAPointerInfo :: Access & Acc , bool IsExact ) { return Acc . getRemoteInst ( ) -> isDroppable ( ) ; } ) ; } ; bool UsedAssumedInformation = false ; return ! A . checkForAllCallLikeInstructions ( DoesNotLeadToKernelArgLoc , * this , UsedAssumedInformation ) ;