<s> Sched :: Preference ARMTargetLowering :: getSchedulingPreference ( SDNode * N ) const { unsigned NumVals = N -> getNumValues ( ) ; if ( ! NumVals ) return Sched :: RegPressure ; for ( unsigned i = 0 ; i != NumVals ; ++ i ) { EVT VT = N -> getValueType ( i ) ; if ( VT == MVT :: Flag || VT == MVT :: Other ) continue ; if ( VT . isFloatingPoint ( ) || VT . isVector ( ) ) return Sched :: Latency ; } if ( ! N -> isMachineOpcode ( ) ) return Sched :: RegPressure ; const TargetInstrInfo * TII = getTargetMachine ( ) . getInstrInfo ( ) ; const TargetInstrDesc & TID = TII -> get ( N -> getMachineOpcode ( ) ) ; if ( TID . getNumDefs ( ) == 0 ) return Sched :: RegPressure ; if ( ! Itins -> isEmpty ( ) && Itins -> getOperandCycle ( TID . getSchedClass ( ) , 0 ) > 2 ) return Sched :: Latency ; return Sched :: RegPressure ; } </s>


<s> SDValue ARMTargetLowering :: PerformDAGCombine ( SDNode * N , DAGCombinerInfo & DCI ) const { switch ( N -> getOpcode ( ) ) { default : break ; case ISD :: ADD : return PerformADDCombine ( N , DCI ) ; case ISD :: SUB : return PerformSUBCombine ( N , DCI ) ; case ISD :: MUL : return PerformMULCombine ( N , DCI , Subtarget ) ; case ISD :: OR : return PerformORCombine ( N , DCI , Subtarget ) ; case ISD :: AND : return PerformANDCombine ( N , DCI ) ; case ARMISD :: VMOVRRD : return PerformVMOVRRDCombine ( N , DCI ) ; case ARMISD :: VMOVDRR : return PerformVMOVDRRCombine ( N , DCI . DAG ) ; case ISD :: BUILD_VECTOR : return PerformBUILD_VECTORCombine ( N , DCI . DAG ) ; case ISD :: VECTOR_SHUFFLE : return PerformVECTOR_SHUFFLECombine ( N , DCI . DAG ) ; case ARMISD :: VDUPLANE : return PerformVDUPLANECombine ( N , DCI ) ; case ISD :: INTRINSIC_WO_CHAIN : return PerformIntrinsicCombine ( N , DCI . DAG ) ; case ISD :: SHL : case ISD :: SRA : case ISD :: SRL : return PerformShiftCombine ( N , DCI . DAG , Subtarget ) ; case ISD :: SIGN_EXTEND : case ISD :: ZERO_EXTEND : case ISD :: ANY_EXTEND : return PerformExtendCombine ( N , DCI . DAG , Subtarget ) ; case ISD :: SELECT_CC : return PerformSELECT_CCCombine ( N , DCI . DAG , Subtarget ) ; } return SDValue ( ) ; } </s>

This method will be invoked for all target nodes and for any target-independent nodes that the target has registered with invoke it for .


<s> unsigned ARMScalarTargetTransformImpl :: getIntImmCost ( const APInt & Imm , Type * Ty ) const { assert ( Ty -> isIntegerTy ( ) ) ; unsigned Bits = Ty -> getPrimitiveSizeInBits ( ) ; if ( Bits == 0 || Bits > 32 ) return 4 ; int32_t SImmVal = Imm . getSExtValue ( ) ; uint32_t ZImmVal = Imm . getZExtValue ( ) ; if ( ! Subtarget -> isThumb ( ) ) { if ( ( SImmVal >= 0 && SImmVal < 65536 ) || ( ARM_AM :: getSOImmVal ( ZImmVal ) != - 1 ) || ( ARM_AM :: getSOImmVal ( ~ ZImmVal ) != - 1 ) ) return 1 ; return Subtarget -> hasV6T2Ops ( ) ? 2 : 3 ; } else if ( Subtarget -> isThumb2 ( ) ) { if ( ( SImmVal >= 0 && SImmVal < 65536 ) || ( ARM_AM :: getT2SOImmVal ( ZImmVal ) != - 1 ) || ( ARM_AM :: getT2SOImmVal ( ~ ZImmVal ) != - 1 ) ) return 1 ; return Subtarget -> hasV6T2Ops ( ) ? 2 : 3 ; } else { if ( SImmVal >= 0 && SImmVal < 256 ) return 1 ; if ( ( ~ ZImmVal < 256 ) || ARM_AM :: isThumbImmShiftedVal ( ZImmVal ) ) return 2 ; return 3 ; } return 2 ; } </s>

Calculate the cost of materializing a 64-bit value .


<s> TargetLoweringBase :: AtomicExpansionKind ARMTargetLowering :: shouldExpandAtomicStoreInIR ( StoreInst * SI ) const { bool has64BitAtomicStore ; if ( Subtarget -> isMClass ( ) ) has64BitAtomicStore = false ; else if ( Subtarget -> isThumb ( ) ) has64BitAtomicStore = Subtarget -> hasV7Ops ( ) ; else has64BitAtomicStore = Subtarget -> hasV6Ops ( ) ; unsigned Size = SI -> getValueOperand ( ) -> getType ( ) -> getPrimitiveSizeInBits ( ) ; return Size == 64 && has64BitAtomicStore ? AtomicExpansionKind :: Expand : AtomicExpansionKind :: None ; } </s>

Returns how the given ( atomic ) store should be expanded by the IR-level AtomicExpand pass into .


<s> bool ARMTargetLowering :: getPostIndexedAddressParts ( SDNode * N , SDNode * Op , SDValue & Base , SDValue & Offset , ISD :: MemIndexedMode & AM , SelectionDAG & DAG ) const { if ( Subtarget -> isThumb1Only ( ) ) return false ; const bool restrict_addressing_modes_for_nacl = ( ( FlagSfiLoad && N -> getOpcode ( ) == ISD :: LOAD ) || ( FlagSfiStore && N -> getOpcode ( ) == ISD :: STORE ) ) ; if ( restrict_addressing_modes_for_nacl ) { return false ; } EVT VT ; SDValue Ptr ; bool isSEXTLoad = false ; if ( LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { VT = LD -> getMemoryVT ( ) ; Ptr = LD -> getBasePtr ( ) ; isSEXTLoad = LD -> getExtensionType ( ) == ISD :: SEXTLOAD ; } else if ( StoreSDNode * ST = dyn_cast < StoreSDNode > ( N ) ) { VT = ST -> getMemoryVT ( ) ; Ptr = ST -> getBasePtr ( ) ; } else return false ; bool isInc ; bool isLegal = false ; if ( Subtarget -> isThumb2 ( ) ) isLegal = getT2IndexedAddressParts ( Op , VT , isSEXTLoad , Base , Offset , isInc , DAG ) ; else isLegal = getARMIndexedAddressParts ( Op , VT , isSEXTLoad , Base , Offset , isInc , DAG ) ; if ( ! isLegal ) return false ; if ( Ptr != Base ) { if ( Ptr == Offset && Op -> getOpcode ( ) == ISD :: ADD && ! Subtarget -> isThumb2 ( ) ) std :: swap ( Base , Offset ) ; if ( Ptr != Base ) return false ; } AM = isInc ? ISD :: POST_INC : ISD :: POST_DEC ; return true ; } </s>

Returns true by value , base pointer and offset pointer and addressing mode by reference if this node can be combined with a load / store to form a post-indexed load / store .

ARM ARM ISD::MemIndexedMode ISD::LOAD ISD::STORE ISD::SEXTLOAD ARM ISD::ADD ISD::POST_INC ISD::POST_DEC


<s> bool ARMTargetLowering :: getPreIndexedAddressParts ( SDNode * N , SDValue & Base , SDValue & Offset , ISD :: MemIndexedMode & AM , SelectionDAG & DAG ) const { if ( Subtarget -> isThumb1Only ( ) ) return false ; const bool restrict_addressing_modes_for_nacl = ( ( FlagSfiLoad && N -> getOpcode ( ) == ISD :: LOAD ) || ( FlagSfiStore && N -> getOpcode ( ) == ISD :: STORE ) ) ; if ( restrict_addressing_modes_for_nacl ) { return false ; } EVT VT ; SDValue Ptr ; bool isSEXTLoad = false ; if ( LoadSDNode * LD = dyn_cast < LoadSDNode > ( N ) ) { Ptr = LD -> getBasePtr ( ) ; VT = LD -> getMemoryVT ( ) ; isSEXTLoad = LD -> getExtensionType ( ) == ISD :: SEXTLOAD ; } else if ( StoreSDNode * ST = dyn_cast < StoreSDNode > ( N ) ) { Ptr = ST -> getBasePtr ( ) ; VT = ST -> getMemoryVT ( ) ; } else return false ; bool isInc ; bool isLegal = false ; if ( Subtarget -> isThumb2 ( ) ) isLegal = getT2IndexedAddressParts ( Ptr . getNode ( ) , VT , isSEXTLoad , Base , Offset , isInc , DAG ) ; else isLegal = getARMIndexedAddressParts ( Ptr . getNode ( ) , VT , isSEXTLoad , Base , Offset , isInc , DAG ) ; if ( ! isLegal ) return false ; AM = isInc ? ISD :: PRE_INC : ISD :: PRE_DEC ; return true ; } </s>

Returns true by value , base pointer and offset pointer and addressing mode by reference if the node 's address can be legally represented as pre-indexed load / store address .

ARM ARM ISD::MemIndexedMode ISD::LOAD ISD::STORE ISD::SEXTLOAD ARM ISD::PRE_INC ISD::PRE_DEC


"expected larger existing stack allocation"

Target-specific cleanup for formal ByVal parameters .


<s> SDValue ARMTargetLowering :: BuildSDIVPow2 ( SDNode * N , const APInt & Divisor , SelectionDAG & DAG , SmallVectorImpl < SDNode * > & Created ) const { if ( N -> getOpcode ( ) != ISD :: SDIV ) return SDValue ( ) ; const auto & ST = DAG . getSubtarget < ARMSubtarget > ( ) ; const bool MinSize = ST . hasMinSize ( ) ; const bool HasDivide = ST . isThumb ( ) ? ST . hasDivideInThumbMode ( ) : ST . hasDivideInARMMode ( ) ; if ( N -> getOperand ( 0 ) . getValueType ( ) . isVector ( ) ) return SDValue ( ) ; if ( ! ( MinSize && HasDivide ) ) return SDValue ( ) ; if ( ! ST . isThumb ( ) ) return SDValue ( N , 0 ) ; if ( Divisor . sgt ( 128 ) ) return SDValue ( ) ; return SDValue ( N , 0 ) ; } </s>

Targets may override this function to provide custom SDIV lowering for power-of-2 denominators .


<s> bool canMergeStoresTo ( unsigned AddressSpace , EVT MemVT , const MachineFunction & MF ) const override { return ( MemVT . getSizeInBits ( ) <= 32 ) ; } </s>

Returns if it 's reasonable to merge stores to MemVT size .


<s> bool convertSetCCLogicToBitwiseLogic ( EVT VT ) const override { return VT . isScalarInteger ( ) ; } </s>

Use bitwise logic to make pairs of compares more efficient .


<s> bool hasStandaloneRem ( EVT VT ) const override { return HasStandaloneRem ; } </s>

Return true if the target can handle a standalone remainder operation .


"Unmatched number of shufflevectors and indices"

Lower interleaved load ( s ) into target specific instructions/intrinsics .


<s>
bool
ARMTargetLowering
::
lowerInterleavedStore
(
StoreInst
*
SI
,
ShuffleVectorInst
*
SVI
,
unsigned
Factor
)
const
{
assert
(
Factor
>=
2
&&
Factor
<=
getMaxSupportedInterleaveFactor
(
)
&&
"Invalid interleave factor"
)
;
VectorType
*
VecTy
=
SVI
->
getType
(
)
;
assert
(
VecTy
->
getVectorNumElements
(
)
%
Factor
==
0
&&
"Invalid interleaved store"
)
;
unsigned
NumSubElts
=
VecTy
->
getVectorNumElements
(
)
/
Factor
;
Type
*
EltTy
=
VecTy
->
getVectorElementType
(
)
;
VectorType
*
SubVecTy
=
VectorType
::
get
(
EltTy
,
NumSubElts
)
;
const
DataLayout
&
DL
=
SI
->
getModule
(
)
->
getDataLayout
(
)
;
unsigned
SubVecSize
=
DL
.
getTypeAllocSizeInBits
(
SubVecTy
)
;
bool
EltIs64Bits
=
DL
.
getTypeAllocSizeInBits
(
EltTy
)
==
64
;
if
(
!
Subtarget
->
hasNEON
(
)
||
(
SubVecSize
!=
64
&&
SubVecSize
!=
128
)
||
EltIs64Bits
)
return
false
;
Value
*
Op0
=
SVI
->
getOperand
(
0
)
;
Value
*
Op1
=
SVI
->
getOperand
(
1
)
;
IRBuilder
<
>
Builder
(
SI
)
;
if
(
EltTy
->
isPointerTy
(
)
)
{
Type
*
IntTy
=
DL
.
getIntPtrType
(
EltTy
)
;
Type
*
IntVecTy
=
VectorType
::
get
(
IntTy
,
Op0
->
getType
(
)
->
getVectorNumElements
(
)
)
;
Op0
=
Builder
.
CreatePtrToInt
(
Op0
,
IntVecTy
)
;
Op1
=
Builder
.
CreatePtrToInt
(
Op1
,
IntVecTy
)
;
SubVecTy
=
VectorType
::
get
(
IntTy
,
NumSubElts
)
;
}
static
Intrinsic
::
ID
StoreInts
[
3
]
=
{
Intrinsic
::
arm_neon_vst2
,
Intrinsic
::
arm_neon_vst3
,
Intrinsic
::
arm_neon_vst4
}
;
SmallVector
<
Value
*
,
6
>
Ops
;
Type
*
Int8Ptr
=
Builder
.
getInt8PtrTy
(
SI
->
getPointerAddressSpace
(
)
)
;
Ops
.
push_back
(
Builder
.
CreateBitCast
(
SI
->
getPointerOperand
(
)
,
Int8Ptr
)
)
;
Type
*
Tys
[
]
=
{
Int8Ptr
,
SubVecTy
}
;
Function
*
VstNFunc
=
Intrinsic
::
getDeclaration
(
SI
->
getModule
(
)
,
StoreInts
[
Factor
2
]
,
Tys
)
;
for
(
unsigned
i
=
0
;
i
<
Factor
;
i
++
)
Ops
.
push_back
(
Builder
.
CreateShuffleVector
(
Op0
,
Op1
,
getSequentialMask
(
Builder
,
NumSubElts
*
i
,
NumSubElts
)
)
)
;
Ops
.
push_back
(
Builder
.
getInt32
(
SI
->
getAlignment
(
)
)
)
;
Builder
.
CreateCall
(
VstNFunc
,
Ops
)
;
return
true
;
}
</s>

Lower interleaved store ( s ) into target specific instructions/intrinsics .


<s> bool preferZeroCompareBranch ( ) const override { return true ; } </s>

Return true if the heuristic to prefer icmp eq zero should be used in code gen prepare .


<s> TargetLowering :: AtomicExpansionKind ARMTargetLowering :: shouldExpandAtomicLoadInIR ( LoadInst * LI ) const { unsigned Size = LI -> getType ( ) -> getPrimitiveSizeInBits ( ) ; return ( ( Size == 64 ) && ! Subtarget -> isMClass ( ) ) ? AtomicExpansionKind :: LLSC : AtomicExpansionKind :: None ; } </s>

Returns how the given ( atomic ) load should be expanded by the IR-level AtomicExpand pass .


<s> bool shouldFormOverflowOp ( unsigned Opcode , EVT VT , bool MathUsed ) const override { return TargetLowering :: shouldFormOverflowOp ( Opcode , VT , true ) ; } </s>

Overflow nodes should get combined/lowered to optimal instructions ( they should allow eliminating explicit compares by getting flags from math ops ) .


<s> bool supportSplitCSR ( MachineFunction * MF ) const override { return MF -> getFunction ( ) . getCallingConv ( ) == CallingConv :: CXX_FAST_TLS && MF -> getFunction ( ) . hasFnAttribute ( Attribute :: NoUnwind ) ; } </s>

Return true if the target supports that a subset of CSRs for the given machine function is handled explicitly via copies .


<s> bool supportSwiftError ( ) const override { return true ; } </s>

Return true if the target supports swifterror attribute .


<s> void Initialize ( const MachineFunction & MF , bool isPIC ) { const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; ConstPoolId2AddrMap . resize ( AFI -> getNumConstPoolEntries ( ) ) ; JumpTableId2AddrMap . resize ( AFI -> getNumJumpTables ( ) ) ; IsPIC = isPIC ; } </s>

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


<s> void Initialize ( const MachineFunction & MF , bool isPIC ) { const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; ConstPoolId2AddrMap . resize ( AFI -> getNumPICLabels ( ) ) ; JumpTableId2AddrMap . resize ( AFI -> getNumJumpTables ( ) ) ; IsPIC = isPIC ; } </s>


<s> void ARMJITInfo :: Initialize ( const MachineFunction & MF , bool isPIC ) { const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; ConstPoolId2AddrMap . resize ( AFI -> getNumPICLabels ( ) ) ; JumpTableId2AddrMap . resize ( AFI -> getNumJumpTables ( ) ) ; IsPIC = isPIC ; } </s>


<s>
const
ARMGOT
&
ARMGNULDBackend
::
getGOT
(
)
const
{
assert
(
m_pGOT
!=
&&
"GOT section not exist"
)
;
return
*
m_pGOT
;
}
</s>

Return a pseudo source value referencing the global offset table ( or something the like ) .


"Unexpected type for the widened instruction"

Called for instructions with the Custom LegalizationAction .


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { MF = & Fn ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TL = STI -> getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; RegClassInfoValid = false ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; if ( isThumb1 ) Modified |= CombineMovBx ( MBB ) ; } Allocator . DestroyAll ( ) ; return Modified ; } </s>


<s> const char * getPassName ( ) const override { return ARM_PREALLOC_LOAD_STORE_OPT_NAME ; } </s>

getPassName - Return a nice clean name for a pass .


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( * Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


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


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


"ARM pre- register allocation load / store optimization pass"


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getTarget ( ) . getTargetData ( ) ; TII = Fn . getTarget ( ) . getInstrInfo ( ) ; TRI = Fn . getTarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < ARMSubtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getTarget ( ) . getDataLayout ( ) ; TII = Fn . getTarget ( ) . getInstrInfo ( ) ; TRI = Fn . getTarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < ARMSubtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


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


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; DT = & getAnalysis < MachineDominatorTree > ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = DistributeIncrements ( ) ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( skipFunction ( Fn . getFunction ( ) ) ) return false ; MF = & Fn ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TL = STI -> getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; RegClassInfoValid = false ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineBasicBlock & MBB : Fn ) { Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; if ( isThumb1 ) Modified |= CombineMovBx ( MBB ) ; } Allocator . DestroyAll ( ) ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( * Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { const TargetMachine & TM = Fn . getTarget ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { const TargetMachine & TM = Fn . getTarget ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; RS = new RegScavenger ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getTarget ( ) . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TL = STI -> getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getTarget ( ) . getTargetData ( ) ; TII = Fn . getTarget ( ) . getInstrInfo ( ) ; TRI = Fn . getTarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < ARMSubtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { const TargetMachine & TM = Fn . getTarget ( ) ; TL = TM . getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; STI = & TM . getSubtarget < ARMSubtarget > ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; if ( isThumb1 ) { delete RS ; return false ; } bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( TM . getSubtarget < ARMSubtarget > ( ) . hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getSubtarget ( ) . getDataLayout ( ) ; TII = Fn . getSubtarget ( ) . getInstrInfo ( ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( skipFunction ( Fn . getFunction ( ) ) ) return false ; MF = & Fn ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TL = STI -> getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; RegClassInfoValid = false ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineBasicBlock & MBB : Fn ) { Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( STI -> hasV5TOps ( ) && ! AFI -> shouldSignReturnAddress ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; if ( isThumb1 ) Modified |= CombineMovBx ( MBB ) ; } Allocator . DestroyAll ( ) ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { const TargetMachine & TM = Fn . getTarget ( ) ; TL = TM . getTargetLowering ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; STI = & TM . getSubtarget < ARMSubtarget > ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; isThumb1 = AFI -> isThumbFunction ( ) && ! isThumb2 ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( TM . getSubtarget < ARMSubtarget > ( ) . hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { const TargetMachine & TM = Fn . getTarget ( ) ; AFI = Fn . getInfo < ARMFunctionInfo > ( ) ; TII = TM . getInstrInfo ( ) ; TRI = TM . getRegisterInfo ( ) ; RS = new RegScavenger ( ) ; isThumb2 = AFI -> isThumb2Function ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= LoadStoreMultipleOpti ( MBB ) ; if ( TM . getSubtarget < ARMSubtarget > ( ) . hasV5TOps ( ) ) Modified |= MergeReturnIntoLDM ( MBB ) ; } delete RS ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores || skipFunction ( Fn . getFunction ( ) ) ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & Fn . getSubtarget < ARMSubtarget > ( ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; DT = & getAnalysis < MachineDominatorTree > ( ) ; MF = & Fn ; AA = & getAnalysis < AAResultsWrapperPass > ( ) . getAAResults ( ) ; bool Modified = DistributeIncrements ( ) ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


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


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = Fn . getSubtarget ( ) . getDataLayout ( ) ; TII = Fn . getSubtarget ( ) . getInstrInfo ( ) ; TRI = Fn . getSubtarget ( ) . getRegisterInfo ( ) ; STI = & Fn . getTarget ( ) . getSubtarget < ARMSubtarget > ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { if ( AssumeMisalignedLoadStores ) return false ; TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineBasicBlock & MFI : Fn ) Modified |= RescheduleLoadStoreInstrs ( & MFI ) ; return Modified ; } </s>


<s> bool ARMPreAllocLoadStoreOpt :: runOnMachineFunction ( MachineFunction & Fn ) { TD = & Fn . getDataLayout ( ) ; STI = & static_cast < const ARMSubtarget & > ( Fn . getSubtarget ( ) ) ; TII = STI -> getInstrInfo ( ) ; TRI = STI -> getRegisterInfo ( ) ; MRI = & Fn . getRegInfo ( ) ; MF = & Fn ; bool Modified = false ; for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) Modified |= RescheduleLoadStoreInstrs ( MFI ) ; return Modified ; } </s>


<s>
void
addInst
(
MachineInstr
*
MI
,
SetVector
<
MachineInstr
*
>
&
Preds
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops: Adding predicated MI: "
<<
*
MI
)
;
if
(
!
Divergent
&&
!
set_difference
(
Preds
,
PredicateThen
->
Predicates
)
.
empty
(
)
)
{
Divergent
=
&
Insts
.
back
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
" - has divergent predicate: "
<<
*
Divergent
->
MI
)
;
}
Insts
.
emplace_back
(
MI
,
Preds
)
;
assert
(
Insts
.
size
(
)
<=
4
&&
"Too many instructions in VPT block!"
)
;
}
</s>

ARM
"ARM Loops: Adding predicated MI: "
" - has divergent predicate: "
4
"Too many instructions in VPT block!"


"ARM Loops: Failed to find all loop components.\n"

Dump the plan to stderr ( for debugging ) .


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
mf
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
MF
=
&
mf
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
->
getName
(
)
<<
" ------------- \n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
RDA
=
&
getAnalysis
<
ReachingDefAnalysis
>
(
)
;
MF
->
getProperties
(
)
.
set
(
MachineFunctionProperties
::
Property
::
TracksLiveness
)
;
MRI
=
&
MF
->
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
TRI
=
ST
.
getRegisterInfo
(
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
*
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
->
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
*
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
)
;
return
Changed
;
}
</s>

ARM
ARM
ARM
ARM
"ARM Loops on "
" ------------- \n"
ARM
ARM
ARM


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
!
static_cast
<
const
ARMSubtarget
&
>
(
MF
.
getSubtarget
(
)
)
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
.
getName
(
)
<<
" ------------- \n"
)
;
auto
&
MLI
=
getAnalysis
<
MachineLoopInfo
>
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
MF
.
getSubtarget
(
)
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
return
Changed
;
}
</s>

ARM
ARM
ARM
"ARM Loops on "
" ------------- \n"
ARM
ARM
ARM


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
const
ARMSubtarget
&
ST
=
mf
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
MF
=
&
mf
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
->
getName
(
)
<<
" ------------- \n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
RDA
=
&
getAnalysis
<
ReachingDefAnalysis
>
(
)
;
MF
->
getProperties
(
)
.
set
(
MachineFunctionProperties
::
Property
::
TracksLiveness
)
;
MRI
=
&
MF
->
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
TRI
=
ST
.
getRegisterInfo
(
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
*
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
->
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
*
MLI
)
{
if
(
ML
->
isOutermost
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
)
;
return
Changed
;
}
</s>


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
!
static_cast
<
const
ARMSubtarget
&
>
(
MF
.
getSubtarget
(
)
)
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
.
getName
(
)
<<
" ------------- \n"
)
;
auto
&
MLI
=
getAnalysis
<
MachineLoopInfo
>
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
MF
.
getSubtarget
(
)
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
.
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
MF
)
;
return
Changed
;
}
</s>


<s>
void
addInst
(
MachineInstr
*
MI
,
SetVector
<
MachineInstr
*
>
&
Preds
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops: Adding predicated MI: "
<<
*
MI
)
;
if
(
!
Divergent
&&
!
set_difference
(
Preds
,
VPST
->
Predicates
)
.
empty
(
)
)
{
Divergent
=
&
Insts
.
back
(
)
;
LLVM_DEBUG
(
dbgs
(
)
<<
" - has divergent predicate: "
<<
*
Divergent
->
MI
)
;
}
Insts
.
emplace_back
(
MI
,
Preds
)
;
assert
(
Insts
.
size
(
)
<=
4
&&
"Too many instructions in VPT block!"
)
;
}
</s>


<s>
static
bool
isValid
(
ReachingDefAnalysis
&
RDA
)
{
for
(
auto
&
Block
:
Blocks
)
{
if
(
isEntryPredicatedOnVCTP
(
Block
,
false
)
||
hasImplicitlyValidVPT
(
Block
,
RDA
)
)
continue
;
SmallVectorImpl
<
MachineInstr
*
>
&
Insts
=
Block
.
getInsts
(
)
;
for
(
auto
*
MI
:
Insts
)
{
if
(
isVCTP
(
MI
)
&&
getVPTInstrPredicate
(
*
MI
)
!=
ARMVCC
::
Then
)
return
false
;
if
(
MI
->
getOpcode
(
)
==
ARM
::
MVE_VPST
||
isVectorPredicate
(
MI
)
)
continue
;
if
(
!
isPredicatedOnVCTP
(
MI
)
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops: Can't convert: "
<<
*
MI
)
;
return
false
;
}
}
}
return
true
;
}
</s>

Returns true if this iterator is still pointing at a valid entry .

ARM
ARMVCC::Then
ARM::MVE_VPST
"ARM Loops: Can't convert: "


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
mf
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
MF
=
&
mf
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
->
getName
(
)
<<
" ------------- \n"
)
;
auto
&
MLI
=
getAnalysis
<
MachineLoopInfo
>
(
)
;
MF
->
getProperties
(
)
.
set
(
MachineFunctionProperties
::
Property
::
TracksLiveness
)
;
MRI
=
&
MF
->
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
*
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
->
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
)
;
return
Changed
;
}
</s>


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
mf
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
MF
=
&
mf
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
->
getName
(
)
<<
" ------------- \n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
RDA
=
&
getAnalysis
<
ReachingDefAnalysis
>
(
)
;
MF
->
getProperties
(
)
.
set
(
MachineFunctionProperties
::
Property
::
TracksLiveness
)
;
MRI
=
&
MF
->
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
*
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
->
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
*
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
)
;
return
Changed
;
}
</s>


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
!
static_cast
<
const
ARMSubtarget
&
>
(
MF
.
getSubtarget
(
)
)
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
.
getName
(
)
<<
" ------------- \n"
)
;
auto
&
MLI
=
getAnalysis
<
MachineLoopInfo
>
(
)
;
MRI
=
&
MF
.
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
MF
.
getSubtarget
(
)
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
.
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
MLI
)
{
if
(
!
ML
->
getParentLoop
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
return
Changed
;
}
</s>


<s> static void addInst ( MachineInstr * MI ) { Blocks . back ( ) . insert ( MI ) ; PredicatedInsts . emplace ( MI , std :: make_unique < PredicatedMI > ( MI , CurrentPredicates ) ) ; } </s>


<s>
static
void
addPredicate
(
MachineInstr
*
MI
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops: Adding VPT Predicate: "
<<
*
MI
)
;
CurrentPredicates
.
insert
(
MI
)
;
}
</s>


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


<s> const SmallVectorImpl < MachineBasicBlock * > & getOrder ( ) const { return Order ; } </s>


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


<s>
void
insert
(
MachineInstr
*
MI
)
{
Insts
.
push_back
(
MI
)
;
assert
(
Insts
.
size
(
)
<=
5
&&
"Too many instructions in VPT block!"
)
;
}
</s>

insert - Append entry to the vector if it does n't already exist .

ARM
5
"Too many instructions in VPT block!"


"Expected VPT block to start with a VPST or VPT!"


<s> static void reset ( ) { Blocks . clear ( ) ; PredicatedInsts . clear ( ) ; CurrentPredicates . clear ( ) ; } </s>

Reset an existing scalar value for Def and a given Instance .


<s>
bool
ARMLowOverheadLoops
::
runOnMachineFunction
(
MachineFunction
&
mf
)
{
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
mf
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
MF
=
&
mf
;
LLVM_DEBUG
(
dbgs
(
)
<<
"ARM Loops on "
<<
MF
->
getName
(
)
<<
" ------------- \n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
RDA
=
&
getAnalysis
<
ReachingDefAnalysis
>
(
)
;
MF
->
getProperties
(
)
.
set
(
MachineFunctionProperties
::
Property
::
TracksLiveness
)
;
MRI
=
&
MF
->
getRegInfo
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
TRI
=
ST
.
getRegisterInfo
(
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
*
MF
)
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
->
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
ML
:
*
MLI
)
{
if
(
ML
->
isOutermost
(
)
)
Changed
|=
ProcessLoop
(
ML
)
;
}
Changed
|=
RevertNonLoops
(
)
;
return
Changed
;
}
</s>


<s> unsigned size ( ) const { return Insts . size ( ) ; } </s>

The number of name/type pairs is returned .


<s> void markGlobalAsPromotedToConstantPool ( const GlobalVariable * GV ) { PromotedGlobals . insert ( GV ) ; } </s>

Indicate to the backend that GV has had its storage changed to inside a constant pool .


<s> unsigned getAlign ( ) const { return Align ; } </s>

Return the minimum known alignment in bytes of the actual memory reference .


<s> unsigned getGlobalBaseReg ( ) const { return GlobalBaseReg ; } </s>

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


<s> const MCExpr * createExprForCAPIVariantKind ( const MCExpr * SubExpr , unsigned VariantKind ) override { switch ( VariantKind ) { case LLVMDisassembler_VariantKind_ARM_HI16 : return ARMMCExpr :: createUpper16 ( SubExpr , Ctx ) ; case LLVMDisassembler_VariantKind_ARM_LO16 : return ARMMCExpr :: createLower16 ( SubExpr , Ctx ) ; default : return MCRelocationInfo :: createExprForCAPIVariantKind ( SubExpr , VariantKind ) ; } } </s>

Create an MCExpr for the target-specific VariantKind .


<s> const MCExpr * createExprForCAPIVariantKind ( const MCExpr * SubExpr , unsigned VariantKind ) override { switch ( VariantKind ) { case LLVMDisassembler_VariantKind_ARM_HI16 : return ARMMCExpr :: CreateUpper16 ( SubExpr , Ctx ) ; case LLVMDisassembler_VariantKind_ARM_LO16 : return ARMMCExpr :: CreateLower16 ( SubExpr , Ctx ) ; default : return MCRelocationInfo :: createExprForCAPIVariantKind ( SubExpr , VariantKind ) ; } } </s>


<s> Expected < const MCExpr * > createExprForCAPIVariantKind ( const MCExpr * SubExpr , unsigned VariantKind ) override { switch ( VariantKind ) { case LLVMDisassembler_VariantKind_ARM_HI16 : return ARMMCExpr :: createUpper16 ( SubExpr , Ctx ) ; case LLVMDisassembler_VariantKind_ARM_LO16 : return ARMMCExpr :: createLower16 ( SubExpr , Ctx ) ; default : return MCRelocationInfo :: createExprForCAPIVariantKind ( SubExpr , VariantKind ) ; } } </s>


<s> void ARMELFMCAsmInfo :: setUseIntegratedAssembler ( bool Value ) { UseIntegratedAssembler = Value ; if ( ! UseIntegratedAssembler ) { DwarfRegNumForCFI = true ; } } </s>

Set whether assembly ( inline or otherwise ) should be parsed .


<s> uint32_t ARMMCCodeEmitter :: getBranchTargetOpValue ( const MCInst & MI , unsigned OpIdx , SmallVectorImpl < MCFixup > & Fixups ) const { if ( isThumb2 ( ) ) return :: getBranchTargetOpValue ( MI , OpIdx , ARM :: fixup_t2_condbranch , Fixups ) ; return getARMBranchTargetOpValue ( MI , OpIdx , Fixups ) ; } </s>

getBranchTargetOpValue - Return binary encoding of the branch target operand .


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
getARMRegisterNumbering
(
Reg
)
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>

getMachineOpValue - Return binary encoding of operand .


<s>
void
ARMMCCodeEmitter
::
encodeInstruction
(
const
MCInst
&
MI
,
raw_ostream
&
OS
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
const
MCInstrDesc
&
Desc
=
MCII
.
get
(
MI
.
getOpcode
(
)
)
;
uint64_t
TSFlags
=
Desc
.
TSFlags
;
if
(
(
TSFlags
&
ARMII
::
FormMask
)
==
ARMII
::
Pseudo
)
return
;
int
Size
;
if
(
Desc
.
getSize
(
)
==
2
||
Desc
.
getSize
(
)
==
4
)
Size
=
Desc
.
getSize
(
)
;
else
llvm_unreachable
(
"Unexpected instruction size!"
)
;
uint32_t
Binary
=
getBinaryCodeForInstr
(
MI
,
Fixups
,
STI
)
;
if
(
isThumb
(
STI
)
&&
Size
==
4
)
{
EmitConstant
(
Binary
>>
16
,
2
,
OS
)
;
EmitConstant
(
Binary
&
0xffff
,
2
,
OS
)
;
}
else
EmitConstant
(
Binary
,
Size
,
OS
)
;
++
MCNumEmitted
;
}
</s>

Encode the given Inst to bytes and append to CB .


<s>
static
uint32_t
getBranchTargetOpValue
(
const
MCInst
&
MI
,
unsigned
OpIdx
,
unsigned
FixupKind
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
{
const
MCOperand
&
MO
=
MI
.
getOperand
(
OpIdx
)
;
if
(
MO
.
isImm
(
)
)
return
MO
.
getImm
(
)
;
assert
(
MO
.
isExpr
(
)
&&
"Unexpected branch target type!"
)
;
const
MCExpr
*
Expr
=
MO
.
getExpr
(
)
;
MCFixupKind
Kind
=
MCFixupKind
(
FixupKind
)
;
Fixups
.
push_back
(
MCFixup
::
create
(
0
,
Expr
,
Kind
,
MI
.
getLoc
(
)
)
)
;
return
0
;
}
</s>


<s> bool isThumb ( const MCSubtargetInfo & STI ) const { return STI . getFeatureBits ( ) [ ARM :: ModeThumb ] ; } </s>

Tests whether the target is Thumb ( little and big endian ) .


<s> uint32_t ARMMCCodeEmitter :: getBranchTargetOpValue ( const MCInst & MI , unsigned OpIdx , SmallVectorImpl < MCFixup > & Fixups ) const { const ARMSubtarget & Subtarget = TM . getSubtarget < ARMSubtarget > ( ) ; if ( Subtarget . isThumb2 ( ) ) return :: getBranchTargetOpValue ( MI , OpIdx , ARM :: fixup_t2_branch , Fixups ) ; return :: getBranchTargetOpValue ( MI , OpIdx , ARM :: fixup_arm_branch , Fixups ) ; } </s>

ARM ARM ARM ARM ARM::fixup_t2_branch ARM::fixup_arm_branch


<s>
const
MCFixupKindInfo
&
getFixupKindInfo
(
MCFixupKind
Kind
)
const
{
const
static
MCFixupKindInfo
Infos
[
]
=
{
{
"fixup_arm_ldst_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_ldst_pcrel_12"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAligned
}
,
{
"fixup_arm_pcrel_10"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_pcrel_10"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_adr_pcrel_12"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_branch"
,
1
,
24
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_t2_branch"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
|
MCFixupKindInfo
::
FKF_IsAligned
}
,
{
"fixup_arm_thumb_bl"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_blx"
,
0
,
32
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cb"
,
0
,
16
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_thumb_cp"
,
1
,
8
,
MCFixupKindInfo
::
FKF_IsPCRel
}
,
{
"fixup_arm_movt_hi16"
,
0
,
16
,
0
}
,
{
"fixup_arm_movw_lo16"
,
0
,
16
,
0
}
,
}
;
if
(
Kind
<
FirstTargetFixupKind
)
return
MCCodeEmitter
::
getFixupKindInfo
(
Kind
)
;
assert
(
unsigned
(
Kind
FirstTargetFixupKind
)
<
getNumFixupKinds
(
)
&&
"Invalid kind!"
)
;
return
Infos
[
Kind
FirstTargetFixupKind
]
;
}
</s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
getARMRegisterNumbering
(
Reg
)
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
return
0
;
}
</s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
CTX
.
getRegisterInfo
(
)
.
getEncodingValue
(
Reg
)
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
CTX
.
getRegisterInfo
(
)
->
getEncodingValue
(
Reg
)
;
if
(
STI
.
getFeatureBits
(
)
[
ARM
::
HasMVEIntegerOps
]
)
return
RegNo
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isDFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
bit_cast
<
double
>
(
MO
.
getDFPImm
(
)
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
CTX
.
getRegisterInfo
(
)
->
getEncodingValue
(
Reg
)
;
if
(
STI
.
getFeatureBits
(
)
[
ARM
::
HasMVEIntegerOps
]
)
return
RegNo
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>


<s> uint32_t ARMMCCodeEmitter :: getBranchTargetOpValue ( const MCInst & MI , unsigned OpIdx , SmallVectorImpl < MCFixup > & Fixups , const MCSubtargetInfo & STI ) const { if ( isThumb2 ( STI ) ) return :: getBranchTargetOpValue ( MI , OpIdx , ARM :: fixup_t2_condbranch , Fixups , STI ) ; return getARMBranchTargetOpValue ( MI , OpIdx , Fixups , STI ) ; } </s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
,
const
MCSubtargetInfo
&
STI
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
CTX
.
getRegisterInfo
(
)
->
getEncodingValue
(
Reg
)
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>


<s> bool isThumb ( const MCSubtargetInfo & STI ) const { return ( STI . getFeatureBits ( ) & ARM :: ModeThumb ) != 0 ; } </s>


<s>
unsigned
ARMMCCodeEmitter
::
getMachineOpValue
(
const
MCInst
&
MI
,
const
MCOperand
&
MO
,
SmallVectorImpl
<
MCFixup
>
&
Fixups
)
const
{
if
(
MO
.
isReg
(
)
)
{
unsigned
Reg
=
MO
.
getReg
(
)
;
unsigned
RegNo
=
CTX
.
getRegisterInfo
(
)
->
getEncodingValue
(
Reg
)
;
switch
(
Reg
)
{
default
:
return
RegNo
;
case
ARM
::
Q0
:
case
ARM
::
Q1
:
case
ARM
::
Q2
:
case
ARM
::
Q3
:
case
ARM
::
Q4
:
case
ARM
::
Q5
:
case
ARM
::
Q6
:
case
ARM
::
Q7
:
case
ARM
::
Q8
:
case
ARM
::
Q9
:
case
ARM
::
Q10
:
case
ARM
::
Q11
:
case
ARM
::
Q12
:
case
ARM
::
Q13
:
case
ARM
::
Q14
:
case
ARM
::
Q15
:
return
2
*
RegNo
;
}
}
else
if
(
MO
.
isImm
(
)
)
{
return
static_cast
<
unsigned
>
(
MO
.
getImm
(
)
)
;
}
else
if
(
MO
.
isFPImm
(
)
)
{
return
static_cast
<
unsigned
>
(
APFloat
(
MO
.
getFPImm
(
)
)
.
bitcastToAPInt
(
)
.
getHiBits
(
32
)
.
getLimitedValue
(
)
)
;
}
llvm_unreachable
(
"Unable to encode MCOperand!"
)
;
}
</s>


<s> const ARMMCExpr * ARMMCExpr :: create ( VariantKind Kind , const MCExpr * Expr , MCContext & Ctx ) { return new ( Ctx ) ARMMCExpr ( Kind , Expr ) ; } </s>


<s> static bool classof ( const ARMMCExpr * ) { return true ; } </s>

Methods for support type inquiry through isa , cast , and dyn_cast :


<s> MCFragment * findAssociatedFragment ( ) const override { return getSubExpr ( ) -> findAssociatedFragment ( ) ; } </s>

Find the `` associated section '' for this expression , which is currently defined as the absolute section for constants , or otherwise the section associated with the first defined symbol in the expression .


<s> static bool classof ( const MCExpr * E ) { return E -> getKind ( ) == MCExpr :: Target ; } </s>


<s> const ARMMCExpr * ARMMCExpr :: Create ( VariantKind Kind , const MCExpr * Expr , MCContext & Ctx ) { return new ( Ctx ) ARMMCExpr ( Kind , Expr ) ; } </s>

Construct a unary instruction , given the opcode and an operand .


<s> VariantKind getKind ( ) const { return Kind ; } </s>


<s> const MCExpr * getSubExpr ( ) const { return Expr ; } </s>

getSubExpr - Get the child of this expression .


"execute-only should not generate constant pools"

Wrapper for MCInstLowering.lowerOperand ( ) for the tblgen'erated pseudo lowering .


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
llvm_unreachable
(
"unknown operand type"
)
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
createReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
createImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
createExpr
(
MCSymbolRefExpr
::
create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
{
MCOp
=
GetSymbolRef
(
MO
,
GetARMGVSymbol
(
MO
.
getGlobal
(
)
,
MO
.
getTargetFlags
(
)
)
)
;
break
;
}
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
createFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
case
MachineOperand
::
MO_RegisterMask
:
return
false
;
}
return
true
;
}
</s>

ARM
ARM
"unknown operand type"
ARM::CPSR
"Subregs should be eliminated!"
ARM


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
llvm_unreachable
(
"unknown operand type"
)
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
CreateReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
CreateImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
CreateExpr
(
MCSymbolRefExpr
::
Create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
MCOp
=
GetSymbolRef
(
MO
,
Mang
->
getSymbol
(
MO
.
getGlobal
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
CreateFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
case
MachineOperand
::
MO_RegisterMask
:
return
false
;
}
return
true
;
}
</s>

ARM
ARM
"unknown operand type"
ARM::CPSR
"Subregs should be eliminated!"


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
assert
(
0
&&
"unknown operand type"
)
;
return
false
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
CreateReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
CreateImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
CreateExpr
(
MCSymbolRefExpr
::
Create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
MCOp
=
GetSymbolRef
(
MO
,
Mang
->
getSymbol
(
MO
.
getGlobal
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
CreateFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
case
MachineOperand
::
MO_RegisterMask
:
return
false
;
}
return
true
;
}
</s>

ARM
ARM
0
"unknown operand type"
ARM::CPSR
"Subregs should be eliminated!"


<s>
MCSymbol
*
ARMMCInstLower
::
GetExternalSymbolSymbol
(
const
MachineOperand
&
MO
)
const
{
switch
(
MO
.
getTargetFlags
(
)
)
{
default
:
assert
(
0
&&
"Unknown target flag on GV operand"
)
;
case
0
:
break
;
}
return
Printer
.
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
;
}
</s>

Return the MCSymbol for the specified ExternalSymbol .


<s> const ARMSubtarget & ARMMCInstLower :: getSubtarget ( ) const { return AsmPrinter . getSubtarget ( ) ; } </s>

getSubtarget - Return the subtarget for which this machine code is being compiled .


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
llvm_unreachable
(
"unknown operand type"
)
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
CreateReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
CreateImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
CreateExpr
(
MCSymbolRefExpr
::
Create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
MCOp
=
GetSymbolRef
(
MO
,
getSymbol
(
MO
.
getGlobal
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
CreateFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
case
MachineOperand
::
MO_RegisterMask
:
return
false
;
}
return
true
;
}
</s>


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
assert
(
0
&&
"unknown operand type"
)
;
return
false
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
CreateReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
CreateImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
CreateExpr
(
MCSymbolRefExpr
::
Create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
MCOp
=
GetSymbolRef
(
MO
,
Mang
->
getSymbol
(
MO
.
getGlobal
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
CreateFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
}
return
true
;
}
</s>


<s>
bool
ARMAsmPrinter
::
lowerOperand
(
const
MachineOperand
&
MO
,
MCOperand
&
MCOp
)
{
switch
(
MO
.
getType
(
)
)
{
default
:
llvm_unreachable
(
"unknown operand type"
)
;
case
MachineOperand
::
MO_Register
:
if
(
MO
.
isImplicit
(
)
&&
MO
.
getReg
(
)
!=
ARM
::
CPSR
)
return
false
;
assert
(
!
MO
.
getSubReg
(
)
&&
"Subregs should be eliminated!"
)
;
MCOp
=
MCOperand
::
CreateReg
(
MO
.
getReg
(
)
)
;
break
;
case
MachineOperand
::
MO_Immediate
:
MCOp
=
MCOperand
::
CreateImm
(
MO
.
getImm
(
)
)
;
break
;
case
MachineOperand
::
MO_MachineBasicBlock
:
MCOp
=
MCOperand
::
CreateExpr
(
MCSymbolRefExpr
::
Create
(
MO
.
getMBB
(
)
->
getSymbol
(
)
,
OutContext
)
)
;
break
;
case
MachineOperand
::
MO_GlobalAddress
:
{
MCOp
=
GetSymbolRef
(
MO
,
GetARMGVSymbol
(
MO
.
getGlobal
(
)
,
MO
.
getTargetFlags
(
)
)
)
;
break
;
}
case
MachineOperand
::
MO_ExternalSymbol
:
MCOp
=
GetSymbolRef
(
MO
,
GetExternalSymbolSymbol
(
MO
.
getSymbolName
(
)
)
)
;
break
;
case
MachineOperand
::
MO_JumpTableIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetJTISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_ConstantPoolIndex
:
MCOp
=
GetSymbolRef
(
MO
,
GetCPISymbol
(
MO
.
getIndex
(
)
)
)
;
break
;
case
MachineOperand
::
MO_BlockAddress
:
MCOp
=
GetSymbolRef
(
MO
,
GetBlockAddressSymbol
(
MO
.
getBlockAddress
(
)
)
)
;
break
;
case
MachineOperand
::
MO_FPImmediate
:
{
APFloat
Val
=
MO
.
getFPImm
(
)
->
getValueAPF
(
)
;
bool
ignored
;
Val
.
convert
(
APFloat
::
IEEEdouble
,
APFloat
::
rmTowardZero
,
&
ignored
)
;
MCOp
=
MCOperand
::
CreateFPImm
(
Val
.
convertToDouble
(
)
)
;
break
;
}
case
MachineOperand
::
MO_RegisterMask
:
return
false
;
}
return
true
;
}
</s>


<s> static ARMCC :: CondCodes getPredicate ( const MCInst & Inst , const MCInstrInfo & Info , unsigned & PredReg ) { const MCInstrDesc & Desc = Info . get ( Inst . getOpcode ( ) ) ; int PIdx = Desc . findFirstPredOperandIdx ( ) ; if ( PIdx == - 1 ) { PredReg = 0 ; return ARMCC :: AL ; } PredReg = Inst . getOperand ( PIdx + 1 ) . getReg ( ) ; return static_cast < ARMCC :: CondCodes > ( Inst . getOperand ( PIdx ) . getImm ( ) ) ; } </s>

Returns the comparison predicate underlying the intrinsic .


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { const MCInstrDesc & Desc = Info -> get ( Inst . getOpcode ( ) ) ; for ( unsigned OpNum = 0 ; OpNum < Desc . getNumOperands ( ) ; ++ OpNum ) { if ( Inst . getOperand ( OpNum ) . isImm ( ) && Desc . OpInfo [ OpNum ] . OperandType == MCOI :: OPERAND_PCREL ) { int64_t Imm = Inst . getOperand ( OpNum ) . getImm ( ) ; Target = ARM_MC :: evaluateBranchTarget ( Desc , Addr , Imm ) ; return true ; } } return false ; } </s>

Given a branch instruction try to get the address the branch targets .


<s> Optional < uint64_t > ARMMCInstrAnalysis :: evaluateMemoryOperandAddress ( const MCInst & Inst , const MCSubtargetInfo * STI , uint64_t Addr , uint64_t Size ) const { const MCInstrDesc & Desc = Info -> get ( Inst . getOpcode ( ) ) ; if ( ! Desc . mayLoad ( ) ) return None ; uint64_t TSFlags = Desc . TSFlags ; unsigned IndexMode = ( TSFlags & ARMII :: IndexModeMask ) >> ARMII :: IndexModeShift ; if ( IndexMode != ARMII :: IndexModeNone ) return None ; unsigned OpIndex = Desc . NumDefs ; while ( OpIndex < Desc . getNumOperands ( ) && Desc . OpInfo [ OpIndex ] . OperandType != MCOI :: OPERAND_MEMORY ) ++ OpIndex ; if ( OpIndex == Desc . getNumOperands ( ) ) return None ; Addr &= ~ 0x3 ; switch ( Desc . TSFlags & ARMII :: FormMask ) { default : Addr += 8 ; break ; case ARMII :: ThumbFrm : Addr += 4 ; break ; case ARMII :: VFPLdStFrm : Addr += STI -> getFeatureBits ( ) [ ARM :: ModeThumb ] ? 4 : 8 ; break ; } unsigned AddrMode = ( TSFlags & ARMII :: AddrModeMask ) ; switch ( AddrMode ) { default : return None ; case ARMII :: AddrMode_i12 : return evaluateMemOpAddrForAddrMode_i12 ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrMode3 : return evaluateMemOpAddrForAddrMode3 ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrMode5 : return evaluateMemOpAddrForAddrMode5 ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrMode5FP16 : return evaluateMemOpAddrForAddrMode5FP16 ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrModeT2_i8s4 : return evaluateMemOpAddrForAddrModeT2_i8s4 ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrModeT2_pc : return evaluateMemOpAddrForAddrModeT2_pc ( Inst , Desc , OpIndex , Addr ) ; case ARMII :: AddrModeT1_s : return evaluateMemOpAddrForAddrModeT1_s ( Inst , Desc , OpIndex , Addr ) ; } } </s>

Given an instruction tries to get the address of a memory operand .


<s> bool ARM_MC :: isPredicated ( const MCInst & MI , const MCInstrInfo * MCII ) { const MCInstrDesc & Desc = MCII -> get ( MI . getOpcode ( ) ) ; int PredOpIdx = Desc . findFirstPredOperandIdx ( ) ; return PredOpIdx != - 1 && MI . getOperand ( PredOpIdx ) . getImm ( ) != ARMCC :: AL ; } </s>

Returns true if the instruction is already predicated .


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ 0 ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; int64_t Imm = Inst . getOperand ( 0 ) . getImm ( ) ; Target = Addr + Imm + 8 ; return true ; } </s>


<s> bool isConditionalBranch ( const MCInst & Inst ) const override { if ( Inst . getOpcode ( ) == ARM :: Bcc && Inst . getOperand ( 1 ) . getImm ( ) == ARMCC :: AL ) return false ; return MCInstrAnalysis :: isConditionalBranch ( Inst ) ; } </s>

Return true if this is a branch which may fall through to the next instruction or may transfer control flow to some other block .


<s> bool isUnconditionalBranch ( const MCInst & Inst ) const override { if ( Inst . getOpcode ( ) == ARM :: Bcc && Inst . getOperand ( 1 ) . getImm ( ) == ARMCC :: AL ) return true ; return MCInstrAnalysis :: isUnconditionalBranch ( Inst ) ; } </s>

Return true if this is a branch which always transfers control flow to some other block .


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { unsigned OpId ; switch ( Inst . getOpcode ( ) ) { default : OpId = 0 ; break ; case ARM :: t2WLS : case ARM :: t2LEUpdate : OpId = 2 ; break ; case ARM :: t2LE : OpId = 1 ; break ; } if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ OpId ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; Target = Addr + Inst . getOperand ( OpId ) . getImm ( ) + 4 ; return true ; } </s>


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ 0 ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; int64_t Imm = Inst . getOperand ( 0 ) . getImm ( ) ; Target = Addr + Imm + 4 ; return true ; } </s>


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { unsigned OpId ; switch ( Inst . getOpcode ( ) ) { default : OpId = 0 ; if ( Inst . getNumOperands ( ) == 0 ) return false ; break ; case ARM :: MVE_WLSTP_8 : case ARM :: MVE_WLSTP_16 : case ARM :: MVE_WLSTP_32 : case ARM :: MVE_WLSTP_64 : case ARM :: t2WLS : case ARM :: MVE_LETP : case ARM :: t2LEUpdate : OpId = 2 ; break ; case ARM :: t2LE : OpId = 1 ; break ; } if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ OpId ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; Target = Addr + Inst . getOperand ( OpId ) . getImm ( ) + 4 ; return true ; } </s>


<s> uint64_t evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size ) const { if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ 0 ] . OperandType != MCOI :: OPERAND_PCREL ) return - 1ULL ; int64_t Imm = Inst . getOperand ( 0 ) . getImm ( ) ; return Addr + Imm + 8 ; } </s>


<s> virtual bool isConditionalBranch ( const MCInst & Inst ) const { if ( Inst . getOpcode ( ) == ARM :: Bcc && Inst . getOperand ( 1 ) . getImm ( ) == ARMCC :: AL ) return false ; return MCInstrAnalysis :: isConditionalBranch ( Inst ) ; } </s>


<s> virtual bool isUnconditionalBranch ( const MCInst & Inst ) const { if ( Inst . getOpcode ( ) == ARM :: Bcc && Inst . getOperand ( 1 ) . getImm ( ) == ARMCC :: AL ) return true ; return MCInstrAnalysis :: isUnconditionalBranch ( Inst ) ; } </s>


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { unsigned OpId ; switch ( Inst . getOpcode ( ) ) { default : OpId = 0 ; break ; case ARM :: MVE_WLSTP_8 : case ARM :: MVE_WLSTP_16 : case ARM :: MVE_WLSTP_32 : case ARM :: MVE_WLSTP_64 : case ARM :: t2WLS : case ARM :: MVE_LETP : case ARM :: t2LEUpdate : OpId = 2 ; break ; case ARM :: t2LE : OpId = 1 ; break ; } if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ OpId ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; Target = Addr + Inst . getOperand ( OpId ) . getImm ( ) + 4 ; return true ; } </s>


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const override { const MCInstrDesc & Desc = Info -> get ( Inst . getOpcode ( ) ) ; bool FoundImm = false ; int64_t Imm ; for ( unsigned OpNum = 0 ; OpNum < Desc . getNumOperands ( ) ; ++ OpNum ) { if ( Inst . getOperand ( OpNum ) . isImm ( ) && Desc . OpInfo [ OpNum ] . OperandType == MCOI :: OPERAND_PCREL ) { Imm = Inst . getOperand ( OpNum ) . getImm ( ) ; FoundImm = true ; } } if ( ! FoundImm ) return false ; uint64_t Offset = ( ( Desc . TSFlags & ARMII :: FormMask ) == ARMII :: ThumbFrm ) ? 4 : 8 ; Target = Addr + Imm + Offset ; return true ; } </s>


<s> bool evaluateBranch ( const MCInst & Inst , uint64_t Addr , uint64_t Size , uint64_t & Target ) const { if ( Info -> get ( Inst . getOpcode ( ) ) . OpInfo [ 0 ] . OperandType != MCOI :: OPERAND_PCREL ) return false ; int64_t Imm = Inst . getOperand ( 0 ) . getImm ( ) ; Target = Addr + Imm + 8 ; return true ; } </s>


<s>
virtual
const
char
*
getPassName
(
)
const
{
return
"ARM Native Client Rewrite Pass"
;
}
</s>

getPassName - Return a nice clean name for a pass .


<s>
StringRef
getPassName
(
)
const
override
{
return
"optimise barriers pass"
;
}
</s>


<s> bool ARMOptimizeBarriersPass :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( MF . getFunction ( ) ) ) return false ; std :: vector < MachineInstr * > ToRemove ; int64_t DMBType = - 1 ; for ( auto & MBB : MF ) { bool IsRemovableNextDMB = false ; for ( auto & MI : MBB ) { if ( MI . getOpcode ( ) == ARM :: DMB ) { if ( IsRemovableNextDMB ) { if ( MI . getOperand ( 0 ) . getImm ( ) == DMBType ) { ToRemove . push_back ( & MI ) ; } else { DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else { IsRemovableNextDMB = true ; DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else if ( ! CanMovePastDMB ( & MI ) ) { IsRemovableNextDMB = false ; } } } bool Changed = false ; for ( auto MI : ToRemove ) { MI -> eraseFromParent ( ) ; ++ NumDMBsRemoved ; Changed = true ; } return Changed ; } </s>

runOnMachineFunction - Emit the function body .


<s> bool ARMOptimizeBarriersPass :: runOnMachineFunction ( MachineFunction & MF ) { std :: vector < MachineInstr * > ToRemove ; int64_t DMBType = - 1 ; for ( auto & MBB : MF ) { bool IsRemovableNextDMB = false ; for ( auto & MI : MBB ) { if ( MI . getOpcode ( ) == ARM :: DMB ) { if ( IsRemovableNextDMB ) { if ( MI . getOperand ( 0 ) . getImm ( ) == DMBType ) { ToRemove . push_back ( & MI ) ; } else { DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else { IsRemovableNextDMB = true ; DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else if ( ! CanMovePastDMB ( & MI ) ) { IsRemovableNextDMB = false ; } } } for ( auto MI : ToRemove ) { MI -> eraseFromParent ( ) ; ++ NumDMBsRemoved ; } return NumDMBsRemoved > 0 ; } </s>


<s>
virtual
const
char
*
getPassName
(
)
const
{
return
"optimise barriers pass"
;
}
</s>


<s> bool ARMOptimizeBarriersPass :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( * MF . getFunction ( ) ) ) return false ; std :: vector < MachineInstr * > ToRemove ; int64_t DMBType = - 1 ; for ( auto & MBB : MF ) { bool IsRemovableNextDMB = false ; for ( auto & MI : MBB ) { if ( MI . getOpcode ( ) == ARM :: DMB ) { if ( IsRemovableNextDMB ) { if ( MI . getOperand ( 0 ) . getImm ( ) == DMBType ) { ToRemove . push_back ( & MI ) ; } else { DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else { IsRemovableNextDMB = true ; DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else if ( ! CanMovePastDMB ( & MI ) ) { IsRemovableNextDMB = false ; } } } bool Changed = false ; for ( auto MI : ToRemove ) { MI -> eraseFromParent ( ) ; ++ NumDMBsRemoved ; Changed = true ; } return Changed ; } </s>


<s>
const
char
*
getPassName
(
)
const
override
{
return
"optimise barriers pass"
;
}
</s>


<s> bool ARMOptimizeBarriersPass :: runOnMachineFunction ( MachineFunction & MF ) { if ( skipFunction ( * MF . getFunction ( ) ) ) return false ; std :: vector < MachineInstr * > ToRemove ; int64_t DMBType = - 1 ; for ( auto & MBB : MF ) { bool IsRemovableNextDMB = false ; for ( auto & MI : MBB ) { if ( MI . getOpcode ( ) == ARM :: DMB ) { if ( IsRemovableNextDMB ) { if ( MI . getOperand ( 0 ) . getImm ( ) == DMBType ) { ToRemove . push_back ( & MI ) ; } else { DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else { IsRemovableNextDMB = true ; DMBType = MI . getOperand ( 0 ) . getImm ( ) ; } } else if ( ! CanMovePastDMB ( & MI ) ) { IsRemovableNextDMB = false ; } } } for ( auto MI : ToRemove ) { MI -> eraseFromParent ( ) ; ++ NumDMBsRemoved ; } return NumDMBsRemoved > 0 ; } </s>


<s> bool ARMPagerandoOptimizer :: runOnMachineFunction ( MachineFunction & MF ) { auto & F = MF . getFunction ( ) ; if ( ! F . isPagerando ( ) || skipFunction ( F ) ) { return false ; } auto BinPrefix = F . getSectionPrefix ( ) . getValue ( ) ; auto & CPEntries = MF . getConstantPool ( ) -> getConstants ( ) ; SmallSet < int , 8 > CPIndices ; int Index = 0 ; for ( auto & E : CPEntries ) { if ( isIntraBin ( E , BinPrefix ) ) CPIndices . insert ( Index ) ; Index ++ ; } if ( CPIndices . empty ( ) ) return false ; std :: vector < MachineInstr * > Uses ; for ( auto & BB : MF ) { for ( auto & MI : BB ) { int Index = getCPIndex ( MI ) ; if ( CPIndices . count ( Index ) ) Uses . push_back ( & MI ) ; } } for ( auto * MI : Uses ) { int Index = getCPIndex ( * MI ) ; auto * Callee = getCallee ( CPEntries [ Index ] ) ; optimizeCalls ( MI , Callee ) ; } deleteCPEntries ( MF , CPIndices ) ; return true ; } </s>


<s>
void
dump
(
)
{
LLVM_DEBUG
(
dbgs
(
)
<<
"Reduction:\n"
;
for
(
auto
*
Add
:
Adds
)
LLVM_DEBUG
(
dbgs
(
)
<<
*
Add
<<
"\n"
)
;
for
(
auto
&
Mul
:
Muls
)
LLVM_DEBUG
(
dbgs
(
)
<<
*
Mul
->
Root
<<
"\n"
<<
"  "
<<
*
Mul
->
LHS
<<
"\n"
<<
"  "
<<
*
Mul
->
RHS
<<
"\n"
)
;
LLVM_DEBUG
(
if
(
Acc
)
dbgs
(
)
<<
"Acc in: "
<<
*
Acc
<<
"\n"
)
)
;
}
</s>

Dump the plan to stderr ( for debugging ) .


<s> Type * getType ( ) const { return Root -> getType ( ) ; } </s>

Overload to return most specific vector type .


"Unaligned memory access not supported: not "

"DSP extension not enabled: not running pass "

"Only supporting little endian: not running pass "

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


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { FunctionPass :: getAnalysisUsage ( AU ) ; AU . addRequired < AssumptionCacheTracker > ( ) ; AU . addRequired < ScalarEvolutionWrapperPass > ( ) ; AU . addRequired < AAResultsWrapperPass > ( ) ; AU . addRequired < TargetLibraryInfoWrapperPass > ( ) ; AU . addRequired < DominatorTreeWrapperPass > ( ) ; AU . addRequired < TargetPassConfig > ( ) ; AU . addPreserved < ScalarEvolutionWrapperPass > ( ) ; AU . addPreserved < GlobalsAAWrapperPass > ( ) ; AU . setPreservesCFG ( ) ; } </s>

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> LoadInst * getLoad ( ) { return NewLd ; } </s>

Loads are not normal binary operators : their result type is not determined by their operands , and they produce a value AND a token chain .


<s> Instruction * getRoot ( ) { return Root ; } </s>

Similar to getMemoryRoot , but also flushes PendingConstrainedFP ( Strict ) items .


<s> bool doInitialization ( Loop * L , LPPassManager & LPM ) override { LoadPairs . clear ( ) ; WideLoads . clear ( ) ; return true ; } </s>

Set up the AsmPrinter when we are working on a new module .


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override { LoopPass :: getAnalysisUsage ( AU ) ; AU . addRequired < AssumptionCacheTracker > ( ) ; AU . addRequired < ScalarEvolutionWrapperPass > ( ) ; AU . addRequired < AAResultsWrapperPass > ( ) ; AU . addRequired < TargetLibraryInfoWrapperPass > ( ) ; AU . addRequired < LoopInfoWrapperPass > ( ) ; AU . addRequired < DominatorTreeWrapperPass > ( ) ; AU . addRequired < TargetPassConfig > ( ) ; AU . addPreserved < LoopInfoWrapperPass > ( ) ; AU . setPreservesCFG ( ) ; } </s>


<s> unsigned size ( ) const { return AllValues . size ( ) ; } </s>

The number of name/type pairs is returned .


<s> ARMPLT1 * ARMPLT :: create ( ) { ARMPLT1 * plt1_entry = new ( std :: nothrow ) ARMPLT1 ( * m_pSectionData ) ; if ( ! plt1_entry ) fatal ( diag :: fail_allocate_memory_plt ) ; return plt1_entry ; } </s>


<s> uint64_t ARMPLT :: emit ( MemoryRegion & pRegion ) { uint64_t result = 0x0 ; iterator it = begin ( ) ; unsigned char * buffer = pRegion . begin ( ) ; memcpy ( buffer , llvm :: cast < ARMPLT0 > ( ( * it ) ) . getValue ( ) , ARMPLT0 :: EntrySize ) ; result += ARMPLT0 :: EntrySize ; ++ it ; ARMPLT1 * plt1 = 0 ; ARMPLT :: iterator ie = end ( ) ; while ( it != ie ) { plt1 = & ( llvm :: cast < ARMPLT1 > ( * it ) ) ; memcpy ( buffer + result , plt1 -> getValue ( ) , ARMPLT1 :: EntrySize ) ; result += ARMPLT1 :: EntrySize ; ++ it ; } return result ; } </s>

Output the remark via the diagnostic handler and to the optimization record file .

ARM ARM 0x0 ARM ARM ARM ARM 0 ARM ARM ARM ARM


<s> RegisterBankInfo :: InstructionMapping ARMRegisterBankInfo :: getInstrMapping ( const MachineInstr & MI ) const { auto Opc = MI . getOpcode ( ) ; if ( ! isPreISelGenericOpcode ( Opc ) ) { InstructionMapping Mapping = getInstrMappingImpl ( MI ) ; if ( Mapping . isValid ( ) ) return Mapping ; } using namespace TargetOpcode ; unsigned NumOperands = MI . getNumOperands ( ) ; const ValueMapping * OperandsMapping = & ARM :: ValueMappings [ 0 ] ; switch ( Opc ) { case G_ADD : case G_LOAD : case G_SEXT : case G_ZEXT : OperandsMapping = & ARM :: ValueMappings [ 0 ] ; break ; case G_FRAME_INDEX : OperandsMapping = getOperandsMapping ( { & ARM :: ValueMappings [ 0 ] , nullptr } ) ; break ; default : return InstructionMapping { } ; } return InstructionMapping { DefaultMappingID , 1 , OperandsMapping , NumOperands } ; } </s>

Get the mapping of the different operands of MI on the register bank .


"Switch should handle all register classes"


<s> RegisterBankInfo :: InstructionMapping ARMRegisterBankInfo :: getInstrMapping ( const MachineInstr & MI ) const { auto Opc = MI . getOpcode ( ) ; if ( ! isPreISelGenericOpcode ( Opc ) ) { InstructionMapping Mapping = getInstrMappingImpl ( MI ) ; if ( Mapping . isValid ( ) ) return Mapping ; } using namespace TargetOpcode ; unsigned NumOperands = MI . getNumOperands ( ) ; const ValueMapping * OperandsMapping = & ARM :: ValueMappings [ 0 ] ; switch ( Opc ) { case G_ADD : case G_LOAD : OperandsMapping = & ARM :: ValueMappings [ 0 ] ; break ; case G_FRAME_INDEX : OperandsMapping = getOperandsMapping ( { & ARM :: ValueMappings [ 0 ] , nullptr } ) ; break ; default : return InstructionMapping { } ; } return InstructionMapping { DefaultMappingID , 1 , OperandsMapping , NumOperands } ; } </s>


<s> void ARMRegisterInfo :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr * Old = I ; DebugLoc dl = Old -> getDebugLoc ( ) ; unsigned Amount = Old -> getOperand ( 0 ) . getImm ( ) ; if ( Amount != 0 ) { ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; unsigned Align = MF . getTarget ( ) . getFrameInfo ( ) -> getStackAlignment ( ) ; Amount = ( Amount + Align - 1 ) / Align * Align ; unsigned Opc = Old -> getOpcode ( ) ; bool isThumb = AFI -> isThumbFunction ( ) ; ARMCC :: CondCodes Pred = isThumb ? ARMCC :: AL : ( ARMCC :: CondCodes ) Old -> getOperand ( 1 ) . getImm ( ) ; if ( Opc == ARM :: ADJCALLSTACKDOWN || Opc == ARM :: tADJCALLSTACKDOWN ) { unsigned PredReg = isThumb ? 0 : Old -> getOperand ( 2 ) . getReg ( ) ; emitSPUpdate ( MBB , I , - Amount , Pred , PredReg , isThumb , TII , * this , dl ) ; } else { unsigned PredReg = isThumb ? 0 : Old -> getOperand ( 3 ) . getReg ( ) ; assert ( Opc == ARM :: ADJCALLSTACKUP || Opc == ARM :: tADJCALLSTACKUP ) ; emitSPUpdate ( MBB , I , Amount , Pred , PredReg , isThumb , TII , * this , dl ) ; } } } MBB . erase ( I ) ; } </s>

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


<s> void ARMRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , unsigned DestReg , int Val , unsigned Pred , unsigned PredReg , const TargetInstrInfo * TII , bool isThumb , DebugLoc dl ) const { MachineFunction & MF = * MBB . getParent ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; Constant * C = ConstantInt :: get ( Type :: Int32Ty , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , 4 ) ; if ( isThumb ) BuildMI ( MBB , MBBI , dl , TII -> get ( ARM :: tLDRcp ) , DestReg ) . addConstantPoolIndex ( Idx ) ; else BuildMI ( MBB , MBBI , dl , TII -> get ( ARM :: LDRcp ) , DestReg ) . addConstantPoolIndex ( Idx ) . addReg ( 0 ) . addImm ( 0 ) . addImm ( Pred ) . addReg ( PredReg ) ; } </s>

emitLoadConstPool - Emits a load from constpool to materialize the specified immediate .


<s> static void emitSPUpdate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , int NumBytes , ARMCC :: CondCodes Pred , unsigned PredReg , bool isThumb , const TargetInstrInfo & TII , const ARMRegisterInfo & MRI , DebugLoc dl ) { if ( isThumb ) emitThumbRegPlusImmediate ( MBB , MBBI , ARM :: SP , ARM :: SP , NumBytes , TII , MRI , dl ) ; else emitARMRegPlusImmediate ( MBB , MBBI , ARM :: SP , ARM :: SP , NumBytes , Pred , PredReg , TII , dl ) ; } </s>

Emit a series of instructions to increment / decrement the stack pointer by a constant value .

ARM ARMCC::CondCodes ARM ARM::SP ARM::SP ARM ARM::SP ARM::SP


<s> const unsigned * ARMRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { static const unsigned CalleeSavedRegs [ ] = { ARM :: LR , ARM :: R11 , ARM :: R10 , ARM :: R9 , ARM :: R8 , ARM :: R7 , ARM :: R6 , ARM :: R5 , ARM :: R4 , ARM :: D15 , ARM :: D14 , ARM :: D13 , ARM :: D12 , ARM :: D11 , ARM :: D10 , ARM :: D9 , ARM :: D8 , 0 } ; static const unsigned DarwinCalleeSavedRegs [ ] = { ARM :: LR , ARM :: R7 , ARM :: R6 , ARM :: R5 , ARM :: R4 , ARM :: R11 , ARM :: R10 , ARM :: R9 , ARM :: R8 , ARM :: D15 , ARM :: D14 , ARM :: D13 , ARM :: D12 , ARM :: D11 , ARM :: D10 , ARM :: D9 , ARM :: D8 , 0 } ; return STI . isTargetDarwin ( ) ? DarwinCalleeSavedRegs : CalleeSavedRegs ; } </s>


<s> int ARMRegisterInfo :: getDwarfRegNum ( unsigned RegNum , bool isEH ) const { return ARMGenRegisterInfo :: getDwarfRegNumFull ( RegNum , 0 ) ; } </s>

Map a target register to an equivalent dwarf register number .


<s> unsigned ARMRegisterInfo :: getFrameRegister ( MachineFunction & MF ) const { if ( STI . isTargetDarwin ( ) || hasFP ( MF ) ) return ( STI . useThumbBacktraces ( ) || STI . isThumb ( ) ) ? ARM :: R7 : ARM :: R11 ; else return ARM :: SP ; } </s>


<s> const TargetRegisterClass * ARMRegisterInfo :: getPointerRegClass ( ) const { return & ARM :: GPRRegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> unsigned ARMRegisterInfo :: getRARegister ( ) const { return ARM :: LR ; } </s>

This method should return the register where the return address can be found .


<s> BitVector ARMRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; if ( STI . isTargetDarwin ( ) || hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; return Reserved ; } </s>

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


<s> bool ARMRegisterInfo :: hasFP ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; return NoFramePointerElim || MFI -> hasVarSizedObjects ( ) ; } </s>

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


<s> bool ARMRegisterInfo :: hasReservedCallFrame ( MachineFunction & MF ) const { const MachineFrameInfo * FFI = MF . getFrameInfo ( ) ; unsigned CFSize = FFI -> getMaxCallFrameSize ( ) ; ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumbFunction ( ) ) { if ( CFSize >= ( ( 1 << 8 ) - 1 ) * 4 / 2 ) return false ; } else { if ( CFSize >= ( ( 1 << 12 ) - 1 ) / 2 ) return false ; } return ! MF . getFrameInfo ( ) -> hasVarSizedObjects ( ) ; } </s>

hasReservedCallFrame - Under normal circumstances , when a frame pointer is not required , we reserve argument space for call sites in the function immediately on entry to the current function .


<s> bool ARMRegisterInfo :: requiresRegisterScavenging ( const MachineFunction & MF ) const { const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; return ThumbRegScavenging || ! AFI -> isThumbFunction ( ) ; } </s>

Returns true if the target requires ( and can make use of ) the register scavenger .


<s> const char * ARMRelocator :: getName ( Relocator :: Type pType ) const { return ApplyFunctions [ pType ] . name ; } </s>

Return a string with the name of the plan and the applicable VFs and UFs .


<s> Relocator :: Size ARMRelocator :: getSize ( Relocation :: Type pType ) const { return 32 ; } </s>

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


<s> const ARMGNULDBackend & getTarget ( ) const { return m_Target ; } </s>

getTarget - Return the target machine this machine code is compiled with


<s> ARMRelocator :: Result none ( Relocation & pReloc , ARMRelocator & pParent ) { return Relocator :: OK ; } </s>

Returns true if none of the bits are set .


<s> ARMRelocator :: Result unsupported ( Relocation & pReloc , ARMRelocator & pParent ) { return Relocator :: Unsupported ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , SDLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { const ARMSubtarget & Subtarget = DAG . getMachineFunction ( ) . getSubtarget < ARMSubtarget > ( ) ; if ( ! Subtarget . isAAPCS_ABI ( ) || Subtarget . isTargetMachO ( ) || Subtarget . isTargetWindows ( ) ) return SDValue ( ) ; const ARMTargetLowering & TLI = * Subtarget . getTargetLowering ( ) ; TargetLowering :: ArgListTy Args ; TargetLowering :: ArgListEntry Entry ; Type * IntPtrTy = TLI . getDataLayout ( ) -> getIntPtrType ( * DAG . getContext ( ) ) ; Entry . Node = Dst ; Entry . Ty = IntPtrTy ; Args . push_back ( Entry ) ; Entry . Node = Size ; Entry . Ty = IntPtrTy ; Entry . isSExt = false ; Args . push_back ( Entry ) ; if ( Src . getValueType ( ) . bitsGT ( MVT :: i32 ) ) Src = DAG . getNode ( ISD :: TRUNCATE , dl , MVT :: i32 , Src ) ; else Src = DAG . getNode ( ISD :: ZERO_EXTEND , dl , MVT :: i32 , Src ) ; Entry . Node = Src ; Entry . Ty = Type :: getInt32Ty ( * DAG . getContext ( ) ) ; Entry . isSExt = true ; Args . push_back ( Entry ) ; TargetLowering :: CallLoweringInfo CLI ( DAG ) ; CLI . setDebugLoc ( dl ) . setChain ( Chain ) . setCallee ( TLI . getLibcallCallingConv ( RTLIB :: MEMSET ) , Type :: getVoidTy ( * DAG . getContext ( ) ) , DAG . getExternalSymbol ( TLI . getLibcallName ( RTLIB :: MEMSET ) , TLI . getPointerTy ( ) ) , std :: move ( Args ) , 0 ) . setDiscardResult ( ) ; std :: pair < SDValue , SDValue > CallResult = TLI . LowerCallTo ( CLI ) ; return CallResult . second ; } </s>

Emit target-specific code that performs a memset .


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemmove ( SelectionDAG & DAG , SDLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { return EmitSpecializedLibcall ( DAG , dl , Chain , Dst , Src , Size , Align , RTLIB :: MEMMOVE ) ; } </s>

Emit target-specific code that performs a memmove .


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , SDLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { return EmitSpecializedLibcall ( DAG , dl , Chain , Dst , Src , Size , Align , RTLIB :: MEMSET ) ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemmove ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { return EmitSpecializedLibcall ( DAG , dl , Chain , Dst , Src , Size , Alignment . value ( ) , RTLIB :: MEMMOVE ) ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { return EmitSpecializedLibcall ( DAG , dl , Chain , Dst , Src , Size , Alignment . value ( ) , RTLIB :: MEMSET ) ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , SDLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { const ARMSubtarget & Subtarget = DAG . getTarget ( ) . getSubtarget < ARMSubtarget > ( ) ; if ( ! Subtarget . isAAPCS_ABI ( ) || Subtarget . isTargetMachO ( ) || Subtarget . isTargetWindows ( ) ) return SDValue ( ) ; const ARMTargetLowering & TLI = * static_cast < const ARMTargetLowering * > ( DAG . getTarget ( ) . getTargetLowering ( ) ) ; TargetLowering :: ArgListTy Args ; TargetLowering :: ArgListEntry Entry ; Type * IntPtrTy = TLI . getDataLayout ( ) -> getIntPtrType ( * DAG . getContext ( ) ) ; Entry . Node = Dst ; Entry . Ty = IntPtrTy ; Args . push_back ( Entry ) ; Entry . Node = Size ; Entry . Ty = IntPtrTy ; Entry . isSExt = false ; Args . push_back ( Entry ) ; if ( Src . getValueType ( ) . bitsGT ( MVT :: i32 ) ) Src = DAG . getNode ( ISD :: TRUNCATE , dl , MVT :: i32 , Src ) ; else Src = DAG . getNode ( ISD :: ZERO_EXTEND , dl , MVT :: i32 , Src ) ; Entry . Node = Src ; Entry . Ty = Type :: getInt32Ty ( * DAG . getContext ( ) ) ; Entry . isSExt = true ; Args . push_back ( Entry ) ; TargetLowering :: CallLoweringInfo CLI ( DAG ) ; CLI . setDebugLoc ( dl ) . setChain ( Chain ) . setCallee ( TLI . getLibcallCallingConv ( RTLIB :: MEMSET ) , Type :: getVoidTy ( * DAG . getContext ( ) ) , DAG . getExternalSymbol ( TLI . getLibcallName ( RTLIB :: MEMSET ) , TLI . getPointerTy ( ) ) , std :: move ( Args ) , 0 ) . setDiscardResult ( ) ; std :: pair < SDValue , SDValue > CallResult = TLI . LowerCallTo ( CLI ) ; return CallResult . second ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , SDLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { if ( ! Subtarget -> isAAPCS_ABI ( ) || Subtarget -> isTargetMachO ( ) || Subtarget -> isTargetWindows ( ) ) return SDValue ( ) ; const ARMTargetLowering & TLI = * static_cast < const ARMTargetLowering * > ( DAG . getTarget ( ) . getTargetLowering ( ) ) ; TargetLowering :: ArgListTy Args ; TargetLowering :: ArgListEntry Entry ; Type * IntPtrTy = TLI . getDataLayout ( ) -> getIntPtrType ( * DAG . getContext ( ) ) ; Entry . Node = Dst ; Entry . Ty = IntPtrTy ; Args . push_back ( Entry ) ; Entry . Node = Size ; Entry . Ty = IntPtrTy ; Entry . isSExt = false ; Args . push_back ( Entry ) ; if ( Src . getValueType ( ) . bitsGT ( MVT :: i32 ) ) Src = DAG . getNode ( ISD :: TRUNCATE , dl , MVT :: i32 , Src ) ; else Src = DAG . getNode ( ISD :: ZERO_EXTEND , dl , MVT :: i32 , Src ) ; Entry . Node = Src ; Entry . Ty = Type :: getInt32Ty ( * DAG . getContext ( ) ) ; Entry . isSExt = true ; Args . push_back ( Entry ) ; TargetLowering :: CallLoweringInfo CLI ( DAG ) ; CLI . setDebugLoc ( dl ) . setChain ( Chain ) . setCallee ( TLI . getLibcallCallingConv ( RTLIB :: MEMSET ) , Type :: getVoidTy ( * DAG . getContext ( ) ) , DAG . getExternalSymbol ( TLI . getLibcallName ( RTLIB :: MEMSET ) , TLI . getPointerTy ( ) ) , & Args , 0 ) . setDiscardResult ( ) ; std :: pair < SDValue , SDValue > CallResult = TLI . LowerCallTo ( CLI ) ; return CallResult . second ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , DebugLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { if ( Subtarget -> isTargetNaCl ( ) || ! Subtarget -> isAAPCS_ABI ( ) || Subtarget -> isTargetDarwin ( ) ) return SDValue ( ) ; const ARMTargetLowering & TLI = * static_cast < const ARMTargetLowering * > ( DAG . getTarget ( ) . getTargetLowering ( ) ) ; TargetLowering :: ArgListTy Args ; TargetLowering :: ArgListEntry Entry ; Type * IntPtrTy = TLI . getDataLayout ( ) -> getIntPtrType ( * DAG . getContext ( ) ) ; Entry . Node = Dst ; Entry . Ty = IntPtrTy ; Args . push_back ( Entry ) ; Entry . Node = Size ; Entry . Ty = IntPtrTy ; Entry . isSExt = false ; Args . push_back ( Entry ) ; if ( Src . getValueType ( ) . bitsGT ( MVT :: i32 ) ) Src = DAG . getNode ( ISD :: TRUNCATE , dl , MVT :: i32 , Src ) ; else Src = DAG . getNode ( ISD :: ZERO_EXTEND , dl , MVT :: i32 , Src ) ; Entry . Node = Src ; Entry . Ty = Type :: getInt32Ty ( * DAG . getContext ( ) ) ; Entry . isSExt = true ; Args . push_back ( Entry ) ; TargetLowering :: CallLoweringInfo CLI ( Chain , Type :: getVoidTy ( * DAG . getContext ( ) ) , false , false , false , false , 0 , TLI . getLibcallCallingConv ( RTLIB :: MEMSET ) , false , false , false , DAG . getExternalSymbol ( TLI . getLibcallName ( RTLIB :: MEMSET ) , TLI . getPointerTy ( ) ) , Args , DAG , dl ) ; std :: pair < SDValue , SDValue > CallResult = TLI . LowerCallTo ( CLI ) ; return CallResult . second ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemset ( SelectionDAG & DAG , DebugLoc dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , unsigned Align , bool isVolatile , MachinePointerInfo DstPtrInfo ) const { if ( ! Subtarget -> isAAPCS_ABI ( ) || Subtarget -> isTargetDarwin ( ) ) return SDValue ( ) ; const ARMTargetLowering & TLI = * static_cast < const ARMTargetLowering * > ( DAG . getTarget ( ) . getTargetLowering ( ) ) ; TargetLowering :: ArgListTy Args ; TargetLowering :: ArgListEntry Entry ; Type * IntPtrTy = TLI . getDataLayout ( ) -> getIntPtrType ( * DAG . getContext ( ) ) ; Entry . Node = Dst ; Entry . Ty = IntPtrTy ; Args . push_back ( Entry ) ; Entry . Node = Size ; Entry . Ty = IntPtrTy ; Entry . isSExt = false ; Args . push_back ( Entry ) ; if ( Src . getValueType ( ) . bitsGT ( MVT :: i32 ) ) Src = DAG . getNode ( ISD :: TRUNCATE , dl , MVT :: i32 , Src ) ; else Src = DAG . getNode ( ISD :: ZERO_EXTEND , dl , MVT :: i32 , Src ) ; Entry . Node = Src ; Entry . Ty = Type :: getInt32Ty ( * DAG . getContext ( ) ) ; Entry . isSExt = true ; Args . push_back ( Entry ) ; TargetLowering :: CallLoweringInfo CLI ( Chain , Type :: getVoidTy ( * DAG . getContext ( ) ) , false , false , false , false , 0 , TLI . getLibcallCallingConv ( RTLIB :: MEMSET ) , false , false , false , DAG . getExternalSymbol ( TLI . getLibcallName ( RTLIB :: MEMSET ) , TLI . getPointerTy ( ) ) , Args , DAG , dl ) ; std :: pair < SDValue , SDValue > CallResult = TLI . LowerCallTo ( CLI ) ; return CallResult . second ; } </s>


<s> SDValue ARMSelectionDAGInfo :: EmitTargetCodeForMemmove ( SelectionDAG & DAG , const SDLoc & dl , SDValue Chain , SDValue Dst , SDValue Src , SDValue Size , Align Alignment , bool isVolatile , bool MustPreserveCheriCapabilities , MachinePointerInfo DstPtrInfo , MachinePointerInfo SrcPtrInfo ) const { return EmitSpecializedLibcall ( DAG , dl , Chain , Dst , Src , Size , Alignment . value ( ) , RTLIB :: MEMMOVE ) ; } </s>