<s> void ARMBaseRegisterInfo :: updateRegAllocHint ( unsigned Reg , unsigned NewReg , MachineFunction & MF ) const { MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; std :: pair < unsigned , unsigned > Hint = MRI -> getRegAllocationHint ( Reg ) ; if ( ( Hint . first == ( unsigned ) ARMRI :: RegPairOdd || Hint . first == ( unsigned ) ARMRI :: RegPairEven ) && Register :: isVirtualRegister ( Hint . second ) ) { unsigned OtherReg = Hint . second ; Hint = MRI -> getRegAllocationHint ( OtherReg ) ; if ( Hint . second == Reg ) { MRI -> setRegAllocationHint ( OtherReg , Hint . first , NewReg ) ; if ( Register :: isVirtualRegister ( NewReg ) ) MRI -> setRegAllocationHint ( NewReg , Hint . first == ( unsigned ) ARMRI :: RegPairOdd ? ARMRI :: RegPairEven : ARMRI :: RegPairOdd , OtherReg ) ; } } } </s>

A callback to allow target a chance to update register allocation hints when a register is `` changed '' ( e.g .


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { bool ghcCall = false ; if ( MF ) { const Function * F = MF -> getFunction ( ) ; ghcCall = ( F ? F -> getCallingConv ( ) == CallingConv :: GHC : false ) ; } if ( ghcCall ) return CSR_NoRegs_SaveList ; else return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getThisReturnPreservedMask ( CallingConv :: ID CC ) const { if ( CC == CallingConv :: GHC ) return NULL ; return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_ThisReturn_RegMask : CSR_AAPCS_ThisReturn_RegMask ; } </s>

getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned ' is on an i32 first argument if the calling convention is one that can ( partially ) model this attribute with a preserved mask ( i.e .


"This resolveFrameIndex does not support Thumb1!"

"Instr doesn't have FrameIndex operand!"

Resolve a frame index operand of an instruction to reference the indicated base register plus offset instead .


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; return ( RealignStack && ( ! MFI -> hasVarSizedObjects ( ) || EnableBasePointer ) ) ; } </s>

True if the stack can be realigned for the target .


"This eliminateCallFramePseudoInstr does not support Thumb1!"

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 ARMBaseRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , DebugLoc dl , unsigned DestReg , unsigned SubIdx , int Val , ARMCC :: CondCodes Pred , unsigned PredReg , unsigned MIFlags ) const { MachineFunction & MF = * MBB . getParent ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; const Constant * C = ConstantInt :: get ( Type :: getInt32Ty ( MF . getFunction ( ) -> getContext ( ) ) , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , 4 ) ; BuildMI ( MBB , MBBI , dl , TII . get ( ARM :: LDRcp ) ) . addReg ( DestReg , getDefRegState ( true ) , SubIdx ) . addConstantPoolIndex ( Idx ) . addImm ( 0 ) . addImm ( Pred ) . addReg ( PredReg ) . setMIFlags ( MIFlags ) ; } </s>

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


<s> static void emitSPUpdate ( bool isARM , MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , DebugLoc dl , const ARMBaseInstrInfo & TII , int NumBytes , ARMCC :: CondCodes Pred = ARMCC :: AL , unsigned PredReg = 0 ) { if ( isARM ) emitARMRegPlusImmediate ( MBB , MBBI , dl , ARM :: SP , ARM :: SP , NumBytes , Pred , PredReg , TII ) ; else emitT2RegPlusImmediate ( MBB , MBBI , dl , ARM :: SP , ARM :: SP , NumBytes , Pred , PredReg , TII ) ; } </s>

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

ARM ARM ARM ARMCC::CondCodes ARMCC::AL 0 ARM ARM ARM::SP ARM::SP ARM::SP ARM::SP


<s> const unsigned * ARMBaseRegisterInfo :: 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 :: 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> const TargetRegisterClass * ARMBaseRegisterInfo :: getCrossCopyRegClass ( const TargetRegisterClass * RC ) const { if ( RC == & ARM :: CCRRegClass ) return 0 ; return RC ; } </s>

getCrossCopyRegClass - Returns a legal register class to copy a register in the specified class to or from .


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i12
:
case
ARMII
::
AddrMode_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrMode3
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrModeT1_s
:
{
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
}
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
break
;
}
return
InstrOffs
*
Scale
;
}
</s>

Get the offset from the referenced frame index in the instruction , if there is one .


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; if ( TFI -> hasFP ( MF ) ) return FramePtr ; return ARM :: SP ; } </s>


<s> const TargetRegisterClass * ARMBaseRegisterInfo :: getLargestLegalSuperClass ( const TargetRegisterClass * RC ) const { const TargetRegisterClass * Super = RC ; TargetRegisterClass :: sc_iterator I = RC -> getSuperClasses ( ) ; do { switch ( Super -> getID ( ) ) { case ARM :: GPRRegClassID : case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : case ARM :: QPRRegClassID : case ARM :: QQPRRegClassID : case ARM :: QQQQPRRegClassID : return Super ; } Super = * I ++ ; } while ( Super ) ; return RC ; } </s>

Returns the largest super class of RC that is legal to use in the current sub-target and has the same spill size .

ARM ARM ARM::GPRRegClassID ARM::SPRRegClassID ARM::DPRRegClassID ARM::QPRRegClassID ARM::QQPRRegClassID ARM::QQQQPRRegClassID


<s>
const
TargetRegisterClass
*
ARMBaseRegisterInfo
::
getMatchingSuperRegClass
(
const
TargetRegisterClass
*
A
,
const
TargetRegisterClass
*
B
,
unsigned
SubIdx
)
const
{
switch
(
SubIdx
)
{
default
:
return
0
;
case
ARM
::
ssub_0
:
case
ARM
::
ssub_1
:
case
ARM
::
ssub_2
:
case
ARM
::
ssub_3
:
{
if
(
A
->
getSize
(
)
==
8
)
{
if
(
B
==
&
ARM
::
SPR_8RegClass
)
return
&
ARM
::
DPR_8RegClass
;
assert
(
B
==
&
ARM
::
SPRRegClass
&&
"Expecting SPR register class!"
)
;
if
(
A
==
&
ARM
::
DPR_8RegClass
)
return
A
;
return
&
ARM
::
DPR_VFP2RegClass
;
}
if
(
A
->
getSize
(
)
==
16
)
{
if
(
B
==
&
ARM
::
SPR_8RegClass
)
return
&
ARM
::
QPR_8RegClass
;
return
&
ARM
::
QPR_VFP2RegClass
;
}
if
(
A
->
getSize
(
)
==
32
)
{
if
(
B
==
&
ARM
::
SPR_8RegClass
)
return
0
;
return
&
ARM
::
QQPR_VFP2RegClass
;
}
assert
(
A
->
getSize
(
)
==
64
&&
"Expecting a QQQQ register class!"
)
;
return
0
;
}
case
ARM
::
dsub_0
:
case
ARM
::
dsub_1
:
case
ARM
::
dsub_2
:
case
ARM
::
dsub_3
:
{
if
(
A
->
getSize
(
)
==
16
)
{
if
(
B
==
&
ARM
::
DPR_VFP2RegClass
)
return
&
ARM
::
QPR_VFP2RegClass
;
if
(
B
==
&
ARM
::
DPR_8RegClass
)
return
0
;
return
A
;
}
if
(
A
->
getSize
(
)
==
32
)
{
if
(
B
==
&
ARM
::
DPR_VFP2RegClass
)
return
&
ARM
::
QQPR_VFP2RegClass
;
if
(
B
==
&
ARM
::
DPR_8RegClass
)
return
0
;
return
A
;
}
assert
(
A
->
getSize
(
)
==
64
&&
"Expecting a QQQQ register class!"
)
;
if
(
B
!=
&
ARM
::
DPRRegClass
)
return
0
;
return
A
;
}
case
ARM
::
dsub_4
:
case
ARM
::
dsub_5
:
case
ARM
::
dsub_6
:
case
ARM
::
dsub_7
:
{
if
(
A
->
getSize
(
)
==
64
&&
B
==
&
ARM
::
DPRRegClass
)
return
A
;
return
0
;
}
case
ARM
::
qsub_0
:
case
ARM
::
qsub_1
:
{
if
(
A
->
getSize
(
)
==
32
)
{
if
(
B
==
&
ARM
::
QPR_VFP2RegClass
)
return
&
ARM
::
QQPR_VFP2RegClass
;
if
(
B
==
&
ARM
::
QPR_8RegClass
)
return
0
;
return
A
;
}
assert
(
A
->
getSize
(
)
==
64
&&
"Expecting a QQQQ register class!"
)
;
if
(
B
==
&
ARM
::
QPRRegClass
)
return
A
;
return
0
;
}
case
ARM
::
qsub_2
:
case
ARM
::
qsub_3
:
{
if
(
A
->
getSize
(
)
==
64
&&
B
==
&
ARM
::
QPRRegClass
)
return
A
;
return
0
;
}
}
return
0
;
}
</s>

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


<s> const TargetRegisterClass * ARMBaseRegisterInfo :: getPointerRegClass ( unsigned Kind ) const { return ARM :: GPRRegisterClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : return TFI -> hasFP ( MF ) ? 4 : 5 ; case ARM :: GPRRegClassID : { unsigned FP = TFI -> hasFP ( MF ) ? 1 : 0 ; return 10 - FP - ( STI . isR9Reserved ( ) ? 1 : 0 ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>

Return the register pressure `` high water mark '' for the specific register class .


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } 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 .


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


<s> void ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock * MBB , unsigned BaseReg , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = MBB -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDrSPi : ARM :: t2ADDri ) ; MachineBasicBlock :: iterator Ins = MBB -> begin ( ) ; DebugLoc DL ; if ( Ins != MBB -> end ( ) ) DL = Ins -> getDebugLoc ( ) ; const MCInstrDesc & MCID = TII . get ( ADDriOpc ) ; MachineRegisterInfo & MRI = MBB -> getParent ( ) -> getRegInfo ( ) ; MRI . constrainRegClass ( BaseReg , TII . getRegClass ( MCID , 0 , this ) ) ; MachineInstrBuilder MIB = AddDefaultPred ( BuildMI ( * MBB , Ins , DL , MCID , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) AddDefaultCC ( MIB ) ; } </s>

Insert defining instruction ( s ) for a pointer to FrameIdx before insertion point I .

ARM ARM ARM ARM ARM::ADDri ARM::tADDrSPi ARM::t2ADDri 0


Returns true if the instruction 's frame index reference would be better served by a base register other than FP or SP .


<s> bool ARMBaseRegisterInfo :: requiresVirtualBaseRegisters ( const MachineFunction & MF ) const { return EnableLocalStackAlloc ; } </s>

Returns true if the target wants the LocalStackAllocation pass to be run and virtual base registers used for more efficient stack access .


"This resolveFrameIndex does not support Thumb1!"

"Instr doesn't have FrameIndex operand!"


"This eliminateCallFramePseudoInstr does not suppor Thumb1!"


<s> void ARMBaseRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , DebugLoc dl , unsigned DestReg , unsigned SubIdx , int Val , ARMCC :: CondCodes Pred , unsigned PredReg ) const { MachineFunction & MF = * MBB . getParent ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; Constant * C = ConstantInt :: get ( Type :: getInt32Ty ( MF . getFunction ( ) -> getContext ( ) ) , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , 4 ) ; BuildMI ( MBB , MBBI , dl , TII . get ( ARM :: LDRcp ) ) . addReg ( DestReg , getDefRegState ( true ) , SubIdx ) . addConstantPoolIndex ( Idx ) . addReg ( 0 ) . addImm ( 0 ) . addImm ( Pred ) . addReg ( PredReg ) ; } </s>


<s> static unsigned estimateStackSize ( MachineFunction & MF , MachineFrameInfo * MFI ) { const MachineFrameInfo * FFI = MF . getFrameInfo ( ) ; int Offset = 0 ; for ( int i = FFI -> getObjectIndexBegin ( ) ; i != 0 ; ++ i ) { int FixedOff = - FFI -> getObjectOffset ( i ) ; if ( FixedOff > Offset ) Offset = FixedOff ; } for ( unsigned i = 0 , e = FFI -> getObjectIndexEnd ( ) ; i != e ; ++ i ) { if ( FFI -> isDeadObjectIndex ( i ) ) continue ; Offset += FFI -> getObjectSize ( i ) ; unsigned Align = FFI -> getObjectAlignment ( i ) ; Offset = ( Offset + Align - 1 ) / Align * Align ; } return ( unsigned ) Offset ; } </s>

Estimate and return the size of the stack frame .


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( MachineFunction & MF ) const { if ( STI . isTargetDarwin ( ) || hasFP ( MF ) ) return FramePtr ; return ARM :: SP ; } </s>


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


<s> BitVector ARMBaseRegisterInfo :: 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>


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

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


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( ! MF . getTarget ( ) . Options . RealignStack ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( MF . getTarget ( ) . getFrameLowering ( ) -> hasReservedCallFrame ( MF ) ) return true ; if ( ! EnableBasePointer ) return false ; return MRI -> canReserveReg ( BasePtr ) ; } </s>

True if the stack can be realigned for the target .


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { bool ghcCall = false ; if ( MF ) { const Function * F = MF -> getFunction ( ) ; ghcCall = ( F ? F -> getCallingConv ( ) == CallingConv :: GHC : false ) ; } if ( ghcCall ) { return CSR_GHC_SaveList ; } else { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( CallingConv :: ID ) const { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>

Return a mask of call-preserved registers for the given calling convention on the current function .


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } const TargetRegisterClass * RC = & ARM :: GPRPairRegClass ; for ( TargetRegisterClass :: iterator I = RC -> begin ( ) , E = RC -> end ( ) ; I != E ; ++ I ) for ( MCSubRegIterator SI ( * I , this ) ; SI . isValid ( ) ; ++ SI ) if ( Reserved . test ( * SI ) ) Reserved . set ( * I ) ; return Reserved ; } </s>


<s> void ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock * MBB , unsigned BaseReg , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = MBB -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDrSPi : ARM :: t2ADDri ) ; MachineBasicBlock :: iterator Ins = MBB -> begin ( ) ; DebugLoc DL ; if ( Ins != MBB -> end ( ) ) DL = Ins -> getDebugLoc ( ) ; const MCInstrDesc & MCID = TII . get ( ADDriOpc ) ; MachineRegisterInfo & MRI = MBB -> getParent ( ) -> getRegInfo ( ) ; const MachineFunction & MF = * MBB -> getParent ( ) ; MRI . constrainRegClass ( BaseReg , TII . getRegClass ( MCID , 0 , this , MF ) ) ; MachineInstrBuilder MIB = AddDefaultPred ( BuildMI ( * MBB , Ins , DL , MCID , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) AddDefaultCC ( MIB ) ; } </s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( "no-realign-stack" ) ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( getFramePointerReg ( MF . getSubtarget < ARMSubtarget > ( ) ) ) ) return false ; if ( MF . getSubtarget ( ) . getFrameLowering ( ) -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; if ( STI . isTargetNaCl ( ) ) return CSR_NaCl_SaveList ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>

ARM ARM ARM ARM "interrupt" "interrupt" "FIQ"


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( STI . isTargetNaCl ( ) ) return CSR_NaCl_RegMask ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const TargetFrameLowering * TFI = STI . getFrameLowering ( ) ; if ( TFI -> hasFP ( MF ) ) return getFramePointerReg ( STI ) ; return ARM :: SP ; } </s>


<s> void ARMBaseRegisterInfo :: getRegAllocationHints ( unsigned VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM ) const { const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; std :: pair < unsigned , unsigned > Hint = MRI . getRegAllocationHint ( VirtReg ) ; unsigned Odd ; switch ( Hint . first ) { case ARMRI :: RegPairEven : Odd = 0 ; break ; case ARMRI :: RegPairOdd : Odd = 1 ; break ; default : TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; return ; } unsigned Paired = Hint . second ; if ( Paired == 0 ) return ; unsigned PairedPhys = 0 ; if ( TargetRegisterInfo :: isPhysicalRegister ( Paired ) ) { PairedPhys = Paired ; } else if ( VRM && VRM -> hasPhys ( Paired ) ) { PairedPhys = getPairedGPR ( VRM -> getPhys ( Paired ) , Odd , this ) ; } if ( PairedPhys && std :: find ( Order . begin ( ) , Order . end ( ) , PairedPhys ) != Order . end ( ) ) Hints . push_back ( PairedPhys ) ; for ( unsigned I = 0 , E = Order . size ( ) ; I != E ; ++ I ) { unsigned Reg = Order [ I ] ; if ( Reg == PairedPhys || ( getEncodingValue ( Reg ) & 1 ) != Odd ) continue ; unsigned Paired = getPairedGPR ( Reg , ! Odd , this ) ; if ( ! Paired || MRI . isReserved ( Paired ) ) continue ; Hints . push_back ( Reg ) ; } } </s>

Get a list of 'hint ' registers that the register allocator should try first when allocating a physical register for the virtual register VirtReg .


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const TargetFrameLowering * TFI = STI . getFrameLowering ( ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : return TFI -> hasFP ( MF ) ? 4 : 5 ; case ARM :: GPRRegClassID : { unsigned FP = TFI -> hasFP ( MF ) ? 1 : 0 ; return 10 - FP - ( STI . isR9Reserved ( ) ? 1 : 0 ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const TargetFrameLowering * TFI = STI . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; Reserved . set ( ARM :: APSR_NZCV ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( getFramePointerReg ( STI ) ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } const TargetRegisterClass * RC = & ARM :: GPRPairRegClass ; for ( TargetRegisterClass :: iterator I = RC -> begin ( ) , E = RC -> end ( ) ; I != E ; ++ I ) for ( MCSubRegIterator SI ( * I , this ) ; SI . isValid ( ) ; ++ SI ) if ( Reserved . test ( * SI ) ) Reserved . set ( * I ) ; return Reserved ; } </s>


"Instr doesn't have FrameIndex operand!"


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; bool UseSplitPush = STI . splitFramePushPop ( * MF ) ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : ( UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ) ; const Function & F = MF -> getFunction ( ) ; if ( F . getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F . hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ; } else if ( F . getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && F . getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) { if ( STI . isTargetDarwin ( ) ) return CSR_iOS_SwiftError_SaveList ; return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList : CSR_AAPCS_SwiftError_SaveList ; } if ( STI . isTargetDarwin ( ) && F . getCallingConv ( ) == CallingConv :: CXX_FAST_TLS ) return MF -> getInfo < ARMFunctionInfo > ( ) -> isSplitCSR ( ) ? CSR_iOS_CXX_TLS_PE_SaveList : CSR_iOS_CXX_TLS_SaveList ; return RegList ; } </s>

ARM ARM ARM ARM "interrupt" "interrupt" "FIQ" ARM


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && MF . getFunction ( ) . getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) return STI . isTargetDarwin ( ) ? CSR_iOS_SwiftError_RegMask : CSR_AAPCS_SwiftError_RegMask ; if ( STI . isTargetDarwin ( ) && CC == CallingConv :: CXX_FAST_TLS ) return CSR_iOS_CXX_TLS_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> bool ARMBaseRegisterInfo :: getRegAllocationHints ( unsigned VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM , const LiveRegMatrix * Matrix ) const { const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; std :: pair < unsigned , unsigned > Hint = MRI . getRegAllocationHint ( VirtReg ) ; unsigned Odd ; switch ( Hint . first ) { case ARMRI :: RegPairEven : Odd = 0 ; break ; case ARMRI :: RegPairOdd : Odd = 1 ; break ; default : TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; return false ; } unsigned Paired = Hint . second ; if ( Paired == 0 ) return false ; unsigned PairedPhys = 0 ; if ( TargetRegisterInfo :: isPhysicalRegister ( Paired ) ) { PairedPhys = Paired ; } else if ( VRM && VRM -> hasPhys ( Paired ) ) { PairedPhys = getPairedGPR ( VRM -> getPhys ( Paired ) , Odd , this ) ; } if ( PairedPhys && is_contained ( Order , PairedPhys ) ) Hints . push_back ( PairedPhys ) ; for ( unsigned Reg : Order ) { if ( Reg == PairedPhys || ( getEncodingValue ( Reg ) & 1 ) != Odd ) continue ; unsigned Paired = getPairedGPR ( Reg , ! Odd , this ) ; if ( ! Paired || MRI . isReserved ( Paired ) ) continue ; Hints . push_back ( Reg ) ; } return false ; } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
)
markSuperRegs
(
Reserved
,
getFramePointerReg
(
STI
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
if
(
STI
.
isR9Reserved
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
const
Function
&
F
=
MF
.
getFunction
(
)
;
if
(
F
.
getCallingConv
(
)
==
CallingConv
::
Mono
)
markSuperRegs
(
Reserved
,
ARM
::
R8
)
;
if
(
!
STI
.
hasVFP3
(
)
||
STI
.
hasD16
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


"\tARM::shouldCoalesce - Coalesced Weight: "


<s> void ARMBaseRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const DebugLoc & dl , unsigned DestReg , unsigned SubIdx , int Val , ARMCC :: CondCodes Pred , unsigned PredReg , unsigned MIFlags ) const { MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; const Constant * C = ConstantInt :: get ( Type :: getInt32Ty ( MF . getFunction ( ) -> getContext ( ) ) , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , 4 ) ; BuildMI ( MBB , MBBI , dl , TII . get ( ARM :: LDRcp ) ) . addReg ( DestReg , getDefRegState ( true ) , SubIdx ) . addConstantPoolIndex ( Idx ) . addImm ( 0 ) . addImm ( Pred ) . addReg ( PredReg ) . setMIFlags ( MIFlags ) ; } </s>

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


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( ! MF . getTarget ( ) . Options . RealignStack ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( MF . getTarget ( ) . getFrameLowering ( ) -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; bool UseSplitPush = STI . splitFramePushPop ( * MF ) ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : ( UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ) ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && F -> getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) { if ( STI . isTargetDarwin ( ) ) return CSR_iOS_SwiftError_SaveList ; return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList : CSR_AAPCS_SwiftError_SaveList ; } if ( STI . isTargetDarwin ( ) && F -> getCallingConv ( ) == CallingConv :: CXX_FAST_TLS ) return MF -> getInfo < ARMFunctionInfo > ( ) -> isSplitCSR ( ) ? CSR_iOS_CXX_TLS_PE_SaveList : CSR_iOS_CXX_TLS_SaveList ; return RegList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && MF . getFunction ( ) -> getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) return STI . isTargetDarwin ( ) ? CSR_iOS_SwiftError_RegMask : CSR_AAPCS_SwiftError_RegMask ; if ( STI . isTargetDarwin ( ) && CC == CallingConv :: CXX_FAST_TLS ) return CSR_iOS_CXX_TLS_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> void ARMBaseRegisterInfo :: getRegAllocationHints ( unsigned VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM , const LiveRegMatrix * Matrix ) const { const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; std :: pair < unsigned , unsigned > Hint = MRI . getRegAllocationHint ( VirtReg ) ; unsigned Odd ; switch ( Hint . first ) { case ARMRI :: RegPairEven : Odd = 0 ; break ; case ARMRI :: RegPairOdd : Odd = 1 ; break ; default : TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; return ; } unsigned Paired = Hint . second ; if ( Paired == 0 ) return ; unsigned PairedPhys = 0 ; if ( TargetRegisterInfo :: isPhysicalRegister ( Paired ) ) { PairedPhys = Paired ; } else if ( VRM && VRM -> hasPhys ( Paired ) ) { PairedPhys = getPairedGPR ( VRM -> getPhys ( Paired ) , Odd , this ) ; } if ( PairedPhys && is_contained ( Order , PairedPhys ) ) Hints . push_back ( PairedPhys ) ; for ( unsigned Reg : Order ) { if ( Reg == PairedPhys || ( getEncodingValue ( Reg ) & 1 ) != Odd ) continue ; unsigned Paired = getPairedGPR ( Reg , ! Odd , this ) ; if ( ! Paired || MRI . isReserved ( Paired ) ) continue ; Hints . push_back ( Reg ) ; } } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
)
markSuperRegs
(
Reserved
,
getFramePointerReg
(
STI
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
if
(
STI
.
isR9Reserved
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
if
(
!
STI
.
hasVFP3
(
)
||
STI
.
hasD16
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; return ( RealignStack && ! AFI -> isThumb1OnlyFunction ( ) && ( ! MFI -> hasVarSizedObjects ( ) || EnableBasePointer ) ) ; } </s>


<s> bool ARMBaseRegisterInfo :: canSimplifyCallFramePseudos ( const MachineFunction & MF ) const { return hasReservedCallFrame ( MF ) || MF . getFrameInfo ( ) -> hasVarSizedObjects ( ) ; } </s>

canSimplifyCallFramePseudos - If there is a reserved call frame , the call frame pseudos can be simplified .


"This eliminateFrameIndex does not support Thumb1!"

"This code isn't needed if offset already handled!"

This method must be overriden to eliminate abstract frame indices from instructions which may use them .


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
TargetInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrMode3
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrModeT1_s
:
{
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
}
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
break
;
}
return
InstrOffs
*
Scale
;
}
</s>

Get the offset from the referenced frame index in the instruction , if there is one .


<s> int ARMBaseRegisterInfo :: getFrameIndexReference ( const MachineFunction & MF , int FI , unsigned & FrameReg ) const { return ResolveFrameIndexReference ( MF , FI , FrameReg , 0 ) ; } </s>

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


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { if ( hasFP ( MF ) ) return FramePtr ; return ARM :: SP ; } </s>


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

ARM ARM ARM::SP ARM::PC ARM::FPSCR ARM::R9


<s> bool ARMBaseRegisterInfo :: hasFP ( const MachineFunction & MF ) const { if ( STI . isTargetDarwin ( ) ) return true ; const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; return ( ( DisableFramePointerElim ( MF ) && MFI -> hasCalls ( ) ) || needsStackRealignment ( MF ) || MFI -> hasVarSizedObjects ( ) || MFI -> isFrameAddressTaken ( ) ) ; } </s>


<s> bool ARMBaseRegisterInfo :: hasReservedCallFrame ( const MachineFunction & MF ) const { const MachineFrameInfo * FFI = MF . getFrameInfo ( ) ; unsigned CFSize = FFI -> getMaxCallFrameSize ( ) ; 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 .


"Instr doesn't have FrameIndex operand!"


<s> void ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock :: iterator I , unsigned BaseReg , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = I -> getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDrSPi : ARM :: t2ADDri ) ; MachineInstrBuilder MIB = BuildMI ( * I -> getParent ( ) , I , I -> getDebugLoc ( ) , TII . get ( ADDriOpc ) , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) AddDefaultCC ( AddDefaultPred ( MIB ) ) ; } </s>

ARM ARM ARM ARM ARM::ADDri ARM::tADDrSPi ARM::t2ADDri


"This resolveFrameIndex does not support Thumb1!"

Resolve a frame index operand of an instruction to reference the indicated base register plus offset instead .


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; Reserved . set ( ARM :: APSR_NZCV ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( getFramePointerReg ( STI ) ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } const TargetRegisterClass * RC = & ARM :: GPRPairRegClass ; for ( TargetRegisterClass :: iterator I = RC -> begin ( ) , E = RC -> end ( ) ; I != E ; ++ I ) for ( MCSubRegIterator SI ( * I , this ) ; SI . isValid ( ) ; ++ SI ) if ( Reserved . test ( * SI ) ) Reserved . set ( * I ) ; 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> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const uint16_t * RegList = ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; if ( ! MF ) return RegList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


"This eliminateCallFramePseudoInstr does not support Thumb1!"

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 ARMBaseRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , DebugLoc dl , unsigned DestReg , unsigned SubIdx , int Val , ARMCC :: CondCodes Pred , unsigned PredReg ) const { MachineFunction & MF = * MBB . getParent ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; const Constant * C = ConstantInt :: get ( Type :: getInt32Ty ( MF . getFunction ( ) -> getContext ( ) ) , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , 4 ) ; BuildMI ( MBB , MBBI , dl , TII . get ( ARM :: LDRcp ) ) . addReg ( DestReg , getDefRegState ( true ) , SubIdx ) . addConstantPoolIndex ( Idx ) . addImm ( 0 ) . addImm ( Pred ) . addReg ( PredReg ) ; } </s>


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
TargetInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i12
:
case
ARMII
::
AddrMode_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrMode3
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrModeT1_s
:
{
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
}
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
break
;
}
return
InstrOffs
*
Scale
;
}
</s>


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameInfo * TFI = MF . getTarget ( ) . getFrameInfo ( ) ; if ( TFI -> hasFP ( MF ) ) return FramePtr ; return ARM :: SP ; } </s>


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameInfo * TFI = MF . getTarget ( ) . getFrameInfo ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; return Reserved ; } </s>


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


Returns true if the instruction 's frame index reference would be better served by a base register other than FP or SP .


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( "no-realign-stack" ) ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( MF . getTarget ( ) . getSubtargetImpl ( ) -> getFrameLowering ( ) -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> unsigned ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getSubtarget ( ) . getFrameLowering ( ) ; if ( TFI -> hasFP ( MF ) ) return FramePtr ; return ARM :: SP ; } </s>


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getSubtarget ( ) . getFrameLowering ( ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : return TFI -> hasFP ( MF ) ? 4 : 5 ; case ARM :: GPRRegClassID : { unsigned FP = TFI -> hasFP ( MF ) ? 1 : 0 ; return 10 - FP - ( STI . isR9Reserved ( ) ? 1 : 0 ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>

Return the register pressure `` high water mark '' for the specific register class .


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getSubtarget ( ) . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; Reserved . set ( ARM :: APSR_NZCV ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; if ( ! STI . hasVFP3 ( ) || STI . hasD16 ( ) ) { assert ( ARM :: D31 == ARM :: D16 + 15 ) ; for ( unsigned i = 0 ; i != 16 ; ++ i ) Reserved . set ( ARM :: D16 + i ) ; } const TargetRegisterClass * RC = & ARM :: GPRPairRegClass ; for ( TargetRegisterClass :: iterator I = RC -> begin ( ) , E = RC -> end ( ) ; I != E ; ++ I ) for ( MCSubRegIterator SI ( * I , this ) ; SI . isValid ( ) ; ++ SI ) if ( Reserved . test ( * SI ) ) Reserved . set ( * I ) ; return Reserved ; } </s>


<s> void ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock * MBB , unsigned BaseReg , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = MBB -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDrSPi : ARM :: t2ADDri ) ; MachineBasicBlock :: iterator Ins = MBB -> begin ( ) ; DebugLoc DL ; if ( Ins != MBB -> end ( ) ) DL = Ins -> getDebugLoc ( ) ; const MachineFunction & MF = * MBB -> getParent ( ) ; MachineRegisterInfo & MRI = MBB -> getParent ( ) -> getRegInfo ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; const MCInstrDesc & MCID = TII . get ( ADDriOpc ) ; MRI . constrainRegClass ( BaseReg , TII . getRegClass ( MCID , 0 , this , MF ) ) ; MachineInstrBuilder MIB = AddDefaultPred ( BuildMI ( * MBB , Ins , DL , MCID , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) AddDefaultCC ( MIB ) ; } </s>

Insert defining instruction ( s ) for a pointer to FrameIdx before insertion point I .


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( "no-realign-stack" ) ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( MF . getSubtarget ( ) . getFrameLowering ( ) -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; if ( ! MF ) return RegList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( CallingConv :: ID CC ) const { if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getThisReturnPreservedMask ( CallingConv :: ID CC ) const { if ( CC == CallingConv :: GHC ) return nullptr ; return STI . isTargetDarwin ( ) ? CSR_iOS_ThisReturn_RegMask : CSR_AAPCS_ThisReturn_RegMask ; } </s>

getThisReturnPreservedMask - Returns a call preserved mask specific to the case that 'returned ' is on an i32 first argument if the calling convention is one that can ( partially ) model this attribute with a preserved mask ( i.e .


<s>
void
ARMBaseRegisterInfo
::
emitLoadConstPool
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
&
MBBI
,
DebugLoc
dl
,
unsigned
DestReg
,
unsigned
SubIdx
,
int
Val
,
ARMCC
::
CondCodes
Pred
,
unsigned
PredReg
,
unsigned
MIFlags
)
const
{
assert
(
!
FlagSfiDisableCP
&&
"unexpected call to emitLoadConstPool"
)
;
MachineFunction
&
MF
=
*
MBB
.
getParent
(
)
;
MachineConstantPool
*
ConstantPool
=
MF
.
getConstantPool
(
)
;
const
Constant
*
C
=
ConstantInt
::
get
(
Type
::
getInt32Ty
(
MF
.
getFunction
(
)
->
getContext
(
)
)
,
Val
)
;
unsigned
Idx
=
ConstantPool
->
getConstantPoolIndex
(
C
,
4
)
;
BuildMI
(
MBB
,
MBBI
,
dl
,
TII
.
get
(
ARM
::
LDRcp
)
)
.
addReg
(
DestReg
,
getDefRegState
(
true
)
,
SubIdx
)
.
addConstantPoolIndex
(
Idx
)
.
addImm
(
0
)
.
addImm
(
Pred
)
.
addReg
(
PredReg
)
.
setMIFlags
(
MIFlags
)
;
}
</s>

ARM
ARM
ARMCC::CondCodes
"unexpected call to emitLoadConstPool"
4
ARM::LDRcp
0


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { if ( ReserveR9 ) return CSR_NaCl_SaveList ; bool ghcCall = false ; if ( MF ) { const Function * F = MF -> getFunction ( ) ; ghcCall = ( F ? F -> getCallingConv ( ) == CallingConv :: GHC : false ) ; } if ( ghcCall ) { return CSR_GHC_SaveList ; } else { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( CallingConv :: ID ) const { if ( ReserveR9 ) return CSR_NaCl_RegMask ; return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; return 5 - HasFP ; } case ARM :: GPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; bool IsPagerando = MF . getFunction ( ) . isPagerando ( ) ; return 10 - HasFP - ( STI . isR9Reserved ( ) || IsPagerando ? 1 : 0 ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
)
markSuperRegs
(
Reserved
,
getFramePointerReg
(
STI
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
if
(
STI
.
isR9Reserved
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
if
(
MF
.
getFunction
(
)
.
isPagerando
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
if
(
!
STI
.
hasVFP3
(
)
||
STI
.
hasD16
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


"This eliminateFrameIndex does not support Thumb1!"

"Instr doesn't have FrameIndex operand!"

"This code isn't needed if offset already handled!"


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; bool UseSplitPush = STI . splitFramePushPop ( ) ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : ( UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ) ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } if ( STI . isTargetDarwin ( ) && STI . getTargetLowering ( ) -> supportSwiftError ( ) && F -> getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) return CSR_iOS_SwiftError_SaveList ; if ( STI . isTargetDarwin ( ) && F -> getCallingConv ( ) == CallingConv :: CXX_FAST_TLS ) return MF -> getInfo < ARMFunctionInfo > ( ) -> isSplitCSR ( ) ? CSR_iOS_CXX_TLS_PE_SaveList : CSR_iOS_CXX_TLS_SaveList ; return RegList ; } </s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; if ( ! MF . getTarget ( ) . Options . RealignStack ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( FramePtr ) ) return false ; if ( ! MFI -> hasVarSizedObjects ( ) ) return true ; if ( ! EnableBasePointer ) return false ; return MRI -> canReserveReg ( BasePtr ) ; } </s>

True if the stack can be realigned for the target .


<s> const unsigned * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return ( STI . isTargetIOS ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( CallingConv :: ID ) const { return ( STI . isTargetIOS ( ) ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>

Return a mask of call-preserved registers for the given calling convention on the current function .


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i12
:
case
ARMII
::
AddrMode_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrMode3
:
{
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
}
case
ARMII
::
AddrModeT1_s
:
{
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
}
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
}
return
InstrOffs
*
Scale
;
}
</s>


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { return ( STI . isTargetIOS ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
)
markSuperRegs
(
Reserved
,
getFramePointerReg
(
STI
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
if
(
STI
.
isR9Reserved
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
if
(
!
STI
.
hasD32
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFunctionInfo * AFI = MF . getInfo < ARMFunctionInfo > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; if ( MF . getFunction ( ) -> hasFnAttribute ( "no-realign-stack" ) ) return false ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; if ( ! MRI -> canReserveReg ( getFramePointerReg ( MF . getSubtarget < ARMSubtarget > ( ) ) ) ) return false ; if ( TFI -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>

ARM ARM ARM ARM ARM "no-realign-stack" ARM


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> void ARMBaseRegisterInfo :: getRegAllocationHints ( unsigned VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM ) const { const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; std :: pair < unsigned , unsigned > Hint = MRI . getRegAllocationHint ( VirtReg ) ; unsigned Odd ; switch ( Hint . first ) { case ARMRI :: RegPairEven : Odd = 0 ; break ; case ARMRI :: RegPairOdd : Odd = 1 ; break ; default : TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; return ; } unsigned PairedPhys = 0 ; if ( VRM && VRM -> hasPhys ( Hint . second ) ) { PairedPhys = getPairedGPR ( VRM -> getPhys ( Hint . second ) , Odd , this ) ; if ( PairedPhys && MRI . isReserved ( PairedPhys ) ) PairedPhys = 0 ; } if ( PairedPhys ) Hints . push_back ( PairedPhys ) ; for ( unsigned I = 0 , E = Order . size ( ) ; I != E ; ++ I ) { unsigned Reg = Order [ I ] ; if ( Reg == PairedPhys || ( getEncodingValue ( Reg ) & 1 ) != Odd ) continue ; unsigned Paired = getPairedGPR ( Reg , ! Odd , this ) ; if ( ! Paired || MRI . isReserved ( Paired ) ) continue ; Hints . push_back ( Reg ) ; } } </s>

Get a list of 'hint ' registers that the register allocator should try first when allocating a physical register for the virtual register VirtReg .


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i8neg
:
case
ARMII
::
AddrModeT2_i8pos
:
case
ARMII
::
AddrModeT2_i12
:
case
ARMII
::
AddrMode_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
case
ARMII
::
AddrMode3
:
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
case
ARMII
::
AddrModeT1_s
:
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
}
return
InstrOffs
*
Scale
;
}
</s>


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { bool ghcCall = false ; if ( MF ) { const Function * F = MF -> getFunction ( ) ; ghcCall = ( F ? F -> getCallingConv ( ) == CallingConv :: GHC : false ) ; } if ( ghcCall ) return CSR_GHC_SaveList ; else return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getThisReturnPreservedMask ( CallingConv :: ID ) const { return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_ThisReturn_RegMask : CSR_AAPCS_ThisReturn_RegMask ; } </s>


<s> const unsigned * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { bool ghcCall = false ; if ( MF ) { const Function * F = MF -> getFunction ( ) ; ghcCall = ( F ? F -> getCallingConv ( ) == CallingConv :: GHC : false ) ; } 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 :: R8 , ARM :: D15 , ARM :: D14 , ARM :: D13 , ARM :: D12 , ARM :: D11 , ARM :: D10 , ARM :: D9 , ARM :: D8 , 0 } ; static const unsigned GhcCalleeSavedRegs [ ] = { 0 } ; return ghcCall ? GhcCalleeSavedRegs : STI . isTargetDarwin ( ) ? DarwinCalleeSavedRegs : CalleeSavedRegs ; } </s>


<s> const uint16_t * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { if ( STI . isTargetNaCl ( ) ) return CSR_NaCl_SaveList ; const uint16_t * RegList = ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; if ( ! MF ) return RegList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( CallingConv :: ID CC ) const { if ( STI . isTargetNaCl ( ) ) return CSR_NaCl_RegMask ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; return ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { if ( STI . isTargetNaCl ( ) ) return CSR_NaCl_SaveList ; const MCPhysReg * RegList = ( STI . isTargetIOS ( ) && ! STI . isAAPCS_ABI ( ) ) ? CSR_iOS_SaveList : CSR_AAPCS_SaveList ; if ( ! MF ) return RegList ; const Function * F = MF -> getFunction ( ) ; if ( F -> getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F -> hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return CSR_AAPCS_SaveList ; } else if ( F -> getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } return RegList ; } </s>


<s> BitVector ARMBaseRegisterInfo :: getReservedRegs ( const MachineFunction & MF ) const { const TargetFrameLowering * TFI = MF . getTarget ( ) . getFrameLowering ( ) ; BitVector Reserved ( getNumRegs ( ) ) ; Reserved . set ( ARM :: SP ) ; Reserved . set ( ARM :: PC ) ; Reserved . set ( ARM :: FPSCR ) ; if ( TFI -> hasFP ( MF ) ) Reserved . set ( FramePtr ) ; if ( hasBasePointer ( MF ) ) Reserved . set ( BasePtr ) ; if ( STI . isR9Reserved ( ) ) Reserved . set ( ARM :: R9 ) ; return Reserved ; } </s>


<s> void ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock * MBB , unsigned BaseReg , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = MBB -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDrSPi : ARM :: t2ADDri ) ; MachineBasicBlock :: iterator Ins = MBB -> begin ( ) ; DebugLoc DL ; if ( Ins != MBB -> end ( ) ) DL = Ins -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( * MBB , Ins , DL , TII . get ( ADDriOpc ) , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) AddDefaultCC ( AddDefaultPred ( MIB ) ) ; } </s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( ! TargetRegisterInfo :: canRealignStack ( MF ) ) return false ; if ( ! MRI -> canReserveReg ( getFramePointerReg ( MF . getSubtarget < ARMSubtarget > ( ) ) ) ) return false ; if ( STI . isGPRegisterReserved ( BasePtr - ARM :: R0 ) ) return false ; if ( TFI -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; return 5 - HasFP ; } case ARM :: GPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; return 10 - HasFP - STI . getNumGPRegistersReserved ( ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
||
STI
.
isTargetDarwin
(
)
)
markSuperRegs
(
Reserved
,
getFramePointerReg
(
STI
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
for
(
size_t
R
=
0
;
R
<
ARM
::
GPRRegClass
.
getNumRegs
(
)
;
++
R
)
{
if
(
STI
.
isGPRegisterReserved
(
R
)
)
{
markSuperRegs
(
Reserved
,
ARM
::
R0
+
R
)
;
}
}
if
(
!
STI
.
hasD32
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
markSuperRegs
(
Reserved
,
ARM
::
ZR
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


<s> bool ARMBaseRegisterInfo :: canRealignStack ( const MachineFunction & MF ) const { const MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( ! TargetRegisterInfo :: canRealignStack ( MF ) ) return false ; if ( ! MRI -> canReserveReg ( STI . getFramePointerReg ( ) ) ) return false ; if ( TFI -> hasReservedCallFrame ( MF ) ) return true ; return MRI -> canReserveReg ( BasePtr ) ; } </s>


<s> void ARMBaseRegisterInfo :: emitLoadConstPool ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const DebugLoc & dl , Register DestReg , unsigned SubIdx , int Val , ARMCC :: CondCodes Pred , Register PredReg , unsigned MIFlags ) const { MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; MachineConstantPool * ConstantPool = MF . getConstantPool ( ) ; const Constant * C = ConstantInt :: get ( Type :: getInt32Ty ( MF . getFunction ( ) . getContext ( ) ) , Val ) ; unsigned Idx = ConstantPool -> getConstantPoolIndex ( C , Align ( 4 ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( ARM :: LDRcp ) ) . addReg ( DestReg , getDefRegState ( true ) , SubIdx ) . addConstantPoolIndex ( Idx ) . addImm ( 0 ) . add ( predOps ( Pred , PredReg ) ) . setMIFlags ( MIFlags ) ; } </s>

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


<s> const MCPhysReg * ARMBaseRegisterInfo :: getCalleeSavedRegs ( const MachineFunction * MF ) const { const ARMSubtarget & STI = MF -> getSubtarget < ARMSubtarget > ( ) ; bool UseSplitPush = STI . splitFramePushPop ( * MF ) ; const MCPhysReg * RegList = STI . isTargetDarwin ( ) ? CSR_iOS_SaveList : ( UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ) ; const Function & F = MF -> getFunction ( ) ; if ( F . getCallingConv ( ) == CallingConv :: GHC ) { return CSR_NoRegs_SaveList ; } else if ( F . getCallingConv ( ) == CallingConv :: CFGuard_Check ) { return CSR_Win_AAPCS_CFGuard_Check_SaveList ; } else if ( F . getCallingConv ( ) == CallingConv :: SwiftTail ) { return STI . isTargetDarwin ( ) ? CSR_iOS_SwiftTail_SaveList : ( UseSplitPush ? CSR_AAPCS_SplitPush_SwiftTail_SaveList : CSR_AAPCS_SwiftTail_SaveList ) ; } else if ( F . hasFnAttribute ( "interrupt" ) ) { if ( STI . isMClass ( ) ) { return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList ; } else if ( F . getFnAttribute ( "interrupt" ) . getValueAsString ( ) == "FIQ" ) { return CSR_FIQ_SaveList ; } else { return CSR_GenericInt_SaveList ; } } if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && F . getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) { if ( STI . isTargetDarwin ( ) ) return CSR_iOS_SwiftError_SaveList ; return UseSplitPush ? CSR_AAPCS_SplitPush_SwiftError_SaveList : CSR_AAPCS_SwiftError_SaveList ; } if ( STI . isTargetDarwin ( ) && F . getCallingConv ( ) == CallingConv :: CXX_FAST_TLS ) return MF -> getInfo < ARMFunctionInfo > ( ) -> isSplitCSR ( ) ? CSR_iOS_CXX_TLS_PE_SaveList : CSR_iOS_CXX_TLS_SaveList ; return RegList ; } </s>


<s> const uint32_t * ARMBaseRegisterInfo :: getCallPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( CC == CallingConv :: GHC ) return CSR_NoRegs_RegMask ; if ( CC == CallingConv :: CFGuard_Check ) return CSR_Win_AAPCS_CFGuard_Check_RegMask ; if ( CC == CallingConv :: SwiftTail ) { return STI . isTargetDarwin ( ) ? CSR_iOS_SwiftTail_RegMask : CSR_AAPCS_SwiftTail_RegMask ; } if ( STI . getTargetLowering ( ) -> supportSwiftError ( ) && MF . getFunction ( ) . getAttributes ( ) . hasAttrSomewhere ( Attribute :: SwiftError ) ) return STI . isTargetDarwin ( ) ? CSR_iOS_SwiftError_RegMask : CSR_AAPCS_SwiftError_RegMask ; if ( STI . isTargetDarwin ( ) && CC == CallingConv :: CXX_FAST_TLS ) return CSR_iOS_CXX_TLS_RegMask ; return STI . isTargetDarwin ( ) ? CSR_iOS_RegMask : CSR_AAPCS_RegMask ; } </s>


<s> const TargetRegisterClass * ARMBaseRegisterInfo :: getCrossCopyRegClass ( const TargetRegisterClass * RC ) const { if ( RC == & ARM :: CCRRegClass ) return & ARM :: rGPRRegClass ; return RC ; } </s>

getCrossCopyRegClass - Returns a legal register class to copy a register in the specified class to or from .

ARM ARM ARM::CCRRegClass ARM::rGPRRegClass


<s>
int64_t
ARMBaseRegisterInfo
::
getFrameIndexInstrOffset
(
const
MachineInstr
*
MI
,
int
Idx
)
const
{
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
AddrMode
=
(
Desc
.
TSFlags
&
ARMII
::
AddrModeMask
)
;
int64_t
InstrOffs
=
0
;
int
Scale
=
1
;
unsigned
ImmIdx
=
0
;
switch
(
AddrMode
)
{
case
ARMII
::
AddrModeT2_i8
:
case
ARMII
::
AddrModeT2_i12
:
case
ARMII
::
AddrMode_i12
:
InstrOffs
=
MI
->
getOperand
(
Idx
+
1
)
.
getImm
(
)
;
Scale
=
1
;
break
;
case
ARMII
::
AddrMode5
:
{
const
MachineOperand
&
OffOp
=
MI
->
getOperand
(
Idx
+
1
)
;
InstrOffs
=
ARM_AM
::
getAM5Offset
(
OffOp
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM5Op
(
OffOp
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
Scale
=
4
;
break
;
}
case
ARMII
::
AddrMode2
:
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM2Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM2Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
case
ARMII
::
AddrMode3
:
ImmIdx
=
Idx
+
2
;
InstrOffs
=
ARM_AM
::
getAM3Offset
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
;
if
(
ARM_AM
::
getAM3Op
(
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
)
==
ARM_AM
::
sub
)
InstrOffs
=
InstrOffs
;
break
;
case
ARMII
::
AddrModeT1_s
:
ImmIdx
=
Idx
+
1
;
InstrOffs
=
MI
->
getOperand
(
ImmIdx
)
.
getImm
(
)
;
Scale
=
4
;
break
;
default
:
llvm_unreachable
(
"Unsupported addressing mode!"
)
;
}
return
InstrOffs
*
Scale
;
}
</s>


<s> Register ARMBaseRegisterInfo :: getFrameRegister ( const MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; if ( TFI -> hasFP ( MF ) ) return STI . getFramePointerReg ( ) ; return ARM :: SP ; } </s>


<s> ArrayRef < MCPhysReg > ARMBaseRegisterInfo :: getIntraCallClobberedRegs ( const MachineFunction * MF ) const { static const MCPhysReg IntraCallClobberedRegs [ ] = { ARM :: R12 } ; return ArrayRef < MCPhysReg > ( IntraCallClobberedRegs ) ; } </s>

Return a list of all of the registers which are clobbered `` inside '' a call to the given function .


<s> const TargetRegisterClass * ARMBaseRegisterInfo :: getLargestLegalSuperClass ( const TargetRegisterClass * RC , const MachineFunction & MF ) const { const TargetRegisterClass * Super = RC ; TargetRegisterClass :: sc_iterator I = RC -> getSuperClasses ( ) ; do { switch ( Super -> getID ( ) ) { case ARM :: GPRRegClassID : case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : case ARM :: GPRPairRegClassID : return Super ; case ARM :: QPRRegClassID : case ARM :: QQPRRegClassID : case ARM :: QQQQPRRegClassID : if ( MF . getSubtarget < ARMSubtarget > ( ) . hasNEON ( ) ) return Super ; break ; case ARM :: MQPRRegClassID : case ARM :: MQQPRRegClassID : case ARM :: MQQQQPRRegClassID : if ( MF . getSubtarget < ARMSubtarget > ( ) . hasMVEIntegerOps ( ) ) return Super ; break ; } Super = * I ++ ; } while ( Super ) ; return RC ; } </s>

Returns the largest super class of RC that is legal to use in the current sub-target and has the same spill size .

ARM ARM ARM::GPRRegClassID ARM::SPRRegClassID ARM::DPRRegClassID ARM::GPRPairRegClassID ARM::QPRRegClassID ARM::QQPRRegClassID ARM::QQQQPRRegClassID ARM ARM::MQPRRegClassID ARM::MQQPRRegClassID ARM::MQQQQPRRegClassID ARM


<s> const uint32_t * ARMBaseRegisterInfo :: getNoPreservedMask ( ) const { return CSR_NoRegs_RegMask ; } </s>

Return a register mask that clobbers everything .


<s> const TargetRegisterClass * ARMBaseRegisterInfo :: getPointerRegClass ( const MachineFunction & MF , unsigned Kind ) const { return & ARM :: GPRRegClass ; } </s>

getPointerRegClass - Returns a TargetRegisterClass used for pointer values .


<s> bool ARMBaseRegisterInfo :: getRegAllocationHints ( Register VirtReg , ArrayRef < MCPhysReg > Order , SmallVectorImpl < MCPhysReg > & Hints , const MachineFunction & MF , const VirtRegMap * VRM , const LiveRegMatrix * Matrix ) const { const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; std :: pair < Register , Register > Hint = MRI . getRegAllocationHint ( VirtReg ) ; unsigned Odd ; switch ( Hint . first ) { case ARMRI :: RegPairEven : Odd = 0 ; break ; case ARMRI :: RegPairOdd : Odd = 1 ; break ; case ARMRI :: RegLR : TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; if ( MRI . getRegClass ( VirtReg ) -> contains ( ARM :: LR ) ) Hints . push_back ( ARM :: LR ) ; return false ; default : return TargetRegisterInfo :: getRegAllocationHints ( VirtReg , Order , Hints , MF , VRM ) ; } Register Paired = Hint . second ; if ( ! Paired ) return false ; Register PairedPhys ; if ( Paired . isPhysical ( ) ) { PairedPhys = Paired ; } else if ( VRM && VRM -> hasPhys ( Paired ) ) { PairedPhys = getPairedGPR ( VRM -> getPhys ( Paired ) , Odd , this ) ; } if ( PairedPhys && is_contained ( Order , PairedPhys ) ) Hints . push_back ( PairedPhys ) ; for ( MCPhysReg Reg : Order ) { if ( Reg == PairedPhys || ( getEncodingValue ( Reg ) & 1 ) != Odd ) continue ; MCPhysReg Paired = getPairedGPR ( Reg , ! Odd , this ) ; if ( ! Paired || MRI . isReserved ( Paired ) ) continue ; Hints . push_back ( Reg ) ; } return false ; } </s>

ARM ARM ARMRI::RegPairEven 0 ARMRI::RegPairOdd 1 ARMRI::RegLR ARM::LR ARM::LR 1


<s> unsigned ARMBaseRegisterInfo :: getRegPressureLimit ( const TargetRegisterClass * RC , MachineFunction & MF ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; switch ( RC -> getID ( ) ) { default : return 0 ; case ARM :: tGPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; return 5 - HasFP ; } case ARM :: GPRRegClassID : { bool HasFP = MF . getFrameInfo ( ) . isMaxCallFrameSizeComputed ( ) ? TFI -> hasFP ( MF ) : true ; return 10 - HasFP - ( STI . isR9Reserved ( ) ? 1 : 0 ) ; } case ARM :: SPRRegClassID : case ARM :: DPRRegClassID : return 32 - 10 ; } } </s>


<s>
BitVector
ARMBaseRegisterInfo
::
getReservedRegs
(
const
MachineFunction
&
MF
)
const
{
const
ARMSubtarget
&
STI
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
const
ARMFrameLowering
*
TFI
=
getFrameLowering
(
MF
)
;
BitVector
Reserved
(
getNumRegs
(
)
)
;
markSuperRegs
(
Reserved
,
ARM
::
SP
)
;
markSuperRegs
(
Reserved
,
ARM
::
PC
)
;
markSuperRegs
(
Reserved
,
ARM
::
FPSCR
)
;
markSuperRegs
(
Reserved
,
ARM
::
APSR_NZCV
)
;
if
(
TFI
->
hasFP
(
MF
)
)
markSuperRegs
(
Reserved
,
STI
.
getFramePointerReg
(
)
)
;
if
(
hasBasePointer
(
MF
)
)
markSuperRegs
(
Reserved
,
BasePtr
)
;
if
(
STI
.
isR9Reserved
(
)
)
markSuperRegs
(
Reserved
,
ARM
::
R9
)
;
if
(
!
STI
.
hasD32
(
)
)
{
static_assert
(
ARM
::
D31
==
ARM
::
D16
+
15
,
"Register list not consecutive!"
)
;
for
(
unsigned
R
=
0
;
R
<
16
;
++
R
)
markSuperRegs
(
Reserved
,
ARM
::
D16
+
R
)
;
}
const
TargetRegisterClass
&
RC
=
ARM
::
GPRPairRegClass
;
for
(
unsigned
Reg
:
RC
)
for
(
MCSubRegIterator
SI
(
Reg
,
this
)
;
SI
.
isValid
(
)
;
++
SI
)
if
(
Reserved
.
test
(
*
SI
)
)
markSuperRegs
(
Reserved
,
Reg
)
;
markSuperRegs
(
Reserved
,
ARM
::
ZR
)
;
assert
(
checkAllSuperRegsMarked
(
Reserved
)
)
;
return
Reserved
;
}
</s>


<s> const uint32_t * ARMBaseRegisterInfo :: getThisReturnPreservedMask ( const MachineFunction & MF , CallingConv :: ID CC ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; if ( CC == CallingConv :: GHC ) return nullptr ; return STI . isTargetDarwin ( ) ? CSR_iOS_ThisReturn_RegMask : CSR_AAPCS_ThisReturn_RegMask ; } </s>


<s> bool ARMBaseRegisterInfo :: isAsmClobberable ( const MachineFunction & MF , MCRegister PhysReg ) const { return ! getReservedRegs ( MF ) . test ( PhysReg ) ; } </s>

Returns false if we ca n't guarantee that Physreg , specified as an IR asm clobber constraint , will be preserved across the statement .


"Instr doesn't have FrameIndex operand!"


<s> bool ARMBaseRegisterInfo :: isInlineAsmReadOnlyReg ( const MachineFunction & MF , unsigned PhysReg ) const { const ARMSubtarget & STI = MF . getSubtarget < ARMSubtarget > ( ) ; const ARMFrameLowering * TFI = getFrameLowering ( MF ) ; BitVector Reserved ( getNumRegs ( ) ) ; markSuperRegs ( Reserved , ARM :: PC ) ; if ( TFI -> hasFP ( MF ) ) markSuperRegs ( Reserved , STI . getFramePointerReg ( ) ) ; if ( hasBasePointer ( MF ) ) markSuperRegs ( Reserved , BasePtr ) ; assert ( checkAllSuperRegsMarked ( Reserved ) ) ; return Reserved . test ( PhysReg ) ; } </s>

Returns true if PhysReg can not be written to in inline asm statements .


<s> Register ARMBaseRegisterInfo :: materializeFrameBaseRegister ( MachineBasicBlock * MBB , int FrameIdx , int64_t Offset ) const { ARMFunctionInfo * AFI = MBB -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; unsigned ADDriOpc = ! AFI -> isThumbFunction ( ) ? ARM :: ADDri : ( AFI -> isThumb1OnlyFunction ( ) ? ARM :: tADDframe : ARM :: t2ADDri ) ; MachineBasicBlock :: iterator Ins = MBB -> begin ( ) ; DebugLoc DL ; if ( Ins != MBB -> end ( ) ) DL = Ins -> getDebugLoc ( ) ; const MachineFunction & MF = * MBB -> getParent ( ) ; MachineRegisterInfo & MRI = MBB -> getParent ( ) -> getRegInfo ( ) ; const TargetInstrInfo & TII = * MF . getSubtarget ( ) . getInstrInfo ( ) ; const MCInstrDesc & MCID = TII . get ( ADDriOpc ) ; Register BaseReg = MRI . createVirtualRegister ( & ARM :: GPRRegClass ) ; MRI . constrainRegClass ( BaseReg , TII . getRegClass ( MCID , 0 , this , MF ) ) ; MachineInstrBuilder MIB = BuildMI ( * MBB , Ins , DL , MCID , BaseReg ) . addFrameIndex ( FrameIdx ) . addImm ( Offset ) ; if ( ! AFI -> isThumb1OnlyFunction ( ) ) MIB . add ( predOps ( ARMCC :: AL ) ) . add ( condCodeOp ( ) ) ; return BaseReg ; } </s>

ARM ARM ARM ARM ARM::ADDri ARM::tADDframe ARM::t2ADDri ARM::GPRRegClass 0 ARMCC::AL


<s> bool ARMBaseRegisterInfo :: requiresFrameIndexScavenging ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the target requires post PEI scavenging of registers for materializing frame index constants .


<s> bool ARMBaseRegisterInfo :: requiresRegisterScavenging ( const MachineFunction & MF ) const { return true ; } </s>

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


<s> bool ARMBaseRegisterInfo :: requiresVirtualBaseRegisters ( const MachineFunction & MF ) const { return true ; } </s>

Returns true if the target wants the LocalStackAllocation pass to be run and virtual base registers used for more efficient stack access .


"This resolveFrameIndex does not support Thumb1!"

Resolve a frame index operand of an instruction to reference the indicated base register plus offset instead .


"\tARM::shouldCoalesce - Coalesced Weight: "


<s> void ARMBaseRegisterInfo :: updateRegAllocHint ( Register Reg , Register NewReg , MachineFunction & MF ) const { MachineRegisterInfo * MRI = & MF . getRegInfo ( ) ; std :: pair < Register , Register > Hint = MRI -> getRegAllocationHint ( Reg ) ; if ( ( Hint . first == ARMRI :: RegPairOdd || Hint . first == ARMRI :: RegPairEven ) && Hint . second . isVirtual ( ) ) { Register OtherReg = Hint . second ; Hint = MRI -> getRegAllocationHint ( OtherReg ) ; if ( Hint . second == Reg ) { MRI -> setRegAllocationHint ( OtherReg , Hint . first , NewReg ) ; if ( Register :: isVirtualRegister ( NewReg ) ) MRI -> setRegAllocationHint ( NewReg , Hint . first == ARMRI :: RegPairOdd ? ARMRI :: RegPairEven : ARMRI :: RegPairOdd , OtherReg ) ; } } } </s>

A callback to allow target a chance to update register allocation hints when a register is `` changed '' ( e.g .

ARM ARM ARMRI::RegPairOdd ARMRI::RegPairEven ARMRI::RegPairOdd ARMRI::RegPairEven ARMRI::RegPairOdd


<s> void clear ( ) { BBInfo . clear ( ) ; } </s>


<s> unsigned getOffsetOf ( MachineBasicBlock * MBB ) const { return BBInfo [ MBB -> getNumber ( ) ] . Offset ; } </s>

getOffsetOf - Return the current offset of the specified machine instruction from the start of the function .


<s> void insert ( unsigned BBNum , BasicBlockInfo BBI ) { BBInfo . insert ( BBInfo . begin ( ) + BBNum , BBI ) ; } </s>

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


<s> unsigned postKnownBits ( Align Align = Align :: None ( ) ) const { return std :: max ( Log2 ( std :: max ( PostAlign , Align ) ) , internalKnownBits ( ) ) ; } </s>

Compute the number of known low bits of postOffset .


<s> unsigned postOffset ( Align Alignment = Align :: None ( ) ) const { unsigned PO = Offset + Size ; const Align PA = std :: max ( PostAlign , Alignment ) ; if ( PA == Align :: None ( ) ) return PO ; return PO + UnknownPadding ( PA , internalKnownBits ( ) ) ; } </s>

Compute the offset immediately following this block .


<s> unsigned postKnownBits ( Align Align = llvm :: Align ( 1 ) ) const { return std :: max ( Log2 ( std :: max ( PostAlign , Align ) ) , internalKnownBits ( ) ) ; } </s>


<s> unsigned postOffset ( Align Alignment = Align ( 1 ) ) const { unsigned PO = Offset + Size ; const Align PA = std :: max ( PostAlign , Alignment ) ; if ( PA == Align ( 1 ) ) return PO ; return PO + UnknownPadding ( PA , internalKnownBits ( ) ) ; } </s>


"Didn't find MI in its own basic block?"


<s> unsigned internalKnownBits ( ) const { unsigned Bits = Unalign ? Unalign : KnownBits ; if ( Size & ( ( 1u << Bits ) - 1 ) ) Bits = countTrailingZeros ( Size ) ; return Bits ; } </s>

Compute the number of known offset bits internally to this block .


<s>
bool
ARMBasicBlockUtils
::
isBBInRange
(
MachineInstr
*
MI
,
MachineBasicBlock
*
DestBB
,
unsigned
MaxDisp
)
const
{
unsigned
PCAdj
=
isThumb
4
:
8
;
unsigned
BrOffset
=
getOffsetOf
(
MI
)
+
PCAdj
;
unsigned
DestOffset
=
BBInfo
[
DestBB
->
getNumber
(
)
]
.
Offset
;
LLVM_DEBUG
(
dbgs
(
)
<<
"Branch of destination "
<<
printMBBReference
(
*
DestBB
)
<<
" from "
<<
printMBBReference
(
*
MI
->
getParent
(
)
)
<<
" max delta="
<<
MaxDisp
<<
" from "
<<
getOffsetOf
(
MI
)
<<
" to "
<<
DestOffset
<<
" offset "
<<
int
(
DestOffset
BrOffset
)
<<
"\t"
<<
*
MI
)
;
if
(
BrOffset
<=
DestOffset
)
{
if
(
DestOffset
BrOffset
<=
MaxDisp
)
return
true
;
}
else
{
if
(
BrOffset
DestOffset
<=
MaxDisp
)
return
true
;
}
return
false
;
}
</s>

isBBInRange - Returns true if the distance between specific MI and specific BB can fit in MI 's displacement field .

ARM
ARM
4
8
"Branch of destination "
" from "
" max delta="
" from "
" to "
" offset "
"\t"


<s> unsigned postKnownBits ( unsigned LogAlign = 0 ) const { return std :: max ( std :: max ( unsigned ( PostAlign ) , LogAlign ) , internalKnownBits ( ) ) ; } </s>


<s> unsigned postOffset ( unsigned LogAlign = 0 ) const { unsigned PO = Offset + Size ; unsigned LA = std :: max ( unsigned ( PostAlign ) , LogAlign ) ; if ( ! LA ) return PO ; return PO + UnknownPadding ( LA , internalKnownBits ( ) ) ; } </s>


"it would convert a WLS from forward to a "

Checks if loop has a backwards branching WLS , and if possible , fixes it .


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

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this .


<s> bool ARMBlockPlacement :: processPostOrderLoops ( MachineLoop * ML ) { bool Changed = false ; for ( auto * InnerML : * ML ) Changed |= processPostOrderLoops ( InnerML ) ; return Changed | fixBackwardsWLS ( ML ) ; } </s>

Updates ordering ( of WLS BB and their loopExits ) in inner loops first Returns true if any change was made in any of the loops .


<s>
bool
ARMBlockPlacement
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
ST
=
MF
.
getSubtarget
<
ARMSubtarget
>
(
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
DEBUG_PREFIX
<<
"Running on "
<<
MF
.
getName
(
)
<<
"\n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
MF
.
RenumberBlocks
(
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
.
front
(
)
)
;
bool
Changed
=
false
;
RevertedWhileLoops
.
clear
(
)
;
for
(
auto
*
ML
:
*
MLI
)
Changed
|=
processPostOrderLoops
(
ML
)
;
for
(
auto
*
WlsInstr
:
RevertedWhileLoops
)
Changed
|=
revertWhileToDoLoop
(
WlsInstr
)
;
return
Changed
;
}
</s>

runOnMachineFunction - Emit the function body .

ARM
ARM
ARM
ARM
"Running on "
"\n"
ARM
ARM
ARM


<s>
bool
ARMBlockPlacement
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
MF
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
DEBUG_PREFIX
<<
"Running on "
<<
MF
.
getName
(
)
<<
"\n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
MF
.
RenumberBlocks
(
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
.
front
(
)
)
;
bool
Changed
=
false
;
RevertedWhileLoops
.
clear
(
)
;
for
(
auto
*
ML
:
*
MLI
)
Changed
|=
processPostOrderLoops
(
ML
)
;
for
(
auto
*
WlsInstr
:
RevertedWhileLoops
)
Changed
|=
revertWhileToDoLoop
(
WlsInstr
)
;
return
Changed
;
}
</s>


"Can't move the target block as it would "

"introduce a new backwards WLS branch\n"


"block as it would convert a WLS from forward to a "


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


<s>
bool
ARMBlockPlacement
::
runOnMachineFunction
(
MachineFunction
&
MF
)
{
if
(
skipFunction
(
MF
.
getFunction
(
)
)
)
return
false
;
const
ARMSubtarget
&
ST
=
static_cast
<
const
ARMSubtarget
&
>
(
MF
.
getSubtarget
(
)
)
;
if
(
!
ST
.
hasLOB
(
)
)
return
false
;
LLVM_DEBUG
(
dbgs
(
)
<<
DEBUG_PREFIX
<<
"Running on "
<<
MF
.
getName
(
)
<<
"\n"
)
;
MLI
=
&
getAnalysis
<
MachineLoopInfo
>
(
)
;
TII
=
static_cast
<
const
ARMBaseInstrInfo
*
>
(
ST
.
getInstrInfo
(
)
)
;
BBUtils
=
std
::
unique_ptr
<
ARMBasicBlockUtils
>
(
new
ARMBasicBlockUtils
(
MF
)
)
;
MF
.
RenumberBlocks
(
)
;
BBUtils
->
computeAllBlockSizes
(
)
;
BBUtils
->
adjustBBOffsetsAfter
(
&
MF
.
front
(
)
)
;
bool
Changed
=
false
;
for
(
auto
*
ML
:
*
MLI
)
Changed
|=
processPostOrderLoops
(
ML
)
;
return
Changed
;
}
</s>


<s> void ARMBranchTargets :: getAnalysisUsage ( AnalysisUsage & AU ) const { AU . setPreservesCFG ( ) ; MachineFunctionPass :: getAnalysisUsage ( AU ) ; } </s>


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

getPassName - Return a nice clean name for a pass .


<s>
unsigned
assignCustomValue
(
const
ARMCallLowering
::
ArgInfo
&
Arg
,
ArrayRef
<
CCValAssign
>
VAs
)
override
{
CCValAssign
VA
=
VAs
[
0
]
;
assert
(
VA
.
needsCustom
(
)
&&
"Value doesn't need custom handling"
)
;
assert
(
VA
.
getValVT
(
)
==
MVT
::
f64
&&
"Unsupported type"
)
;
CCValAssign
NextVA
=
VAs
[
1
]
;
assert
(
NextVA
.
needsCustom
(
)
&&
"Value doesn't need custom handling"
)
;
assert
(
NextVA
.
getValVT
(
)
==
MVT
::
f64
&&
"Unsupported type"
)
;
assert
(
VA
.
getValNo
(
)
==
NextVA
.
getValNo
(
)
&&
"Values belong to different arguments"
)
;
assert
(
VA
.
isRegLoc
(
)
&&
"Value should be in reg"
)
;
assert
(
NextVA
.
isRegLoc
(
)
&&
"Value should be in reg"
)
;
unsigned
NewRegs
[
]
=
{
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
32
)
)
,
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
32
)
)
}
;
assignValueToReg
(
NewRegs
[
0
]
,
VA
.
getLocReg
(
)
,
VA
)
;
assignValueToReg
(
NewRegs
[
1
]
,
NextVA
.
getLocReg
(
)
,
NextVA
)
;
bool
IsLittle
=
MIRBuilder
.
getMF
(
)
.
getSubtarget
<
ARMSubtarget
>
(
)
.
isLittle
(
)
;
if
(
!
IsLittle
)
std
::
swap
(
NewRegs
[
0
]
,
NewRegs
[
1
]
)
;
MIRBuilder
.
buildMerge
(
Arg
.
Reg
,
NewRegs
)
;
return
1
;
}
</s>

Handle custom values , which may be passed into one or more of VAs .


<s>
void
assignValueToAddress
(
unsigned
ValVReg
,
unsigned
Addr
,
uint64_t
Size
,
MachinePointerInfo
&
MPO
,
CCValAssign
&
VA
)
override
{
assert
(
(
Size
==
1
||
Size
==
2
||
Size
==
4
||
Size
==
8
)
&&
"Unsupported size"
)
;
if
(
VA
.
getLocInfo
(
)
==
CCValAssign
::
SExt
||
VA
.
getLocInfo
(
)
==
CCValAssign
::
ZExt
)
{
Size
=
4
;
assert
(
MRI
.
getType
(
ValVReg
)
.
isScalar
(
)
&&
"Only scalars supported atm"
)
;
auto
LoadVReg
=
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
32
)
)
;
buildLoad
(
LoadVReg
,
Addr
,
Size
,
0
,
MPO
)
;
MIRBuilder
.
buildTrunc
(
ValVReg
,
LoadVReg
)
;
}
else
{
buildLoad
(
ValVReg
,
Addr
,
Size
,
0
,
MPO
)
;
}
}
</s>

An overload which takes an ArgInfo if additional information about the arg is needed .


<s>
void
assignValueToReg
(
unsigned
ValVReg
,
unsigned
PhysReg
,
CCValAssign
&
VA
)
override
{
assert
(
VA
.
isRegLoc
(
)
&&
"Value shouldn't be assigned to reg"
)
;
assert
(
VA
.
getLocReg
(
)
==
PhysReg
&&
"Assigning to the wrong reg?"
)
;
auto
ValSize
=
VA
.
getValVT
(
)
.
getSizeInBits
(
)
;
auto
LocSize
=
VA
.
getLocVT
(
)
.
getSizeInBits
(
)
;
assert
(
ValSize
<=
64
&&
"Unsupported value size"
)
;
assert
(
LocSize
<=
64
&&
"Unsupported location size"
)
;
markPhysRegUsed
(
PhysReg
)
;
if
(
ValSize
==
LocSize
)
{
MIRBuilder
.
buildCopy
(
ValVReg
,
PhysReg
)
;
}
else
{
assert
(
ValSize
<
LocSize
&&
"Extensions not supported"
)
;
auto
PhysRegToVReg
=
MRI
.
createGenericVirtualRegister
(
LLT
::
scalar
(
LocSize
)
)
;
MIRBuilder
.
buildCopy
(
PhysRegToVReg
,
PhysReg
)
;
MIRBuilder
.
buildTrunc
(
ValVReg
,
PhysRegToVReg
)
;
}
}
</s>

The specified value has been assigned to a physical register , handle the appropriate COPY ( either to or from ) and mark any relevant uses/defines as needed .

ARM
"Value shouldn't be assigned to reg"
"Assigning to the wrong reg?"
64
"Unsupported value size"
64
"Unsupported location size"
"Extensions not supported"


<s> void buildLoad ( unsigned Val , unsigned Addr , uint64_t Size , unsigned Alignment , MachinePointerInfo & MPO ) { auto MMO = MIRBuilder . getMF ( ) . getMachineMemOperand ( MPO , MachineMemOperand :: MOLoad , Size , Alignment ) ; MIRBuilder . buildLoad ( Val , Addr , * MMO ) ; } </s>

Build and insert a G_LOAD instruction , while constructing the MachineMemOperand .


<s>
unsigned
getStackAddress
(
uint64_t
Size
,
int64_t
Offset
,
MachinePointerInfo
&
MPO
)
override
{
assert
(
(
Size
==
1
||
Size
==
2
||
Size
==
4
||
Size
==
8
)
&&
"Unsupported size"
)
;
auto
&
MFI
=
MIRBuilder
.
getMF
(
)
.
getFrameInfo
(
)
;
int
FI
=
MFI
.
CreateFixedObject
(
Size
,
Offset
,
true
)
;
MPO
=
MachinePointerInfo
::
getFixedStack
(
MIRBuilder
.
getMF
(
)
,
FI
)
;
unsigned
AddrReg
=
MRI
.
createGenericVirtualRegister
(
LLT
::
pointer
(
MPO
.
getAddrSpace
(
)
,
32
)
)
;
MIRBuilder
.
buildFrameIndex
(
AddrReg
,
FI
)
;
return
AddrReg
;
}
</s>

Materialize a VReg containing the address of the specified stack-based object .