<s> bool Thumb2SizeReduce :: ReduceMBB ( MachineBasicBlock & MBB ) { bool Modified = false ; bool LiveCPSR = MBB . isLiveIn ( <STR_LIT> ) ; MachineInstr * BundleMI = nullptr ; CPSRDef = nullptr ; HighLatencyCPSR = false ; for ( auto * Pred : MBB . predecessors ( ) ) { const MBBInfo & PInfo = BlockInfo [ Pred -> getNumber ( ) ] ; if ( ! PInfo . Visited ) { continue ; } if ( PInfo . HighLatencyCPSR ) { HighLatencyCPSR = true ; break ; } } bool IsSelfLoop = MBB . isSuccessor ( & MBB ) ; MachineBasicBlock :: instr_iterator MII = MBB . instr_begin ( ) , E = MBB . instr_end ( ) ; MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = std :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } if ( MI -> isDebugInstr ( ) ) continue ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ; if ( ReduceMI ( MBB , MI , LiveCPSR , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = std :: prev ( NextMII ) ; MI = & * I ; if ( NextInSameBundle && ! NextMII -> isBundledWithPred ( ) ) NextMII -> bundleWithPred ( ) ; } if ( BundleMI && ! NextInSameBundle && MI -> isInsideBundle ( ) ) { if ( BundleMI -> killsRegister ( <STR_LIT> ) ) LiveCPSR = false ; MachineOperand * MO = BundleMI -> findRegisterDefOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isDead ( ) ) LiveCPSR = true ; MO = BundleMI -> findRegisterUseOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isKill ( ) ) LiveCPSR = true ; } bool DefCPSR = false ; LiveCPSR = UpdateCPSRDef ( * MI , LiveCPSR , DefCPSR ) ; if ( MI -> isCall ( ) ) { CPSRDef = nullptr ; HighLatencyCPSR = false ; IsSelfLoop = false ; } else if ( DefCPSR ) { CPSRDef = MI ; HighLatencyCPSR = isHighLatencyCPSR ( CPSRDef ) ; IsSelfLoop = false ; } } MBBInfo & Info = BlockInfo [ MBB . getNumber ( ) ] ; Info . HighLatencyCPSR = HighLatencyCPSR ; Info . Visited = true ;


<s> } if ( PInfo . HighLatencyCPSR ) { HighLatencyCPSR = true ; break ; } } bool IsSelfLoop = MBB . isSuccessor ( & MBB ) ; MachineBasicBlock :: instr_iterator MII = MBB . instr_begin ( ) , E = MBB . instr_end ( ) ; MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = std :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } if ( MI -> isDebugInstr ( ) ) continue ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ; if ( ReduceMI ( MBB , MI , LiveCPSR , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = std :: prev ( NextMII ) ; MI = & * I ; if ( NextInSameBundle && ! NextMII -> isBundledWithPred ( ) ) NextMII -> bundleWithPred ( ) ; } if ( BundleMI && ! NextInSameBundle && MI -> isInsideBundle ( ) ) { if ( BundleMI -> killsRegister ( <STR_LIT> ) ) LiveCPSR = false ; MachineOperand * MO = BundleMI -> findRegisterDefOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isDead ( ) ) LiveCPSR = true ; MO = BundleMI -> findRegisterUseOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isKill ( ) ) LiveCPSR = true ; } bool DefCPSR = false ; LiveCPSR = UpdateCPSRDef ( * MI , LiveCPSR , DefCPSR ) ; if ( MI -> isCall ( ) ) { CPSRDef = nullptr ; HighLatencyCPSR = false ; IsSelfLoop = false ; } else if ( DefCPSR ) { CPSRDef = MI ; HighLatencyCPSR = isHighLatencyCPSR ( CPSRDef ) ; IsSelfLoop = false ; } } MBBInfo & Info = BlockInfo [ MBB . getNumber ( ) ] ; Info . HighLatencyCPSR = HighLatencyCPSR ;


<s> if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <STR_LIT> ) return false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) && MI -> getOperand ( MCID . getNumOperands ( ) - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) return false ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( Imm / <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; LLVM_DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoadOrStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) != <STR_LIT> ) break ; if ( MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ;


<s> bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) MIB . add ( HasCC ? t1CondCodeOp ( CCDead ) : condCodeOp ( ) ) ; unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( SkipPred && MCID . OpInfo [ i ] . isPredicate ( ) ) continue ; MIB . add ( MI -> getOperand ( i ) ) ; } MIB . setMIFlags ( MI -> getFlags ( ) ) ; LLVM_DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ;


<s> unsigned CommOpIdx2 = TargetInstrInfo :: CommuteAnyOperandIndex ; if ( ! TII -> findCommutedOpIndices ( * MI , CommOpIdx1 , CommOpIdx2 ) || MI -> getOperand ( CommOpIdx2 ) . getReg ( ) != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ;

MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ;


<s> if ( PredicateFtor && ! PredicateFtor ( MF . getFunction ( ) ) ) return false ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( MF . getSubtarget ( ) ) ; if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) . hasOptSize ( ) ; MinimizeSize = STI -> hasMinSize ( ) ; BlockInfo . clear ( ) ;

BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ;


<s> OptimizeSize = MinimizeSize = false ; for ( unsigned i = <NUM_LIT> , e = array_lengthof ( ReduceTable ) ; i != e ; ++ i ) { unsigned FromOpc = ReduceTable [ i ] . WideOpc ; if ( ! ReduceOpcodeMap . insert ( std :: make_pair ( FromOpc , i ) ) . second ) llvm_unreachable ( <STR_LIT> ) ;


<s> OptimizeSize = MinimizeSize = false ; for ( unsigned i = <NUM_LIT> , e = array_lengthof ( ReduceTable ) ; i != e ; ++ i ) { unsigned FromOpc = ReduceTable [ i ] . WideOpc ; if ( ! ReduceOpcodeMap . insert ( std :: make_pair ( FromOpc , i ) ) . second ) llvm_unreachable ( <STR_LIT> ) ; }


<s> for ( const MachineOperand & MO : Use -> operands ( ) ) { if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isDef ( ) ) continue ; Register Reg = MO . getReg ( ) ; if ( Defs . count ( Reg ) ) return false ; } if ( HighLatencyCPSR ) return true ; if ( Use -> getOpcode ( ) == <STR_LIT> || Use -> getOpcode ( ) == <STR_LIT> ) return false ;


<s> Register PredReg ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } case <STR_LIT> : { Register PredReg ; if ( getInstrPredicate ( * MI , PredReg ) != <STR_LIT> ) break ; if ( MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } }


<s> unsigned CommOpIdx1 = <NUM_LIT> ; unsigned CommOpIdx2 = TargetInstrInfo :: CommuteAnyOperandIndex ; if ( ! TII -> findCommutedOpIndices ( * MI , CommOpIdx1 , CommOpIdx2 ) || MI -> getOperand ( CommOpIdx2 ) . getReg ( ) != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { Register Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; Register PredReg ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ;

HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ;


<s> if ( NewMCID . hasOptionalDef ( ) ) MIB . add ( HasCC ? t1CondCodeOp ( CCDead ) : condCodeOp ( ) ) ; MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; } else { MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) MIB . add ( HasCC ? t1CondCodeOp ( CCDead ) : condCodeOp ( ) ) ; } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && MCID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . add ( MO ) ; } if ( ! MCID . isPredicable ( ) && NewMCID . isPredicable ( ) ) MIB . add ( predOps ( <STR_LIT> ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; LLVM_DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ;


<s> break ; case <STR_LIT> : case <STR_LIT> : { if ( ! MinimizeSize ) return false ; if ( ! MI -> hasOneMemOperand ( ) || ( * MI -> memoperands_begin ( ) ) -> getAlign ( ) < Align ( <NUM_LIT> ) ) return false ; bool IsStore = Entry . WideOpc == <STR_LIT> ; Register Rt = MI -> getOperand ( IsStore ? <NUM_LIT> : <NUM_LIT> ) . getReg ( ) ; Register Rn = MI -> getOperand ( IsStore ? <NUM_LIT> : <NUM_LIT> ) . getReg ( ) ; unsigned Offset = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned PredImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; Register PredReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( is<ISA_LIT>LowRegister ( Rt ) ) ; assert ( is<ISA_LIT>LowRegister ( Rn ) ) ; if ( Offset != <NUM_LIT> ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; auto MIB = BuildMI ( MBB , MI , dl , TII -> get ( Entry . NarrowOpc1 ) ) . addReg ( Rn , RegState :: Define ) . addReg ( Rn ) . addImm ( PredImm ) . addReg ( PredReg ) . addReg ( Rt , IsStore ? <NUM_LIT> : RegState :: Define ) ; MIB . setMemRefs ( MI -> memoperands ( ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; MI -> eraseFromBundle ( ) ; ++ NumLdSts ; return true ; } case <STR_LIT> : { Register BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( is<ISA_LIT>LowRegister ( BaseReg ) ) ; bool isOK = false ; for ( const MachineOperand & MO : llvm :: drop_begin ( MI -> operands ( ) , <NUM_LIT> ) ) { if ( MO . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : { if ( ! MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ) return false ; Register BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; for ( const MachineOperand & MO : llvm :: drop_begin ( MI -> operands ( ) , <NUM_LIT> ) ) if ( MO . getReg ( ) == BaseReg ) return false ; break ; } case <STR_LIT> : { Register BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ; Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; }


<s> FunctionPass * llvm :: createThumb2SizeReductionPass ( ) { return new Thumb2SizeReduce ( ) ;


<s> bool HasOffReg = true ; bool isLdStMul = false ; unsigned Opc = Entry . NarrowOpc1 ; unsigned OpNum = <NUM_LIT> ; uint8_t ImmLimit = Entry . Imm1Limit ; switch ( Entry . WideOpc ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> ) { Opc = Entry . NarrowOpc2 ; ImmLimit = Entry . Imm2Limit ; HasOffReg = false ; } Scale = <NUM_LIT> ; HasImmOffset = true ; break ; } case <STR_LIT> : case <STR_LIT> : HasImmOffset = true ; break ; case <STR_LIT> : case <STR_LIT> : Scale = <NUM_LIT> ; HasImmOffset = true ; 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> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; <STR_LIT> Mode = <STR_LIT> ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || Mode != <STR_LIT> ) return false ; bool isOK = false ; for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ;


<s> MachineBasicBlock :: iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = llvm :: next ( MII ) ; MachineInstr * MI = & * MII ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; }


<s> unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR ) ;


<s> if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = TID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && TID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( SkipPred && TID . OpInfo [ i ] . isPredicate ( ) ) continue ; MIB . addOperand ( MI -> getOperand ( i ) ) ; } DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase ( MI ) ;


<s> } if ( ! VerifyPredAndCC ( MI , Entry , false , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = TID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && TID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( TID . getOpcode ( ) == <STR_LIT> || TID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && TID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( Scale > <NUM_LIT> && ! isPred && MO . isImm ( ) ) MIB . addImm ( MO . getImm ( ) / Scale ) ; else { if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . addOperand ( MO ) ; }


<s> TII = static_cast < const Thumb2InstrInfo * > ( TM . getInstrInfo ( ) ) ; bool Modified = false ;

for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * I ) ;


<s> const TargetMachine & TM = MF . getTarget ( ) ; TII = static_cast < const Thumb2InstrInfo * > ( TM . getInstrInfo ( ) ) ;


<s> unsigned FromOpc = ReduceTable [ i ] . WideOpc ;

if ( ! ReduceOpcodeMap . insert ( std :: make_pair ( FromOpc , i ) ) . second ) assert ( false && <STR_LIT> ) ;


<s> if ( ! ReduceOpcodeMap . insert ( std :: make_pair ( FromOpc , i ) ) . second ) assert ( false && <STR_LIT> ) ;


<s> bool HasDef = false ; for ( unsigned i = <NUM_LIT> , e = MI . getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI . getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isUse ( ) ) continue ; if ( MO . getReg ( ) != <STR_LIT> ) continue ; if ( ! MO . isDead ( ) ) HasDef = true ; }


<s> for ( unsigned i = <NUM_LIT> , e = MI . getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI . getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isDef ( ) ) continue ; if ( MO . getReg ( ) != <STR_LIT> ) continue ; assert ( LiveCPSR && <STR_LIT> ) ; if ( MO . isKill ( ) ) {


<s> bool isPCOk = ( Opc == <STR_LIT> || Opc == <STR_LIT> || Opc == <STR_LIT> ) ; bool isLROk = ( Opc == <STR_LIT> ) ; bool isSPOk = isPCOk || isLROk || ( Opc == <STR_LIT> ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; if ( isPCOk && Reg == <STR_LIT> ) continue ; if ( isLROk && Reg == <STR_LIT> ) continue ; if ( Reg == <STR_LIT> ) { if ( isSPOk ) continue ;

if ( i == <NUM_LIT> && ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ) continue ;


<s> unsigned Opc = MI -> getOpcode ( ) ; bool isPCOk = ( Opc == <STR_LIT> || Opc == <STR_LIT> || Opc == <STR_LIT> ) ; bool isLROk = ( Opc == <STR_LIT> ) ; bool isSPOk = isPCOk || isLROk || ( Opc == <STR_LIT> ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; if ( isPCOk && Reg == <STR_LIT> ) continue ; if ( isLROk && Reg == <STR_LIT> ) continue ; if ( Reg == <STR_LIT> ) { if ( isSPOk ) continue ; if ( i == <NUM_LIT> && ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ) continue ; } if ( ! is<ISA_LIT>LowRegister ( Reg ) ) return false ; }


<s> unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! is<ISA_LIT>LowRegister ( Reg0 ) || ! is<ISA_LIT>LowRegister ( Reg1 ) || ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; if ( Reg0 != Reg2 ) { if ( Reg1 != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( MI ) ; if ( ! CommutedMI ) return false ; } } else if ( Reg0 != Reg1 ) { unsigned CommOpIdx1 , CommOpIdx2 ; if ( ! TII -> findCommutedOpIndices ( MI , CommOpIdx1 , CommOpIdx2 ) || CommOpIdx1 != <NUM_LIT> || MI -> getOperand ( CommOpIdx2 ) . getReg ( ) != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( MI ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ;


<s> } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) {

if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ;


<s> } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && MCID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . addOperand ( MO ) ; } if ( ! MCID . isPredicable ( ) && NewMCID . isPredicable ( ) ) AddDefaultPred ( MIB ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ;


<s> bool Thumb2SizeReduce :: runOnMachineFunction ( MachineFunction & MF ) { STI = & static_cast < const <ISA_LIT>Subtarget & > ( MF . getSubtarget ( ) ) ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; AttributeSet FnAttrs = MF . getFunction ( ) -> getAttributes ( ) ; OptimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: OptimizeForSize ) ; MinimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: MinSize ) ; BlockInfo . clear ( ) ;


<s> OptimizeSize = MinimizeSize = false ; for ( unsigned i = <NUM_LIT> , e = array_lengthof ( ReduceTable ) ; i != e ; ++ i ) { unsigned FromOpc = ReduceTable [ i ] . WideOpc ;


<s> for ( unsigned i = <NUM_LIT> , e = array_lengthof ( ReduceTable ) ; i != e ; ++ i ) { unsigned FromOpc = ReduceTable [ i ] . WideOpc ;


<s> bool isSPOk = isPCOk || isLROk ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ;


<s> unsigned Scale = <NUM_LIT> ; bool HasImmOffset = false ; bool HasShift = false ; bool HasOffReg = true ; bool isLdStMul = false ; unsigned Opc = Entry . NarrowOpc1 ; unsigned OpNum = <NUM_LIT> ; uint8_t ImmLimit = Entry . Imm1Limit ; switch ( Entry . WideOpc ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) { Opc = Entry . NarrowOpc2 ; ImmLimit = Entry . Imm2Limit ; HasOffReg = false ; } Scale = <NUM_LIT> ; HasImmOffset = true ; HasOffReg = false ; break ; case <STR_LIT> : case <STR_LIT> : HasImmOffset = true ; HasOffReg = false ; break ; case <STR_LIT> : case <STR_LIT> : Scale = <NUM_LIT> ; HasImmOffset = true ; HasOffReg = false ; 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> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || Entry . WideOpc != <STR_LIT> ) return false ; bool isOK = false ; for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ; Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> && ( Entry . WideOpc == <STR_LIT> || Entry . WideOpc == <STR_LIT> ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; }


<s> } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> && ( Entry . WideOpc == <STR_LIT> || Entry . WideOpc == <STR_LIT> ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , TII -> get ( Opc ) ) ; if ( ! isLdStMul ) { MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ;

if ( HasImmOffset ) MIB . addImm ( OffsetImm / Scale ) ;


<s> if ( ! PInfo . Visited ) { continue ; } if ( PInfo . HighLatencyCPSR ) { HighLatencyCPSR = true ; break ; } } bool IsSelfLoop = MBB . isSuccessor ( & MBB ) ; MachineBasicBlock :: instr_iterator MII = MBB . instr_begin ( ) , E = MBB . instr_end ( ) ; MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = std :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } if ( MI -> isDebugValue ( ) ) continue ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ;

bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ;


<s> BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ; ReversePostOrderTraversal < MachineFunction * > RPOT ( & MF ) ; bool Modified = false ;

for ( ReversePostOrderTraversal < MachineFunction * > :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * * I ) ;


<s> bool Modified = false ; for ( ReversePostOrderTraversal < MachineFunction * > :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * * I ) ;


<s> TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) . optForSize ( ) ; MinimizeSize = MF . getFunction ( ) . optForMinSize ( ) ; BlockInfo . clear ( ) ; BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ; ReversePostOrderTraversal < MachineFunction * > RPOT ( & MF ) ; bool Modified = false ;


<s> OptimizeSize = MF . getFunction ( ) . optForSize ( ) ; MinimizeSize = MF . getFunction ( ) . optForMinSize ( ) ; BlockInfo . clear ( ) ; BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ; ReversePostOrderTraversal < MachineFunction * > RPOT ( & MF ) ; bool Modified = false ; for ( ReversePostOrderTraversal < MachineFunction * > :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * * I ) ; return Modified ;


<s> StringRef getPassName ( ) const override { return <STR_LIT> ;


<s> StringRef getPassName ( ) const override {


<s> BundleMI = MI ; continue ; } if ( MI -> isDebugValue ( ) ) continue ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ; if ( ReduceMI ( MBB , MI , LiveCPSR , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = std :: prev ( NextMII ) ; MI = & * I ; if ( NextInSameBundle && ! NextMII -> isBundledWithPred ( ) ) NextMII -> bundleWithPred ( ) ; } if ( BundleMI && ! NextInSameBundle && MI -> isInsideBundle ( ) ) { if ( BundleMI -> killsRegister ( <STR_LIT> ) ) LiveCPSR = false ; MachineOperand * MO = BundleMI -> findRegisterDefOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isDead ( ) ) LiveCPSR = true ; MO = BundleMI -> findRegisterUseOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isKill ( ) ) LiveCPSR = true ; } bool DefCPSR = false ; LiveCPSR = UpdateCPSRDef ( * MI , LiveCPSR , DefCPSR ) ; if ( MI -> isCall ( ) ) {


<s> return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Imm & <NUM_LIT> || Imm > <NUM_LIT> ) return false ; if ( ! is<ISA_LIT>LowRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return false ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <STR_LIT> ) return false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) && MI -> getOperand ( MCID . getNumOperands ( ) - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) return false ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( Imm / <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoadOrStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ;


<s> if ( MI -> getOpcode ( ) == <STR_LIT> ) { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! is<ISA_LIT>LowRegister ( Reg0 ) || ! is<ISA_LIT>LowRegister ( Reg1 ) || ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; if ( Reg0 != Reg2 ) { if ( Reg1 != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI ) ; if ( ! CommutedMI ) return false ; } } else if ( Reg0 != Reg1 ) { unsigned CommOpIdx1 = <NUM_LIT> ; unsigned CommOpIdx2 = TargetInstrInfo :: CommuteAnyOperandIndex ; if ( ! TII -> findCommutedOpIndices ( * MI , CommOpIdx1 , CommOpIdx2 ) || MI -> getOperand ( CommOpIdx2 ) . getReg ( ) != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ;

if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ;


<s> if ( Reg1 != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI ) ; if ( ! CommutedMI ) return false ; } } else if ( Reg0 != Reg1 ) { unsigned CommOpIdx1 = <NUM_LIT> ; unsigned CommOpIdx2 = TargetInstrInfo :: CommuteAnyOperandIndex ; if ( ! TII -> findCommutedOpIndices ( * MI , CommOpIdx1 , CommOpIdx2 ) || MI -> getOperand ( CommOpIdx2 ) . getReg ( ) != Reg0 ) return false ; MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ;

const MCInstrDesc & MCID = MI -> getDesc ( ) ;


<s> MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) MIB . add ( HasCC ? t1CondCodeOp ( CCDead ) : condCodeOp ( ) ) ; unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && MCID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . add ( MO ) ; } if ( ! MCID . isPredicable ( ) && NewMCID . isPredicable ( ) ) MIB . add ( predOps ( <STR_LIT> ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ;


<s> case <STR_LIT> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || Entry . WideOpc != <STR_LIT> ) return false ; bool isOK = false ; for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ; Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> && ( Entry . WideOpc == <STR_LIT> || Entry . WideOpc == <STR_LIT> ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ;


<s> bool Thumb2SizeReduce :: ReduceSpecial ( MachineBasicBlock & MBB , MachineInstr * MI , const ReduceEntry & Entry , bool LiveCPSR ) { if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; const TargetInstrDesc & TID = MI -> getDesc ( ) ; if ( TID . mayLoad ( ) || TID . mayStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; unsigned Opc = MI -> getOpcode ( ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR ) ; } }


<s> bool isLROk = ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ; bool isSPOk = isPCOk || isLROk || ( Opc == <STR_LIT> ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ; unsigned Reg = MO . getReg ( ) ;

if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ;


<s> MachineInstr * MI = & * MII ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; } goto ProcessNext ; } if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) {


<s> if ( * I == <STR_LIT> ) { LiveCPSR = true ; break ; } } MachineBasicBlock :: iterator MII = MBB . begin ( ) , E = MBB . end ( ) ; MachineBasicBlock :: iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = next ( MII ) ; MachineInstr * MI = & * MII ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) {

if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR ) ) {


<s> unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR ) ; } } break ;


<s> unsigned Reg0 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Reg1 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Reg0 != Reg1 ) return false ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = TID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && TID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( SkipPred && TID . OpInfo [ i ] . isPredicate ( ) ) continue ; MIB . addOperand ( MI -> getOperand ( i ) ) ; } DOUT << <STR_LIT> << * MI << <STR_LIT> << * MIB ; MBB . erase ( MI ) ; ++ Num2Addrs ; return true ;


<s> unsigned Reg1 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Reg0 != Reg1 ) return false ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ;


<s> } else if ( MO . isImm ( ) && ! TID . OpInfo [ i ] . isPredicate ( ) ) { if ( MO . getImm ( ) > Limit || ( MO . getImm ( ) & ( Scale - <NUM_LIT> ) ) != <NUM_LIT> ) return false ; } } const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc1 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , false , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = TID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && TID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( TID . getOpcode ( ) == <STR_LIT> || TID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && TID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( Scale > <NUM_LIT> && ! isPred && MO . isImm ( ) ) MIB . addImm ( MO . getImm ( ) / Scale ) ; else { if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . addOperand ( MO ) ; } } if ( ! TID . isPredicable ( ) && NewTID . isPredicable ( ) ) AddDefaultPred ( MIB ) ; DOUT << <STR_LIT> << * MI << <STR_LIT> << * MIB ;


<s> Opc = Entry . NarrowOpc2 ; ImmLimit = Entry . Imm2Limit ; } Scale = <NUM_LIT> ; HasImmOffset = true ; HasOffReg = false ; break ; case <STR_LIT> : case <STR_LIT> : HasImmOffset = true ; HasOffReg = false ; break ; case <STR_LIT> : case <STR_LIT> : Scale = <NUM_LIT> ; HasImmOffset = true ; HasOffReg = false ; 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> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : { if ( ! MBB . getParent ( ) -> getFunction ( ) -> optForMinSize ( ) ) return false ; if ( ! MI -> hasOneMemOperand ( ) || ( * MI -> memoperands_begin ( ) ) -> getAlignment ( ) < <NUM_LIT> ) return false ; bool IsStore = Entry . WideOpc == <STR_LIT> ; unsigned Rt = MI -> getOperand ( IsStore ? <NUM_LIT> : <NUM_LIT> ) . getReg ( ) ; unsigned Rn = MI -> getOperand ( IsStore ? <NUM_LIT> : <NUM_LIT> ) . getReg ( ) ; unsigned Offset = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned PredImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned PredReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( is<ISA_LIT>LowRegister ( Rt ) ) ; assert ( is<ISA_LIT>LowRegister ( Rn ) ) ; if ( Offset != <NUM_LIT> ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; auto MIB = BuildMI ( MBB , MI , dl , TII -> get ( Entry . NarrowOpc1 ) ) . addReg ( Rn , RegState :: Define ) . addReg ( Rn ) . addImm ( PredImm ) . addReg ( PredReg ) . addReg ( Rt , IsStore ? <NUM_LIT> : RegState :: Define ) ; MIB -> setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; MI -> eraseFromBundle ( ) ; ++ NumLdSts ; return true ; } case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( is<ISA_LIT>LowRegister ( BaseReg ) ) ; bool isOK = false ; for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ;


<s> MachineInstr * CommutedMI = TII -> commuteInstruction ( * MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ;


<s> MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && MCID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . addOperand ( MO ) ; } if ( ! MCID . isPredicable ( ) && NewMCID . isPredicable ( ) ) AddDefaultPred ( MIB ) ;

MIB . setMIFlags ( MI -> getFlags ( ) ) ;


<s> bool Thumb2SizeReduce :: canAddPseudoFlagDep ( MachineInstr * Def , MachineInstr * Use , bool FirstInSelfLoop ) { if ( MinimizeSize || ! STI -> avoidCPSRPartialUpdate ( ) ) return false ; if ( ! Def ) return FirstInSelfLoop ; SmallSet < unsigned , <NUM_LIT> > Defs ; for ( unsigned i = <NUM_LIT> , e = Def -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = Def -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isUse ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; Defs . insert ( Reg ) ; } for ( unsigned i = <NUM_LIT> , e = Use -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = Use -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isDef ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Defs . count ( Reg ) ) return false ; } return true ;


<s> if ( ! Def ) return FirstInSelfLoop ; SmallSet < unsigned , <NUM_LIT> > Defs ; for ( unsigned i = <NUM_LIT> , e = Def -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = Def -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isUse ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; Defs . insert ( Reg ) ; }

for ( unsigned i = <NUM_LIT> , e = Use -> getNumOperands ( ) ; i != e ; ++ i ) {


<s> if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ; if ( ReduceMI ( MBB , MI , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; if ( NextInSameBundle && ! NextMII -> isBundledWithPred ( ) ) NextMII -> bundleWithPred ( ) ; }

if ( ! NextInSameBundle && MI -> isInsideBundle ( ) ) {


<s> bool IsSelfLoop = MBB . isSuccessor ( & MBB ) ; MachineBasicBlock :: instr_iterator MII = MBB . instr_begin ( ) , E = MBB . instr_end ( ) ; MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = llvm :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; bool NextInSameBundle = NextMII != E && NextMII -> isBundledWithPred ( ) ;

if ( ReduceMI ( MBB , MI , LiveCPSR , CPSRDef , IsSelfLoop ) ) {


<s> if ( Entry . Special ) return ReduceSpecial ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ;

if ( Entry . NarrowOpc1 && ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ;


<s> if ( Opc == <STR_LIT> ) { if ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) != <STR_LIT> ) { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; } unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Imm & <NUM_LIT> || Imm > <NUM_LIT> ) return false ; if ( ! is<ISA_LIT>LowRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return false ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <STR_LIT> ) return false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) && MI -> getOperand ( MCID . getNumOperands ( ) - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) return false ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( Imm / <NUM_LIT> ) ; AddDefaultPred ( MIB ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoad ( ) || MI -> mayStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; } } break ; } case <STR_LIT> :


<s> if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ;


<s> if ( ReduceLimit != - <NUM_LIT> && ( ( int ) NumNarrows >= ReduceLimit ) ) return false ; if ( ! MinimizeSize && ! OptimizeSize && Entry . AvoidMovs && STI -> avoidMOVsShifterOperand ( ) ) return false ; unsigned Limit = ~ <NUM_LIT> ; if ( Entry . Imm1Limit ) Limit = ( <NUM_LIT> << Entry . Imm1Limit ) - <NUM_LIT> ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; for ( unsigned i = <NUM_LIT> , e = MCID . getNumOperands ( ) ; i != e ; ++ i ) { if ( MCID . OpInfo [ i ] . isPredicate ( ) ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) ) { unsigned Reg = MO . getReg ( ) ; if ( ! Reg || Reg == <STR_LIT> ) continue ; if ( Entry . LowRegs1 && ! is<ISA_LIT>LowRegister ( Reg ) ) return false ; } else if ( MO . isImm ( ) && ! MCID . OpInfo [ i ] . isPredicate ( ) ) { if ( ( ( unsigned ) MO . getImm ( ) ) > Limit ) return false ; } } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc1 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ;

HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ;


<s> if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , false , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( CPSRDef , MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( ( MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> || MCID . getOpcode ( ) == <STR_LIT> ) && i == <NUM_LIT> ) continue ; bool isPred = ( i < NumOps && MCID . OpInfo [ i ] . isPredicate ( ) ) ; if ( SkipPred && isPred ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) && MO . isImplicit ( ) && MO . getReg ( ) == <STR_LIT> ) continue ; MIB . addOperand ( MO ) ; } if ( ! MCID . isPredicable ( ) && NewMCID . isPredicable ( ) ) AddDefaultPred ( MIB ) ;


<s> OptimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: OptimizeForSize ) ; MinimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: MinSize ) ; bool Modified = false ;

for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * I ) ;


<s> STI = & TM . getSubtarget < <ISA_LIT>Subtarget > ( ) ; AttributeSet FnAttrs = MF . getFunction ( ) -> getAttributes ( ) ; OptimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: OptimizeForSize ) ;

MinimizeSize = FnAttrs . hasAttribute ( AttributeSet :: FunctionIndex , Attribute :: MinSize ) ;


<s> bool HasDef = false ; for ( unsigned i = <NUM_LIT> , e = MI . getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = MI . getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isUse ( ) ) continue ;

if ( MO . getReg ( ) != <STR_LIT> ) continue ;


<s> STI = & static_cast < const <ISA_LIT>Subtarget & > ( MF . getSubtarget ( ) ) ; if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) . hasOptSize ( ) ; MinimizeSize = STI -> hasMinSize ( ) ;


<s> if ( PredicateFtor && ! PredicateFtor ( MF . getFunction ( ) ) ) return false ; STI = & static_cast < const <ISA_LIT>Subtarget & > ( MF . getSubtarget ( ) ) ; if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) . hasOptSize ( ) ;


<s> MinimizeSize = STI -> hasMinSize ( ) ; BlockInfo . clear ( ) ; BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ; ReversePostOrderTraversal < MachineFunction * > RPOT ( & MF ) ; bool Modified = false ; for ( MachineBasicBlock * MBB : RPOT ) Modified |= ReduceMBB ( * MBB ) ; return Modified ;


<s> if ( PredicateFtor && ! PredicateFtor ( MF . getFunction ( ) ) ) return false ; STI = & MF . getSubtarget < <ISA_LIT>Subtarget > ( ) ; if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) . hasOptSize ( ) ;


<s> } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoadOrStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ;


<s> return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Imm & <NUM_LIT> || Imm > <NUM_LIT> ) return false ; if ( ! is<ISA_LIT>LowRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return false ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <STR_LIT> ) return false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) && MI -> getOperand ( MCID . getNumOperands ( ) - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) return false ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . add ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( Imm / <NUM_LIT> ) . add ( predOps ( <STR_LIT> ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoadOrStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , IsSelfLoop ) ) return true ;


<s> OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , TII -> get ( Opc ) ) ; if ( ! isLdStMul ) { MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( Opc != <STR_LIT> && Opc != <STR_LIT> ) { MIB . addImm ( OffsetImm / Scale ) ; } assert ( ( ! HasShift || OffsetReg ) && <STR_LIT> ) ; if ( HasOffReg ) MIB . addReg ( OffsetReg , getKillRegState ( OffsetKill ) ) ; } for ( unsigned e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . addOperand ( MI -> getOperand ( OpNum ) ) ; ( * MIB ) . setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase ( MI ) ;


<s> bool isLdStMul = false ; unsigned Opc = Entry . NarrowOpc1 ; unsigned OpNum = <NUM_LIT> ; uint8_t ImmLimit = Entry . Imm1Limit ; switch ( Entry . WideOpc ) { default : llvm_unreachable ( <STR_LIT> ) ; case <STR_LIT> : case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> ) { Opc = Entry . NarrowOpc2 ; ImmLimit = Entry . Imm2Limit ; HasOffReg = false ; } Scale = <NUM_LIT> ; HasImmOffset = true ; break ; } case <STR_LIT> : case <STR_LIT> : HasImmOffset = true ; break ; case <STR_LIT> : case <STR_LIT> : Scale = <NUM_LIT> ; HasImmOffset = true ; 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> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Mode = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( BaseReg == <STR_LIT> && <STR_LIT> ( Mode ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( Entry . WideOpc == <STR_LIT> || ! is<ISA_LIT>LowRegister ( BaseReg ) || ! <STR_LIT> ( Mode ) || <STR_LIT> ( Mode ) != <STR_LIT> ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , TII -> get ( Opc ) ) ; if ( ! isLdStMul ) { MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( Opc != <STR_LIT> && Opc != <STR_LIT> ) { MIB . addImm ( OffsetImm / Scale ) ; } assert ( ( ! HasShift || OffsetReg ) && <STR_LIT> ) ; if ( HasOffReg ) MIB . addReg ( OffsetReg , getKillRegState ( OffsetKill ) ) ;


<s> MachineInstr * MI = & * MII ; LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; } goto ProcessNext ; } if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; goto ProcessNext ;


<s> if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ; } goto ProcessNext ; } if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR ) ) { Modified = true ; MachineBasicBlock :: iterator I = prior ( NextMII ) ; MI = & * I ;


<s> const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ;

MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ;


<s> if ( ! MO . isReg ( ) || MO . isImplicit ( ) ) continue ; unsigned Reg = MO . getReg ( ) ; if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; if ( isPCOk && Reg == <STR_LIT> ) continue ; if ( isLROk && Reg == <STR_LIT> ) continue ; if ( Reg == <STR_LIT> ) { if ( isSPOk ) continue ; if ( i == <NUM_LIT> && ( Opc == <STR_LIT> || Opc == <STR_LIT> ) ) continue ; } if ( ! is<ISA_LIT>LowRegister ( Reg ) ) return false ; }


<s> if ( Opc == <STR_LIT> ) { if ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) != <STR_LIT> ) { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( Imm & <NUM_LIT> || Imm > <NUM_LIT> ) return false ; if ( ! is<ISA_LIT>LowRegister ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) return false ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) != <STR_LIT> ) return false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) && MI -> getOperand ( MCID . getNumOperands ( ) - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) return false ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addImm ( Imm / <NUM_LIT> ) ; AddDefaultPred ( MIB ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoadOrStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> :


<s> MachineInstr * CommutedMI = TII -> commuteInstruction ( MI , false , CommOpIdx1 , CommOpIdx2 ) ; if ( ! CommutedMI ) return false ; } if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const MCInstrDesc & NewMCID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( * MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewMCID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewMCID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; if ( MCID . hasOptionalDef ( ) ) { unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ;

MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ;


<s> if ( Reg == <NUM_LIT> || Reg == <STR_LIT> ) continue ; Defs . insert ( Reg ) ; } for ( unsigned i = <NUM_LIT> , e = Use -> getNumOperands ( ) ; i != e ; ++ i ) { const MachineOperand & MO = Use -> getOperand ( i ) ; if ( ! MO . isReg ( ) || MO . isUndef ( ) || MO . isDef ( ) ) continue ; unsigned Reg = MO . getReg ( ) ;

if ( Defs . count ( Reg ) ) return false ;


<s> MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = llvm :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; } goto ProcessNext ; } if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; goto ProcessNext ; } if ( Entry . NarrowOpc1 && ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; } } ProcessNext : if ( NextMII != E && MI -> isInsideBundle ( ) && ! NextMII -> isInsideBundle ( ) ) { if ( BundleMI -> killsRegister ( <STR_LIT> ) ) LiveCPSR = false ; MachineOperand * MO = BundleMI -> findRegisterDefOperand ( <STR_LIT> ) ; if ( MO && ! MO -> isDead ( ) ) LiveCPSR = true ; } bool DefCPSR = false ; LiveCPSR = UpdateCPSRDef ( * MI , LiveCPSR , DefCPSR ) ; if ( MI -> isCall ( ) ) { CPSRDef = <NUM_LIT> ; IsSelfLoop = false ; } else if ( DefCPSR ) { CPSRDef = MI ; IsSelfLoop = false ;


<s> AddDefaultPred ( MIB ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ; ++ NumNarrows ; return true ; } if ( Entry . LowRegs1 && ! VerifyLowRegs ( MI ) ) return false ; if ( MI -> mayLoad ( ) || MI -> mayStore ( ) ) return ReduceLoadStore ( MBB , MI , Entry ) ; switch ( Opc ) { default : break ; case <STR_LIT> : case <STR_LIT> : { unsigned PredReg = <NUM_LIT> ; if ( getInstrPredicate ( MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : { if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; } case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , CPSRDef , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ; }


<s> unsigned NumOps = MCID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; if ( Entry . PartFlag && NewMCID . hasOptionalDef ( ) && HasCC && canAddPseudoFlagDep ( CPSRDef , MI , IsSelfLoop ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , NewMCID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewMCID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = MCID . getNumOperands ( ) ; for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) { if ( i < NumOps && MCID . OpInfo [ i ] . isOptionalDef ( ) ) continue ; if ( SkipPred && MCID . OpInfo [ i ] . isPredicate ( ) ) continue ; MIB . addOperand ( MI -> getOperand ( i ) ) ; } MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ;


<s> STI = & TM . getSubtarget < <ISA_LIT>Subtarget > ( ) ; bool Modified = false ; for ( MachineFunction :: iterator I = MF . begin ( ) , E = MF . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * I ) ; return Modified ;


<s> const TargetMachine & TM = MF . getTarget ( ) ; TII = static_cast < const Thumb2InstrInfo * > ( TM . getInstrInfo ( ) ) ; STI = & TM . getSubtarget < <ISA_LIT>Subtarget > ( ) ; bool Modified = false ;


<s> bool IsSelfLoop = MBB . isSuccessor ( & MBB ) ; MachineBasicBlock :: instr_iterator MII = MBB . instr_begin ( ) , E = MBB . instr_end ( ) ; MachineBasicBlock :: instr_iterator NextMII ; for ( ; MII != E ; MII = NextMII ) { NextMII = llvm :: next ( MII ) ; MachineInstr * MI = & * MII ; if ( MI -> isBundle ( ) ) { BundleMI = MI ; continue ; } LiveCPSR = UpdateCPSRUse ( * MI , LiveCPSR ) ; unsigned Opcode = MI -> getOpcode ( ) ; DenseMap < unsigned , unsigned > :: iterator OPI = ReduceOpcodeMap . find ( Opcode ) ; if ( OPI != ReduceOpcodeMap . end ( ) ) { const ReduceEntry & Entry = ReduceTable [ OPI -> second ] ; if ( Entry . Special ) { if ( ReduceSpecial ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; } goto ProcessNext ; } if ( Entry . NarrowOpc2 && ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ; MI = & * I ; goto ProcessNext ; } if ( Entry . NarrowOpc1 && ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , CPSRDef , IsSelfLoop ) ) { Modified = true ; MachineBasicBlock :: instr_iterator I = prior ( NextMII ) ;


<s> break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; bool OffsetInternal = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; OffsetInternal = MI -> getOperand ( <NUM_LIT> ) . isInternalRead ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , TII -> get ( Opc ) ) ; if ( ! isLdStMul ) { MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( HasImmOffset ) MIB . addImm ( OffsetImm / Scale ) ; assert ( ( ! HasShift || OffsetReg ) && <STR_LIT> ) ; if ( HasOffReg ) MIB . addReg ( OffsetReg , getKillRegState ( OffsetKill ) | getInternalReadRegState ( OffsetInternal ) ) ; } for ( unsigned e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . addOperand ( MI -> getOperand ( OpNum ) ) ; MIB -> setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ;


<s> case <STR_LIT> : case <STR_LIT> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; assert ( is<ISA_LIT>LowRegister ( BaseReg ) ) ; bool isOK = false ; for ( unsigned i = <NUM_LIT> ; i < MI -> getNumOperands ( ) ; ++ i ) { if ( MI -> getOperand ( i ) . getReg ( ) == BaseReg ) { isOK = true ; break ; } } if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ; Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> && ( Entry . WideOpc == <STR_LIT> || Entry . WideOpc == <STR_LIT> ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; bool OffsetInternal = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; OffsetInternal = MI -> getOperand ( <NUM_LIT> ) . isInternalRead ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; }


<s> if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ; OptimizeSize = MF . getFunction ( ) -> hasFnAttribute ( Attribute :: OptimizeForSize ) ;

MinimizeSize = MF . getFunction ( ) -> hasFnAttribute ( Attribute :: MinSize ) ;


<s> if ( ! isOK ) return false ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : if ( ! MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ) return false ; break ; case <STR_LIT> : { unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg != <STR_LIT> ) return false ; Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; isLdStMul = true ; break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( BaseReg == <STR_LIT> && ( Entry . WideOpc == <STR_LIT> || Entry . WideOpc == <STR_LIT> ) ) { Opc = Entry . NarrowOpc2 ; OpNum = <NUM_LIT> ; } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; bool OffsetInternal = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; OffsetInternal = MI -> getOperand ( <NUM_LIT> ) . isInternalRead ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , TII -> get ( Opc ) ) ; if ( Entry . WideOpc == <STR_LIT> ) MIB . addReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) , RegState :: Define | RegState :: Dead ) ; if ( ! isLdStMul ) { MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ;


<s> case <STR_LIT> : Scale = <NUM_LIT> ; HasImmOffset = true ; 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> : HasShift = true ; OpNum = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : { OpNum = <NUM_LIT> ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Mode = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; if ( BaseReg == <STR_LIT> && <STR_LIT> ( Mode ) ) { Opc = Entry . NarrowOpc2 ; isPopPush = true ; OpNum = <NUM_LIT> ; } else if ( Entry . WideOpc == <STR_LIT> || ! is<ISA_LIT>LowRegister ( BaseReg ) || ! <STR_LIT> ( Mode ) || <STR_LIT> ( Mode ) != <STR_LIT> ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << Entry . Imm1Limit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , TII -> get ( Opc ) ) ; if ( ! isLdStMul ) { MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( Entry . NarrowOpc1 != <STR_LIT> && Entry . NarrowOpc1 != <STR_LIT> ) { MIB . addImm ( OffsetImm / Scale ) ; } assert ( ( ! HasShift || OffsetReg ) && <STR_LIT> ) ; MIB . addReg ( OffsetReg , getKillRegState ( OffsetKill ) ) ; } for ( unsigned e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . addOperand ( MI -> getOperand ( OpNum ) ) ; DOUT ( llvm :: dbgs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase ( MI ) ; ++ NumLdSts ; return true ;


<s> bool Thumb2SizeReduce :: ReduceTo2Addr ( MachineBasicBlock & MBB , MachineInstr * MI , const ReduceEntry & Entry , bool LiveCPSR ) { if ( ReduceLimit2Addr != - <NUM_LIT> && ( ( int ) Num2Addrs >= ReduceLimit2Addr ) ) return false ; const TargetInstrDesc & TID = MI -> getDesc ( ) ; unsigned Reg0 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned Reg1 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Reg0 != Reg1 ) return false ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg0 ) ) return false ; if ( Entry . Imm2Limit ) { unsigned Imm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned Limit = ( <NUM_LIT> << Entry . Imm2Limit ) - <NUM_LIT> ; if ( Imm > Limit ) return false ; } else { unsigned Reg2 = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; if ( Entry . LowRegs2 && ! is<ISA_LIT>LowRegister ( Reg2 ) ) return false ; } const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc2 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , true , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) { if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ; else AddNoT1CC ( MIB ) ; } unsigned NumOps = TID . getNumOperands ( ) ;

for ( unsigned i = <NUM_LIT> , e = MI -> getNumOperands ( ) ; i != e ; ++ i ) {


<s> const TargetInstrDesc & TID = MI -> getDesc ( ) ; for ( unsigned i = <NUM_LIT> , e = TID . getNumOperands ( ) ; i != e ; ++ i ) { if ( TID . OpInfo [ i ] . isPredicate ( ) ) continue ; const MachineOperand & MO = MI -> getOperand ( i ) ; if ( MO . isReg ( ) ) { unsigned Reg = MO . getReg ( ) ; if ( ! Reg || Reg == <STR_LIT> ) continue ; if ( Entry . WideOpc == <STR_LIT> && Reg == <STR_LIT> ) continue ; if ( Entry . LowRegs1 && ! is<ISA_LIT>LowRegister ( Reg ) ) return false ; } else if ( MO . isImm ( ) && ! TID . OpInfo [ i ] . isPredicate ( ) ) { if ( MO . getImm ( ) > Limit || ( MO . getImm ( ) & ( Scale - <NUM_LIT> ) ) != <NUM_LIT> ) return false ; } } const TargetInstrDesc & NewTID = TII -> get ( Entry . NarrowOpc1 ) ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( MI , PredReg ) ; bool SkipPred = false ; if ( Pred != <STR_LIT> ) { if ( ! NewTID . isPredicable ( ) ) return false ; } else { SkipPred = ! NewTID . isPredicable ( ) ; } bool HasCC = false ; bool CCDead = false ; if ( TID . hasOptionalDef ( ) ) { unsigned NumOps = TID . getNumOperands ( ) ; HasCC = ( MI -> getOperand ( NumOps - <NUM_LIT> ) . getReg ( ) == <STR_LIT> ) ; if ( HasCC && MI -> getOperand ( NumOps - <NUM_LIT> ) . isDead ( ) ) CCDead = true ; } if ( ! VerifyPredAndCC ( MI , Entry , false , Pred , LiveCPSR , HasCC , CCDead ) ) return false ; DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , * MI , dl , NewTID ) ; MIB . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( NewTID . hasOptionalDef ( ) ) {

if ( HasCC ) AddDefaultT1CC ( MIB , CCDead ) ;


<s> bool Thumb2SizeReduce :: runOnMachineFunction ( MachineFunction & MF ) { STI = & static_cast < const <ISA_LIT>Subtarget & > ( MF . getSubtarget ( ) ) ; if ( STI -> isThumb1Only ( ) || STI -> prefers32BitThumb ( ) ) return false ; TII = static_cast < const Thumb2InstrInfo * > ( STI -> getInstrInfo ( ) ) ;

OptimizeSize = MF . getFunction ( ) -> hasFnAttribute ( Attribute :: OptimizeForSize ) ;


<s> OptimizeSize = MF . getFunction ( ) -> hasFnAttribute ( Attribute :: OptimizeForSize ) ; MinimizeSize = MF . getFunction ( ) -> hasFnAttribute ( Attribute :: MinSize ) ; BlockInfo . clear ( ) ; BlockInfo . resize ( MF . getNumBlockIDs ( ) ) ; ReversePostOrderTraversal < MachineFunction * > RPOT ( & MF ) ; bool Modified = false ; for ( ReversePostOrderTraversal < MachineFunction * > :: rpo_iterator I = RPOT . begin ( ) , E = RPOT . end ( ) ; I != E ; ++ I ) Modified |= ReduceMBB ( * * I ) ;


<s> } else if ( ! is<ISA_LIT>LowRegister ( BaseReg ) || ( Entry . WideOpc != <STR_LIT> && Entry . WideOpc != <STR_LIT> ) ) { return false ; } isLdStMul = true ; break ; } } unsigned OffsetReg = <NUM_LIT> ; bool OffsetKill = false ; bool OffsetInternal = false ; if ( HasShift ) { OffsetReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; OffsetKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; OffsetInternal = MI -> getOperand ( <NUM_LIT> ) . isInternalRead ( ) ; if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) return false ; } unsigned OffsetImm = <NUM_LIT> ; if ( HasImmOffset ) { OffsetImm = MI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned MaxOffset = ( ( <NUM_LIT> << ImmLimit ) - <NUM_LIT> ) * Scale ; if ( ( OffsetImm & ( Scale - <NUM_LIT> ) ) || OffsetImm > MaxOffset ) return false ; } DebugLoc dl = MI -> getDebugLoc ( ) ; MachineInstrBuilder MIB = BuildMI ( MBB , MI , dl , TII -> get ( Opc ) ) ; if ( Entry . WideOpc == <STR_LIT> ) MIB . addReg ( MI -> getOperand ( <NUM_LIT> ) . getReg ( ) , RegState :: Define | RegState :: Dead ) ; if ( ! isLdStMul ) { MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; MIB . add ( MI -> getOperand ( <NUM_LIT> ) ) ; if ( HasImmOffset ) MIB . addImm ( OffsetImm / Scale ) ; assert ( ( ! HasShift || OffsetReg ) && <STR_LIT> ) ; if ( HasOffReg ) MIB . addReg ( OffsetReg , getKillRegState ( OffsetKill ) | getInternalReadRegState ( OffsetInternal ) ) ; } for ( unsigned e = MI -> getNumOperands ( ) ; OpNum != e ; ++ OpNum ) MIB . add ( MI -> getOperand ( OpNum ) ) ; MIB -> setMemRefs ( MI -> memoperands_begin ( ) , MI -> memoperands_end ( ) ) ; MIB . setMIFlags ( MI -> getFlags ( ) ) ; LLVM_DEBUG ( errs ( ) << <STR_LIT> << * MI << <STR_LIT> << * MIB ) ; MBB . erase_instr ( MI ) ;


<s> if ( getInstrPredicate ( * MI , PredReg ) == <STR_LIT> ) { switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } }


<s> switch ( Opc ) { default : break ; case <STR_LIT> : if ( ReduceTo2Addr ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ) return true ; LLVM_FALLTHROUGH ; case <STR_LIT> : return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } } break ; } case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : if ( MI -> getOperand ( <NUM_LIT> ) . isImm ( ) ) return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; break ; case <STR_LIT> : { static const ReduceEntry NarrowEntry = { <STR_LIT> , <STR_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> } ; if ( ReduceToNarrow ( MBB , MI , NarrowEntry , LiveCPSR , IsSelfLoop ) ) return true ; return ReduceToNarrow ( MBB , MI , Entry , LiveCPSR , IsSelfLoop ) ; } }