<s> MachineInstr * PrevVCMP = nullptr ; MachineOperand * PrevVCMPResultKiller = nullptr ; for ( MachineInstr & Instr : MBB . instrs ( ) ) { if ( PrevVCMP ) { if ( MachineOperand * MO = Instr . findRegisterUseOperand ( PrevVCMP -> getOperand ( <NUM_LIT> ) . getReg ( ) , true ) ) { PrevVCMPResultKiller = MO ; } } if ( getVPTInstrPredicate ( Instr ) != <STR_LIT> ) continue ; if ( ! IsVCMP ( Instr . getOpcode ( ) ) ) { if ( IsWritingToVCCR ( Instr ) ) PrevVCMP = nullptr ; continue ; } if ( ! PrevVCMP || ! IsVPNOTEquivalent ( Instr , * PrevVCMP ) ) { PrevVCMP = & Instr ; continue ; } Register PrevVCMPResultReg = PrevVCMP -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineInstrBuilder MIBuilder = BuildMI ( MBB , & Instr , Instr . getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . add ( Instr . getOperand ( <NUM_LIT> ) ) . addReg ( PrevVCMPResultReg ) ; addUnpredicatedMveVpredNOp ( MIBuilder ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ;

MIBuilder . getInstr ( ) -> dump ( ) ; dbgs ( ) << <STR_LIT> ;


<s> if ( PrevVCMP ) { if ( MachineOperand * MO = Instr . findRegisterUseOperand ( PrevVCMP -> getOperand ( <NUM_LIT> ) . getReg ( ) , true ) ) { PrevVCMPResultKiller = MO ; } } if ( getVPTInstrPredicate ( Instr ) != <STR_LIT> ) continue ; if ( ! IsVCMP ( Instr . getOpcode ( ) ) ) { if ( IsWritingToVCCR ( Instr ) ) PrevVCMP = nullptr ; continue ; } if ( ! PrevVCMP || ! IsVPNOTEquivalent ( Instr , * PrevVCMP ) ) { PrevVCMP = & Instr ; continue ; } Register PrevVCMPResultReg = PrevVCMP -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineInstrBuilder MIBuilder = BuildMI ( MBB , & Instr , Instr . getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . add ( Instr . getOperand ( <NUM_LIT> ) ) . addReg ( PrevVCMPResultReg ) ; addUnpredicatedMveVpredNOp ( MIBuilder ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; MIBuilder . getInstr ( ) -> dump ( ) ; dbgs ( ) << <STR_LIT> ;


<s> FunctionPass * llvm :: createNEONMoveFixPass ( ) {


<s> FunctionPass * llvm :: createNEONMoveFixPass ( ) { return new NEONMoveFixPass ( ) ;


<s> Domain = DefMI -> second -> getDesc ( ) . TSFlags & <STR_LIT> ; if ( Domain == <STR_LIT> ) Domain = <STR_LIT> ; } if ( Domain & <STR_LIT> ) { unsigned DestReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; DEBUG ( { errs ( ) << <STR_LIT> ; MI -> dump ( ) ; } ) ; AddDefaultPred ( BuildMI ( MBB , * MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , DestReg ) . addReg ( SrcReg ) ) ; MBB . erase ( MI ) ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; DEBUG ( { errs ( ) << <STR_LIT> ; MI -> dump ( ) ; } ) ; Modified = true ; ++ NumVMovs ; } else { assert ( ( Domain & <STR_LIT> ) && <STR_LIT> ) ;


<s> NEONMoveFixPass ( ) : MachineFunctionPass ( ID ) {


<s> const TargetMachine & TM = Fn . getTarget ( ) ; if ( AFI -> isThumb1OnlyFunction ( ) ) return false ; TRI = TM . getRegisterInfo ( ) ;

TII = static_cast < const <ISA_LIT>BaseInstrInfo * > ( TM . getInstrInfo ( ) ) ;


<s> NEONMoveFixPass ( ) : MachineFunctionPass ( & ID ) {


<s> for ( MachineFunction :: iterator MFI = Fn . begin ( ) , E = Fn . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ;


<s> MachineInstr * RegSeq = <NUM_LIT> ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { const MachineOperand & MO = MI -> getOperand ( FirstOpnd + R ) ; assert ( MO . isReg ( ) && MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; unsigned VirtReg = MO . getReg ( ) ; assert ( TargetRegisterInfo :: isVirtualRegister ( VirtReg ) && <STR_LIT> ) ; if ( ! MRI -> hasOneNonDBGUse ( VirtReg ) ) return false ; MachineInstr * UseMI = & * MRI -> use_nodbg_begin ( VirtReg ) ; if ( ! UseMI -> isRegSequence ( ) ) return false ; if ( RegSeq && RegSeq != UseMI ) return false ; unsigned OpIdx = <NUM_LIT> + ( Offset + R * Stride ) * <NUM_LIT> ; if ( UseMI -> getOperand ( OpIdx ) . getReg ( ) != VirtReg ) llvm_unreachable ( <STR_LIT> ) ; unsigned SubIdx = UseMI -> getOperand ( OpIdx + <NUM_LIT> ) . getImm ( ) ; if ( LastSubIdx ) { if ( LastSubIdx != SubIdx - Stride ) return false ; } else { if ( SubIdx != ( <STR_LIT> + Offset ) && SubIdx != ( <STR_LIT> + Offset ) ) return false ; } RegSeq = UseMI ; LastSubIdx = SubIdx ; } if ( NumRegs == <NUM_LIT> ) { unsigned OpIdx = <NUM_LIT> + ( Offset + <NUM_LIT> * Stride ) * <NUM_LIT> ; const MachineOperand & MO = RegSeq -> getOperand ( OpIdx ) ; unsigned VirtReg = MO . getReg ( ) ; MachineInstr * DefMI = MRI -> getVRegDef ( VirtReg ) ; if ( ! DefMI || ! DefMI -> isImplicitDef ( ) ) return false ; } return true ;


<s> case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> :


<s> NEONPreAllocPass ( ) : MachineFunctionPass ( ID ) {


<s> MRI = & MF . getRegInfo ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = MF . begin ( ) , E = MF . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= PreAllocNEONRegisters ( MBB ) ;


<s> bool NEONPreAllocPass :: runOnMachineFunction ( MachineFunction & MF ) { TII = MF . getTarget ( ) . getInstrInfo ( ) ; MRI = & MF . getRegInfo ( ) ; bool Modified = false ; for ( MachineFunction :: iterator MFI = MF . begin ( ) , E = MF . end ( ) ; MFI != E ; ++ MFI ) { MachineBasicBlock & MBB = * MFI ; Modified |= PreAllocNEONRegisters ( MBB ) ; }


<s> AddDefaultPred ( BuildMI ( MBB , MBBI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , MO . getReg ( ) ) . addReg ( VirtReg ) ) ; if ( MO . isKill ( ) ) { MachineInstr * CopyMI = prior ( MBBI ) ; CopyMI -> findRegisterUseOperand ( VirtReg ) -> setIsKill ( ) ; } MO . setIsKill ( ) ; } else if ( MO . isDef ( ) && ! MO . isDead ( ) ) { AddDefaultPred ( BuildMI ( MBB , NextI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , VirtReg ) . addReg ( MO . getReg ( ) ) ) ; } } } return Modified ;


<s> MachineInstr * MI = & * MBBI ; unsigned FirstOpnd , NumRegs ; if ( ! isNEONMultiRegOp ( MI -> getOpcode ( ) , FirstOpnd , NumRegs ) ) continue ; MachineBasicBlock :: iterator NextI = next ( MBBI ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { MachineOperand & MO = MI -> getOperand ( FirstOpnd + R ) ; assert ( MO . isReg ( ) && MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; unsigned VirtReg = MO . getReg ( ) ; assert ( TargetRegisterInfo :: isVirtualRegister ( VirtReg ) && <STR_LIT> ) ; static const unsigned NEONDRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; MO . setReg ( NEONDRegs [ R ] ) ; if ( MO . isUse ( ) ) { AddDefaultPred ( BuildMI ( MBB , MBBI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , MO . getReg ( ) ) . addReg ( VirtReg ) ) ; if ( MO . isKill ( ) ) { MachineInstr * CopyMI = prior ( MBBI ) ; CopyMI -> findRegisterUseOperand ( VirtReg ) -> setIsKill ( ) ; }


<s> bool NEONPreAllocPass :: PreAllocNEONRegisters ( MachineBasicBlock & MBB ) { bool Modified = false ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) , E = MBB . end ( ) ; for ( ; MBBI != E ; ++ MBBI ) { MachineInstr * MI = & * MBBI ; unsigned FirstOpnd , NumRegs ; if ( ! isNEONMultiRegOp ( MI -> getOpcode ( ) , FirstOpnd , NumRegs ) ) continue ; MachineBasicBlock :: iterator NextI = llvm :: next ( MBBI ) ; for ( unsigned R = <NUM_LIT> ; R < NumRegs ; ++ R ) { MachineOperand & MO = MI -> getOperand ( FirstOpnd + R ) ; assert ( MO . isReg ( ) && MO . getSubReg ( ) == <NUM_LIT> && <STR_LIT> ) ; unsigned VirtReg = MO . getReg ( ) ; assert ( TargetRegisterInfo :: isVirtualRegister ( VirtReg ) && <STR_LIT> ) ; static const unsigned NEONDRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; MO . setReg ( NEONDRegs [ R ] ) ; if ( MO . isUse ( ) ) { AddDefaultPred ( BuildMI ( MBB , MBBI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) , MO . getReg ( ) ) . addReg ( VirtReg ) ) ; if ( MO . isKill ( ) ) { MachineInstr * CopyMI = prior ( MBBI ) ; CopyMI -> findRegisterUseOperand ( VirtReg ) -> setIsKill ( ) ; }


<s> case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ; NumRegs = <NUM_LIT> ; Offset = <NUM_LIT> ; Stride = <NUM_LIT> ; return true ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : FirstOpnd = <NUM_LIT> ;


<s> FunctionPass * llvm :: createNEONPreAllocPass ( ) { return new NEONPreAllocPass ( ) ;


<s> NEONPreAllocPass ( ) : MachineFunctionPass ( & ID ) {


<s> static const unsigned NEONDRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; MO . setReg ( NEONDRegs [ Offset + R * Stride ] ) ; if ( MO . isUse ( ) ) { TII -> copyRegToReg ( MBB , MBBI , MO . getReg ( ) , VirtReg , <STR_LIT> , <STR_LIT> ) ; if ( MO . isKill ( ) ) { MachineInstr * CopyMI = prior ( MBBI ) ; CopyMI -> findRegisterUseOperand ( VirtReg ) -> setIsKill ( ) ; } MO . setIsKill ( ) ; } else if ( MO . isDef ( ) && ! MO . isDead ( ) ) { TII -> copyRegToReg ( MBB , NextI , VirtReg , MO . getReg ( ) , <STR_LIT> , <STR_LIT> ) ; }


<s> for ( MachineFunction :: iterator MFI = MF . begin ( ) , E = MF . end ( ) ; MFI != E ; ++ MFI ) {


<s> size_t THMTo<ISA_LIT>Stub :: alignment ( ) const { return <NUM_LIT> ;


<s> return new THMTo<ISA_LIT>Stub ( m_pData , m_Size , fixup_begin ( ) , fixup_end ( ) , m_bUsingThumb2 ) ;


<s> const uint8_t * THMTo<ISA_LIT>Stub :: getContent ( ) const { return reinterpret_cast < const uint8_t * > ( m_pData ) ;


<s> const uint8_t * THMTo<ISA_LIT>Stub :: getContent ( ) const {

return reinterpret_cast < const uint8_t * > ( m_pData ) ;


<s> uint64_t THMTo<ISA_LIT>Stub :: initSymValue ( ) const { return <NUM_LIT> ;


<s> uint64_t THMTo<ISA_LIT>Stub :: initSymValue ( ) const {


<s> switch ( pReloc . type ( ) ) { case llvm :: ELF :: R_<ISA_LIT>_THM_CALL : { uint64_t dest = pTargetSymValue + pReloc . addend ( ) + <NUM_LIT> ; int64_t branch_offset = static_cast < int64_t > ( dest ) - pSource ; if ( m_bUsingThumb2 ) { if ( ( branch_offset > <ISA_LIT>GNULDBackend :: THM2_MAX_FWD_BRANCH_OFFSET ) || ( branch_offset < <ISA_LIT>GNULDBackend :: THM2_MAX_BWD_BRANCH_OFFSET ) ) { result = true ; break ; } } else { if ( ( branch_offset > <ISA_LIT>GNULDBackend :: THM_MAX_FWD_BRANCH_OFFSET ) || ( branch_offset < <ISA_LIT>GNULDBackend :: THM_MAX_BWD_BRANCH_OFFSET ) ) { result = true ; break ; } } break ; }

case llvm :: ELF :: R_<ISA_LIT>_THM_JUMP24 : {


<s> bool result = false ; if ( ( pTargetSymValue & <NUM_LIT> ) == <NUM_LIT> ) { switch ( pReloc . type ( ) ) { case llvm :: ELF :: R_<ISA_LIT>_THM_CALL : { uint64_t dest = pTargetSymValue + pReloc . addend ( ) + <NUM_LIT> ; int64_t branch_offset = static_cast < int64_t > ( dest ) - pSource ; if ( m_bUsingThumb2 ) { if ( ( branch_offset > <ISA_LIT>GNULDBackend :: THM2_MAX_FWD_BRANCH_OFFSET ) || ( branch_offset < <ISA_LIT>GNULDBackend :: THM2_MAX_BWD_BRANCH_OFFSET ) ) { result = true ; break ;


<s> const std :: string & THMTo<ISA_LIT>Stub :: name ( ) const { return m_Name ;


<s> THMTo<ISA_LIT>Stub :: THMTo<ISA_LIT>Stub ( const uint32_t * pData , size_t pSize , const_fixup_iterator pBegin , const_fixup_iterator pEnd , bool pUsingThumb2 ) : m_pData ( pData ) , m_Name ( <STR_LIT> ) , m_Size ( pSize ) , m_bUsingThumb2 ( pUsingThumb2 ) { for ( const_fixup_iterator it = pBegin , ie = pEnd ; it != ie ; ++ it ) addFixup ( * * it ) ;


<s> THMTo<ISA_LIT>Stub :: ~ THMTo<ISA_LIT>Stub ( ) {


<s> size_t THMToTHMStub :: alignment ( ) const { return <NUM_LIT> ;


<s> size_t THMToTHMStub :: alignment ( ) const {


<s> return new THMToTHMStub ( m_pData , m_Size , fixup_begin ( ) , fixup_end ( ) , m_bUsingThumb2 ) ;


<s> uint64_t dest = pTargetSymValue + pReloc . addend ( ) + <NUM_LIT> ; int64_t branch_offset = static_cast < int64_t > ( dest ) - pSource ; if ( m_bUsingThumb2 ) { if ( ( branch_offset > <ISA_LIT>GNULDBackend :: THM2_MAX_FWD_BRANCH_OFFSET ) || ( branch_offset < <ISA_LIT>GNULDBackend :: THM2_MAX_BWD_BRANCH_OFFSET ) ) { result = true ; break ; } } else { if ( ( branch_offset > <ISA_LIT>GNULDBackend :: THM_MAX_FWD_BRANCH_OFFSET ) || ( branch_offset < <ISA_LIT>GNULDBackend :: THM_MAX_BWD_BRANCH_OFFSET ) ) { result = true ; break ; } } break ; } default : break ;


<s> size_t THMToTHMStub :: size ( ) const { return m_Size ;


<s> THMToTHMStub :: THMToTHMStub ( const uint32_t * pData , size_t pSize , const_fixup_iterator pBegin , const_fixup_iterator pEnd , bool pUsingThumb2 ) : m_pData ( pData ) , m_Name ( <STR_LIT> ) , m_Size ( pSize ) , m_bUsingThumb2 ( pUsingThumb2 ) { for ( const_fixup_iterator it = pBegin , ie = pEnd ; it != ie ; ++ it ) addFixup ( * * it ) ;


<s> THMToTHMStub :: ~ THMToTHMStub ( ) {


<s> static void emitSPUpdate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const TargetInstrInfo & TII , DebugLoc dl , const Thumb1RegisterInfo & MRI , int NumBytes ) {

emitThumbRegPlusImmediate ( MBB , MBBI , <STR_LIT> , <STR_LIT> , NumBytes , TII , MRI , dl ) ;


<s> const MachineFrameInfo * FFI = MF . getFrameInfo ( ) ; unsigned CFSize = FFI -> getMaxCallFrameSize ( ) ; if ( CFSize >= ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> / <NUM_LIT> ) return false ;

return ! MF . getFrameInfo ( ) -> hasVarSizedObjects ( ) ;


<s> if ( CFSize >= ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> / <NUM_LIT> ) return false ;


<s> if ( MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . isFI ( ) && isCalleeSavedRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) , CSRegs ) ) return true ; else if ( MI -> getOpcode ( ) == <STR_LIT> ) { for ( int i = <NUM_LIT> , e = MI -> getNumOperands ( ) - <NUM_LIT> ; i != e ; ++ i ) if ( ! isCalleeSavedRegister ( MI -> getOperand ( i ) . getReg ( ) , CSRegs ) ) return false ; return true ; } return false ;


<s> const TargetInstrInfo & TII = * MF . getTarget ( ) . getInstrInfo ( ) ; bool isVarArg = AFI -> getVarArgsRegSaveSize ( ) > <NUM_LIT> ; DebugLoc DL = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; bool NumRegs = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( Reg == <STR_LIT> ) { if ( isVarArg ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; MI = MBB . erase ( MI ) ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ; NumRegs = true ; }

if ( NumRegs ) MBB . insert ( MI , & * MIB ) ;


<s> MachineFunction & MF = * MBB . getParent ( ) ; const TargetInstrInfo & TII = * MF . getTarget ( ) . getInstrInfo ( ) ; if ( MI != MBB . end ( ) ) DL = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; bool isKill = true ; if ( Reg == <STR_LIT> ) { MachineFunction & MF = * MBB . getParent ( ) ; if ( MF . getFrameInfo ( ) -> isReturnAddressTaken ( ) && MF . getRegInfo ( ) . isLiveIn ( Reg ) ) isKill = false ; }


<s> explicit Thumb1FrameInfo ( const <ISA_LIT>Subtarget & sti ) : <ISA_LIT>FrameInfo ( sti ) {


<s> const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr & Old = * I ; DebugLoc dl = Old . getDebugLoc ( ) ; unsigned Amount = TII . getFrameSize ( Old ) ;


<s> emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , <STR_LIT> , NumBytes , TII , MRI , MIFlags ) ;


<s> if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else { unsigned ScratchRegister = <STR_LIT> ; bool HasFP = hasFP ( MF ) ; for ( auto & I : MFI . getCalleeSavedInfo ( ) ) { unsigned Reg = I . getReg ( ) ; if ( is<ISA_LIT>LowRegister ( Reg ) && ! ( HasFP && Reg == FramePtr ) ) { ScratchRegister = Reg ; break ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ;

} else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * MBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ;


<s> const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( ) ; int NumBytes = ( int ) MFI . getStackSize ( ) ; assert ( ( unsigned ) NumBytes >= ArgRegsSaveSize && <STR_LIT> ) ; const MCPhysReg * CSRegs = RegInfo -> getCalleeSavedRegs ( & MF ) ; Register FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize , <STR_LIT> , MachineInstr :: NoFlags ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else { unsigned ScratchRegister = <STR_LIT> ; bool HasFP = hasFP ( MF ) ; for ( auto & I : MFI . getCalleeSavedInfo ( ) ) { unsigned Reg = I . getReg ( ) ; if ( is<ISA_LIT>LowRegister ( Reg ) && ! ( HasFP && Reg == FramePtr ) ) { ScratchRegister = Reg ; break ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ;

if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ;


<s> static const unsigned * findNextOrderedReg ( const unsigned * CurrentReg , const <ISA_LIT>RegSet & EnabledRegs , const unsigned * OrderEnd ) { while ( CurrentReg != OrderEnd && ! EnabledRegs [ * CurrentReg ] ) ++ CurrentReg ; return CurrentReg ;


<s> while ( CurrentReg != OrderEnd && ! EnabledRegs [ * CurrentReg ] ) ++ CurrentReg ; return CurrentReg ;


<s> PopReg = TmpReg = <NUM_LIT> ; for ( auto Reg : GPRsNoLRSP . set_bits ( ) ) { if ( ! UsedRegs . contains ( Reg ) ) { if ( PopFriendly . test ( Reg ) ) { PopReg = Reg ; TmpReg = <NUM_LIT> ; break ; } TmpReg = Reg ; } }


<s> unsigned CFSize = MFI . getMaxCallFrameSize ( ) ;

if ( CFSize >= ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> / <NUM_LIT> ) return false ;


<s> unsigned CFSize = MFI . getMaxCallFrameSize ( ) ; if ( CFSize >= ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> / <NUM_LIT> ) return false ;


<s> static bool isCSRestore ( MachineInstr & MI , const MCPhysReg * CSRegs ) { if ( MI . getOpcode ( ) == <STR_LIT> && MI . getOperand ( <NUM_LIT> ) . isFI ( ) && isCalleeSavedRegister ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) , CSRegs ) ) return true ;

else if ( MI . getOpcode ( ) == <STR_LIT> ) {


<s> bool Thumb1FrameLowering :: needPopSpecialFixUp ( const MachineFunction & MF ) const {

<ISA_LIT>FunctionInfo * AFI = const_cast < MachineFunction * > ( & MF ) -> getInfo < <ISA_LIT>FunctionInfo > ( ) ;


<s> } if ( ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) && ! MF . getRegInfo ( ) . isLiveIn ( Reg ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs [ Reg ] = true ; } for ( unsigned ArgReg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) if ( ! MF . getRegInfo ( ) . isLiveIn ( ArgReg ) ) CopyRegs [ ArgReg ] = true ; const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; if ( ! LoRegsToSave . none ( ) ) { MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; for ( unsigned Reg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) { if ( LoRegsToSave [ Reg ] ) { bool isKill = ! MRI . isLiveIn ( Reg ) ; if ( isKill && ! MRI . isReserved ( Reg ) ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ;

const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ;


<s> MachineBasicBlock * TmpMBB = const_cast < MachineBasicBlock * > ( & MBB ) ; return emitPopSpecialFixUp ( * TmpMBB , false ) ;


<s> if ( ! needPopSpecialFixUp ( * MBB . getParent ( ) ) ) return true ; MachineBasicBlock * TmpMBB = const_cast < MachineBasicBlock * > ( & MBB ) ; return emitPopSpecialFixUp ( * TmpMBB , false ) ;


<s> eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr * Old = I ; DebugLoc dl = Old -> getDebugLoc ( ) ; unsigned Amount = Old -> getOperand ( <NUM_LIT> ) . getImm ( ) ;


<s> MachineInstr * Old = I ; DebugLoc dl = Old -> getDebugLoc ( ) ; unsigned Amount = Old -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Amount != <NUM_LIT> ) { unsigned Align = getStackAlignment ( ) ; Amount = ( Amount + Align - <NUM_LIT> ) / Align * Align ; unsigned Opc = Old -> getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { emitSPUpdate ( MBB , I , TII , dl , * RegInfo , - Amount ) ; } else { assert ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ; emitSPUpdate ( MBB , I , TII , dl , * RegInfo , Amount ) ; } } }


<s> void Thumb1FrameLowering :: emitEpilogue ( MachineFunction & MF , MachineBasicBlock & MBB ) const { MachineBasicBlock :: iterator MBBI = MBB . getFirstTerminator ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; <ISA_LIT>FunctionInfo * AFI = MF . getInfo < <ISA_LIT>FunctionInfo > ( ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( ) ; int NumBytes = ( int ) MFI -> getStackSize ( ) ; assert ( ( unsigned ) NumBytes >= ArgRegsSaveSize && <STR_LIT> ) ; const MCPhysReg * CSRegs = RegInfo -> getCalleeSavedRegs ( & MF ) ; unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize ) ;


<s> AFI -> setDPRCalleeSavedAreaOffset ( DPRCSOffset ) ; NumBytes = DPRCSOffset ; int FramePtrOffsetInBlock = <NUM_LIT> ; unsigned adjustedGPRCS1Size = GPRCS1Size ; if ( tryFoldSPUpdateIntoPushPop ( STI , MF , std :: prev ( MBBI ) , NumBytes ) ) { FramePtrOffsetInBlock = NumBytes ; adjustedGPRCS1Size += NumBytes ; NumBytes = <NUM_LIT> ; } if ( adjustedGPRCS1Size ) { CFAOffset -= adjustedGPRCS1Size ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } for ( std :: vector < CalleeSavedInfo > :: const_iterator I = CSI . begin ( ) , E = CSI . end ( ) ; I != E ; ++ I ) { unsigned Reg = I -> getReg ( ) ; int FI = I -> getFrameIdx ( ) ; switch ( Reg ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( STI . isTargetMachO ( ) ) break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createOffset ( nullptr , MRI -> getDwarfRegNum ( Reg , true ) , MFI -> getObjectOffset ( FI ) ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; break ; } } if ( HasFP ) { FramePtrOffsetInBlock += MFI -> getObjectOffset ( FramePtrSpillFI ) + GPRCS1Size + ArgRegsSaveSize ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , FramePtr ) . addReg ( <STR_LIT> ) . addImm ( FramePtrOffsetInBlock / <NUM_LIT> ) . setMIFlags ( MachineInstr :: FrameSetup ) ) ; if ( FramePtrOffsetInBlock ) { CFAOffset += FramePtrOffsetInBlock ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfa ( nullptr , MRI -> getDwarfRegNum ( FramePtr , true ) , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } else { unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaRegister ( nullptr , MRI -> getDwarfRegNum ( FramePtr , true ) ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } if ( NumBytes > <NUM_LIT> ) AFI -> setShouldRestoreSPFromFP ( true ) ; } if ( NumBytes ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - NumBytes , MachineInstr :: FrameSetup ) ;


<s> if ( CFSize >= ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> / <NUM_LIT> ) return false ;


<s> for ( int i = <NUM_LIT> , e = MI -> getNumOperands ( ) - <NUM_LIT> ; i != e ; ++ i ) if ( ! isCalleeSavedRegister ( MI -> getOperand ( i ) . getReg ( ) , CSRegs ) ) return false ; return true ;


<s> if ( MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . isFI ( ) && isCalleeSavedRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) , CSRegs ) ) return true ; else if ( MI -> getOpcode ( ) == <STR_LIT> ) { for ( int i = <NUM_LIT> , e = MI -> getNumOperands ( ) - <NUM_LIT> ; i != e ; ++ i ) if ( ! isCalleeSavedRegister ( MI -> getOperand ( i ) . getReg ( ) , CSRegs ) ) return false ; return true ; } return false ;


<s> for ( const CalleeSavedInfo & CSI : MF . getFrameInfo ( ) -> getCalleeSavedInfo ( ) ) if ( CSI . getReg ( ) == <STR_LIT> ) return true ;


<s> unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; bool isKill = true ; if ( Reg == <STR_LIT> ) { MachineFunction & MF = * MBB . getParent ( ) ; if ( MF . getFrameInfo ( ) -> isReturnAddressTaken ( ) && MF . getRegInfo ( ) . isLiveIn ( Reg ) ) isKill = false ; } if ( isKill ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ;


<s> Thumb1FrameLowering :: Thumb1FrameLowering ( const <ISA_LIT>Subtarget & sti ) : <ISA_LIT>FrameLowering ( sti ) {


<s> const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr & Old = * I ; DebugLoc dl = Old . getDebugLoc ( ) ; unsigned Amount = TII . getFrameSize ( Old ) ; if ( Amount != <NUM_LIT> ) { Amount = alignTo ( Amount , getStackAlign ( ) ) ; unsigned Opc = Old . getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { emitCallSPUpdate ( MBB , I , TII , dl , * RegInfo , - Amount ) ;


<s> Amount = alignTo ( Amount , getStackAlign ( ) ) ; unsigned Opc = Old . getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { emitCallSPUpdate ( MBB , I , TII , dl , * RegInfo , - Amount ) ; } else {

assert ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ;


<s> MBBI = PrevMBBI ; UseLDRSP = true ; } } } if ( ! DoIt && ! PopReg && ! TemporaryReg ) return false ; assert ( ( PopReg || TemporaryReg ) && <STR_LIT> ) ; if ( UseLDRSP ) { assert ( PopReg && <STR_LIT> ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( PopReg , RegState :: Define ) . addReg ( <STR_LIT> ) . addImm ( MBBI -> getNumExplicitOperands ( ) - <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( PopReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ; MBBI ++ ; emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , ArgRegsSaveSize + <NUM_LIT> , <STR_LIT> , MachineInstr :: NoFlags ) ; return true ; } if ( TemporaryReg ) { assert ( ! PopReg && <STR_LIT> ) ; PopReg = PopFriendly . find_first ( ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( TemporaryReg , RegState :: Define ) . addReg ( PopReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ; } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; bool Popped = false ; for ( auto MO : MBBI -> operands ( ) ) if ( MO . isReg ( ) && ( MO . isImplicit ( ) || MO . isDef ( ) ) && MO . getReg ( ) != <STR_LIT> ) { MIB . add ( MO ) ; if ( ! MO . isImplicit ( ) ) Popped = true ; } if ( ! Popped ) MBB . erase ( MIB . getInstr ( ) ) ; MBB . erase ( MBBI ) ; MBBI = BuildMI ( MBB , MBB . end ( ) , dl , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; } assert ( PopReg && <STR_LIT> ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) . addReg ( PopReg , RegState :: Define ) ;

emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , ArgRegsSaveSize , <STR_LIT> , MachineInstr :: NoFlags ) ;


<s> CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ; HiRegToRestore = findNextOrderedReg ( ++ HiRegToRestore , HiRegsToRestore , AllHighRegsEnd ) ; } } MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; bool NeedsPop = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { CalleeSavedInfo & Info = CSI [ i - <NUM_LIT> ] ; unsigned Reg = Info . getReg ( ) ; if ( ! ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) ) continue ; if ( Reg == <STR_LIT> ) { Info . setRestored ( false ) ; if ( ! MBB . succ_empty ( ) || MI -> getOpcode ( ) == <STR_LIT> || MI -> getOpcode ( ) == <STR_LIT> ) continue ; if ( isVarArg ) continue ; if ( ! STI . hasV5TOps ( ) ) continue ; if ( AFI -> isCmseNSEntryFunction ( ) ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; if ( MI != MBB . end ( ) ) MIB . copyImplicitOps ( * MI ) ; MI = MBB . erase ( MI ) ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ; NeedsPop = true ; } if ( NeedsPop ) MBB . insert ( MI , & * MIB ) ; else MF . DeleteMachineInstr ( MIB ) ; return true ;


<s> unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) { LoRegsToSave [ Reg ] = true ; } else if ( <STR_LIT> . contains ( Reg ) && Reg != <STR_LIT> ) { HiRegsToSave [ Reg ] = true ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) && ! MF . getRegInfo ( ) . isLiveIn ( Reg ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs [ Reg ] = true ; } for ( unsigned ArgReg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) if ( ! MF . getRegInfo ( ) . isLiveIn ( ArgReg ) ) CopyRegs [ ArgReg ] = true ; const MachineRegisterInfo & MRI = MF . getRegInfo ( ) ; if ( ! LoRegsToSave . none ( ) ) { MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; for ( unsigned Reg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) { if ( LoRegsToSave [ Reg ] ) { bool isKill = ! MRI . isLiveIn ( Reg ) ; if ( isKill && ! MRI . isReserved ( Reg ) ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; const unsigned * HiRegToSave = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToSave , AllHighRegsEnd ) ; while ( HiRegToSave != AllHighRegsEnd ) { const unsigned * CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ;

MachineInstrBuilder PushMIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) . setMIFlags ( MachineInstr :: FrameSetup ) ;


<s> if ( NumBytes != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( MBBI , CSRegs ) ) ; if ( ! isCSRestore ( MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( MF . getRegInfo ( ) . isPhysRegUsed ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != MBBI && prior ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) {

MachineBasicBlock :: iterator PMBBI = prior ( MBBI ) ;


<s> void Thumb1FrameLowering :: emitPrologue ( MachineFunction & MF ) const { MachineBasicBlock & MBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; <ISA_LIT>FunctionInfo * AFI = MF . getInfo < <ISA_LIT>FunctionInfo > ( ) ; const Thumb1RegisterInfo * RegInfo = static_cast < const Thumb1RegisterInfo * > ( MF . getTarget ( ) . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( MF . getTarget ( ) . getInstrInfo ( ) ) ; unsigned Align = MF . getTarget ( ) . getFrameLowering ( ) -> getStackAlignment ( ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( Align ) ; unsigned NumBytes = MFI -> getStackSize ( ) ; const std :: vector < CalleeSavedInfo > & CSI = MFI -> getCalleeSavedInfo ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; unsigned BasePtr = RegInfo -> getBaseRegister ( ) ; NumBytes = ( NumBytes + <NUM_LIT> ) & ~ <NUM_LIT> ; MFI -> setStackSize ( NumBytes ) ; unsigned GPRCS1Size = <NUM_LIT> , GPRCS2Size = <NUM_LIT> , DPRCSSize = <NUM_LIT> ; int FramePtrSpillFI = <NUM_LIT> ; if ( ArgRegsSaveSize ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ArgRegsSaveSize , MachineInstr :: FrameSetup ) ; if ( ! AFI -> hasStackFrame ( ) ) {

if ( NumBytes != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - NumBytes , MachineInstr :: FrameSetup ) ;


<s> case <STR_LIT> : if ( Reg == FramePtr ) FramePtrSpillFI = FI ; if ( STI . isTargetIOS ( ) ) { AFI -> addGPRCalleeSavedArea2Frame ( FI ) ; GPRCS2Size += <NUM_LIT> ; } else { AFI -> addGPRCalleeSavedArea1Frame ( FI ) ; GPRCS1Size += <NUM_LIT> ; } break ; default : AFI -> addDPRCalleeSavedAreaFrame ( FI ) ; DPRCSSize += <NUM_LIT> ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { ++ MBBI ; if ( MBBI != MBB . end ( ) ) dl = MBBI -> getDebugLoc ( ) ; } unsigned DPRCSOffset = NumBytes - ( GPRCS1Size + GPRCS2Size + DPRCSSize ) ; unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize ; unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size ; bool HasFP = hasFP ( MF ) ; if ( HasFP ) AFI -> setFramePtrSpillOffset ( MFI -> getObjectOffset ( FramePtrSpillFI ) + NumBytes ) ; AFI -> setGPRCalleeSavedArea1Offset ( GPRCS1Offset ) ; AFI -> setGPRCalleeSavedArea2Offset ( GPRCS2Offset ) ; AFI -> setDPRCalleeSavedAreaOffset ( DPRCSOffset ) ; NumBytes = DPRCSOffset ; if ( HasFP ) { AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , FramePtr ) . addFrameIndex ( FramePtrSpillFI ) . addImm ( <NUM_LIT> ) . setMIFlags ( MachineInstr :: FrameSetup ) ) ; if ( NumBytes > <NUM_LIT> ) AFI -> setShouldRestoreSPFromFP ( true ) ; } if ( NumBytes ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - NumBytes , MachineInstr :: FrameSetup ) ; if ( STI . isTargetELF ( ) && HasFP ) MFI -> setOffsetAdjustment ( MFI -> getOffsetAdjustment ( ) - AFI -> getFramePtrSpillOffset ( ) ) ; AFI -> setGPRCalleeSavedArea1Size ( GPRCS1Size ) ; AFI -> setGPRCalleeSavedArea2Size ( GPRCS2Size ) ; AFI -> setDPRCalleeSavedAreaSize ( DPRCSSize ) ;

if ( RegInfo -> needsStackRealignment ( MF ) ) report_fatal_error ( <STR_LIT> ) ;


<s> unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( Reg == <STR_LIT> ) { if ( isVarArg ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; MIB . copyImplicitOps ( & * MI ) ; MI = MBB . erase ( MI ) ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ;


<s> explicit Thumb1FrameLowering ( const <ISA_LIT>Subtarget & sti ) : <ISA_LIT>FrameLowering ( sti ) {


<s> static void findTemporariesForLR ( const BitVector & GPRsNoLRSP , const BitVector & PopFriendly , const LivePhysRegs & UsedRegs , unsigned & PopReg , unsigned & TmpReg , MachineRegisterInfo & MRI ) { PopReg = TmpReg = <NUM_LIT> ;

for ( auto Reg : GPRsNoLRSP . set_bits ( ) ) {


<s> const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr & Old = * I ; DebugLoc dl = Old . getDebugLoc ( ) ; unsigned Amount = TII . getFrameSize ( Old ) ; if ( Amount != <NUM_LIT> ) { Amount = alignTo ( Amount , getStackAlignment ( ) ) ; unsigned Opc = Old . getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) {

emitSPUpdate ( MBB , I , TII , dl , * RegInfo , - Amount ) ;


<s> if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr & Old = * I ; DebugLoc dl = Old . getDebugLoc ( ) ; unsigned Amount = TII . getFrameSize ( Old ) ; if ( Amount != <NUM_LIT> ) { Amount = alignTo ( Amount , getStackAlignment ( ) ) ; unsigned Opc = Old . getOpcode ( ) ; if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) { emitSPUpdate ( MBB , I , TII , dl , * RegInfo , - Amount ) ; } else { assert ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ; emitSPUpdate ( MBB , I , TII , dl , * RegInfo , Amount ) ; }


<s> if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ;


<s> emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , <STR_LIT> , NumBytes , TII , MRI , MIFlags ) ;


<s> static void emitSPUpdate ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator & MBBI , const TargetInstrInfo & TII , const DebugLoc & dl , const ThumbRegisterInfo & MRI , int NumBytes , unsigned MIFlags = MachineInstr :: NoFlags ) { emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , <STR_LIT> , NumBytes , TII , MRI , MIFlags ) ;


<s> bool enableShrinkWrapping ( const MachineFunction & MF ) const override { return false ;


<s> static bool isCSRestore ( MachineInstr & MI , const MCPhysReg * CSRegs ) { if ( MI . getOpcode ( ) == <STR_LIT> && MI . getOperand ( <NUM_LIT> ) . isFI ( ) && isCalleeSavedRegister ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) , CSRegs ) ) return true ; else if ( MI . getOpcode ( ) == <STR_LIT> ) { return true ; } else if ( MI . getOpcode ( ) == <STR_LIT> ) { unsigned Dst = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Src = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; return ( ( <STR_LIT> . contains ( Src ) || Src == <STR_LIT> ) && <STR_LIT> . contains ( Dst ) ) ;


<s> unsigned Dst = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Src = MI . getOperand ( <NUM_LIT> ) . getReg ( ) ; return ( ( <STR_LIT> . contains ( Src ) || Src == <STR_LIT> ) && <STR_LIT> . contains ( Dst ) ) ; } return false ;


<s> <ISA_LIT>RegSet CopyRegs ; for ( CalleeSavedInfo I : CSI ) { unsigned Reg = I . getReg ( ) ; if ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) { LoRegsToRestore [ Reg ] = true ; } else if ( <STR_LIT> . contains ( Reg ) && Reg != <STR_LIT> ) { HiRegsToRestore [ Reg ] = true ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( ( <STR_LIT> . contains ( Reg ) ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs [ Reg ] = true ; } auto Terminator = MBB . getFirstTerminator ( ) ; if ( Terminator != MBB . end ( ) && Terminator -> getOpcode ( ) == <STR_LIT> ) { CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; for ( auto Op : Terminator -> implicit_operands ( ) ) { if ( Op . isReg ( ) ) CopyRegs [ Op . getReg ( ) ] = false ; } } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; auto HiRegToRestore = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToRestore , AllHighRegsEnd ) ; while ( HiRegToRestore != AllHighRegsEnd ) { assert ( ! CopyRegs . none ( ) ) ; auto CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PopMIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; while ( HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { PopMIB . addReg ( * CopyReg , RegState :: Define ) ; BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * HiRegToRestore , RegState :: Define ) . addReg ( * CopyReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ; CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ; HiRegToRestore = findNextOrderedReg ( ++ HiRegToRestore , HiRegsToRestore , AllHighRegsEnd ) ; } } MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; bool NeedsPop = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { CalleeSavedInfo & Info = CSI [ i - <NUM_LIT> ] ;


<s> MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; const unsigned * HiRegToSave = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToSave , AllHighRegsEnd ) ; while ( HiRegToSave != AllHighRegsEnd ) { const unsigned * CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PushMIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; SmallVector < unsigned , <NUM_LIT> > RegsToPush ; while ( HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { if ( HiRegsToSave [ * HiRegToSave ] ) { bool isKill = ! MRI . isLiveIn ( * HiRegToSave ) ; if ( isKill && ! MRI . isReserved ( * HiRegToSave ) ) MBB . addLiveIn ( * HiRegToSave ) ; BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * CopyReg , RegState :: Define ) . addReg ( * HiRegToSave , getKillRegState ( isKill ) ) . add ( predOps ( <STR_LIT> ) ) ; RegsToPush . push_back ( * CopyReg ) ;

CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ;


<s> const TargetInstrInfo & TII = * STI . getInstrInfo ( ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; auto MBBI = MBB . getFirstTerminator ( ) ; bool CanRestoreDirectly = STI . hasV5TOps ( ) && ! ArgRegsSaveSize ; if ( CanRestoreDirectly ) { if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) != <STR_LIT> ) CanRestoreDirectly = ( MBBI -> getOpcode ( ) == <STR_LIT> || MBBI -> getOpcode ( ) == <STR_LIT> ) ; else { auto MBBI_prev = MBBI ; MBBI_prev -- ; assert ( MBBI_prev -> getOpcode ( ) == <STR_LIT> ) ; assert ( MBB . succ_size ( ) == <NUM_LIT> ) ; if ( ( * MBB . succ_begin ( ) ) -> begin ( ) -> getOpcode ( ) == <STR_LIT> ) MBBI = MBBI_prev ; else CanRestoreDirectly = false ; } } if ( CanRestoreDirectly ) { if ( ! DoIt || MBBI -> getOpcode ( ) == <STR_LIT> ) return true ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; for ( auto MO : MBBI -> operands ( ) ) if ( MO . isReg ( ) && ( MO . isImplicit ( ) || MO . isDef ( ) ) ) MIB . add ( MO ) ; MIB . addReg ( <STR_LIT> , RegState :: Define ) ; MBB . erase ( MBBI ) ; return true ; } LivePhysRegs UsedRegs ( STI . getRegisterInfo ( ) ) ; UsedRegs . addLiveOuts ( MBB ) ; const TargetRegisterInfo * TRI = STI . getRegisterInfo ( ) ; const MCPhysReg * CSRegs = TRI -> getCalleeSavedRegs ( & MF ) ; for ( unsigned i = <NUM_LIT> ; CSRegs [ i ] ; ++ i ) UsedRegs . addReg ( CSRegs [ i ] ) ; DebugLoc dl = DebugLoc ( ) ; if ( MBBI != MBB . end ( ) ) { dl = MBBI -> getDebugLoc ( ) ; auto InstUpToMBBI = MBB . end ( ) ; while ( InstUpToMBBI != MBBI ) UsedRegs . stepBackward ( * -- InstUpToMBBI ) ; } unsigned PopReg = <NUM_LIT> ;


<s> while ( CurrentReg != OrderEnd && ! EnabledRegs . count ( * CurrentReg ) ) ++ CurrentReg ;


<s> } else if ( <STR_LIT> . contains ( Reg ) && Reg != <STR_LIT> ) { HiRegsToRestore . insert ( Reg ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( ( <STR_LIT> . contains ( Reg ) ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs . insert ( Reg ) ; } auto Terminator = MBB . getFirstTerminator ( ) ; if ( Terminator != MBB . end ( ) && Terminator -> getOpcode ( ) == <STR_LIT> ) { CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; for ( auto Op : Terminator -> implicit_operands ( ) ) { if ( Op . isReg ( ) ) CopyRegs . erase ( Op . getReg ( ) ) ; } } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; auto HiRegToRestore = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToRestore , AllHighRegsEnd ) ; while ( HiRegToRestore != AllHighRegsEnd ) { assert ( ! CopyRegs . empty ( ) ) ; auto CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PopMIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; while ( HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { PopMIB . addReg ( * CopyReg , RegState :: Define ) ; BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * HiRegToRestore , RegState :: Define ) . addReg ( * CopyReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ; CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ; HiRegToRestore = findNextOrderedReg ( ++ HiRegToRestore , HiRegsToRestore , AllHighRegsEnd ) ; } } MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; bool NeedsPop = false ;

for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) {


<s> if ( LoRegsToSave . count ( Reg ) ) { bool isKill = ! MF . getRegInfo ( ) . isLiveIn ( Reg ) ; if ( isKill ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; const unsigned * HiRegToSave = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToSave , AllHighRegsEnd ) ; while ( HiRegToSave != AllHighRegsEnd ) { const unsigned * CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PushMIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; SmallVector < unsigned , <NUM_LIT> > RegsToPush ; while ( HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { if ( HiRegsToSave . count ( * HiRegToSave ) ) { bool isKill = ! MF . getRegInfo ( ) . isLiveIn ( * HiRegToSave ) ; if ( isKill ) MBB . addLiveIn ( * HiRegToSave ) ;

BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * CopyReg , RegState :: Define ) . addReg ( * HiRegToSave , getKillRegState ( isKill ) ) . add ( predOps ( <STR_LIT> ) ) ;


<s> MachineBasicBlock :: iterator Thumb1FrameLowering :: eliminateCallFramePseudoInstr ( MachineFunction & MF , MachineBasicBlock & MBB , MachineBasicBlock :: iterator I ) const { const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; if ( ! hasReservedCallFrame ( MF ) ) { MachineInstr & Old = * I ; DebugLoc dl = Old . getDebugLoc ( ) ; unsigned Amount = Old . getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Amount != <NUM_LIT> ) { unsigned Align = getStackAlignment ( ) ; Amount = ( Amount + Align - <NUM_LIT> ) / Align * Align ; unsigned Opc = Old . getOpcode ( ) ;

if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) {


<s> unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } } if ( needPopSpecialFixUp ( MF ) ) {

bool Done = emitPopSpecialFixUp ( MBB , true ) ;


<s> if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes ) ;

} else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ;


<s> break ; } TemporaryReg = Register ; } } if ( ! DoIt && ! PopReg && ! TemporaryReg ) return false ; assert ( ( PopReg || TemporaryReg ) && <STR_LIT> ) ; if ( TemporaryReg ) { assert ( ! PopReg && <STR_LIT> ) ; PopReg = PopFriendly . find_first ( ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( TemporaryReg , RegState :: Define ) . addReg ( PopReg , RegState :: Kill ) ) ; } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { MachineInstrBuilder MIB = AddDefaultPred ( BuildMI ( MBB , MBBI , MBBI -> getDebugLoc ( ) , TII . get ( <STR_LIT> ) ) ) ; bool Popped = false ; for ( auto MO : MBBI -> operands ( ) ) if ( MO . isReg ( ) && ( MO . isImplicit ( ) || MO . isDef ( ) ) && MO . getReg ( ) != <STR_LIT> ) { MIB . addOperand ( MO ) ; if ( ! MO . isImplicit ( ) ) Popped = true ; } if ( ! Popped ) MBB . erase ( MIB . getInstr ( ) ) ; MBB . erase ( MBBI ) ; MBBI = AddDefaultPred ( BuildMI ( MBB , MBB . end ( ) , dl , TII . get ( <STR_LIT> ) ) ) ; } assert ( PopReg && <STR_LIT> ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) ) . addReg ( PopReg , RegState :: Define ) ; emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , ArgRegsSaveSize ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( PopReg , RegState :: Kill ) ) ; if ( TemporaryReg ) AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( PopReg , RegState :: Define ) . addReg ( TemporaryReg , RegState :: Kill ) ) ;


<s> } auto Terminator = MBB . getFirstTerminator ( ) ; if ( Terminator != MBB . end ( ) && Terminator -> getOpcode ( ) == <STR_LIT> ) { CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; CopyRegs . insert ( <STR_LIT> ) ; for ( auto Op : Terminator -> implicit_operands ( ) ) { if ( Op . isReg ( ) ) CopyRegs . erase ( Op . getReg ( ) ) ; } } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; auto HiRegToRestore = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToRestore , AllHighRegsEnd ) ; while ( HiRegToRestore != AllHighRegsEnd ) { assert ( ! CopyRegs . empty ( ) ) ; auto CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PopMIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( PopMIB ) ; while ( HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { PopMIB . addReg ( * CopyReg , RegState :: Define ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; MIB . addReg ( * HiRegToRestore , RegState :: Define ) ; MIB . addReg ( * CopyReg , RegState :: Kill ) ; AddDefaultPred ( MIB ) ; CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ; HiRegToRestore = findNextOrderedReg ( ++ HiRegToRestore , HiRegsToRestore , AllHighRegsEnd ) ; } } MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; bool NeedsPop = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( ! ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) ) continue ; if ( Reg == <STR_LIT> ) { if ( MBB . succ_empty ( ) ) { if ( isVarArg ) continue ; if ( ! STI . hasV5TOps ( ) ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; if ( MI != MBB . end ( ) ) MIB . copyImplicitOps ( * MI ) ; MI = MBB . erase ( MI ) ; } else continue ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ;


<s> } else if ( <STR_LIT> . contains ( Reg ) && Reg != <STR_LIT> ) { HiRegsToSave . insert ( Reg ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) && ! MF . getRegInfo ( ) . isLiveIn ( Reg ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs . insert ( Reg ) ; } for ( unsigned ArgReg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) if ( ! MF . getRegInfo ( ) . isLiveIn ( ArgReg ) ) CopyRegs . insert ( ArgReg ) ; if ( ! LoRegsToSave . empty ( ) ) { MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; for ( unsigned Reg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) { if ( LoRegsToSave . count ( Reg ) ) { bool isKill = ! MF . getRegInfo ( ) . isLiveIn ( Reg ) ; if ( isKill ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; const unsigned * HiRegToSave = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToSave , AllHighRegsEnd ) ; while ( HiRegToSave != AllHighRegsEnd ) { const unsigned * CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PushMIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( PushMIB ) ; SmallVector < unsigned , <NUM_LIT> > RegsToPush ; while ( HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { if ( HiRegsToSave . count ( * HiRegToSave ) ) {

bool isKill = ! MF . getRegInfo ( ) . isLiveIn ( * HiRegToSave ) ;


<s> do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( MBBI , CSRegs ) ) ; if ( ! isCSRestore ( MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( MF . getRegInfo ( ) . isPhysRegUsed ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , PMBBI , NumBytes ) ) emitSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } } if ( ArgRegsSaveSize ) {


<s> NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( MF . getRegInfo ( ) . isPhysRegUsed ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , PMBBI , NumBytes ) ) emitSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } } if ( ArgRegsSaveSize ) {


<s> void Thumb1FrameLowering :: emitPrologue ( MachineFunction & MF ) const { MachineBasicBlock & MBB = MF . front ( ) ; MachineBasicBlock :: iterator MBBI = MBB . begin ( ) ; MachineFrameInfo * MFI = MF . getFrameInfo ( ) ; <ISA_LIT>FunctionInfo * AFI = MF . getInfo < <ISA_LIT>FunctionInfo > ( ) ; MachineModuleInfo & MMI = MF . getMMI ( ) ; const MCRegisterInfo * MRI = MMI . getContext ( ) . getRegisterInfo ( ) ; const Thumb1RegisterInfo * RegInfo = static_cast < const Thumb1RegisterInfo * > ( MF . getTarget ( ) . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( MF . getTarget ( ) . getInstrInfo ( ) ) ; unsigned Align = MF . getTarget ( ) . getFrameLowering ( ) -> getStackAlignment ( ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( Align ) ; unsigned NumBytes = MFI -> getStackSize ( ) ; assert ( NumBytes >= ArgRegsSaveSize && <STR_LIT> ) ; const std :: vector < CalleeSavedInfo > & CSI = MFI -> getCalleeSavedInfo ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; unsigned BasePtr = RegInfo -> getBaseRegister ( ) ; int CFAOffset = <NUM_LIT> ; NumBytes = ( NumBytes + <NUM_LIT> ) & ~ <NUM_LIT> ; MFI -> setStackSize ( NumBytes ) ; unsigned GPRCS1Size = <NUM_LIT> , GPRCS2Size = <NUM_LIT> , DPRCSSize = <NUM_LIT> ; int FramePtrSpillFI = <NUM_LIT> ; if ( ArgRegsSaveSize ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ArgRegsSaveSize , MachineInstr :: FrameSetup ) ; CFAOffset -= ArgRegsSaveSize ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) ; } if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ( NumBytes - ArgRegsSaveSize ) , MachineInstr :: FrameSetup ) ; CFAOffset -= NumBytes - ArgRegsSaveSize ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) ; } return ;


<s> const TargetRegisterInfo & TRI = * STI . getRegisterInfo ( ) ; LivePhysRegs UsedRegs ( TRI ) ; UsedRegs . addLiveOuts ( MBB ) ; const MCPhysReg * CSRegs = TRI . getCalleeSavedRegs ( & MF ) ; for ( unsigned i = <NUM_LIT> ; CSRegs [ i ] ; ++ i ) UsedRegs . addReg ( CSRegs [ i ] ) ; DebugLoc dl = DebugLoc ( ) ; if ( MBBI != MBB . end ( ) ) { dl = MBBI -> getDebugLoc ( ) ; auto InstUpToMBBI = MBB . end ( ) ; while ( InstUpToMBBI != MBBI ) UsedRegs . stepBackward ( * -- InstUpToMBBI ) ; } unsigned PopReg = <NUM_LIT> ; unsigned TemporaryReg = <NUM_LIT> ; BitVector PopFriendly = TRI . getAllocatableSet ( MF , TRI . getRegClass ( <STR_LIT> ) ) ; if ( STI . useR7AsFramePointer ( ) ) PopFriendly . set ( <STR_LIT> ) ; assert ( PopFriendly . any ( ) && <STR_LIT> ) ; BitVector GPRsNoLRSP = TRI . getAllocatableSet ( MF , TRI . getRegClass ( <STR_LIT> ) ) ; GPRsNoLRSP |= PopFriendly ; GPRsNoLRSP . reset ( <STR_LIT> ) ; GPRsNoLRSP . reset ( <STR_LIT> ) ; GPRsNoLRSP . reset ( <STR_LIT> ) ; findTemporariesForLR ( GPRsNoLRSP , PopFriendly , UsedRegs , PopReg , TemporaryReg ) ; bool UseLDRSP = false ; if ( ! PopReg && MBBI != MBB . begin ( ) ) { auto PrevMBBI = MBBI ; PrevMBBI -- ; if ( PrevMBBI -> getOpcode ( ) == <STR_LIT> ) { UsedRegs . stepBackward ( * PrevMBBI ) ; findTemporariesForLR ( GPRsNoLRSP , PopFriendly , UsedRegs , PopReg , TemporaryReg ) ; if ( PopReg ) { MBBI = PrevMBBI ; UseLDRSP = true ; } } } if ( ! DoIt && ! PopReg && ! TemporaryReg ) return false ; assert ( ( PopReg || TemporaryReg ) && <STR_LIT> ) ; if ( UseLDRSP ) { assert ( PopReg && <STR_LIT> ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( PopReg , RegState :: Define ) . addReg ( <STR_LIT> ) . addImm ( MBBI -> getNumExplicitOperands ( ) - <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( PopReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ;


<s> unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ( NumBytes - ArgRegsSaveSize ) , MachineInstr :: FrameSetup ) ; CFAOffset -= NumBytes - ArgRegsSaveSize ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } return ; } for ( unsigned i = <NUM_LIT> , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; switch ( Reg ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( STI . isTargetMachO ( ) ) { GPRCS2Size += <NUM_LIT> ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( Reg == FramePtr ) FramePtrSpillFI = FI ; GPRCS1Size += <NUM_LIT> ; break ; default : DPRCSSize += <NUM_LIT> ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { ++ MBBI ; if ( MBBI != MBB . end ( ) ) dl = MBBI -> getDebugLoc ( ) ; } unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize - ( GPRCS1Size + GPRCS2Size + DPRCSSize ) ; unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize ; unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size ; bool HasFP = hasFP ( MF ) ; if ( HasFP ) AFI -> setFramePtrSpillOffset ( MFI -> getObjectOffset ( FramePtrSpillFI ) + NumBytes ) ; AFI -> setGPRCalleeSavedArea1Offset ( GPRCS1Offset ) ; AFI -> setGPRCalleeSavedArea2Offset ( GPRCS2Offset ) ; AFI -> setDPRCalleeSavedAreaOffset ( DPRCSOffset ) ; NumBytes = DPRCSOffset ; int FramePtrOffsetInBlock = <NUM_LIT> ; unsigned adjustedGPRCS1Size = GPRCS1Size ; if ( tryFoldSPUpdateIntoPushPop ( STI , MF , std :: prev ( MBBI ) , NumBytes ) ) { FramePtrOffsetInBlock = NumBytes ; adjustedGPRCS1Size += NumBytes ; NumBytes = <NUM_LIT> ; } if ( adjustedGPRCS1Size ) { CFAOffset -= adjustedGPRCS1Size ;


<s> MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; bool NumRegs = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( Reg == <STR_LIT> ) { if ( isVarArg ) continue ; if ( STI . hasV4TOps ( ) && ! STI . hasV5TOps ( ) ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; MIB . copyImplicitOps ( & * MI ) ; MI = MBB . erase ( MI ) ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ; NumRegs = true ; } if ( NumRegs ) MBB . insert ( MI , & * MIB ) ; else MF . DeleteMachineInstr ( MIB ) ; return true ;


<s> bool NumRegs = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( Reg == <STR_LIT> ) { if ( isVarArg ) continue ; if ( STI . hasV4TOps ( ) && ! STI . hasV5TOps ( ) ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; MIB . copyImplicitOps ( & * MI ) ; MI = MBB . erase ( MI ) ; } MIB . addReg ( Reg , getDefRegState ( true ) ) ; NumRegs = true ;


<s> if ( MI != MBB . end ( ) ) DL = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) {

unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ;


<s> if ( Reg == <STR_LIT> ) { MachineFunction & MF = * MBB . getParent ( ) ; if ( MF . getFrameInfo ( ) -> isReturnAddressTaken ( ) && MF . getRegInfo ( ) . isLiveIn ( Reg ) ) isKill = false ; } if ( isKill ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ;


<s> const MCPhysReg * CSRegs = RegInfo -> getCalleeSavedRegs ( ) ; unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( MBBI , CSRegs ) ) ; if ( ! isCSRestore ( MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( MF . getRegInfo ( ) . isPhysRegUsed ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) {

MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ;


<s> for ( unsigned i = <NUM_LIT> , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; switch ( Reg ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( Reg == FramePtr ) FramePtrSpillFI = FI ; AFI -> addGPRCalleeSavedArea1Frame ( FI ) ; GPRCS1Size += <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( Reg == FramePtr ) FramePtrSpillFI = FI ; if ( STI . isTargetIOS ( ) ) { AFI -> addGPRCalleeSavedArea2Frame ( FI ) ; GPRCS2Size += <NUM_LIT> ; } else { AFI -> addGPRCalleeSavedArea1Frame ( FI ) ; GPRCS1Size += <NUM_LIT> ; } break ; default : AFI -> addDPRCalleeSavedAreaFrame ( FI ) ; DPRCSSize += <NUM_LIT> ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { ++ MBBI ; if ( MBBI != MBB . end ( ) ) dl = MBBI -> getDebugLoc ( ) ; } unsigned DPRCSOffset = NumBytes - ( GPRCS1Size + GPRCS2Size + DPRCSSize ) ; unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize ; unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size ; AFI -> setFramePtrSpillOffset ( MFI -> getObjectOffset ( FramePtrSpillFI ) + NumBytes ) ; AFI -> setGPRCalleeSavedArea1Offset ( GPRCS1Offset ) ; AFI -> setGPRCalleeSavedArea2Offset ( GPRCS2Offset ) ; AFI -> setDPRCalleeSavedAreaOffset ( DPRCSOffset ) ; NumBytes = DPRCSOffset ; if ( hasFP ( MF ) ) { AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , FramePtr ) . addFrameIndex ( FramePtrSpillFI ) . addImm ( <NUM_LIT> ) . setMIFlags ( MachineInstr :: FrameSetup ) ) ; if ( NumBytes > <NUM_LIT> ) AFI -> setShouldRestoreSPFromFP ( true ) ; }

if ( NumBytes ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - NumBytes , MachineInstr :: FrameSetup ) ;


<s> while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else { unsigned ScratchRegister = <STR_LIT> ; bool HasFP = hasFP ( MF ) ; for ( auto & I : MFI . getCalleeSavedInfo ( ) ) { Register Reg = I . getReg ( ) ; if ( is<ISA_LIT>LowRegister ( Reg ) && ! ( HasFP && Reg == FramePtr ) ) { ScratchRegister = Reg ; break ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * MBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ; } }


<s> MachineBasicBlock :: iterator MBBI = MBB . getFirstTerminator ( ) ; DebugLoc dl = MBBI != MBB . end ( ) ? MBBI -> getDebugLoc ( ) : DebugLoc ( ) ; MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; <ISA_LIT>FunctionInfo * AFI = MF . getInfo < <ISA_LIT>FunctionInfo > ( ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( ) ; int NumBytes = ( int ) MFI . getStackSize ( ) ; assert ( ( unsigned ) NumBytes >= ArgRegsSaveSize && <STR_LIT> ) ; const MCPhysReg * CSRegs = RegInfo -> getCalleeSavedRegs ( & MF ) ; Register FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize , <STR_LIT> , MachineInstr :: NoFlags ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else {


<s> <ISA_LIT>RegSet CopyRegs ; for ( CalleeSavedInfo I : CSI ) { Register Reg = I . getReg ( ) ; if ( <STR_LIT> . contains ( Reg ) || Reg == <STR_LIT> ) { LoRegsToRestore [ Reg ] = true ; } else if ( <STR_LIT> . contains ( Reg ) && Reg != <STR_LIT> ) { HiRegsToRestore [ Reg ] = true ; } else { llvm_unreachable ( <STR_LIT> ) ; } if ( ( <STR_LIT> . contains ( Reg ) ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs [ Reg ] = true ; } auto Terminator = MBB . getFirstTerminator ( ) ; if ( Terminator != MBB . end ( ) && Terminator -> getOpcode ( ) == <STR_LIT> ) { CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; for ( auto Op : Terminator -> implicit_operands ( ) ) { if ( Op . isReg ( ) ) CopyRegs [ Op . getReg ( ) ] = false ; } } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; auto HiRegToRestore = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToRestore , AllHighRegsEnd ) ; while ( HiRegToRestore != AllHighRegsEnd ) { assert ( ! CopyRegs . none ( ) ) ; auto CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PopMIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; while ( HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { PopMIB . addReg ( * CopyReg , RegState :: Define ) ; BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * HiRegToRestore , RegState :: Define ) . addReg ( * CopyReg , RegState :: Kill ) . add ( predOps ( <STR_LIT> ) ) ; CopyReg = findNextOrderedReg ( ++ CopyReg , CopyRegs , AllCopyRegsEnd ) ; HiRegToRestore = findNextOrderedReg ( ++ HiRegToRestore , HiRegsToRestore , AllHighRegsEnd ) ; } } MachineInstrBuilder MIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; bool NeedsPop = false ; for ( CalleeSavedInfo & Info : llvm :: reverse ( CSI ) ) {


<s> for ( unsigned Reg : { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ) { if ( LoRegsToSave [ Reg ] ) { bool isKill = ! MRI . isLiveIn ( Reg ) ; if ( isKill && ! MRI . isReserved ( Reg ) ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; const unsigned * HiRegToSave = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToSave , AllHighRegsEnd ) ; while ( HiRegToSave != AllHighRegsEnd ) { const unsigned * CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PushMIB = BuildMI ( MF , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) . setMIFlags ( MachineInstr :: FrameSetup ) ; SmallVector < unsigned , <NUM_LIT> > RegsToPush ; while ( HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) { if ( HiRegsToSave [ * HiRegToSave ] ) { bool isKill = ! MRI . isLiveIn ( * HiRegToSave ) ; if ( isKill && ! MRI . isReserved ( * HiRegToSave ) ) MBB . addLiveIn ( * HiRegToSave ) ;

BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . addReg ( * CopyReg , RegState :: Define ) . addReg ( * HiRegToSave , getKillRegState ( isKill ) ) . add ( predOps ( <STR_LIT> ) ) . setMIFlags ( MachineInstr :: FrameSetup ) ;


<s> MachineFrameInfo & MFI = MF . getFrameInfo ( ) ; <ISA_LIT>FunctionInfo * AFI = MF . getInfo < <ISA_LIT>FunctionInfo > ( ) ; const ThumbRegisterInfo * RegInfo = static_cast < const ThumbRegisterInfo * > ( STI . getRegisterInfo ( ) ) ; const Thumb1InstrInfo & TII = * static_cast < const Thumb1InstrInfo * > ( STI . getInstrInfo ( ) ) ; unsigned ArgRegsSaveSize = AFI -> getArgRegsSaveSize ( ) ; int NumBytes = ( int ) MFI . getStackSize ( ) ; assert ( ( unsigned ) NumBytes >= ArgRegsSaveSize && <STR_LIT> ) ; const MCPhysReg * CSRegs = RegInfo -> getCalleeSavedRegs ( & MF ) ; unsigned FramePtr = RegInfo -> getFrameRegister ( MF ) ; if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize , <STR_LIT> , MachineInstr :: NoFlags ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else { unsigned ScratchRegister = <STR_LIT> ; bool HasFP = hasFP ( MF ) ; for ( auto & I : MFI . getCalleeSavedInfo ( ) ) { unsigned Reg = I . getReg ( ) ; if ( is<ISA_LIT>LowRegister ( Reg ) && ! ( HasFP && Reg == FramePtr ) ) { ScratchRegister = Reg ; break ;


<s> if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes - ArgRegsSaveSize , <STR_LIT> , MachineInstr :: NoFlags ) ; } else { if ( MBBI != MBB . begin ( ) ) { do -- MBBI ; while ( MBBI != MBB . begin ( ) && isCSRestore ( * MBBI , CSRegs ) ) ; if ( ! isCSRestore ( * MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( ! MFI . getPristineRegs ( MF ) . test ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; } else BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) . add ( predOps ( <STR_LIT> ) ) ; } else { unsigned ScratchRegister = <STR_LIT> ; bool HasFP = hasFP ( MF ) ; for ( auto & I : MFI . getCalleeSavedInfo ( ) ) { unsigned Reg = I . getReg ( ) ; if ( is<ISA_LIT>LowRegister ( Reg ) && ! ( HasFP && Reg == FramePtr ) ) { ScratchRegister = Reg ; break ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != & * MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * PMBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , & * MBBI , NumBytes ) ) emitPrologueEpilogueSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes , ScratchRegister , MachineInstr :: NoFlags ) ; } } if ( needPopSpecialFixUp ( MF ) ) { bool Done = emitPopSpecialFixUp ( MBB , true ) ; ( void ) Done ;


<s> explicit Thumb1FrameLowering ( const <ISA_LIT>BaseTargetMachine & tm , const <ISA_LIT>Subtarget & sti ) : <ISA_LIT>FrameLowering ( tm , sti ) {


<s> } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } } bool IsV4PopReturn = false ; for ( const CalleeSavedInfo & CSI : MFI -> getCalleeSavedInfo ( ) ) if ( CSI . getReg ( ) == <STR_LIT> ) IsV4PopReturn = true ; IsV4PopReturn &= STI . hasV4TOps ( ) && ! STI . hasV5TOps ( ) ; if ( ArgRegsSaveSize || IsV4PopReturn ) { MBBI = MBB . getLastNonDebugInstr ( ) ; assert ( MBBI -> getOpcode ( ) == <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( AFI -> getReturnRegsCount ( ) <= <NUM_LIT> ) { AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) ) . addReg ( <STR_LIT> , RegState :: Define ) ; emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , ArgRegsSaveSize ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Kill ) ; AddDefaultPred ( MIB ) ; MIB . copyImplicitOps ( & * MBBI ) ; MBB . erase ( MBBI ) ; } else { AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( <STR_LIT> , RegState :: Kill ) ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) ) . addReg ( <STR_LIT> , RegState :: Define ) ; emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , ArgRegsSaveSize ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( <STR_LIT> , RegState :: Kill ) ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) . addReg ( <STR_LIT> , RegState :: Define ) . addReg ( <STR_LIT> , RegState :: Kill ) ) ; } }


<s> while ( MBBI != MBB . begin ( ) && isCSRestore ( MBBI , CSRegs ) ) ; if ( ! isCSRestore ( MBBI , CSRegs ) ) ++ MBBI ; } NumBytes -= ( AFI -> getGPRCalleeSavedArea1Size ( ) + AFI -> getGPRCalleeSavedArea2Size ( ) + AFI -> getDPRCalleeSavedAreaSize ( ) + ArgRegsSaveSize ) ; if ( AFI -> shouldRestoreSPFromFP ( ) ) { NumBytes = AFI -> getFramePtrSpillOffset ( ) - NumBytes ; if ( NumBytes ) { assert ( MF . getRegInfo ( ) . isPhysRegUsed ( <STR_LIT> ) && <STR_LIT> ) ; emitThumbRegPlusImmediate ( MBB , MBBI , dl , <STR_LIT> , FramePtr , - NumBytes , TII , * RegInfo ) ; AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( <STR_LIT> ) ) ; } else AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) , <STR_LIT> ) . addReg ( FramePtr ) ) ; } else { if ( MBBI -> getOpcode ( ) == <STR_LIT> && & MBB . front ( ) != MBBI && std :: prev ( MBBI ) -> getOpcode ( ) == <STR_LIT> ) { MachineBasicBlock :: iterator PMBBI = std :: prev ( MBBI ) ; if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , PMBBI , NumBytes ) ) emitSPUpdate ( MBB , PMBBI , TII , dl , * RegInfo , NumBytes ) ; } else if ( ! tryFoldSPUpdateIntoPushPop ( STI , MF , MBBI , NumBytes ) ) emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , NumBytes ) ; } } bool IsV4PopReturn = false ; for ( const CalleeSavedInfo & CSI : MFI -> getCalleeSavedInfo ( ) ) if ( CSI . getReg ( ) == <STR_LIT> ) IsV4PopReturn = true ; IsV4PopReturn &= STI . hasV4TOps ( ) && ! STI . hasV5TOps ( ) ; if ( ArgRegsSaveSize || IsV4PopReturn ) { MBBI = MBB . getLastNonDebugInstr ( ) ; assert ( MBBI -> getOpcode ( ) == <STR_LIT> ) ; DebugLoc dl = MBBI -> getDebugLoc ( ) ; if ( AFI -> getReturnRegsCount ( ) <= <NUM_LIT> ) {

AddDefaultPred ( BuildMI ( MBB , MBBI , dl , TII . get ( <STR_LIT> ) ) ) . addReg ( <STR_LIT> , RegState :: Define ) ;


<s> MFI -> setStackSize ( NumBytes ) ; unsigned GPRCS1Size = <NUM_LIT> , GPRCS2Size = <NUM_LIT> , DPRCSSize = <NUM_LIT> ; int FramePtrSpillFI = <NUM_LIT> ; if ( ArgRegsSaveSize ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ArgRegsSaveSize , MachineInstr :: FrameSetup ) ; CFAOffset -= ArgRegsSaveSize ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } if ( ! AFI -> hasStackFrame ( ) ) { if ( NumBytes - ArgRegsSaveSize != <NUM_LIT> ) { emitSPUpdate ( MBB , MBBI , TII , dl , * RegInfo , - ( NumBytes - ArgRegsSaveSize ) , MachineInstr :: FrameSetup ) ; CFAOffset -= NumBytes - ArgRegsSaveSize ; unsigned CFIIndex = MMI . addFrameInst ( MCCFIInstruction :: createDefCfaOffset ( nullptr , CFAOffset ) ) ; BuildMI ( MBB , MBBI , dl , TII . get ( TargetOpcode :: CFI_INSTRUCTION ) ) . addCFIIndex ( CFIIndex ) . setMIFlags ( MachineInstr :: FrameSetup ) ; } return ; } for ( unsigned i = <NUM_LIT> , e = CSI . size ( ) ; i != e ; ++ i ) { unsigned Reg = CSI [ i ] . getReg ( ) ; int FI = CSI [ i ] . getFrameIdx ( ) ; switch ( Reg ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( STI . isTargetMachO ( ) ) { GPRCS2Size += <NUM_LIT> ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( Reg == FramePtr ) FramePtrSpillFI = FI ; GPRCS1Size += <NUM_LIT> ; break ; default : DPRCSSize += <NUM_LIT> ; } } if ( MBBI != MBB . end ( ) && MBBI -> getOpcode ( ) == <STR_LIT> ) { ++ MBBI ; if ( MBBI != MBB . end ( ) ) dl = MBBI -> getDebugLoc ( ) ; } unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize - ( GPRCS1Size + GPRCS2Size + DPRCSSize ) ; unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize ; unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size ; bool HasFP = hasFP ( MF ) ; if ( HasFP ) AFI -> setFramePtrSpillOffset ( MFI -> getObjectOffset ( FramePtrSpillFI ) + NumBytes ) ; AFI -> setGPRCalleeSavedArea1Offset ( GPRCS1Offset ) ; AFI -> setGPRCalleeSavedArea2Offset ( GPRCS2Offset ) ; AFI -> setDPRCalleeSavedAreaOffset ( DPRCSOffset ) ; NumBytes = DPRCSOffset ; int FramePtrOffsetInBlock = <NUM_LIT> ; unsigned adjustedGPRCS1Size = GPRCS1Size ; if ( tryFoldSPUpdateIntoPushPop ( STI , MF , std :: prev ( MBBI ) , NumBytes ) ) { FramePtrOffsetInBlock = NumBytes ; adjustedGPRCS1Size += NumBytes ; NumBytes = <NUM_LIT> ;


<s> static bool isCSRestore ( MachineInstr & MI , const MCPhysReg * CSRegs ) { if ( MI . getOpcode ( ) == <STR_LIT> && MI . getOperand ( <NUM_LIT> ) . isFI ( ) && isCalleeSavedRegister ( MI . getOperand ( <NUM_LIT> ) . getReg ( ) , CSRegs ) ) return true ; else if ( MI . getOpcode ( ) == <STR_LIT> ) {

for ( int i = <NUM_LIT> , e = MI . getNumOperands ( ) - <NUM_LIT> ; i != e ; ++ i ) if ( ! isCalleeSavedRegister ( MI . getOperand ( i ) . getReg ( ) , CSRegs ) ) return false ;


<s> AddDefaultPred ( MIB ) ; bool NeedsPop = false ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; if ( Reg == <STR_LIT> ) { if ( MBB . succ_empty ( ) ) { if ( isVarArg ) continue ; if ( ! STI . hasV5TOps ( ) ) continue ; Reg = <STR_LIT> ; ( * MIB ) . setDesc ( TII . get ( <STR_LIT> ) ) ; if ( MI != MBB . end ( ) ) MIB . copyImplicitOps ( * MI ) ; MI = MBB . erase ( MI ) ;


<s> bool Thumb1FrameLowering :: spillCalleeSavedRegisters ( MachineBasicBlock & MBB , MachineBasicBlock :: iterator MI , const std :: vector < CalleeSavedInfo > & CSI , const TargetRegisterInfo * TRI ) const { if ( CSI . empty ( ) ) return false ; DebugLoc DL ; const TargetInstrInfo & TII = * STI . getInstrInfo ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) ; AddDefaultPred ( MIB ) ; for ( unsigned i = CSI . size ( ) ; i != <NUM_LIT> ; -- i ) { unsigned Reg = CSI [ i - <NUM_LIT> ] . getReg ( ) ; bool isKill = true ; if ( Reg == <STR_LIT> ) { MachineFunction & MF = * MBB . getParent ( ) ; if ( MF . getFrameInfo ( ) . isReturnAddressTaken ( ) && MF . getRegInfo ( ) . isLiveIn ( Reg ) ) isKill = false ; } if ( isKill ) MBB . addLiveIn ( Reg ) ; MIB . addReg ( Reg , getKillRegState ( isKill ) ) ; } MIB . setMIFlags ( MachineInstr :: FrameSetup ) ; return true ;


<s> if ( Reg == <STR_LIT> ) I . setRestored ( false ) ; if ( ( <STR_LIT> . contains ( Reg ) ) && ! ( hasFP ( MF ) && Reg == RegInfo -> getFrameRegister ( MF ) ) ) CopyRegs [ Reg ] = true ; } auto Terminator = MBB . getFirstTerminator ( ) ; if ( Terminator != MBB . end ( ) && Terminator -> getOpcode ( ) == <STR_LIT> ) { CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; CopyRegs [ <STR_LIT> ] = true ; for ( auto Op : Terminator -> implicit_operands ( ) ) { if ( Op . isReg ( ) ) CopyRegs [ Op . getReg ( ) ] = false ; } } static const unsigned AllCopyRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllHighRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; static const unsigned AllLoRegs [ ] = { <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> , <STR_LIT> } ; const unsigned * AllCopyRegsEnd = std :: end ( AllCopyRegs ) ; const unsigned * AllHighRegsEnd = std :: end ( AllHighRegs ) ; auto HiRegToRestore = findNextOrderedReg ( std :: begin ( AllHighRegs ) , HiRegsToRestore , AllHighRegsEnd ) ; while ( HiRegToRestore != AllHighRegsEnd ) { assert ( ! CopyRegs . none ( ) ) ; auto CopyReg = findNextOrderedReg ( std :: begin ( AllCopyRegs ) , CopyRegs , AllCopyRegsEnd ) ; MachineInstrBuilder PopMIB = BuildMI ( MBB , MI , DL , TII . get ( <STR_LIT> ) ) . add ( predOps ( <STR_LIT> ) ) ; while ( HiRegToRestore != AllHighRegsEnd && CopyReg != AllCopyRegsEnd ) {

PopMIB . addReg ( * CopyReg , RegState :: Define ) ;