<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const TargetSchedModel & SchedModel , const MachineRegisterInfo * MRI , const MachineInstr & DefMI , unsigned DefIdx , const MachineInstr & UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI . getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI . getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . nonpipelinedVFP ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; unsigned Latency = SchedModel . computeOperandLatency ( & DefMI , DefIdx , & UseMI , UseIdx ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>

Compute operand latency between a def of 'Reg ' and a use in the current loop .

ARM ARM ARMII::DomainMask ARMII::DomainMask ARMII::DomainVFP ARMII::DomainVFP 3 ARMII::DomainVFP ARMII::DomainNEON ARMII::DomainVFP ARMII::DomainNEON


<s> bool ARMBaseInstrInfo :: hasLowDefLatency ( const TargetSchedModel & SchedModel , const MachineInstr & DefMI , unsigned DefIdx ) const { const InstrItineraryData * ItinData = SchedModel . getInstrItineraries ( ) ; if ( ! ItinData || ItinData -> isEmpty ( ) ) return false ; unsigned DDomain = DefMI . getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( DDomain == ARMII :: DomainGeneral ) { unsigned DefClass = DefMI . getDesc ( ) . getSchedClass ( ) ; int DefCycle = ItinData -> getOperandCycle ( DefClass , DefIdx ) ; return ( DefCycle != - 1 && DefCycle <= 2 ) ; } return false ; } </s>

Compute operand latency of a def of 'Reg ' .

ARM ARM ARMII::DomainMask ARMII::DomainGeneral 1 2


<s> static inline bool isIndirectCall ( const MachineInstr & MI ) { int Opc = MI . getOpcode ( ) ; switch ( Opc ) { case ARM :: BLX : case ARM :: BLX_noip : case ARM :: BLX_pred : case ARM :: BLX_pred_noip : case ARM :: BX_CALL : case ARM :: BMOVPCRX_CALL : case ARM :: TCRETURNri : case ARM :: TAILJMPr : case ARM :: TAILJMPr4 : case ARM :: tBLXr : case ARM :: tBLXr_noip : case ARM :: tBLXNSr : case ARM :: tBLXNS_CALL : case ARM :: tBX_CALL : case ARM :: tTAILJMPr : assert ( MI . isCall ( MachineInstr :: IgnoreBundle ) ) ; return true ; case ARM :: BL : case ARM :: BL_pred : case ARM :: BMOVPCB_CALL : case ARM :: BL_PUSHLR : case ARM :: BLXi : case ARM :: TCRETURNdi : case ARM :: TAILJMPd : case ARM :: SVC : case ARM :: HVC : case ARM :: TPsoft : case ARM :: tTAILJMPd : case ARM :: t2SMC : case ARM :: t2HVC : case ARM :: tBL : case ARM :: tBLXi : case ARM :: tBL_PUSHLR : case ARM :: tTAILJMPdND : case ARM :: tSVC : case ARM :: tTPsoft : assert ( MI . isCall ( MachineInstr :: IgnoreBundle ) ) ; return false ; } assert ( ! MI . isCall ( MachineInstr :: IgnoreBundle ) ) ; return false ; } </s>

Return true if the callsite is an indirect call .


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 3 ) . isImm ( ) && MI . getOperand ( 2 ) . getReg ( ) == 0 && MI . getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLD1q64 : case ARM :: VLD1d64TPseudo : case ARM :: VLD1d64QPseudo : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

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


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

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


<s> bool ARMBaseInstrInfo :: isPredicable ( MachineInstr & MI ) const { if ( ! MI . isPredicable ( ) ) return false ; if ( ! isEligibleForITBlock ( & MI ) ) return false ; ARMFunctionInfo * AFI = MI . getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumb2Function ( ) ) { if ( getSubtarget ( ) . restrictIT ( ) ) return isV8EligibleForIT ( & MI ) ; } else { if ( ( MI . getDesc ( ) . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) return false ; } return true ; } </s>

Return true if the specified instruction can be predicated .

ARM ARM ARM ARM ARMII::DomainMask ARMII::DomainNEON


<s> bool ARMBaseInstrInfo :: isPredicated ( const MachineInstr & MI ) const { if ( MI . isBundle ( ) ) { MachineBasicBlock :: const_instr_iterator I = MI . getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI . getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { int PIdx = I -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 && I -> getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ) return true ; } return false ; } int PIdx = MI . findFirstPredOperandIdx ( ) ; return PIdx != - 1 && MI . getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ; } </s>

Returns true if the instruction is already predicated .


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & TMBB , unsigned TCycles , unsigned TExtra , MachineBasicBlock & FMBB , unsigned FCycles , unsigned FExtra , BranchProbability Probability ) const { if ( ! TCycles || ! FCycles ) return false ; const unsigned ScalingUpFactor = 1024 ; unsigned TUnpredCost = Probability . scale ( TCycles * ScalingUpFactor ) ; unsigned FUnpredCost = Probability . getCompl ( ) . scale ( FCycles * ScalingUpFactor ) ; unsigned UnpredCost = TUnpredCost + FUnpredCost ; UnpredCost += 1 * ScalingUpFactor ; UnpredCost += Subtarget . getMispredictionPenalty ( ) * ScalingUpFactor / 10 ; return ( TCycles + FCycles + TExtra + FExtra ) * ScalingUpFactor <= UnpredCost ; } </s>


<s> bool ARMBaseInstrInfo :: isProfitableToUnpredicate ( MachineBasicBlock & TMBB , MachineBasicBlock & FMBB ) const { return Subtarget . isProfitableToUnpredicate ( ) ; } </s>

Return true if it 's profitable to unpredicate one side of a 'diamond ' , i.e .


<s> bool ARMBaseInstrInfo :: isSchedulingBoundary ( const MachineInstr & MI , const MachineBasicBlock * MBB , const MachineFunction & MF ) const { if ( MI . isDebugValue ( ) ) return false ; if ( MI . isTerminator ( ) || MI . isPosition ( ) ) return true ; MachineBasicBlock :: const_iterator I = MI ; while ( ++ I != MBB -> end ( ) && I -> isDebugValue ( ) ) ; if ( I != MBB -> end ( ) && I -> getOpcode ( ) == ARM :: t2IT ) return true ; if ( ! MI . isCall ( ) && MI . definesRegister ( ARM :: SP ) ) return true ; return false ; } </s>

isSchedulingBoundary - Overrides the isSchedulingBoundary from Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR intructions and prevent it from being re-scheduled .


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: STRrs : case ARM :: t2STRs : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 3 ) . isImm ( ) && MI . getOperand ( 2 ) . getReg ( ) == 0 && MI . getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: STRi12 : case ARM :: t2STRi12 : case ARM :: tSTRspi : case ARM :: VSTRD : case ARM :: VSTRS : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VST1q64 : case ARM :: VST1d64TPseudo : case ARM :: VST1d64QPseudo : if ( MI . getOperand ( 0 ) . isFI ( ) && MI . getOperand ( 2 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 0 ) . getIndex ( ) ; return MI . getOperand ( 2 ) . getReg ( ) ; } break ; case ARM :: VSTMQIA : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


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

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


<s> bool isUnspillableTerminatorImpl ( const MachineInstr * MI ) const override { return MI -> getOpcode ( ) == ARM :: t2LoopEndDec || MI -> getOpcode ( ) == ARM :: t2DoLoopStartTP || MI -> getOpcode ( ) == ARM :: t2WhileLoopStartLR || MI -> getOpcode ( ) == ARM :: t2WhileLoopStartTP ; } </s>

Return true if the given terminator MI is not expected to spill .


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
&
MI
,
SmallPtrSetImpl
<
MachineInstr
*
>
&
SeenMIs
,
bool
PreferFalse
)
const
{
assert
(
(
MI
.
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
.
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
MachineRegisterInfo
&
MRI
=
MI
.
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
.
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
.
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
nullptr
;
MachineOperand
FalseReg
=
MI
.
getOperand
(
Invert
2
:
1
)
;
unsigned
DestReg
=
MI
.
getOperand
(
0
)
.
getReg
(
)
;
const
TargetRegisterClass
*
PreviousClass
=
MRI
.
getRegClass
(
FalseReg
.
getReg
(
)
)
;
if
(
!
MRI
.
constrainRegClass
(
DestReg
,
PreviousClass
)
)
return
nullptr
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
.
getParent
(
)
,
MI
,
MI
.
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
DestReg
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
.
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
.
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
.
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
SeenMIs
.
insert
(
NewMI
)
;
SeenMIs
.
erase
(
DefMI
)
;
if
(
DefMI
->
getParent
(
)
!=
MI
.
getParent
(
)
)
NewMI
->
clearKillInfo
(
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>

Given a select instruction that was understood by analyzeSelect and returned Optimizable = true , attempt to optimize MI by merging it with one of its operands .


<s> bool ARMBaseInstrInfo :: PredicateInstruction ( MachineInstr & MI , ArrayRef < MachineOperand > Pred ) const { unsigned Opc = MI . getOpcode ( ) ; if ( isUncondBranchOpcode ( Opc ) ) { MI . setDesc ( get ( getMatchingCondBranchOpcode ( Opc ) ) ) ; MachineInstrBuilder ( * MI . getParent ( ) -> getParent ( ) , MI ) . addImm ( Pred [ 0 ] . getImm ( ) ) . addReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } int PIdx = MI . findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 ) { MachineOperand & PMO = MI . getOperand ( PIdx ) ; PMO . setImm ( Pred [ 0 ] . getImm ( ) ) ; MI . getOperand ( PIdx + 1 ) . setReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } return false ; } </s>

Convert the instruction into a predicated instruction .


<s> void ARMBaseInstrInfo :: reMaterialize ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned DestReg , unsigned SubIdx , const MachineInstr & Orig , const TargetRegisterInfo & TRI ) const { unsigned Opcode = Orig . getOpcode ( ) ; switch ( Opcode ) { default : { MachineInstr * MI = MBB . getParent ( ) -> CloneMachineInstr ( & Orig ) ; MI -> substituteRegister ( Orig . getOperand ( 0 ) . getReg ( ) , DestReg , SubIdx , TRI ) ; MBB . insert ( I , MI ) ; break ; } case ARM :: tLDRpci_pic : case ARM :: t2LDRpci_pic : { MachineFunction & MF = * MBB . getParent ( ) ; unsigned CPI = Orig . getOperand ( 1 ) . getIndex ( ) ; unsigned PCLabelId = duplicateCPV ( MF , CPI ) ; MachineInstrBuilder MIB = BuildMI ( MBB , I , Orig . getDebugLoc ( ) , get ( Opcode ) , DestReg ) . addConstantPoolIndex ( CPI ) . addImm ( PCLabelId ) ; MIB -> setMemRefs ( Orig . memoperands_begin ( ) , Orig . memoperands_end ( ) ) ; break ; } } } </s>

Re-issue the specified 'original ' instruction at the specific location targeting a new destination register .


<s> bool ARMBaseInstrInfo :: SubsumesPredicate ( ArrayRef < MachineOperand > Pred1 , ArrayRef < MachineOperand > Pred2 ) const { if ( Pred1 . size ( ) > 2 || Pred2 . size ( ) > 2 ) return false ; ARMCC :: CondCodes CC1 = ( ARMCC :: CondCodes ) Pred1 [ 0 ] . getImm ( ) ; ARMCC :: CondCodes CC2 = ( ARMCC :: CondCodes ) Pred2 [ 0 ] . getImm ( ) ; if ( CC1 == CC2 ) return true ; switch ( CC1 ) { default : return false ; case ARMCC :: AL : return true ; case ARMCC :: HS : return CC2 == ARMCC :: HI ; case ARMCC :: LS : return CC2 == ARMCC :: LO || CC2 == ARMCC :: EQ ; case ARMCC :: GE : return CC2 == ARMCC :: GT ; case ARMCC :: LE : return CC2 == ARMCC :: LT ; } } </s>

Returns true if the first specified predicate subsumes the second , e.g .

ARM ARM 2 2 ARMCC::CondCodes ARMCC::CondCodes 0 ARMCC::CondCodes ARMCC::CondCodes 0 ARMCC::AL ARMCC::HS ARMCC::HI ARMCC::LS ARMCC::LO ARMCC::EQ ARMCC::GE ARMCC::GT ARMCC::LE ARMCC::LT


"Pseudo flag setting opcodes only exist in Selection DAG"

Perform target-specific instruction verification .


<s> MachineInstr * ARMBaseInstrInfo :: commuteInstructionImpl ( MachineInstr * MI , bool NewMI , unsigned OpIdx1 , unsigned OpIdx2 ) const { switch ( MI -> getOpcode ( ) ) { case ARM :: MOVCCr : case ARM :: t2MOVCCr : { unsigned PredReg = 0 ; ARMCC :: CondCodes CC = getInstrPredicate ( MI , PredReg ) ; if ( CC == ARMCC :: AL || PredReg != ARM :: CPSR ) return nullptr ; MI = TargetInstrInfo :: commuteInstructionImpl ( MI , NewMI , OpIdx1 , OpIdx2 ) ; if ( ! MI ) return nullptr ; MI -> getOperand ( MI -> findFirstPredOperandIdx ( ) ) . setImm ( ARMCC :: getOppositeCondition ( CC ) ) ; return MI ; } } return TargetInstrInfo :: commuteInstructionImpl ( MI , NewMI , OpIdx1 , OpIdx2 ) ; } </s>

Commutes the operands in the given instruction by changing the operands order and/or changing the instruction 's opcode and/or the immediate value operand .

ARM ARM ARM::MOVCCr ARM::t2MOVCCr 0 ARMCC::CondCodes ARMCC::AL ARM::CPSR ARMCC::getOppositeCondition


"LOAD_STACK_GUARD currently supported only for MachO."

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


<s> std :: pair < uint16_t , uint16_t > ARMBaseInstrInfo :: getExecutionDomain ( const MachineInstr * MI ) const { if ( Subtarget . hasNEON ( ) ) { if ( MI -> getOpcode ( ) == ARM :: VMOVD && ! isPredicated ( MI ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; if ( Subtarget . isCortexA9 ( ) && ! isPredicated ( MI ) && ( MI -> getOpcode ( ) == ARM :: VMOVRS || MI -> getOpcode ( ) == ARM :: VMOVSR || MI -> getOpcode ( ) == ARM :: VMOVS ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; } unsigned Domain = MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Domain & ARMII :: DomainNEON ) return std :: make_pair ( ExeNEON , 0 ) ; if ( ( Domain & ARMII :: DomainNEONA8 ) && Subtarget . isCortexA8 ( ) ) return std :: make_pair ( ExeNEON , 0 ) ; if ( Domain & ARMII :: DomainVFP ) return std :: make_pair ( ExeVFP , 0 ) ; return std :: make_pair ( ExeGeneric , 0 ) ; } </s>

Return the current execution domain and bit mask of possible domains for instruction .


<s> unsigned ARMBaseInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , const MachineInstr * MI , unsigned * PredCost ) const { if ( MI -> isCopyLike ( ) || MI -> isInsertSubreg ( ) || MI -> isRegSequence ( ) || MI -> isImplicitDef ( ) ) return 1 ; if ( MI -> isBundle ( ) ) { unsigned Latency = 0 ; MachineBasicBlock :: const_instr_iterator I = MI -> getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { if ( I -> getOpcode ( ) != ARM :: t2IT ) Latency += getInstrLatency ( ItinData , & * I , PredCost ) ; } return Latency ; } const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( PredCost && ( MCID . isCall ( ) || MCID . hasImplicitDefOfPhysReg ( ARM :: CPSR ) ) ) { * PredCost = 1 ; } if ( ! ItinData ) return MI -> mayLoad ( ) ? 3 : 1 ; unsigned Class = MCID . getSchedClass ( ) ; if ( ! ItinData -> isEmpty ( ) && ItinData -> getNumMicroOps ( Class ) < 0 ) return getNumMicroOps ( ItinData , MI ) ; unsigned Latency = ItinData -> getStageLatency ( Class ) ; unsigned DefAlign = MI -> hasOneMemOperand ( ) ? ( * MI -> memoperands_begin ( ) ) -> getAlignment ( ) : 0 ; int Adj = adjustDefLatency ( Subtarget , MI , & MCID , DefAlign ) ; if ( Adj >= 0 || ( int ) Latency > - Adj ) { return Latency + Adj ; } return Latency ; } </s>

Compute the instruction latency of a given instruction .


<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const TargetSchedModel & SchedModel , const MachineRegisterInfo * MRI , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . isCortexA8 ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; unsigned Latency = SchedModel . computeOperandLatency ( DefMI , DefIdx , UseMI , UseIdx ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>

Compute operand latency between a def of 'Reg ' and a use in the current loop .


<s> bool ARMBaseInstrInfo :: hasLowDefLatency ( const TargetSchedModel & SchedModel , const MachineInstr * DefMI , unsigned DefIdx ) const { const InstrItineraryData * ItinData = SchedModel . getInstrItineraries ( ) ; if ( ! ItinData || ItinData -> isEmpty ( ) ) return false ; unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( DDomain == ARMII :: DomainGeneral ) { unsigned DefClass = DefMI -> getDesc ( ) . getSchedClass ( ) ; int DefCycle = ItinData -> getOperandCycle ( DefClass , DefIdx ) ; return ( DefCycle != - 1 && DefCycle <= 2 ) ; } return false ; } </s>

Compute operand latency of a def of 'Reg ' .


<s> bool ARMBaseInstrInfo :: isPredicable ( MachineInstr * MI ) const { if ( ! MI -> isPredicable ( ) ) return false ; if ( ! isEligibleForITBlock ( MI ) ) return false ; ARMFunctionInfo * AFI = MI -> getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumb2Function ( ) ) { if ( getSubtarget ( ) . restrictIT ( ) ) return isV8EligibleForIT ( MI ) ; } else { if ( ( MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) return false ; } return true ; } </s>

Return true if the specified instruction can be predicated .


<s> bool ARMBaseInstrInfo :: isPredicated ( const MachineInstr * MI ) const { if ( MI -> isBundle ( ) ) { MachineBasicBlock :: const_instr_iterator I = MI -> getIterator ( ) ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { int PIdx = I -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 && I -> getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ) return true ; } return false ; } int PIdx = MI -> findFirstPredOperandIdx ( ) ; return PIdx != - 1 && MI -> getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ; } </s>

Returns true if the instruction is already predicated .


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & MBB , unsigned NumCycles , unsigned ExtraPredCycles , BranchProbability Probability ) const { if ( ! NumCycles ) return false ; if ( MBB . getParent ( ) -> getFunction ( ) -> optForSize ( ) ) { MachineBasicBlock * Pred = * MBB . pred_begin ( ) ; if ( ! Pred -> empty ( ) ) { MachineInstr * LastMI = & * Pred -> rbegin ( ) ; if ( LastMI -> getOpcode ( ) == ARM :: t2Bcc ) { MachineBasicBlock :: iterator CmpMI = LastMI ; if ( CmpMI != Pred -> begin ( ) ) { -- CmpMI ; if ( CmpMI -> getOpcode ( ) == ARM :: tCMPi8 || CmpMI -> getOpcode ( ) == ARM :: t2CMPri ) { unsigned Reg = CmpMI -> getOperand ( 0 ) . getReg ( ) ; unsigned PredReg = 0 ; ARMCC :: CondCodes P = getInstrPredicate ( CmpMI , PredReg ) ; if ( P == ARMCC :: AL && CmpMI -> getOperand ( 1 ) . getImm ( ) == 0 && isARMLowRegister ( Reg ) ) return false ; } } } } } const unsigned ScalingUpFactor = 1024 ; unsigned UnpredCost = Probability . scale ( NumCycles * ScalingUpFactor ) ; UnpredCost += ScalingUpFactor ; UnpredCost += Subtarget . getMispredictionPenalty ( ) * ScalingUpFactor / 10 ; return ( NumCycles + ExtraPredCycles ) * ScalingUpFactor <= UnpredCost ; } </s>


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
*
MI
,
SmallPtrSetImpl
<
MachineInstr
*
>
&
SeenMIs
,
bool
PreferFalse
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
MachineRegisterInfo
&
MRI
=
MI
->
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
nullptr
;
MachineOperand
FalseReg
=
MI
->
getOperand
(
Invert
2
:
1
)
;
unsigned
DestReg
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
const
TargetRegisterClass
*
PreviousClass
=
MRI
.
getRegClass
(
FalseReg
.
getReg
(
)
)
;
if
(
!
MRI
.
constrainRegClass
(
DestReg
,
PreviousClass
)
)
return
nullptr
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
->
getParent
(
)
,
MI
,
MI
->
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
DestReg
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
->
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
->
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
.
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
SeenMIs
.
insert
(
NewMI
)
;
SeenMIs
.
erase
(
DefMI
)
;
if
(
DefMI
->
getParent
(
)
!=
MI
->
getParent
(
)
)
NewMI
->
clearKillInfo
(
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>


<s> bool ARMBaseInstrInfo :: PredicateInstruction ( MachineInstr * MI , ArrayRef < MachineOperand > Pred ) const { unsigned Opc = MI -> getOpcode ( ) ; if ( isUncondBranchOpcode ( Opc ) ) { MI -> setDesc ( get ( getMatchingCondBranchOpcode ( Opc ) ) ) ; MachineInstrBuilder ( * MI -> getParent ( ) -> getParent ( ) , MI ) . addImm ( Pred [ 0 ] . getImm ( ) ) . addReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } int PIdx = MI -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 ) { MachineOperand & PMO = MI -> getOperand ( PIdx ) ; PMO . setImm ( Pred [ 0 ] . getImm ( ) ) ; MI -> getOperand ( PIdx + 1 ) . setReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } return false ; } </s>


<s> bool ARMBaseInstrInfo :: areLoadsFromSameBasePtr ( SDNode * Load1 , SDNode * Load2 , int64_t & Offset1 , int64_t & Offset2 ) const { if ( Subtarget . isThumb1Only ( ) ) return false ; if ( ! Load1 -> isMachineOpcode ( ) || ! Load2 -> isMachineOpcode ( ) ) return false ; switch ( Load1 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDRi12 : case ARM :: LDRBi12 : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRDi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRSHi12 : break ; } switch ( Load2 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDRi12 : case ARM :: LDRBi12 : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRDi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRSHi12 : break ; } if ( Load1 -> getOperand ( 0 ) != Load2 -> getOperand ( 0 ) || Load1 -> getOperand ( 4 ) != Load2 -> getOperand ( 4 ) ) return false ; if ( Load1 -> getOperand ( 3 ) != Load2 -> getOperand ( 3 ) ) return false ; if ( isa < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) && isa < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) ) { Offset1 = cast < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; Offset2 = cast < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; return true ; } return false ; } </s>

areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to determine if two loads are loading from the same base address .


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetHazardRecognizer ( const TargetMachine * TM , const ScheduleDAG * DAG ) const { if ( usePreRAHazardRecognizer ( ) ) { const InstrItineraryData * II = TM -> getInstrItineraryData ( ) ; return new ScoreboardHazardRecognizer ( II , DAG , "pre-RA-sched" ) ; } return TargetInstrInfoImpl :: CreateTargetHazardRecognizer ( TM , DAG ) ; } </s>

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructions before register allocation .


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetPostRAHazardRecognizer ( const InstrItineraryData * II , const ScheduleDAG * DAG ) const { if ( Subtarget . isThumb2 ( ) || Subtarget . hasVFP2 ( ) ) return ( ScheduleHazardRecognizer * ) new ARMHazardRecognizer ( II , * this , getRegisterInfo ( ) , Subtarget , DAG ) ; return TargetInstrInfoImpl :: CreateTargetPostRAHazardRecognizer ( II , DAG ) ; } </s>

Allocate and return a hazard recognizer to use for by non-scheduling passes .


<s> MachineInstr * ARMBaseInstrInfo :: duplicate ( MachineInstr * Orig , MachineFunction & MF ) const { MachineInstr * MI = TargetInstrInfoImpl :: duplicate ( Orig , MF ) ; switch ( Orig -> getOpcode ( ) ) { case ARM :: tLDRpci_pic : case ARM :: t2LDRpci_pic : { unsigned CPI = Orig -> getOperand ( 1 ) . getIndex ( ) ; unsigned PCLabelId = duplicateCPV ( MF , CPI ) ; Orig -> getOperand ( 1 ) . setIndex ( CPI ) ; Orig -> getOperand ( 2 ) . setImm ( PCLabelId ) ; break ; } } return MI ; } </s>

Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore .


<s>
bool
ARMBaseInstrInfo
::
expandPostRAPseudo
(
MachineBasicBlock
::
iterator
MI
)
const
{
if
(
!
WidenVMOVS
||
!
MI
->
isCopy
(
)
)
return
false
;
unsigned
DstRegS
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
unsigned
SrcRegS
=
MI
->
getOperand
(
1
)
.
getReg
(
)
;
if
(
!
ARM
::
SPRRegClass
.
contains
(
DstRegS
,
SrcRegS
)
)
return
false
;
const
TargetRegisterInfo
*
TRI
=
&
getRegisterInfo
(
)
;
unsigned
DstRegD
=
TRI
->
getMatchingSuperReg
(
DstRegS
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
unsigned
SrcRegD
=
TRI
->
getMatchingSuperReg
(
SrcRegS
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
if
(
!
DstRegD
||
!
SrcRegD
)
return
false
;
if
(
!
MI
->
definesRegister
(
DstRegD
,
TRI
)
||
MI
->
readsRegister
(
DstRegD
,
TRI
)
)
return
false
;
if
(
MI
->
getOperand
(
0
)
.
isDead
(
)
)
return
false
;
DEBUG
(
dbgs
(
)
<<
"widening:    "
<<
*
MI
)
;
int
ImpDefIdx
=
MI
->
findRegisterDefOperandIdx
(
DstRegD
)
;
if
(
ImpDefIdx
!=
1
)
MI
->
RemoveOperand
(
ImpDefIdx
)
;
MI
->
setDesc
(
get
(
ARM
::
VMOVD
)
)
;
MI
->
getOperand
(
0
)
.
setReg
(
DstRegD
)
;
MI
->
getOperand
(
1
)
.
setReg
(
SrcRegD
)
;
AddDefaultPred
(
MachineInstrBuilder
(
MI
)
)
;
MI
->
getOperand
(
1
)
.
setIsUndef
(
)
;
MachineInstrBuilder
(
MI
)
.
addReg
(
SrcRegS
,
RegState
::
Implicit
)
;
if
(
MI
->
getOperand
(
1
)
.
isKill
(
)
)
{
MI
->
getOperand
(
1
)
.
setIsKill
(
false
)
;
MI
->
addRegisterKilled
(
SrcRegS
,
TRI
,
true
)
;
}
DEBUG
(
dbgs
(
)
<<
"replaced by: "
<<
*
MI
)
;
return
true
;
}
</s>


<s> std :: pair < uint16_t , uint16_t > ARMBaseInstrInfo :: getExecutionDomain ( const MachineInstr * MI ) const { if ( MI -> getOpcode ( ) == ARM :: VMOVD && ! isPredicated ( MI ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; unsigned Domain = MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Domain & ARMII :: DomainNEON ) return std :: make_pair ( ExeNEON , 0 ) ; if ( ( Domain & ARMII :: DomainNEONA8 ) && Subtarget . isCortexA8 ( ) ) return std :: make_pair ( ExeNEON , 0 ) ; if ( Domain & ARMII :: DomainVFP ) return std :: make_pair ( ExeVFP , 0 ) ; return std :: make_pair ( ExeGeneric , 0 ) ; } </s>


<s> int ARMBaseInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , const MachineInstr * MI , unsigned * PredCost ) const { if ( MI -> isCopyLike ( ) || MI -> isInsertSubreg ( ) || MI -> isRegSequence ( ) || MI -> isImplicitDef ( ) ) return 1 ; if ( ! ItinData || ItinData -> isEmpty ( ) ) return 1 ; if ( MI -> isBundle ( ) ) { int Latency = 0 ; MachineBasicBlock :: const_instr_iterator I = MI ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { if ( I -> getOpcode ( ) != ARM :: t2IT ) Latency += getInstrLatency ( ItinData , I , PredCost ) ; } return Latency ; } const MCInstrDesc & MCID = MI -> getDesc ( ) ; unsigned Class = MCID . getSchedClass ( ) ; unsigned UOps = ItinData -> Itineraries [ Class ] . NumMicroOps ; if ( PredCost && ( MCID . isCall ( ) || MCID . hasImplicitDefOfPhysReg ( ARM :: CPSR ) ) ) * PredCost = 1 ; if ( UOps ) return ItinData -> getStageLatency ( Class ) ; return getNumMicroOps ( ItinData , MI ) ; } </s>


<s>
unsigned
ARMBaseInstrInfo
::
getNumMicroOps
(
const
InstrItineraryData
*
ItinData
,
const
MachineInstr
*
MI
)
const
{
if
(
!
ItinData
||
ItinData
->
isEmpty
(
)
)
return
1
;
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
Class
=
Desc
.
getSchedClass
(
)
;
unsigned
UOps
=
ItinData
->
Itineraries
[
Class
]
.
NumMicroOps
;
if
(
UOps
)
return
UOps
;
unsigned
Opc
=
MI
->
getOpcode
(
)
;
switch
(
Opc
)
{
default
:
llvm_unreachable
(
"Unexpected multi-uops instruction!"
)
;
case
ARM
::
VLDMQIA
:
case
ARM
::
VSTMQIA
:
return
2
;
case
ARM
::
VLDMDIA
:
case
ARM
::
VLDMDIA_UPD
:
case
ARM
::
VLDMDDB_UPD
:
case
ARM
::
VLDMSIA
:
case
ARM
::
VLDMSIA_UPD
:
case
ARM
::
VLDMSDB_UPD
:
case
ARM
::
VSTMDIA
:
case
ARM
::
VSTMDIA_UPD
:
case
ARM
::
VSTMDDB_UPD
:
case
ARM
::
VSTMSIA
:
case
ARM
::
VSTMSIA_UPD
:
case
ARM
::
VSTMSDB_UPD
:
{
unsigned
NumRegs
=
MI
->
getNumOperands
(
)
Desc
.
getNumOperands
(
)
;
return
(
NumRegs
/
2
)
+
(
NumRegs
%
2
)
+
1
;
}
case
ARM
::
LDMIA_RET
:
case
ARM
::
LDMIA
:
case
ARM
::
LDMDA
:
case
ARM
::
LDMDB
:
case
ARM
::
LDMIB
:
case
ARM
::
LDMIA_UPD
:
case
ARM
::
LDMDA_UPD
:
case
ARM
::
LDMDB_UPD
:
case
ARM
::
LDMIB_UPD
:
case
ARM
::
STMIA
:
case
ARM
::
STMDA
:
case
ARM
::
STMDB
:
case
ARM
::
STMIB
:
case
ARM
::
STMIA_UPD
:
case
ARM
::
STMDA_UPD
:
case
ARM
::
STMDB_UPD
:
case
ARM
::
STMIB_UPD
:
case
ARM
::
tLDMIA
:
case
ARM
::
tLDMIA_UPD
:
case
ARM
::
tSTMIA_UPD
:
case
ARM
::
tPOP_RET
:
case
ARM
::
tPOP
:
case
ARM
::
tPUSH
:
case
ARM
::
t2LDMIA_RET
:
case
ARM
::
t2LDMIA
:
case
ARM
::
t2LDMDB
:
case
ARM
::
t2LDMIA_UPD
:
case
ARM
::
t2LDMDB_UPD
:
case
ARM
::
t2STMIA
:
case
ARM
::
t2STMDB
:
case
ARM
::
t2STMIA_UPD
:
case
ARM
::
t2STMDB_UPD
:
{
unsigned
NumRegs
=
MI
->
getNumOperands
(
)
Desc
.
getNumOperands
(
)
+
1
;
if
(
Subtarget
.
isCortexA8
(
)
)
{
if
(
NumRegs
<
4
)
return
2
;
UOps
=
(
NumRegs
/
2
)
;
if
(
NumRegs
%
2
)
++
UOps
;
return
UOps
;
}
else
if
(
Subtarget
.
isCortexA9
(
)
)
{
UOps
=
(
NumRegs
/
2
)
;
if
(
(
NumRegs
%
2
)
||
!
MI
->
hasOneMemOperand
(
)
||
(
*
MI
->
memoperands_begin
(
)
)
->
getAlignment
(
)
<
8
)
++
UOps
;
return
UOps
;
}
else
{
return
NumRegs
;
}
}
}
}
</s>

Return the number of issue slots required for this MI .


<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const InstrItineraryData * ItinData , const MachineRegisterInfo * MRI , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . isCortexA8 ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; int Latency = getOperandLatency ( ItinData , DefMI , DefIdx , UseMI , UseIdx ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLD1q64 : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

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


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: STRrs : case ARM :: t2STRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: STRi12 : case ARM :: t2STRi12 : case ARM :: tSTRspi : case ARM :: VSTRD : case ARM :: VSTRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VST1q64 : if ( MI -> getOperand ( 0 ) . isFI ( ) && MI -> getOperand ( 2 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 0 ) . getIndex ( ) ; return MI -> getOperand ( 2 ) . getReg ( ) ; } break ; case ARM :: VSTMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


<s> bool ARMBaseInstrInfo :: PredicateInstruction ( MachineInstr * MI , const SmallVectorImpl < MachineOperand > & Pred ) const { unsigned Opc = MI -> getOpcode ( ) ; if ( isUncondBranchOpcode ( Opc ) ) { MI -> setDesc ( get ( getMatchingCondBranchOpcode ( Opc ) ) ) ; MI -> addOperand ( MachineOperand :: CreateImm ( Pred [ 0 ] . getImm ( ) ) ) ; MI -> addOperand ( MachineOperand :: CreateReg ( Pred [ 1 ] . getReg ( ) , false ) ) ; return true ; } int PIdx = MI -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 ) { MachineOperand & PMO = MI -> getOperand ( PIdx ) ; PMO . setImm ( Pred [ 0 ] . getImm ( ) ) ; MI -> getOperand ( PIdx + 1 ) . setReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } return false ; } </s>

Convert the instruction into a predicated instruction .


<s>
void
ARMBaseInstrInfo
::
setExecutionDomain
(
MachineInstr
*
MI
,
unsigned
Domain
)
const
{
assert
(
MI
->
getOpcode
(
)
==
ARM
::
VMOVD
&&
"Can only swizzle VMOVD"
)
;
if
(
Domain
!=
ExeNEON
)
return
;
assert
(
!
isPredicated
(
MI
)
&&
"Cannot predicate a VORRd"
)
;
MI
->
RemoveOperand
(
3
)
;
MI
->
RemoveOperand
(
2
)
;
MI
->
setDesc
(
get
(
ARM
::
VORRd
)
)
;
AddDefaultPred
(
MachineInstrBuilder
(
MI
)
.
addOperand
(
MI
->
getOperand
(
1
)
)
)
;
}
</s>

Change the opcode of MI to execute in Domain .

ARM
ARM
ARM::VMOVD
"Can only swizzle VMOVD"
"Cannot predicate a VORRd"
3
2
ARM::VORRd
1


<s> bool ARMBaseInstrInfo :: analyzeCompare ( const MachineInstr * MI , unsigned & SrcReg , unsigned & SrcReg2 , int & CmpMask , int & CmpValue ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: CMPri : case ARM :: t2CMPri : SrcReg = MI -> getOperand ( 0 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = ~ 0 ; CmpValue = MI -> getOperand ( 1 ) . getImm ( ) ; return true ; case ARM :: CMPrr : case ARM :: t2CMPrr : SrcReg = MI -> getOperand ( 0 ) . getReg ( ) ; SrcReg2 = MI -> getOperand ( 1 ) . getReg ( ) ; CmpMask = ~ 0 ; CmpValue = 0 ; return true ; case ARM :: TSTri : case ARM :: t2TSTri : SrcReg = MI -> getOperand ( 0 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = MI -> getOperand ( 1 ) . getImm ( ) ; CmpValue = 0 ; return true ; } return false ; } </s>

analyzeCompare - For a comparison instruction , return the source registers in SrcReg and SrcReg2 if having two register operands , and the value it compares against in CmpValue .


<s>
bool
ARMBaseInstrInfo
::
analyzeSelect
(
const
MachineInstr
*
MI
,
SmallVectorImpl
<
MachineOperand
>
&
Cond
,
unsigned
&
TrueOp
,
unsigned
&
FalseOp
,
bool
&
Optimizable
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
TrueOp
=
1
;
FalseOp
=
2
;
Cond
.
push_back
(
MI
->
getOperand
(
3
)
)
;
Cond
.
push_back
(
MI
->
getOperand
(
4
)
)
;
Optimizable
=
true
;
return
false
;
}
</s>

Analyze the given select instruction , returning true if it can not be understood .


<s> bool ARMBaseInstrInfo :: areLoadsFromSameBasePtr ( SDNode * Load1 , SDNode * Load2 , int64_t & Offset1 , int64_t & Offset2 ) const { if ( Subtarget . isThumb1Only ( ) ) return false ; if ( ! Load1 -> isMachineOpcode ( ) || ! Load2 -> isMachineOpcode ( ) ) return false ; switch ( Load1 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDRi12 : case ARM :: LDRBi12 : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRBi8 : case ARM :: t2LDRDi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRBi12 : case ARM :: t2LDRSHi12 : break ; } switch ( Load2 -> getMachineOpcode ( ) ) { default : return false ; case ARM :: LDRi12 : case ARM :: LDRBi12 : case ARM :: LDRD : case ARM :: LDRH : case ARM :: LDRSB : case ARM :: LDRSH : case ARM :: VLDRD : case ARM :: VLDRS : case ARM :: t2LDRi8 : case ARM :: t2LDRBi8 : case ARM :: t2LDRSHi8 : case ARM :: t2LDRi12 : case ARM :: t2LDRBi12 : case ARM :: t2LDRSHi12 : break ; } if ( Load1 -> getOperand ( 0 ) != Load2 -> getOperand ( 0 ) || Load1 -> getOperand ( 4 ) != Load2 -> getOperand ( 4 ) ) return false ; if ( Load1 -> getOperand ( 3 ) != Load2 -> getOperand ( 3 ) ) return false ; if ( isa < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) && isa < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) ) { Offset1 = cast < ConstantSDNode > ( Load1 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; Offset2 = cast < ConstantSDNode > ( Load2 -> getOperand ( 1 ) ) -> getSExtValue ( ) ; return true ; } return false ; } </s>


"Can't break virtual register dependencies."

Insert a dependency-breaking instruction before MI to eliminate an unwanted dependency on OpNum .


<s> MachineInstr * ARMBaseInstrInfo :: commuteInstruction ( MachineInstr * MI , bool NewMI ) const { switch ( MI -> getOpcode ( ) ) { case ARM :: MOVCCr : case ARM :: t2MOVCCr : { unsigned PredReg = 0 ; ARMCC :: CondCodes CC = getInstrPredicate ( MI , PredReg ) ; if ( CC == ARMCC :: AL || PredReg != ARM :: CPSR ) return NULL ; MI = TargetInstrInfo :: commuteInstruction ( MI , NewMI ) ; if ( ! MI ) return NULL ; MI -> getOperand ( MI -> findFirstPredOperandIdx ( ) ) . setImm ( ARMCC :: getOppositeCondition ( CC ) ) ; return MI ; } } return TargetInstrInfo :: commuteInstruction ( MI , NewMI ) ; } </s>

This method commutes the operands of the given machine instruction MI .


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetHazardRecognizer ( const TargetMachine * TM , const ScheduleDAG * DAG ) const { if ( usePreRAHazardRecognizer ( ) ) { const InstrItineraryData * II = TM -> getInstrItineraryData ( ) ; return new ScoreboardHazardRecognizer ( II , DAG , "pre-RA-sched" ) ; } return TargetInstrInfo :: CreateTargetHazardRecognizer ( TM , DAG ) ; } </s>


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetPostRAHazardRecognizer ( const InstrItineraryData * II , const ScheduleDAG * DAG ) const { if ( Subtarget . isThumb2 ( ) || Subtarget . hasVFP2 ( ) ) return ( ScheduleHazardRecognizer * ) new ARMHazardRecognizer ( II , DAG ) ; return TargetInstrInfo :: CreateTargetPostRAHazardRecognizer ( II , DAG ) ; } </s>


<s> MachineInstr * ARMBaseInstrInfo :: duplicate ( MachineInstr * Orig , MachineFunction & MF ) const { MachineInstr * MI = TargetInstrInfo :: duplicate ( Orig , MF ) ; switch ( Orig -> getOpcode ( ) ) { case ARM :: tLDRpci_pic : case ARM :: t2LDRpci_pic : { unsigned CPI = Orig -> getOperand ( 1 ) . getIndex ( ) ; unsigned PCLabelId = duplicateCPV ( MF , CPI ) ; Orig -> getOperand ( 1 ) . setIndex ( CPI ) ; Orig -> getOperand ( 2 ) . setImm ( PCLabelId ) ; break ; } } return MI ; } </s>


<s>
bool
ARMBaseInstrInfo
::
expandPostRAPseudo
(
MachineBasicBlock
::
iterator
MI
)
const
{
if
(
!
WidenVMOVS
||
!
MI
->
isCopy
(
)
||
Subtarget
.
isCortexA15
(
)
)
return
false
;
unsigned
DstRegS
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
unsigned
SrcRegS
=
MI
->
getOperand
(
1
)
.
getReg
(
)
;
if
(
!
ARM
::
SPRRegClass
.
contains
(
DstRegS
,
SrcRegS
)
)
return
false
;
const
TargetRegisterInfo
*
TRI
=
&
getRegisterInfo
(
)
;
unsigned
DstRegD
=
TRI
->
getMatchingSuperReg
(
DstRegS
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
unsigned
SrcRegD
=
TRI
->
getMatchingSuperReg
(
SrcRegS
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
if
(
!
DstRegD
||
!
SrcRegD
)
return
false
;
if
(
!
MI
->
definesRegister
(
DstRegD
,
TRI
)
||
MI
->
readsRegister
(
DstRegD
,
TRI
)
)
return
false
;
if
(
MI
->
getOperand
(
0
)
.
isDead
(
)
)
return
false
;
DEBUG
(
dbgs
(
)
<<
"widening:    "
<<
*
MI
)
;
MachineInstrBuilder
MIB
(
*
MI
->
getParent
(
)
->
getParent
(
)
,
MI
)
;
int
ImpDefIdx
=
MI
->
findRegisterDefOperandIdx
(
DstRegD
)
;
if
(
ImpDefIdx
!=
1
)
MI
->
RemoveOperand
(
ImpDefIdx
)
;
MI
->
setDesc
(
get
(
ARM
::
VMOVD
)
)
;
MI
->
getOperand
(
0
)
.
setReg
(
DstRegD
)
;
MI
->
getOperand
(
1
)
.
setReg
(
SrcRegD
)
;
AddDefaultPred
(
MIB
)
;
MI
->
getOperand
(
1
)
.
setIsUndef
(
)
;
MIB
.
addReg
(
SrcRegS
,
RegState
::
Implicit
)
;
if
(
MI
->
getOperand
(
1
)
.
isKill
(
)
)
{
MI
->
getOperand
(
1
)
.
setIsKill
(
false
)
;
MI
->
addRegisterKilled
(
SrcRegS
,
TRI
,
true
)
;
}
DEBUG
(
dbgs
(
)
<<
"replaced by: "
<<
*
MI
)
;
return
true
;
}
</s>

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


<s> std :: pair < uint16_t , uint16_t > ARMBaseInstrInfo :: getExecutionDomain ( const MachineInstr * MI ) const { if ( MI -> getOpcode ( ) == ARM :: VMOVD && ! isPredicated ( MI ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; if ( Subtarget . isCortexA9 ( ) && ! isPredicated ( MI ) && ( MI -> getOpcode ( ) == ARM :: VMOVRS || MI -> getOpcode ( ) == ARM :: VMOVSR || MI -> getOpcode ( ) == ARM :: VMOVS ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; unsigned Domain = MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Domain & ARMII :: DomainNEON ) return std :: make_pair ( ExeNEON , 0 ) ; if ( ( Domain & ARMII :: DomainNEONA8 ) && Subtarget . isCortexA8 ( ) ) return std :: make_pair ( ExeNEON , 0 ) ; if ( Domain & ARMII :: DomainVFP ) return std :: make_pair ( ExeVFP , 0 ) ; return std :: make_pair ( ExeGeneric , 0 ) ; } </s>

Return the current execution domain and bit mask of possible domains for instruction .


<s> int ARMBaseInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , SDNode * Node ) const { if ( ! Node -> isMachineOpcode ( ) ) return 1 ; if ( ! ItinData || ItinData -> isEmpty ( ) ) return 1 ; unsigned Opcode = Node -> getMachineOpcode ( ) ; switch ( Opcode ) { default : return ItinData -> getStageLatency ( get ( Opcode ) . getSchedClass ( ) ) ; case ARM :: VLDMQIA : case ARM :: VSTMQIA : return 2 ; } } </s>

Compute the instruction latency of a given instruction .


<s> unsigned ARMBaseInstrInfo :: getNumLDMAddresses ( const MachineInstr * MI ) const { unsigned Size = 0 ; for ( MachineInstr :: mmo_iterator I = MI -> memoperands_begin ( ) , E = MI -> memoperands_end ( ) ; I != E ; ++ I ) { Size += ( * I ) -> getSize ( ) ; } return Size / 4 ; } </s>

Get the number of addresses by LDM or VLDM or zero for unknown .


<s>
unsigned
ARMBaseInstrInfo
::
getPartialRegUpdateClearance
(
const
MachineInstr
*
MI
,
unsigned
OpNum
,
const
TargetRegisterInfo
*
TRI
)
const
{
if
(
!
SwiftPartialUpdateClearance
||
!
(
Subtarget
.
isSwift
(
)
||
Subtarget
.
isCortexA15
(
)
)
)
return
0
;
assert
(
TRI
&&
"Need TRI instance"
)
;
const
MachineOperand
&
MO
=
MI
->
getOperand
(
OpNum
)
;
if
(
MO
.
readsReg
(
)
)
return
0
;
unsigned
Reg
=
MO
.
getReg
(
)
;
int
UseOp
=
1
;
switch
(
MI
->
getOpcode
(
)
)
{
case
ARM
::
VLDRS
:
case
ARM
::
FCONSTS
:
case
ARM
::
VMOVSR
:
case
ARM
::
VMOVv8i8
:
case
ARM
::
VMOVv4i16
:
case
ARM
::
VMOVv2i32
:
case
ARM
::
VMOVv2f32
:
case
ARM
::
VMOVv1i64
:
UseOp
=
MI
->
findRegisterUseOperandIdx
(
Reg
,
false
,
TRI
)
;
break
;
case
ARM
::
VLD1LNd32
:
UseOp
=
3
;
break
;
default
:
return
0
;
}
if
(
UseOp
!=
1
&&
MI
->
getOperand
(
UseOp
)
.
readsReg
(
)
)
return
0
;
if
(
TargetRegisterInfo
::
isVirtualRegister
(
Reg
)
)
{
if
(
!
MO
.
getSubReg
(
)
||
MI
->
readsVirtualRegister
(
Reg
)
)
return
0
;
}
else
if
(
ARM
::
SPRRegClass
.
contains
(
Reg
)
)
{
unsigned
DReg
=
TRI
->
getMatchingSuperReg
(
Reg
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
if
(
!
DReg
||
!
MI
->
definesRegister
(
DReg
,
TRI
)
)
return
0
;
}
return
SwiftPartialUpdateClearance
;
}
</s>

Inform the BreakFalseDeps pass how many idle instructions we would like before a partial register update .


<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const InstrItineraryData * ItinData , const MachineRegisterInfo * MRI , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . isCortexA8 ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; int Latency = computeOperandLatency ( ItinData , DefMI , DefIdx , UseMI , UseIdx ) ; if ( Latency < 0 ) Latency = getInstrLatency ( ItinData , DefMI ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>

Compute operand latency between a def of 'Reg ' and a use in the current loop .

ARM ARM ARMII::DomainMask ARMII::DomainMask ARMII::DomainVFP ARMII::DomainVFP 0 3 ARMII::DomainVFP ARMII::DomainNEON ARMII::DomainVFP ARMII::DomainNEON


<s> bool ARMBaseInstrInfo :: hasLowDefLatency ( const InstrItineraryData * ItinData , const MachineInstr * DefMI , unsigned DefIdx ) const { if ( ! ItinData || ItinData -> isEmpty ( ) ) return false ; unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( DDomain == ARMII :: DomainGeneral ) { unsigned DefClass = DefMI -> getDesc ( ) . getSchedClass ( ) ; int DefCycle = ItinData -> getOperandCycle ( DefClass , DefIdx ) ; return ( DefCycle != - 1 && DefCycle <= 2 ) ; } return false ; } </s>

Compute operand latency of a def of 'Reg ' .


<s> bool ARMBaseInstrInfo :: isFpMLxInstruction ( unsigned Opcode , unsigned & MulOpc , unsigned & AddSubOpc , bool & NegAcc , bool & HasLane ) const { DenseMap < unsigned , unsigned > :: const_iterator I = MLxEntryMap . find ( Opcode ) ; if ( I == MLxEntryMap . end ( ) ) return false ; const ARM_MLxEntry & Entry = ARM_MLxTable [ I -> second ] ; MulOpc = Entry . MulOpc ; AddSubOpc = Entry . AddSubOpc ; NegAcc = Entry . NegAcc ; HasLane = Entry . HasLane ; return true ; } </s>

isFpMLxInstruction - This version also returns the multiply opcode and the addition / subtraction opcode to expand to .


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLD1q64 : case ARM :: VLD1d64TPseudo : case ARM :: VLD1d64QPseudo : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlotPostFE ( const MachineInstr * MI , int & FrameIndex ) const { const MachineMemOperand * Dummy ; return MI -> mayLoad ( ) && hasLoadFromStackSlot ( MI , Dummy , FrameIndex ) ; } </s>

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


<s> bool ARMBaseInstrInfo :: isPredicable ( MachineInstr * MI ) const { if ( ! MI -> isPredicable ( ) ) return false ; ARMFunctionInfo * AFI = MI -> getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumb2Function ( ) ) { if ( getSubtarget ( ) . restrictIT ( ) ) return isV8EligibleForIT ( MI ) ; } else { if ( ( MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) return false ; } return true ; } </s>

Return true if the specified instruction can be predicated .


<s> bool ARMBaseInstrInfo :: isPredicated ( const MachineInstr * MI ) const { if ( MI -> isBundle ( ) ) { MachineBasicBlock :: const_instr_iterator I = MI ; MachineBasicBlock :: const_instr_iterator E = MI -> getParent ( ) -> instr_end ( ) ; while ( ++ I != E && I -> isInsideBundle ( ) ) { int PIdx = I -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 && I -> getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ) return true ; } return false ; } int PIdx = MI -> findFirstPredOperandIdx ( ) ; return PIdx != - 1 && MI -> getOperand ( PIdx ) . getImm ( ) != ARMCC :: AL ; } </s>

Returns true if the instruction is already predicated .


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & TMBB , unsigned TCycles , unsigned TExtra , MachineBasicBlock & FMBB , unsigned FCycles , unsigned FExtra , const BranchProbability & Probability ) const { if ( ! TCycles || ! FCycles ) return false ; unsigned TUnpredCost = Probability . getNumerator ( ) * TCycles ; TUnpredCost /= Probability . getDenominator ( ) ; uint32_t Comp = Probability . getDenominator ( ) - Probability . getNumerator ( ) ; unsigned FUnpredCost = Comp * FCycles ; FUnpredCost /= Probability . getDenominator ( ) ; unsigned UnpredCost = TUnpredCost + FUnpredCost ; UnpredCost += 1 ; UnpredCost += Subtarget . getMispredictionPenalty ( ) / 10 ; return ( TCycles + FCycles + TExtra + FExtra ) <= UnpredCost ; } </s>


<s> bool ARMBaseInstrInfo :: isProfitableToUnpredicate ( MachineBasicBlock & TMBB , MachineBasicBlock & FMBB ) const { return Subtarget . isSwift ( ) ; } </s>

Return true if it 's profitable to unpredicate one side of a 'diamond ' , i.e .


<s> bool ARMBaseInstrInfo :: isSchedulingBoundary ( const MachineInstr * MI , const MachineBasicBlock * MBB , const MachineFunction & MF ) const { if ( MI -> isDebugValue ( ) ) return false ; if ( MI -> isTerminator ( ) || MI -> isPosition ( ) ) return true ; MachineBasicBlock :: const_iterator I = MI ; while ( ++ I != MBB -> end ( ) && I -> isDebugValue ( ) ) ; if ( I != MBB -> end ( ) && I -> getOpcode ( ) == ARM :: t2IT ) return true ; if ( ! MI -> isCall ( ) && MI -> definesRegister ( ARM :: SP ) ) return true ; return false ; } </s>

isSchedulingBoundary - Overrides the isSchedulingBoundary from Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR intructions and prevent it from being re-scheduled .


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: STRrs : case ARM :: t2STRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: STRi12 : case ARM :: t2STRi12 : case ARM :: tSTRspi : case ARM :: VSTRD : case ARM :: VSTRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VST1q64 : case ARM :: VST1d64TPseudo : case ARM :: VST1d64QPseudo : if ( MI -> getOperand ( 0 ) . isFI ( ) && MI -> getOperand ( 2 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 0 ) . getIndex ( ) ; return MI -> getOperand ( 2 ) . getReg ( ) ; } break ; case ARM :: VSTMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


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

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


<s> bool ARMBaseInstrInfo :: isSwiftFastImmShift ( const MachineInstr * MI ) const { if ( MI -> getNumOperands ( ) < 4 ) return true ; unsigned ShOpVal = MI -> getOperand ( 3 ) . getImm ( ) ; unsigned ShImm = ARM_AM :: getSORegOffset ( ShOpVal ) ; if ( ( ShImm == 1 && ARM_AM :: getSORegShOp ( ShOpVal ) == ARM_AM :: lsr ) || ( ( ShImm == 1 || ShImm == 2 ) && ARM_AM :: getSORegShOp ( ShOpVal ) == ARM_AM :: lsl ) ) return true ; return false ; } </s>

Returns true if the instruction has a shift by immediate that can be executed in one cycle less .


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
*
MI
,
bool
PreferFalse
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
MachineRegisterInfo
&
MRI
=
MI
->
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
0
;
MachineOperand
FalseReg
=
MI
->
getOperand
(
Invert
2
:
1
)
;
unsigned
DestReg
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
const
TargetRegisterClass
*
PreviousClass
=
MRI
.
getRegClass
(
FalseReg
.
getReg
(
)
)
;
if
(
!
MRI
.
constrainRegClass
(
DestReg
,
PreviousClass
)
)
return
0
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
->
getParent
(
)
,
MI
,
MI
->
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
DestReg
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
->
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
->
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
.
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>

Given a select instruction that was understood by analyzeSelect and returned Optimizable = true , attempt to optimize MI by merging it with one of its operands .


<s> bool ARMBaseInstrInfo :: PredicateInstruction ( MachineInstr * MI , const SmallVectorImpl < MachineOperand > & Pred ) const { unsigned Opc = MI -> getOpcode ( ) ; if ( isUncondBranchOpcode ( Opc ) ) { MI -> setDesc ( get ( getMatchingCondBranchOpcode ( Opc ) ) ) ; MachineInstrBuilder ( * MI -> getParent ( ) -> getParent ( ) , MI ) . addImm ( Pred [ 0 ] . getImm ( ) ) . addReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } int PIdx = MI -> findFirstPredOperandIdx ( ) ; if ( PIdx != - 1 ) { MachineOperand & PMO = MI -> getOperand ( PIdx ) ; PMO . setImm ( Pred [ 0 ] . getImm ( ) ) ; MI -> getOperand ( PIdx + 1 ) . setReg ( Pred [ 1 ] . getReg ( ) ) ; return true ; } return false ; } </s>

Convert the instruction into a predicated instruction .


<s> void ARMBaseInstrInfo :: reMaterialize ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator I , unsigned DestReg , unsigned SubIdx , const MachineInstr * Orig , const TargetRegisterInfo & TRI ) const { unsigned Opcode = Orig -> getOpcode ( ) ; switch ( Opcode ) { default : { MachineInstr * MI = MBB . getParent ( ) -> CloneMachineInstr ( Orig ) ; MI -> substituteRegister ( Orig -> getOperand ( 0 ) . getReg ( ) , DestReg , SubIdx , TRI ) ; MBB . insert ( I , MI ) ; break ; } case ARM :: tLDRpci_pic : case ARM :: t2LDRpci_pic : { MachineFunction & MF = * MBB . getParent ( ) ; unsigned CPI = Orig -> getOperand ( 1 ) . getIndex ( ) ; unsigned PCLabelId = duplicateCPV ( MF , CPI ) ; MachineInstrBuilder MIB = BuildMI ( MBB , I , Orig -> getDebugLoc ( ) , get ( Opcode ) , DestReg ) . addConstantPoolIndex ( CPI ) . addImm ( PCLabelId ) ; MIB -> setMemRefs ( Orig -> memoperands_begin ( ) , Orig -> memoperands_end ( ) ) ; break ; } } } </s>

Re-issue the specified 'original ' instruction at the specific location targeting a new destination register .


<s> bool ARMBaseInstrInfo :: shouldScheduleLoadsNear ( SDNode * Load1 , SDNode * Load2 , int64_t Offset1 , int64_t Offset2 , unsigned NumLoads ) const { if ( Subtarget . isThumb1Only ( ) ) return false ; assert ( Offset2 > Offset1 ) ; if ( ( Offset2 - Offset1 ) / 8 > 64 ) return false ; if ( ( Load1 -> getMachineOpcode ( ) != Load2 -> getMachineOpcode ( ) ) && ! ( ( Load1 -> getMachineOpcode ( ) == ARM :: t2LDRBi8 && Load2 -> getMachineOpcode ( ) == ARM :: t2LDRBi12 ) || ( Load1 -> getMachineOpcode ( ) == ARM :: t2LDRBi12 && Load2 -> getMachineOpcode ( ) == ARM :: t2LDRBi8 ) ) ) return false ; if ( NumLoads >= 3 ) return false ; return true ; } </s>

shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to determine ( in conjunction with areLoadsFromSameBasePtr ) if two loads should be scheduled togther .


<s> bool ARMBaseInstrInfo :: SubsumesPredicate ( const SmallVectorImpl < MachineOperand > & Pred1 , const SmallVectorImpl < MachineOperand > & Pred2 ) const { if ( Pred1 . size ( ) > 2 || Pred2 . size ( ) > 2 ) return false ; ARMCC :: CondCodes CC1 = ( ARMCC :: CondCodes ) Pred1 [ 0 ] . getImm ( ) ; ARMCC :: CondCodes CC2 = ( ARMCC :: CondCodes ) Pred2 [ 0 ] . getImm ( ) ; if ( CC1 == CC2 ) return true ; switch ( CC1 ) { default : return false ; case ARMCC :: AL : return true ; case ARMCC :: HS : return CC2 == ARMCC :: HI ; case ARMCC :: LS : return CC2 == ARMCC :: LO || CC2 == ARMCC :: EQ ; case ARMCC :: GE : return CC2 == ARMCC :: GT ; case ARMCC :: LE : return CC2 == ARMCC :: LT ; } } </s>

Returns true if the first specified predicate subsumes the second , e.g .


"Pseudo flag setting opcodes only exist in Selection DAG"

Perform target-specific instruction verification .


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetPostRAHazardRecognizer ( const InstrItineraryData * II , const ScheduleDAG * DAG ) const { if ( Subtarget . isThumb2 ( ) || Subtarget . hasVFP2 ( ) ) return ( ScheduleHazardRecognizer * ) new ARMHazardRecognizer ( II , * this , getRegisterInfo ( ) , Subtarget , DAG ) ; return TargetInstrInfo :: CreateTargetPostRAHazardRecognizer ( II , DAG ) ; } </s>

Allocate and return a hazard recognizer to use for by non-scheduling passes .


<s> std :: pair < uint16_t , uint16_t > ARMBaseInstrInfo :: getExecutionDomain ( const MachineInstr * MI ) const { if ( MI -> getOpcode ( ) == ARM :: VMOVD && ! isPredicated ( MI ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; if ( Subtarget . isLikeA9 ( ) && ! isPredicated ( MI ) && ( MI -> getOpcode ( ) == ARM :: VMOVRS || MI -> getOpcode ( ) == ARM :: VMOVSR || MI -> getOpcode ( ) == ARM :: VMOVS ) ) return std :: make_pair ( ExeVFP , ( 1 << ExeVFP ) | ( 1 << ExeNEON ) ) ; unsigned Domain = MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Domain & ARMII :: DomainNEON ) return std :: make_pair ( ExeNEON , 0 ) ; if ( ( Domain & ARMII :: DomainNEONA8 ) && Subtarget . isCortexA8 ( ) ) return std :: make_pair ( ExeNEON , 0 ) ; if ( Domain & ARMII :: DomainVFP ) return std :: make_pair ( ExeVFP , 0 ) ; return std :: make_pair ( ExeGeneric , 0 ) ; } </s>

Return the current execution domain and bit mask of possible domains for instruction .


<s> int ARMBaseInstrInfo :: getOperandLatency ( const InstrItineraryData * ItinData , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { if ( ! ItinData || ItinData -> isEmpty ( ) ) return - 1 ; const MachineOperand & DefMO = DefMI -> getOperand ( DefIdx ) ; unsigned Reg = DefMO . getReg ( ) ; const MCInstrDesc * DefMCID = & DefMI -> getDesc ( ) ; const MCInstrDesc * UseMCID = & UseMI -> getDesc ( ) ; unsigned DefAdj = 0 ; if ( DefMI -> isBundle ( ) ) { DefMI = getBundledDefMI ( & getRegisterInfo ( ) , DefMI , Reg , DefIdx , DefAdj ) ; DefMCID = & DefMI -> getDesc ( ) ; } if ( DefMI -> isCopyLike ( ) || DefMI -> isInsertSubreg ( ) || DefMI -> isRegSequence ( ) || DefMI -> isImplicitDef ( ) ) { return 1 ; } unsigned UseAdj = 0 ; if ( UseMI -> isBundle ( ) ) { unsigned NewUseIdx ; const MachineInstr * NewUseMI = getBundledUseMI ( & getRegisterInfo ( ) , UseMI , Reg , NewUseIdx , UseAdj ) ; if ( ! NewUseMI ) return - 1 ; UseMI = NewUseMI ; UseIdx = NewUseIdx ; UseMCID = & UseMI -> getDesc ( ) ; } if ( Reg == ARM :: CPSR ) { if ( DefMI -> getOpcode ( ) == ARM :: FMSTAT ) { return Subtarget . isLikeA9 ( ) ? 1 : 20 ; } if ( UseMI -> isBranch ( ) ) return 0 ; unsigned Latency = getInstrLatency ( ItinData , DefMI ) ; if ( Latency > 0 && Subtarget . isThumb2 ( ) ) { const MachineFunction * MF = DefMI -> getParent ( ) -> getParent ( ) ; if ( MF -> getFunction ( ) -> getFnAttributes ( ) . hasAttribute ( Attributes :: OptimizeForSize ) ) -- Latency ; } return Latency ; } if ( DefMO . isImplicit ( ) || UseMI -> getOperand ( UseIdx ) . isImplicit ( ) ) return - 1 ; unsigned DefAlign = DefMI -> hasOneMemOperand ( ) ? ( * DefMI -> memoperands_begin ( ) ) -> getAlignment ( ) : 0 ; unsigned UseAlign = UseMI -> hasOneMemOperand ( ) ? ( * UseMI -> memoperands_begin ( ) ) -> getAlignment ( ) : 0 ; int Latency = getOperandLatency ( ItinData , * DefMCID , DefIdx , DefAlign , * UseMCID , UseIdx , UseAlign ) ; if ( Latency < 0 ) return Latency ; int Adj = DefAdj + UseAdj ; Adj += adjustDefLatency ( Subtarget , DefMI , DefMCID , DefAlign ) ; if ( Adj >= 0 || ( int ) Latency > - Adj ) { return Latency + Adj ; } return Latency ; } </s>

Compute and return the use operand latency of a given pair of def and use .


<s>
unsigned
ARMBaseInstrInfo
::
getPartialRegUpdateClearance
(
const
MachineInstr
*
MI
,
unsigned
OpNum
,
const
TargetRegisterInfo
*
TRI
)
const
{
if
(
!
SwiftPartialUpdateClearance
||
!
Subtarget
.
isSwift
(
)
)
return
0
;
assert
(
TRI
&&
"Need TRI instance"
)
;
const
MachineOperand
&
MO
=
MI
->
getOperand
(
OpNum
)
;
if
(
MO
.
readsReg
(
)
)
return
0
;
unsigned
Reg
=
MO
.
getReg
(
)
;
int
UseOp
=
1
;
switch
(
MI
->
getOpcode
(
)
)
{
case
ARM
::
VLDRS
:
case
ARM
::
FCONSTS
:
case
ARM
::
VMOVSR
:
case
ARM
::
VMOVv8i8
:
case
ARM
::
VMOVv4i16
:
case
ARM
::
VMOVv2i32
:
case
ARM
::
VMOVv2f32
:
case
ARM
::
VMOVv1i64
:
UseOp
=
MI
->
findRegisterUseOperandIdx
(
Reg
,
false
,
TRI
)
;
break
;
case
ARM
::
VLD1LNd32
:
UseOp
=
1
;
break
;
default
:
return
0
;
}
if
(
UseOp
!=
1
&&
MI
->
getOperand
(
UseOp
)
.
readsReg
(
)
)
return
0
;
if
(
TargetRegisterInfo
::
isVirtualRegister
(
Reg
)
)
{
if
(
!
MO
.
getSubReg
(
)
||
MI
->
readsVirtualRegister
(
Reg
)
)
return
0
;
}
else
if
(
ARM
::
SPRRegClass
.
contains
(
Reg
)
)
{
unsigned
DReg
=
TRI
->
getMatchingSuperReg
(
Reg
,
ARM
::
ssub_0
,
&
ARM
::
DPRRegClass
)
;
if
(
!
DReg
||
!
MI
->
definesRegister
(
DReg
,
TRI
)
)
return
0
;
}
return
SwiftPartialUpdateClearance
;
}
</s>

Inform the BreakFalseDeps pass how many idle instructions we would like before a partial register update .


<s> bool ARMBaseInstrInfo :: hasHighOperandLatency ( const InstrItineraryData * ItinData , const MachineRegisterInfo * MRI , const MachineInstr * DefMI , unsigned DefIdx , const MachineInstr * UseMI , unsigned UseIdx ) const { unsigned DDomain = DefMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; unsigned UDomain = UseMI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ; if ( Subtarget . isCortexA8 ( ) && ( DDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainVFP ) ) return true ; int Latency = computeOperandLatency ( ItinData , DefMI , DefIdx , UseMI , UseIdx , false ) ; if ( Latency < 0 ) Latency = getInstrLatency ( ItinData , DefMI ) ; if ( Latency <= 3 ) return false ; return DDomain == ARMII :: DomainVFP || DDomain == ARMII :: DomainNEON || UDomain == ARMII :: DomainVFP || UDomain == ARMII :: DomainNEON ; } </s>

Compute operand latency between a def of 'Reg ' and a use in the current loop .


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
*
MI
,
bool
PreferFalse
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
const
MachineRegisterInfo
&
MRI
=
MI
->
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
0
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
->
getParent
(
)
,
MI
,
MI
->
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
MI
->
getOperand
(
0
)
.
getReg
(
)
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
->
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
->
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
MachineOperand
FalseReg
=
MI
->
getOperand
(
Invert
2
:
1
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
->
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>


<s> unsigned ARMBaseInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { const MachineBasicBlock & MBB = * MI . getParent ( ) ; const MachineFunction * MF = MBB . getParent ( ) ; const MCAsmInfo * MAI = MF -> getTarget ( ) . getMCAsmInfo ( ) ; const MCInstrDesc & MCID = MI . getDesc ( ) ; if ( MCID . getSize ( ) ) return MCID . getSize ( ) ; if ( MI . getOpcode ( ) == ARM :: INLINEASM ) return getInlineAsmLength ( MI . getOperand ( 0 ) . getSymbolName ( ) , * MAI ) ; unsigned Opc = MI . getOpcode ( ) ; switch ( Opc ) { default : return 0 ; case TargetOpcode :: BUNDLE : return getInstBundleLength ( MI ) ; case ARM :: MOVi16_ga_pcrel : case ARM :: MOVTi16_ga_pcrel : case ARM :: t2MOVi16_ga_pcrel : case ARM :: t2MOVTi16_ga_pcrel : return 4 ; case ARM :: MOVi32imm : case ARM :: t2MOVi32imm : return 8 ; case ARM :: CONSTPOOL_ENTRY : case ARM :: JUMPTABLE_INSTS : case ARM :: JUMPTABLE_ADDRS : case ARM :: JUMPTABLE_TBB : case ARM :: JUMPTABLE_TBH : return MI . getOperand ( 2 ) . getImm ( ) ; case ARM :: Int_eh_sjlj_longjmp : return 16 ; case ARM :: tInt_eh_sjlj_longjmp : return 10 ; case ARM :: tInt_WIN_eh_sjlj_longjmp : return 12 ; case ARM :: Int_eh_sjlj_setjmp : case ARM :: Int_eh_sjlj_setjmp_nofp : return 20 ; case ARM :: tInt_eh_sjlj_setjmp : case ARM :: t2Int_eh_sjlj_setjmp : case ARM :: t2Int_eh_sjlj_setjmp_nofp : return 12 ; case ARM :: SPACE : return MI . getOperand ( 1 ) . getImm ( ) ; } } </s>

Returns the size in bytes of the specified MachineInstr , or ~0U when this function is not implemented by a target .


"LOAD_STACK_GUARD currently supported only for MachO."

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


<s> bool ARMBaseInstrInfo :: isPredicable ( const MachineInstr & MI ) const { if ( ! MI . isPredicable ( ) ) return false ; if ( MI . isBundle ( ) ) return false ; if ( ! isEligibleForITBlock ( & MI ) ) return false ; const ARMFunctionInfo * AFI = MI . getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumb2Function ( ) ) { if ( getSubtarget ( ) . restrictIT ( ) ) return isV8EligibleForIT ( & MI ) ; } else { if ( ( MI . getDesc ( ) . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) return false ; } return true ; } </s>

Return true if the specified instruction can be predicated .


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & , unsigned TCycles , unsigned TExtra , MachineBasicBlock & , unsigned FCycles , unsigned FExtra , BranchProbability Probability ) const { if ( ! TCycles ) return false ; const unsigned ScalingUpFactor = 1024 ; unsigned TUnpredCost = Probability . scale ( TCycles * ScalingUpFactor ) ; unsigned FUnpredCost = Probability . getCompl ( ) . scale ( FCycles * ScalingUpFactor ) ; unsigned UnpredCost = TUnpredCost + FUnpredCost ; UnpredCost += 1 * ScalingUpFactor ; UnpredCost += Subtarget . getMispredictionPenalty ( ) * ScalingUpFactor / 10 ; return ( TCycles + FCycles + TExtra + FExtra ) * ScalingUpFactor <= UnpredCost ; } </s>


<s> MachineInstr * ARMBaseInstrInfo :: commuteInstruction ( MachineInstr * MI , bool NewMI ) const { switch ( MI -> getOpcode ( ) ) { case ARM :: MOVCCr : case ARM :: t2MOVCCr : { unsigned PredReg = 0 ; ARMCC :: CondCodes CC = getInstrPredicate ( MI , PredReg ) ; if ( CC == ARMCC :: AL || PredReg != ARM :: CPSR ) return nullptr ; MI = TargetInstrInfo :: commuteInstruction ( MI , NewMI ) ; if ( ! MI ) return nullptr ; MI -> getOperand ( MI -> findFirstPredOperandIdx ( ) ) . setImm ( ARMCC :: getOppositeCondition ( CC ) ) ; return MI ; } } return TargetInstrInfo :: commuteInstruction ( MI , NewMI ) ; } </s>

This method commutes the operands of the given machine instruction MI .


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & TMBB , unsigned TCycles , unsigned TExtra , MachineBasicBlock & FMBB , unsigned FCycles , unsigned FExtra , const BranchProbability & Probability ) const { if ( ! TCycles || ! FCycles ) return false ; unsigned TUnpredCost = Probability . scale ( TCycles ) ; unsigned FUnpredCost = Probability . getCompl ( ) . scale ( FCycles ) ; unsigned UnpredCost = TUnpredCost + FUnpredCost ; UnpredCost += 1 ; UnpredCost += Subtarget . getMispredictionPenalty ( ) / 10 ; return ( TCycles + FCycles + TExtra + FExtra ) <= UnpredCost ; } </s>


<s>
MachineInstr
*
ARMBaseInstrInfo
::
optimizeSelect
(
MachineInstr
*
MI
,
bool
PreferFalse
)
const
{
assert
(
(
MI
->
getOpcode
(
)
==
ARM
::
MOVCCr
||
MI
->
getOpcode
(
)
==
ARM
::
t2MOVCCr
)
&&
"Unknown select instruction"
)
;
MachineRegisterInfo
&
MRI
=
MI
->
getParent
(
)
->
getParent
(
)
->
getRegInfo
(
)
;
MachineInstr
*
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
2
)
.
getReg
(
)
,
MRI
,
this
)
;
bool
Invert
=
!
DefMI
;
if
(
!
DefMI
)
DefMI
=
canFoldIntoMOVCC
(
MI
->
getOperand
(
1
)
.
getReg
(
)
,
MRI
,
this
)
;
if
(
!
DefMI
)
return
nullptr
;
MachineOperand
FalseReg
=
MI
->
getOperand
(
Invert
2
:
1
)
;
unsigned
DestReg
=
MI
->
getOperand
(
0
)
.
getReg
(
)
;
const
TargetRegisterClass
*
PreviousClass
=
MRI
.
getRegClass
(
FalseReg
.
getReg
(
)
)
;
if
(
!
MRI
.
constrainRegClass
(
DestReg
,
PreviousClass
)
)
return
nullptr
;
MachineInstrBuilder
NewMI
=
BuildMI
(
*
MI
->
getParent
(
)
,
MI
,
MI
->
getDebugLoc
(
)
,
DefMI
->
getDesc
(
)
,
DestReg
)
;
const
MCInstrDesc
&
DefDesc
=
DefMI
->
getDesc
(
)
;
for
(
unsigned
i
=
1
,
e
=
DefDesc
.
getNumOperands
(
)
;
i
!=
e
&&
!
DefDesc
.
OpInfo
[
i
]
.
isPredicate
(
)
;
++
i
)
NewMI
.
addOperand
(
DefMI
->
getOperand
(
i
)
)
;
unsigned
CondCode
=
MI
->
getOperand
(
3
)
.
getImm
(
)
;
if
(
Invert
)
NewMI
.
addImm
(
ARMCC
::
getOppositeCondition
(
ARMCC
::
CondCodes
(
CondCode
)
)
)
;
else
NewMI
.
addImm
(
CondCode
)
;
NewMI
.
addOperand
(
MI
->
getOperand
(
4
)
)
;
if
(
NewMI
->
hasOptionalDef
(
)
)
AddDefaultCC
(
NewMI
)
;
FalseReg
.
setImplicit
(
)
;
NewMI
.
addOperand
(
FalseReg
)
;
NewMI
->
tieOperands
(
0
,
NewMI
->
getNumOperands
(
)
1
)
;
DefMI
->
eraseFromParent
(
)
;
return
NewMI
;
}
</s>


<s> bool ARMBaseInstrInfo :: isPredicable ( MachineInstr * MI ) const { if ( ! MI -> isPredicable ( ) ) return false ; ARMFunctionInfo * AFI = MI -> getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; if ( AFI -> isThumb2Function ( ) ) { if ( getSubtarget ( ) . hasV8Ops ( ) ) return isV8EligibleForIT ( MI ) ; } else { if ( ( MI -> getDesc ( ) . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) return false ; } return true ; } </s>


<s>
void
ARMBaseInstrInfo
::
copyPhysReg
(
MachineBasicBlock
&
MBB
,
MachineBasicBlock
::
iterator
I
,
DebugLoc
DL
,
unsigned
DestReg
,
unsigned
SrcReg
,
bool
KillSrc
)
const
{
bool
GPRDest
=
ARM
::
GPRRegClass
.
contains
(
DestReg
)
;
bool
GPRSrc
=
ARM
::
GPRRegClass
.
contains
(
SrcReg
)
;
if
(
GPRDest
&&
GPRSrc
)
{
AddDefaultCC
(
AddDefaultPred
(
BuildMI
(
MBB
,
I
,
DL
,
get
(
ARM
::
MOVr
)
,
DestReg
)
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
)
)
;
return
;
}
bool
SPRDest
=
ARM
::
SPRRegClass
.
contains
(
DestReg
)
;
bool
SPRSrc
=
ARM
::
SPRRegClass
.
contains
(
SrcReg
)
;
unsigned
Opc
=
0
;
if
(
SPRDest
&&
SPRSrc
)
Opc
=
ARM
::
VMOVS
;
else
if
(
GPRDest
&&
SPRSrc
)
Opc
=
ARM
::
VMOVRS
;
else
if
(
SPRDest
&&
GPRSrc
)
Opc
=
ARM
::
VMOVSR
;
else
if
(
ARM
::
DPRRegClass
.
contains
(
DestReg
,
SrcReg
)
)
Opc
=
ARM
::
VMOVD
;
else
if
(
ARM
::
QPRRegClass
.
contains
(
DestReg
,
SrcReg
)
)
Opc
=
ARM
::
VORRq
;
if
(
Opc
)
{
MachineInstrBuilder
MIB
=
BuildMI
(
MBB
,
I
,
DL
,
get
(
Opc
)
,
DestReg
)
;
MIB
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
if
(
Opc
==
ARM
::
VORRq
)
MIB
.
addReg
(
SrcReg
,
getKillRegState
(
KillSrc
)
)
;
AddDefaultPred
(
MIB
)
;
return
;
}
if
(
ARM
::
QQPRRegClass
.
contains
(
DestReg
,
SrcReg
)
||
ARM
::
QQQQPRRegClass
.
contains
(
DestReg
,
SrcReg
)
)
{
const
TargetRegisterInfo
*
TRI
=
&
getRegisterInfo
(
)
;
assert
(
ARM
::
qsub_0
+
3
==
ARM
::
qsub_3
&&
"Expected contiguous enum."
)
;
unsigned
EndSubReg
=
ARM
::
QQPRRegClass
.
contains
(
DestReg
,
SrcReg
)
ARM
::
qsub_1
:
ARM
::
qsub_3
;
for
(
unsigned
i
=
ARM
::
qsub_0
,
e
=
EndSubReg
+
1
;
i
!=
e
;
++
i
)
{
unsigned
Dst
=
TRI
->
getSubReg
(
DestReg
,
i
)
;
unsigned
Src
=
TRI
->
getSubReg
(
SrcReg
,
i
)
;
MachineInstrBuilder
Mov
=
AddDefaultPred
(
BuildMI
(
MBB
,
I
,
I
->
getDebugLoc
(
)
,
get
(
ARM
::
VORRq
)
)
.
addReg
(
Dst
,
RegState
::
Define
)
.
addReg
(
Src
,
getKillRegState
(
KillSrc
)
)
.
addReg
(
Src
,
getKillRegState
(
KillSrc
)
)
)
;
if
(
i
==
EndSubReg
)
{
Mov
->
addRegisterDefined
(
DestReg
,
TRI
)
;
if
(
KillSrc
)
Mov
->
addRegisterKilled
(
SrcReg
,
TRI
)
;
}
}
return
;
}
llvm_unreachable
(
"Impossible reg-to-reg copy"
)
;
}
</s>

ARM
ARM
ARM::GPRRegClass
ARM::GPRRegClass
ARM::MOVr
ARM::SPRRegClass
ARM::SPRRegClass
0
ARM::VMOVS
ARM::VMOVRS
ARM::VMOVSR
ARM::DPRRegClass
ARM::VMOVD
ARM::QPRRegClass
ARM::VORRq
ARM::VORRq
ARM::QQPRRegClass
ARM::QQQQPRRegClass
ARM::qsub_0
3
ARM::qsub_3
"Expected contiguous enum."
ARM::QQPRRegClass
ARM::qsub_1
ARM::qsub_3
ARM::qsub_0
1
ARM::VORRq
"Impossible reg-to-reg copy"


<s> int ARMBaseInstrInfo :: getInstrLatency ( const InstrItineraryData * ItinData , const MachineInstr * MI , unsigned * PredCost ) const { if ( MI -> isCopyLike ( ) || MI -> isInsertSubreg ( ) || MI -> isRegSequence ( ) || MI -> isImplicitDef ( ) ) return 1 ; if ( ! ItinData || ItinData -> isEmpty ( ) ) return 1 ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; unsigned Class = MCID . getSchedClass ( ) ; unsigned UOps = ItinData -> Itineraries [ Class ] . NumMicroOps ; if ( PredCost && MCID . hasImplicitDefOfPhysReg ( ARM :: CPSR ) ) * PredCost = 1 ; if ( UOps ) return ItinData -> getStageLatency ( Class ) ; return getNumMicroOps ( ItinData , MI ) ; } </s>

Compute the instruction latency of a given instruction .


<s>
unsigned
ARMBaseInstrInfo
::
getNumMicroOps
(
const
InstrItineraryData
*
ItinData
,
const
MachineInstr
*
MI
)
const
{
if
(
!
ItinData
||
ItinData
->
isEmpty
(
)
)
return
1
;
const
MCInstrDesc
&
Desc
=
MI
->
getDesc
(
)
;
unsigned
Class
=
Desc
.
getSchedClass
(
)
;
unsigned
UOps
=
ItinData
->
Itineraries
[
Class
]
.
NumMicroOps
;
if
(
UOps
)
return
UOps
;
unsigned
Opc
=
MI
->
getOpcode
(
)
;
switch
(
Opc
)
{
default
:
llvm_unreachable
(
"Unexpected multi-uops instruction!"
)
;
break
;
case
ARM
::
VLDMQIA
:
case
ARM
::
VSTMQIA
:
return
2
;
case
ARM
::
VLDMDIA
:
case
ARM
::
VLDMDIA_UPD
:
case
ARM
::
VLDMDDB_UPD
:
case
ARM
::
VLDMSIA
:
case
ARM
::
VLDMSIA_UPD
:
case
ARM
::
VLDMSDB_UPD
:
case
ARM
::
VSTMDIA
:
case
ARM
::
VSTMDIA_UPD
:
case
ARM
::
VSTMDDB_UPD
:
case
ARM
::
VSTMSIA
:
case
ARM
::
VSTMSIA_UPD
:
case
ARM
::
VSTMSDB_UPD
:
{
unsigned
NumRegs
=
MI
->
getNumOperands
(
)
Desc
.
getNumOperands
(
)
;
return
(
NumRegs
/
2
)
+
(
NumRegs
%
2
)
+
1
;
}
case
ARM
::
LDMIA_RET
:
case
ARM
::
LDMIA
:
case
ARM
::
LDMDA
:
case
ARM
::
LDMDB
:
case
ARM
::
LDMIB
:
case
ARM
::
LDMIA_UPD
:
case
ARM
::
LDMDA_UPD
:
case
ARM
::
LDMDB_UPD
:
case
ARM
::
LDMIB_UPD
:
case
ARM
::
STMIA
:
case
ARM
::
STMDA
:
case
ARM
::
STMDB
:
case
ARM
::
STMIB
:
case
ARM
::
STMIA_UPD
:
case
ARM
::
STMDA_UPD
:
case
ARM
::
STMDB_UPD
:
case
ARM
::
STMIB_UPD
:
case
ARM
::
tLDMIA
:
case
ARM
::
tLDMIA_UPD
:
case
ARM
::
tSTMIA_UPD
:
case
ARM
::
tPOP_RET
:
case
ARM
::
tPOP
:
case
ARM
::
tPUSH
:
case
ARM
::
t2LDMIA_RET
:
case
ARM
::
t2LDMIA
:
case
ARM
::
t2LDMDB
:
case
ARM
::
t2LDMIA_UPD
:
case
ARM
::
t2LDMDB_UPD
:
case
ARM
::
t2STMIA
:
case
ARM
::
t2STMDB
:
case
ARM
::
t2STMIA_UPD
:
case
ARM
::
t2STMDB_UPD
:
{
unsigned
NumRegs
=
MI
->
getNumOperands
(
)
Desc
.
getNumOperands
(
)
+
1
;
if
(
Subtarget
.
isCortexA8
(
)
)
{
if
(
NumRegs
<
4
)
return
2
;
UOps
=
(
NumRegs
/
2
)
;
if
(
NumRegs
%
2
)
++
UOps
;
return
UOps
;
}
else
if
(
Subtarget
.
isCortexA9
(
)
)
{
UOps
=
(
NumRegs
/
2
)
;
if
(
(
NumRegs
%
2
)
||
!
MI
->
hasOneMemOperand
(
)
||
(
*
MI
->
memoperands_begin
(
)
)
->
getAlignment
(
)
<
8
)
++
UOps
;
return
UOps
;
}
else
{
return
NumRegs
;
}
}
}
}
</s>

Return the number of issue slots required for this MI .


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLD1q64Pseudo : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

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


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlotPostFE ( const MachineInstr * MI , int & FrameIndex ) const { const MachineMemOperand * Dummy ; return MI -> getDesc ( ) . mayLoad ( ) && hasLoadFromStackSlot ( MI , Dummy , FrameIndex ) ; } </s>

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


<s> bool ARMBaseInstrInfo :: isPredicable ( MachineInstr * MI ) const { const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( ! MCID . isPredicable ( ) ) return false ; if ( ( MCID . TSFlags & ARMII :: DomainMask ) == ARMII :: DomainNEON ) { ARMFunctionInfo * AFI = MI -> getParent ( ) -> getParent ( ) -> getInfo < ARMFunctionInfo > ( ) ; return AFI -> isThumb2Function ( ) ; } return true ; } </s>

ARM ARM ARMII::DomainMask ARMII::DomainNEON ARM ARM


<s> bool ARMBaseInstrInfo :: isSchedulingBoundary ( const MachineInstr * MI , const MachineBasicBlock * MBB , const MachineFunction & MF ) const { if ( MI -> isDebugValue ( ) ) return false ; if ( MI -> getDesc ( ) . isTerminator ( ) || MI -> isLabel ( ) ) return true ; MachineBasicBlock :: const_iterator I = MI ; while ( ++ I != MBB -> end ( ) && I -> isDebugValue ( ) ) ; if ( I != MBB -> end ( ) && I -> getOpcode ( ) == ARM :: t2IT ) return true ; if ( MI -> definesRegister ( ARM :: SP ) ) return true ; return false ; } </s>

isSchedulingBoundary - Overrides the isSchedulingBoundary from Codegen/TargetInstrInfo.cpp to make it capable of identifying ENDBR intructions and prevent it from being re-scheduled .


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlot ( const MachineInstr * MI , int & FrameIndex ) const { switch ( MI -> getOpcode ( ) ) { default : break ; case ARM :: STRrs : case ARM :: t2STRs : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isReg ( ) && MI -> getOperand ( 3 ) . isImm ( ) && MI -> getOperand ( 2 ) . getReg ( ) == 0 && MI -> getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: STRi12 : case ARM :: t2STRi12 : case ARM :: tSTRspi : case ARM :: VSTRD : case ARM :: VSTRS : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 2 ) . isImm ( ) && MI -> getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VST1q64Pseudo : if ( MI -> getOperand ( 0 ) . isFI ( ) && MI -> getOperand ( 2 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 0 ) . getIndex ( ) ; return MI -> getOperand ( 2 ) . getReg ( ) ; } break ; case ARM :: VSTMQIA : if ( MI -> getOperand ( 1 ) . isFI ( ) && MI -> getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI -> getOperand ( 1 ) . getIndex ( ) ; return MI -> getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>

isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot , return the virtual or physical register number of the source reg along with the FrameIndex of the loaded stack slot .


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

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


<s> bool ARMBaseInstrInfo :: analyzeCompare ( const MachineInstr & MI , unsigned & SrcReg , unsigned & SrcReg2 , int & CmpMask , int & CmpValue ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: CMPri : case ARM :: t2CMPri : case ARM :: tCMPi8 : SrcReg = MI . getOperand ( 0 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = ~ 0 ; CmpValue = MI . getOperand ( 1 ) . getImm ( ) ; return true ; case ARM :: CMPrr : case ARM :: t2CMPrr : case ARM :: tCMPr : SrcReg = MI . getOperand ( 0 ) . getReg ( ) ; SrcReg2 = MI . getOperand ( 1 ) . getReg ( ) ; CmpMask = ~ 0 ; CmpValue = 0 ; return true ; case ARM :: TSTri : case ARM :: t2TSTri : SrcReg = MI . getOperand ( 0 ) . getReg ( ) ; SrcReg2 = 0 ; CmpMask = MI . getOperand ( 1 ) . getImm ( ) ; CmpValue = 0 ; return true ; } return false ; } </s>

analyzeCompare - For a comparison instruction , return the source registers in SrcReg and SrcReg2 if having two register operands , and the value it compares against in CmpValue .


<s> ScheduleHazardRecognizer * ARMBaseInstrInfo :: CreateTargetPostRAHazardRecognizer ( const InstrItineraryData * II , const ScheduleDAG * DAG ) const { if ( Subtarget . isThumb2 ( ) || Subtarget . hasVFP2Base ( ) ) return ( ScheduleHazardRecognizer * ) new ARMHazardRecognizer ( II , DAG ) ; return TargetInstrInfo :: CreateTargetPostRAHazardRecognizer ( II , DAG ) ; } </s>

Allocate and return a hazard recognizer to use for by non-scheduling passes .


"LOAD_STACK_GUARD currently supported only for MachO."


<s> unsigned ARMBaseInstrInfo :: getInstSizeInBytes ( const MachineInstr & MI ) const { const MachineBasicBlock & MBB = * MI . getParent ( ) ; const MachineFunction * MF = MBB . getParent ( ) ; const MCAsmInfo * MAI = MF -> getTarget ( ) . getMCAsmInfo ( ) ; const MCInstrDesc & MCID = MI . getDesc ( ) ; if ( MCID . getSize ( ) ) return MCID . getSize ( ) ; switch ( MI . getOpcode ( ) ) { default : return 0 ; case TargetOpcode :: BUNDLE : return getInstBundleLength ( MI ) ; case ARM :: MOVi16_ga_pcrel : case ARM :: MOVTi16_ga_pcrel : case ARM :: t2MOVi16_ga_pcrel : case ARM :: t2MOVTi16_ga_pcrel : return 4 ; case ARM :: MOVi32imm : case ARM :: t2MOVi32imm : return 8 ; case ARM :: CONSTPOOL_ENTRY : case ARM :: JUMPTABLE_INSTS : case ARM :: JUMPTABLE_ADDRS : case ARM :: JUMPTABLE_TBB : case ARM :: JUMPTABLE_TBH : return MI . getOperand ( 2 ) . getImm ( ) ; case ARM :: Int_eh_sjlj_longjmp : return 16 ; case ARM :: tInt_eh_sjlj_longjmp : return 10 ; case ARM :: tInt_WIN_eh_sjlj_longjmp : return 12 ; case ARM :: Int_eh_sjlj_setjmp : case ARM :: Int_eh_sjlj_setjmp_nofp : return 20 ; case ARM :: tInt_eh_sjlj_setjmp : case ARM :: t2Int_eh_sjlj_setjmp : case ARM :: t2Int_eh_sjlj_setjmp_nofp : return 12 ; case ARM :: SPACE : return MI . getOperand ( 1 ) . getImm ( ) ; case ARM :: INLINEASM : case ARM :: INLINEASM_BR : { unsigned Size = getInlineAsmLength ( MI . getOperand ( 0 ) . getSymbolName ( ) , * MAI ) ; if ( ! MF -> getInfo < ARMFunctionInfo > ( ) -> isThumbFunction ( ) ) Size = alignTo ( Size , 4 ) ; return Size ; } } } </s>


<s> unsigned ARMBaseInstrInfo :: getNumLDMAddresses ( const MachineInstr & MI ) const { unsigned Size = 0 ; for ( MachineInstr :: mmo_iterator I = MI . memoperands_begin ( ) , E = MI . memoperands_end ( ) ; I != E ; ++ I ) { Size += ( * I ) -> getSize ( ) ; } return std :: min ( Size / 4 , 16U ) ; } </s>

Get the number of addresses by LDM or VLDM or zero for unknown .


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: LDRrs : case ARM :: t2LDRs : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 3 ) . isImm ( ) && MI . getOperand ( 2 ) . getReg ( ) == 0 && MI . getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: LDRi12 : case ARM :: t2LDRi12 : case ARM :: tLDRspi : case ARM :: VLDRD : case ARM :: VLDRS : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDR_P0_off : if ( MI . getOperand ( 0 ) . isFI ( ) && MI . getOperand ( 1 ) . isImm ( ) && MI . getOperand ( 1 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 0 ) . getIndex ( ) ; return ARM :: P0 ; } break ; case ARM :: VLD1q64 : case ARM :: VLD1d8TPseudo : case ARM :: VLD1d16TPseudo : case ARM :: VLD1d32TPseudo : case ARM :: VLD1d64TPseudo : case ARM :: VLD1d8QPseudo : case ARM :: VLD1d16QPseudo : case ARM :: VLD1d32QPseudo : case ARM :: VLD1d64QPseudo : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VLDMQIA : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>


<s> unsigned ARMBaseInstrInfo :: isLoadFromStackSlotPostFE ( const MachineInstr & MI , int & FrameIndex ) const { SmallVector < const MachineMemOperand * , 1 > Accesses ; if ( MI . mayLoad ( ) && hasLoadFromStackSlot ( MI , Accesses ) && Accesses . size ( ) == 1 ) { FrameIndex = cast < FixedStackPseudoSourceValue > ( Accesses . front ( ) -> getPseudoValue ( ) ) -> getFrameIndex ( ) ; return true ; } return false ; } </s>


<s> bool ARMBaseInstrInfo :: isProfitableToIfCvt ( MachineBasicBlock & TBB , unsigned TCycles , unsigned TExtra , MachineBasicBlock & FBB , unsigned FCycles , unsigned FExtra , BranchProbability Probability ) const { if ( ! TCycles ) return false ; if ( Subtarget . isThumb2 ( ) && TBB . getParent ( ) -> getFunction ( ) . hasMinSize ( ) ) { if ( TBB . pred_size ( ) != 1 || FBB . pred_size ( ) != 1 ) return false ; } const unsigned ScalingUpFactor = 1024 ; unsigned PredCost = ( TCycles + FCycles + TExtra + FExtra ) * ScalingUpFactor ; unsigned UnpredCost ; if ( ! Subtarget . hasBranchPredictor ( ) ) { unsigned NotTakenBranchCost = 1 ; unsigned TakenBranchCost = Subtarget . getMispredictionPenalty ( ) ; unsigned TUnpredCycles , FUnpredCycles ; if ( ! FCycles ) { TUnpredCycles = TCycles + NotTakenBranchCost ; FUnpredCycles = TakenBranchCost ; } else { TUnpredCycles = TCycles + TakenBranchCost ; FUnpredCycles = FCycles + NotTakenBranchCost ; PredCost -= 1 * ScalingUpFactor ; } unsigned TUnpredCost = Probability . scale ( TUnpredCycles * ScalingUpFactor ) ; unsigned FUnpredCost = Probability . getCompl ( ) . scale ( FUnpredCycles * ScalingUpFactor ) ; UnpredCost = TUnpredCost + FUnpredCost ; if ( Subtarget . isThumb2 ( ) && TCycles + FCycles > 4 ) { PredCost += ( ( TCycles + FCycles - 4 ) / 4 ) * ScalingUpFactor ; } } else { unsigned TUnpredCost = Probability . scale ( TCycles * ScalingUpFactor ) ; unsigned FUnpredCost = Probability . getCompl ( ) . scale ( FCycles * ScalingUpFactor ) ; UnpredCost = TUnpredCost + FUnpredCost ; UnpredCost += 1 * ScalingUpFactor ; UnpredCost += Subtarget . getMispredictionPenalty ( ) * ScalingUpFactor / 10 ; } return PredCost <= UnpredCost ; } </s>


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlot ( const MachineInstr & MI , int & FrameIndex ) const { switch ( MI . getOpcode ( ) ) { default : break ; case ARM :: STRrs : case ARM :: t2STRs : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isReg ( ) && MI . getOperand ( 3 ) . isImm ( ) && MI . getOperand ( 2 ) . getReg ( ) == 0 && MI . getOperand ( 3 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: STRi12 : case ARM :: t2STRi12 : case ARM :: tSTRspi : case ARM :: VSTRD : case ARM :: VSTRS : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 2 ) . isImm ( ) && MI . getOperand ( 2 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; case ARM :: VSTR_P0_off : if ( MI . getOperand ( 0 ) . isFI ( ) && MI . getOperand ( 1 ) . isImm ( ) && MI . getOperand ( 1 ) . getImm ( ) == 0 ) { FrameIndex = MI . getOperand ( 0 ) . getIndex ( ) ; return ARM :: P0 ; } break ; case ARM :: VST1q64 : case ARM :: VST1d64TPseudo : case ARM :: VST1d64QPseudo : if ( MI . getOperand ( 0 ) . isFI ( ) && MI . getOperand ( 2 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 0 ) . getIndex ( ) ; return MI . getOperand ( 2 ) . getReg ( ) ; } break ; case ARM :: VSTMQIA : if ( MI . getOperand ( 1 ) . isFI ( ) && MI . getOperand ( 0 ) . getSubReg ( ) == 0 ) { FrameIndex = MI . getOperand ( 1 ) . getIndex ( ) ; return MI . getOperand ( 0 ) . getReg ( ) ; } break ; } return 0 ; } </s>


<s> unsigned ARMBaseInstrInfo :: isStoreToStackSlotPostFE ( const MachineInstr & MI , int & FrameIndex ) const { SmallVector < const MachineMemOperand * , 1 > Accesses ; if ( MI . mayStore ( ) && hasStoreToStackSlot ( MI , Accesses ) && Accesses . size ( ) == 1 ) { FrameIndex = cast < FixedStackPseudoSourceValue > ( Accesses . front ( ) -> getPseudoValue ( ) ) -> getFrameIndex ( ) ; return true ; } return false ; } </s>


<s> bool ARMBaseInstrInfo :: shouldSink ( const MachineInstr & MI ) const { if ( isPredicated ( MI ) ) return true ; MachineBasicBlock :: const_iterator Next = & MI ; ++ Next ; unsigned SrcReg , SrcReg2 ; int CmpMask , CmpValue ; bool IsThumb1 ; if ( Next != MI . getParent ( ) -> end ( ) && analyzeCompare ( * Next , SrcReg , SrcReg2 , CmpMask , CmpValue ) && isRedundantFlagInstr ( & * Next , SrcReg , SrcReg2 , CmpValue , & MI , IsThumb1 ) ) return false ; return true ; } </s>

Return true if the instruction should be sunk by MachineSink .


"Pseudo flag setting opcodes only exist in Selection DAG"

"Non-flag-setting Thumb1 mov is v6-only"

"Unsupported register in Thumb1 push/pop"

Perform target-specific instruction verification .