<s> auto * TPC = & getAnalysis < TargetPassConfig > ( ) ; if ( ! TPC ) return false ; const TargetMachine & TM = TPC -> getTM < TargetMachine > ( ) ; ST = & TM . getSubtarget < <ISA_LIT>Subtarget > ( F ) ; bool MadeChange = false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << F . getName ( ) << <STR_LIT> ) ; for ( BasicBlock & BB : F ) { auto & Insts = BB . getInstList ( ) ; for ( auto & I : Insts ) { if ( AllVisited . count ( & I ) ) continue ; if ( isa < ICmpInst > ( I ) ) { auto & CI = cast < ICmpInst > ( I ) ; if ( CI . isSigned ( ) || ! isa < IntegerType > ( CI . getOperand ( <NUM_LIT> ) -> getType ( ) ) ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << CI << <STR_LIT> ) ; for ( auto & Op : CI . operands ( ) ) { if ( auto * I = dyn_cast < Instruction > ( Op ) ) { if ( isa < ZExtInst > ( I ) ) MadeChange |= TryToPromote ( I -> getOperand ( <NUM_LIT> ) ) ; else MadeChange |= TryToPromote ( I ) ; } }


<s> auto & Insts = BB . getInstList ( ) ; for ( auto & I : Insts ) { if ( AllVisited . count ( & I ) ) continue ; if ( isa < ICmpInst > ( I ) ) { auto & CI = cast < ICmpInst > ( I ) ; if ( CI . isSigned ( ) || ! isa < IntegerType > ( CI . getOperand ( <NUM_LIT> ) -> getType ( ) ) ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << CI << <STR_LIT> ) ; for ( auto & Op : CI . operands ( ) ) { if ( auto * I = dyn_cast < Instruction > ( Op ) ) { if ( isa < ZExtInst > ( I ) ) MadeChange |= TryToPromote ( I -> getOperand ( <NUM_LIT> ) ) ; else MadeChange |= TryToPromote ( I ) ; } } } } Promoter -> Cleanup ( ) ; LLVM_DEBUG ( if ( verifyFunction ( F , & dbgs ( ) ) ) { dbgs ( ) ; report_fatal_error ( <STR_LIT> ) ; } ) ; } if ( MadeChange ) LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << F << <STR_LIT> ) ; return MadeChange ;


<s> if ( ! isa < IntegerType > ( V -> getType ( ) ) ) return false ; if ( isa < StoreInst > ( I ) || isa < TerminatorInst > ( I ) || isa < TruncInst > ( I ) || isa < ICmpInst > ( I ) ) return false ; if ( auto * ZExt = dyn_cast < ZExtInst > ( I ) ) return ! ZExt -> getDestTy ( ) -> isIntegerTy ( <NUM_LIT> ) ;


<s> return true ; } ; while ( ! WorkList . empty ( ) ) { Value * V = WorkList . back ( ) ; WorkList . pop_back ( ) ; if ( CurrentVisited . count ( V ) ) continue ; if ( ! isa < Instruction > ( V ) && ! isSource ( V ) ) continue ; if ( AllVisited . count ( V ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; return false ; } CurrentVisited . insert ( V ) ; AllVisited . insert ( V ) ; if ( isSink ( V ) ) Roots . insert ( cast < Instruction > ( V ) ) ; if ( isSource ( V ) ) Leaves . insert ( V ) ; else if ( auto * I = dyn_cast < Instruction > ( V ) ) { for ( auto & U : I -> operands ( ) ) { if ( ! AddLegalInst ( U ) ) return false ; } } if ( isSource ( V ) || shouldPromote ( V ) ) { for ( Use & U : V -> uses ( ) ) { if ( ! AddLegalInst ( U . getUser ( ) ) ) return false ; } } } unsigned NumToPromote = <NUM_LIT> ; unsigned Cost = <NUM_LIT> ; for ( auto * V : CurrentVisited ) { if ( isa < TruncInst > ( V ) ) ++ Cost ; else if ( auto * Arg = dyn_cast < Argument > ( V ) ) { if ( ! Arg -> hasZExtAttr ( ) ) ++ Cost ; } if ( Leaves . count ( V ) || isa < StoreInst > ( V ) || ! isa < Instruction > ( V ) ) continue ; if ( Roots . count ( cast < Instruction > ( V ) ) ) { ++ Cost ; continue ; } if ( shouldPromote ( V ) ) ++ NumToPromote ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; for ( auto * I : CurrentVisited ) I -> dump ( ) ;


<s> if ( auto * Const = dyn_cast < ConstantInt > ( CI -> getOperand ( <NUM_LIT> ) ) ) if ( Const -> isNegative ( ) ) return false ; if ( auto * Const = dyn_cast < ConstantInt > ( CI -> getOperand ( <NUM_LIT> ) ) ) if ( Const -> isNegative ( ) ) return false ; bool NegImm = cast < ConstantInt > ( I -> getOperand ( <NUM_LIT> ) ) -> isNegative ( ) ; bool IsDecreasing = ( ( Opc == Instruction :: Sub ) && ! NegImm ) || ( ( Opc == Instruction :: Add ) && NegImm ) ;


<s> auto InsertZExt = [ & ] ( Value * V , Instruction * InsertPt ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; Builder . SetInsertPoint ( InsertPt ) ; if ( auto * I = dyn_cast < Instruction > ( V ) ) Builder . SetCurrentDebugLocation ( I -> getDebugLoc ( ) ) ; auto * ZExt = cast < Instruction > ( Builder . CreateZExt ( V , ExtTy ) ) ; if ( isa < Argument > ( V ) ) ZExt -> moveBefore ( InsertPt ) ; else ZExt -> moveAfter ( InsertPt ) ; ReplaceAllUsersOfWith ( V , ZExt ) ; NewInsts . insert ( ZExt ) ; TruncTysMap [ ZExt ] = TruncTysMap [ V ] ; } ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; for ( auto V : Sources ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; if ( auto * I = dyn_cast < Instruction > ( V ) ) InsertZExt ( I , I ) ; else if ( auto * Arg = dyn_cast < Argument > ( V ) ) { BasicBlock & BB = Arg -> getParent ( ) -> front ( ) ; InsertZExt ( Arg , & * BB . getFirstInsertionPt ( ) ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } Promoted . insert ( V ) ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; for ( auto * V : Visited ) { if ( Sources . count ( V ) ) continue ; auto * I = cast < Instruction > ( V ) ; if ( Sinks . count ( I ) ) continue ; for ( unsigned i = <NUM_LIT> , e = I -> getNumOperands ( ) ; i < e ; ++ i ) { Value * Op = I -> getOperand ( i ) ; if ( ( Op -> getType ( ) == ExtTy ) || ! isa < IntegerType > ( Op -> getType ( ) ) ) continue ; if ( auto * Const = dyn_cast < ConstantInt > ( Op ) ) FixConst ( Const , I ) ; else if ( isa < UndefValue > ( Op ) ) I -> setOperand ( i , UndefValue :: get ( ExtTy ) ) ; } if ( shouldPromote ( I ) ) { I -> mutateType ( ExtTy ) ; Promoted . insert ( I ) ; } } for ( auto * V : Visited ) { if ( Sources . count ( V ) ) continue ;

if ( ! shouldPromote ( V ) || isPromotedResultSafe ( V ) ) continue ;


<s> Value * Src = ZExt -> getOperand ( <NUM_LIT> ) ; if ( ZExt -> getSrcTy ( ) == ZExt -> getDestTy ( ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * ZExt << <STR_LIT> ) ; ReplaceAllUsersOfWith ( ZExt , Src ) ; continue ; } if ( NewInsts . count ( Src ) && isa < TruncInst > ( Src ) && Src -> getType ( ) == OrigTy ) {

auto * Trunc = cast < TruncInst > ( Src ) ;


<s> if ( ! isa < Instruction > ( V ) ) return true ; if ( generateSignBits ( V ) ) return false ;

return ! isa < OverflowingBinaryOperator > ( V ) ;


<s> if ( generateSignBits ( V ) ) return false ;


<s> if ( isa < SExtInst > ( V ) ) return false ; if ( auto * Cast = dyn_cast < CastInst > ( V ) ) return isSupportedType ( Cast ) || isSupportedType ( Cast -> getOperand ( <NUM_LIT> ) ) ; if ( auto * Call = dyn_cast < CallInst > ( V ) ) return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; if ( ! isa < BinaryOperator > ( V ) ) return false ;

if ( ! isSupportedType ( V ) ) return false ;


<s> bool <ISA_LIT>CodeGenPrepare :: isSupportedValue ( Value * V ) { if ( auto * I = dyn_cast < ICmpInst > ( V ) ) { if ( isa < PointerType > ( I -> getOperand ( <NUM_LIT> ) -> getType ( ) ) ) return true ; return EqualTypeSize ( I -> getOperand ( <NUM_LIT> ) ) ; } if ( isa < StoreInst > ( V ) || isa < GetElementPtrInst > ( V ) ) return true ; if ( isa < BranchInst > ( V ) || isa < SwitchInst > ( V ) || isa < BasicBlock > ( V ) ) return true ; if ( ( isa < Constant > ( V ) && ! isa < ConstantExpr > ( V ) ) || isa < Argument > ( V ) ) return isSupportedType ( V ) ; if ( isa < PHINode > ( V ) || isa < SelectInst > ( V ) || isa < ReturnInst > ( V ) || isa < LoadInst > ( V ) ) return isSupportedType ( V ) ; if ( isa < SExtInst > ( V ) ) return false ; if ( auto * Cast = dyn_cast < CastInst > ( V ) ) return isSupportedType ( Cast ) || isSupportedType ( Cast -> getOperand ( <NUM_LIT> ) ) ; if ( auto * Call = dyn_cast < CallInst > ( V ) ) return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; if ( ! isa < BinaryOperator > ( V ) ) return false ; if ( ! isSupportedType ( V ) ) return false ; if ( generateSignBits ( V ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; }


<s> assert ( OrigTy -> getPrimitiveSizeInBits ( ) < ExtTy -> getPrimitiveSizeInBits ( ) && <STR_LIT> ) ; this -> Visited = & Visited ; this -> Sources = & Sources ; this -> Sinks = & Sinks ; this -> SafeToPromote = & SafeToPromote ; for ( auto * I : Sinks ) { if ( auto * Call = dyn_cast < CallInst > ( I ) ) { for ( unsigned i = <NUM_LIT> ; i < Call -> getNumArgOperands ( ) ; ++ i ) { Value * Arg = Call -> getArgOperand ( i ) ; TruncTysMap [ Call ] . push_back ( Arg -> getType ( ) ) ; } } else if ( auto * Switch = dyn_cast < SwitchInst > ( I ) ) TruncTysMap [ I ] . push_back ( Switch -> getCondition ( ) -> getType ( ) ) ; else { for ( unsigned i = <NUM_LIT> ; i < I -> getNumOperands ( ) ; ++ i ) TruncTysMap [ I ] . push_back ( I -> getOperand ( i ) -> getType ( ) ) ; } } PrepareConstants ( ) ; ExtendSources ( ) ; ConvertTruncs ( ) ; PromoteTree ( ) ;


<s> if ( ! isa < Instruction > ( V ) ) continue ; auto * I = cast < Instruction > ( V ) ; if ( SafeToPromote -> count ( I ) ) { if ( ! isa < OverflowingBinaryOperator > ( I ) ) continue ; if ( auto * Const = dyn_cast < ConstantInt > ( I -> getOperand ( <NUM_LIT> ) ) ) { if ( ! Const -> isNegative ( ) ) break ; unsigned Opc = I -> getOpcode ( ) ; if ( Opc != Instruction :: Add && Opc != Instruction :: Sub ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * I << <STR_LIT> ) ; auto * NewConst = ConstantInt :: get ( Ctx , Const -> getValue ( ) . abs ( ) ) ; Builder . SetInsertPoint ( I ) ; Value * NewVal = Opc == Instruction :: Sub ? Builder . CreateAdd ( I -> getOperand ( <NUM_LIT> ) , NewConst ) : Builder . CreateSub ( I -> getOperand ( <NUM_LIT> ) , NewConst ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * NewVal << <STR_LIT> ) ; if ( auto * NewInst = dyn_cast < Instruction > ( NewVal ) ) { NewInst -> copyIRFlags ( I ) ; NewInsts . insert ( NewInst ) ; } InstsToRemove . insert ( I ) ; I -> replaceAllUsesWith ( NewVal ) ; }


<s> } WorkList . insert ( V ) ; return true ; } ; while ( ! WorkList . empty ( ) ) { Value * V = WorkList . back ( ) ; WorkList . pop_back ( ) ; if ( CurrentVisited . count ( V ) ) continue ; if ( ! isa < Instruction > ( V ) && ! isSource ( V ) ) continue ; if ( AllVisited . count ( V ) ) return false ; CurrentVisited . insert ( V ) ; AllVisited . insert ( V ) ; if ( isSink ( V ) ) Sinks . insert ( cast < Instruction > ( V ) ) ; if ( isSource ( V ) ) Sources . insert ( V ) ; if ( ! isSink ( V ) && ! isSource ( V ) ) { if ( auto * I = dyn_cast < Instruction > ( V ) ) {


<s> Value * Src = ZExt -> getOperand ( <NUM_LIT> ) ; if ( ZExt -> getSrcTy ( ) == ZExt -> getDestTy ( ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * ZExt << <STR_LIT> ) ; ReplaceAllUsersOfWith ( ZExt , Src ) ; continue ; } if ( NewInsts . count ( Src ) && isa < TruncInst > ( Src ) && Src -> getType ( ) == OrigTy ) { auto * Trunc = cast < TruncInst > ( Src ) ; assert ( Trunc -> getOperand ( <NUM_LIT> ) -> getType ( ) == ExtTy && <STR_LIT> ) ; ReplaceAllUsersOfWith ( ZExt , Trunc -> getOperand ( <NUM_LIT> ) ) ; } }


<s> return Opc == Instruction :: AShr || Opc == Instruction :: SDiv || Opc == Instruction :: SRem || Opc == Instruction :: SExt ;


<s> if ( isa < PointerType > ( I -> getOperand ( <NUM_LIT> ) -> getType ( ) ) ) return true ; return EqualTypeSize ( I -> getOperand ( <NUM_LIT> ) ) ; case Instruction :: Call : { auto * Call = cast < CallInst > ( I ) ; return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; } } } else if ( isa < Constant > ( V ) && ! isa < ConstantExpr > ( V ) ) { return isSupportedType ( V ) ; } else if ( isa < Argument > ( V ) ) return isSupportedType ( V ) ;


<s> this -> OrigTy = cast < IntegerType > ( OrigTy ) ; assert ( OrigTy -> getPrimitiveSizeInBits ( ) < ExtTy -> getPrimitiveSizeInBits ( ) && <STR_LIT> ) ; this -> Visited = & Visited ; this -> Sources = & Sources ; this -> Sinks = & Sinks ; this -> SafeToPromote = & SafeToPromote ; for ( auto * I : Sinks ) { if ( auto * Call = dyn_cast < CallInst > ( I ) ) { for ( unsigned i = <NUM_LIT> ; i < Call -> getNumArgOperands ( ) ; ++ i ) { Value * Arg = Call -> getArgOperand ( i ) ;

TruncTysMap [ Call ] . push_back ( Arg -> getType ( ) ) ;


<s> if ( Opc != Instruction :: Add && Opc != Instruction :: Sub ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * I << <STR_LIT> ) ; auto * NewConst = ConstantInt :: get ( Ctx , Const -> getValue ( ) . abs ( ) ) ; Builder . SetInsertPoint ( I ) ; Value * NewVal = Opc == Instruction :: Sub ? Builder . CreateAdd ( I -> getOperand ( <NUM_LIT> ) , NewConst ) : Builder . CreateSub ( I -> getOperand ( <NUM_LIT> ) , NewConst ) ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * NewVal << <STR_LIT> ) ;

if ( auto * NewInst = dyn_cast < Instruction > ( NewVal ) ) {


<s> while ( ! WorkList . empty ( ) ) { Value * V = WorkList . back ( ) ; WorkList . pop_back ( ) ; if ( CurrentVisited . count ( V ) ) continue ; if ( ! isa < Instruction > ( V ) && ! isSource ( V ) ) continue ; if ( AllVisited . count ( V ) ) return false ; CurrentVisited . insert ( V ) ; AllVisited . insert ( V ) ; if ( isSink ( V ) ) Sinks . insert ( cast < Instruction > ( V ) ) ; if ( isSource ( V ) ) Sources . insert ( V ) ; if ( ! isSink ( V ) && ! isSource ( V ) ) { if ( auto * I = dyn_cast < Instruction > ( V ) ) { for ( auto & U : I -> operands ( ) ) { if ( ! AddLegalInst ( U ) ) return false ; } } } if ( isSource ( V ) || shouldPromote ( V ) ) { for ( Use & U : V -> uses ( ) ) { if ( ! AddLegalInst ( U . getUser ( ) ) ) return false ; } } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; for ( auto * I : CurrentVisited ) I -> dump ( ) ; ) ; unsigned ToPromote = <NUM_LIT> ; for ( auto * V : CurrentVisited ) {


<s> if ( ! isa < Instruction > ( V ) ) return false ;

unsigned Opc = cast < Instruction > ( V ) -> getOpcode ( ) ;


<s> static bool GenerateSignBits ( Value * V ) { if ( auto * Arg = dyn_cast < Argument > ( V ) ) return Arg -> hasSExtAttr ( ) ; if ( ! isa < Instruction > ( V ) ) return false ;


<s> if ( isa < PHINode > ( V ) || isa < SelectInst > ( V ) || isa < ReturnInst > ( V ) || isa < LoadInst > ( V ) ) return isSupportedType ( V ) ; if ( auto * Cast = dyn_cast < CastInst > ( V ) ) return isSupportedType ( Cast ) || isSupportedType ( Cast -> getOperand ( <NUM_LIT> ) ) ; if ( auto * Call = dyn_cast < CallInst > ( V ) ) return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; if ( ! isa < BinaryOperator > ( V ) ) return false ; if ( ! isSupportedType ( V ) ) return false ;


<s> } if ( isa < StoreInst > ( V ) || isa < GetElementPtrInst > ( V ) ) return true ; if ( isa < BranchInst > ( V ) || isa < SwitchInst > ( V ) || isa < BasicBlock > ( V ) ) return true ; if ( ( isa < Constant > ( V ) && ! isa < ConstantExpr > ( V ) ) || isa < Argument > ( V ) ) return isSupportedType ( V ) ; if ( isa < PHINode > ( V ) || isa < SelectInst > ( V ) || isa < ReturnInst > ( V ) || isa < LoadInst > ( V ) ) return isSupportedType ( V ) ; if ( auto * Cast = dyn_cast < CastInst > ( V ) ) return isSupportedType ( Cast ) || isSupportedType ( Cast -> getOperand ( <NUM_LIT> ) ) ; if ( auto * Call = dyn_cast < CallInst > ( V ) ) return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ;

if ( ! isa < BinaryOperator > ( V ) ) return false ;


<s> <ISA_LIT>CodeGenPrepare ( ) : FunctionPass ( ID ) {


<s> for ( auto * I : InstsToRemove ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * I << <STR_LIT> ) ; I -> dropAllReferences ( ) ; I -> eraseFromParent ( ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>CodeGenPreparePass ( ) {

return new <ISA_LIT>CodeGenPrepare ( ) ;


<s> Promoter = new IRPromoter ( & M ) ; return false ;


<s> if ( ! isa < Instruction > ( V ) ) return false ; unsigned Opc = cast < Instruction > ( V ) -> getOpcode ( ) ;

return Opc == Instruction :: AShr || Opc == Instruction :: SDiv || Opc == Instruction :: SRem ;


<s> void getAnalysisUsage ( AnalysisUsage & AU ) const override {

AU . addRequired < TargetPassConfig > ( ) ;


<s> break ; case Instruction :: Add : return <ISA_LIT>CodeGenPrepare :: TypeSize == <NUM_LIT> ? <STR_LIT> : <STR_LIT> ; case Instruction :: Sub : return <ISA_LIT>CodeGenPrepare :: TypeSize == <NUM_LIT> ? <STR_LIT> : <STR_LIT> ; } llvm_unreachable ( <STR_LIT> ) ;


<s> IRPromoter ( Module * M ) : M ( M ) , Ctx ( M -> getContext ( ) ) {


<s> if ( ! ST -> hasDSP ( ) || ! EnableDSP || ! isSupportedType ( I ) ) return false ; if ( ST -> isThumb ( ) && ! ST -> hasThumb2 ( ) ) return false ; if ( I -> getOpcode ( ) != Instruction :: Add && I -> getOpcode ( ) != Instruction :: Sub ) return false ; for ( auto & Op : I -> operands ( ) ) { if ( isa < Constant > ( Op ) ) { if ( ! EnableDSPWithImms ) return false ; } }


<s> auto * I = cast < Instruction > ( V ) ; if ( I -> hasOneUse ( ) && isSink ( * I -> use_begin ( ) ) ) return true ; if ( isa < OverflowingBinaryOperator > ( I ) ) return isSafeOverflow ( I ) ; return true ;


<s> if ( generateSignBits ( V ) ) return false ; auto * I = cast < Instruction > ( V ) ; if ( I -> hasOneUse ( ) && isSink ( * I -> use_begin ( ) ) ) return true ;

if ( isa < OverflowingBinaryOperator > ( I ) ) return isSafeOverflow ( I ) ;


<s> if ( CI -> isSigned ( ) ) return false ; bool NegImm = cast < ConstantInt > ( I -> getOperand ( <NUM_LIT> ) ) -> isNegative ( ) ; bool IsDecreasing = ( ( Opc == Instruction :: Sub ) && ! NegImm ) || ( ( Opc == Instruction :: Add ) && NegImm ) ; if ( ! IsDecreasing ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * I << <STR_LIT> ) ; return true ; } for ( auto & Op : I -> operands ( ) ) { if ( auto * Const = dyn_cast < ConstantInt > ( Op ) ) if ( Const -> isNegative ( ) ) return false ;


<s> auto UsesNarrowValue = [ ] ( Value * V ) { return V -> getType ( ) -> getScalarSizeInBits ( ) == <ISA_LIT>CodeGenPrepare :: TypeSize ; } ; if ( auto * Store = dyn_cast < StoreInst > ( V ) ) return UsesNarrowValue ( Store -> getValueOperand ( ) ) ; if ( auto * Return = dyn_cast < ReturnInst > ( V ) ) return UsesNarrowValue ( Return -> getReturnValue ( ) ) ; if ( auto * Trunc = dyn_cast < TruncInst > ( V ) ) return UsesNarrowValue ( Trunc -> getOperand ( <NUM_LIT> ) ) ;

if ( auto * ZExt = dyn_cast < ZExtInst > ( V ) ) return UsesNarrowValue ( ZExt -> getOperand ( <NUM_LIT> ) ) ;


<s> if ( isa < Argument > ( V ) ) return true ; else if ( isa < LoadInst > ( V ) ) return true ; else if ( auto * Call = dyn_cast < CallInst > ( V ) ) return Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ;


<s> if ( ! isa < IntegerType > ( V -> getType ( ) ) ) return false ; if ( isa < Argument > ( V ) ) return true ; else if ( isa < LoadInst > ( V ) ) return true ; else if ( auto * Call = dyn_cast < CallInst > ( V ) ) return Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; return false ;


<s> if ( auto * Ld = dyn_cast < LoadInst > ( V ) ) Ty = cast < PointerType > ( Ld -> getPointerOperandType ( ) ) -> getElementType ( ) ; const IntegerType * IntTy = dyn_cast < IntegerType > ( Ty ) ; if ( ! IntTy ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; }

return IntTy -> getBitWidth ( ) == <ISA_LIT>CodeGenPrepare :: TypeSize ;


<s> Type * Ty = V -> getType ( ) ; if ( Ty -> isVoidTy ( ) || Ty -> isPointerTy ( ) ) return true ; if ( auto * Ld = dyn_cast < LoadInst > ( V ) ) Ty = cast < PointerType > ( Ld -> getPointerOperandType ( ) ) -> getElementType ( ) ;

const IntegerType * IntTy = dyn_cast < IntegerType > ( Ty ) ;


<s> if ( isa < PHINode > ( V ) || isa < SelectInst > ( V ) || isa < ReturnInst > ( V ) || isa < LoadInst > ( V ) ) return isSupportedType ( V ) ; if ( auto * Trunc = dyn_cast < TruncInst > ( V ) ) return isSupportedType ( Trunc -> getOperand ( <NUM_LIT> ) ) ; if ( auto * ZExt = dyn_cast < ZExtInst > ( V ) ) return isSupportedType ( ZExt -> getOperand ( <NUM_LIT> ) ) ; if ( auto * Call = dyn_cast < CallInst > ( V ) ) return isSupportedType ( Call ) && Call -> hasRetAttr ( Attribute :: AttrKind :: ZExt ) ; if ( ! isa < BinaryOperator > ( V ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; return false ; }


<s> Builder . SetCurrentDebugLocation ( I -> getDebugLoc ( ) ) ; Value * Args [ ] = { I -> getOperand ( <NUM_LIT> ) , I -> getOperand ( <NUM_LIT> ) } ; CallInst * Call = Builder . CreateCall ( DSPInst , Args ) ; ReplaceAllUsersOfWith ( I , Call ) ; InstsToRemove . push_back ( I ) ; NewInsts . insert ( Call ) ; TruncTysMap [ Call ] = OrigTy ; } ; auto InsertZExt = [ & ] ( Value * V , Instruction * InsertPt ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; Builder . SetInsertPoint ( InsertPt ) ; if ( auto * I = dyn_cast < Instruction > ( V ) ) Builder . SetCurrentDebugLocation ( I -> getDebugLoc ( ) ) ; auto * ZExt = cast < Instruction > ( Builder . CreateZExt ( V , ExtTy ) ) ; if ( isa < Argument > ( V ) ) ZExt -> moveBefore ( InsertPt ) ; else ZExt -> moveAfter ( InsertPt ) ; ReplaceAllUsersOfWith ( V , ZExt ) ; NewInsts . insert ( ZExt ) ; TruncTysMap [ ZExt ] = TruncTysMap [ V ] ; } ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; for ( auto V : Sources ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; if ( auto * I = dyn_cast < Instruction > ( V ) ) InsertZExt ( I , I ) ; else if ( auto * Arg = dyn_cast < Argument > ( V ) ) { BasicBlock & BB = Arg -> getParent ( ) -> front ( ) ; InsertZExt ( Arg , & * BB . getFirstInsertionPt ( ) ) ; } else { llvm_unreachable ( <STR_LIT> ) ; } Promoted . insert ( V ) ; } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; for ( auto * V : Visited ) { if ( Sources . count ( V ) ) continue ; auto * I = cast < Instruction > ( V ) ; if ( Sinks . count ( I ) ) continue ; for ( unsigned i = <NUM_LIT> , e = I -> getNumOperands ( ) ; i < e ; ++ i ) { Value * Op = I -> getOperand ( i ) ; if ( ( Op -> getType ( ) == ExtTy ) || ! isa < IntegerType > ( Op -> getType ( ) ) ) continue ; if ( auto * Const = dyn_cast < ConstantInt > ( Op ) ) FixConst ( Const , I ) ; else if ( isa < UndefValue > ( Op ) ) I -> setOperand ( i , UndefValue :: get ( ExtTy ) ) ; } if ( shouldPromote ( I ) ) { I -> mutateType ( ExtTy ) ;


<s> auto & CI = cast < ICmpInst > ( I ) ; if ( CI . isSigned ( ) || ! isa < IntegerType > ( CI . getOperand ( <NUM_LIT> ) -> getType ( ) ) ) continue ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << CI << <STR_LIT> ) ; for ( auto & Op : CI . operands ( ) ) { if ( auto * I = dyn_cast < Instruction > ( Op ) ) MadeChange |= TryToPromote ( I ) ; } } } Promoter -> Cleanup ( ) ;

LLVM_DEBUG ( if ( verifyFunction ( F , & dbgs ( ) ) ) {


<s> static bool shouldPromote ( Value * V ) { if ( ! isa < IntegerType > ( V -> getType ( ) ) || isSink ( V ) ) {

LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ;


<s> TypeSize = OrigTy -> getPrimitiveSizeInBits ( ) ; if ( TypeSize > <NUM_LIT> || TypeSize < <NUM_LIT> ) return false ; if ( ! isSupportedValue ( V ) || ! shouldPromote ( V ) || ! isLegalToPromote ( V ) ) return false ; LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> << TypeSize << <STR_LIT> ) ; SetVector < Value * > WorkList ; SmallPtrSet < Value * , <NUM_LIT> > Sources ; SmallPtrSet < Instruction * , <NUM_LIT> > Sinks ; WorkList . insert ( V ) ; SmallPtrSet < Value * , <NUM_LIT> > CurrentVisited ; CurrentVisited . clear ( ) ; auto AddLegalInst = [ & ] ( Value * V ) { if ( CurrentVisited . count ( V ) ) return true ; if ( isa < GetElementPtrInst > ( V ) ) return true ; if ( ! isSupportedValue ( V ) || ( shouldPromote ( V ) && ! isLegalToPromote ( V ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; return false ; } WorkList . insert ( V ) ; return true ; } ; while ( ! WorkList . empty ( ) ) { Value * V = WorkList . back ( ) ; WorkList . pop_back ( ) ; if ( CurrentVisited . count ( V ) ) continue ; if ( ! isa < Instruction > ( V ) && ! isSource ( V ) ) continue ; if ( AllVisited . count ( V ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; return false ; } CurrentVisited . insert ( V ) ; AllVisited . insert ( V ) ; if ( isSink ( V ) ) Sinks . insert ( cast < Instruction > ( V ) ) ; if ( isSource ( V ) ) Sources . insert ( V ) ; else if ( auto * I = dyn_cast < Instruction > ( V ) ) { for ( auto & U : I -> operands ( ) ) { if ( ! AddLegalInst ( U ) ) return false ; } } if ( isSource ( V ) || shouldPromote ( V ) ) { for ( Use & U : V -> uses ( ) ) { if ( ! AddLegalInst ( U . getUser ( ) ) ) return false ; } } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; for ( auto * I : CurrentVisited ) I -> dump ( ) ; ) ; unsigned ToPromote = <NUM_LIT> ; for ( auto * V : CurrentVisited ) { if ( Sources . count ( V ) ) continue ; if ( Sinks . count ( cast < Instruction > ( V ) ) ) continue ; ++ ToPromote ; }

if ( ToPromote < <NUM_LIT> ) return false ;


<s> if ( ! isSupportedValue ( V ) || ( shouldPromote ( V ) && ! isLegalToPromote ( V ) ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; return false ; } WorkList . insert ( V ) ; return true ; } ; while ( ! WorkList . empty ( ) ) { Value * V = WorkList . back ( ) ; WorkList . pop_back ( ) ; if ( CurrentVisited . count ( V ) ) continue ; if ( ! isa < Instruction > ( V ) && ! isSource ( V ) ) continue ; if ( AllVisited . count ( V ) ) { LLVM_DEBUG ( dbgs ( ) << <STR_LIT> << * V << <STR_LIT> ) ; return false ; } CurrentVisited . insert ( V ) ; AllVisited . insert ( V ) ; if ( isSink ( V ) ) Sinks . insert ( cast < Instruction > ( V ) ) ; if ( isSource ( V ) ) Sources . insert ( V ) ; else if ( auto * I = dyn_cast < Instruction > ( V ) ) { for ( auto & U : I -> operands ( ) ) { if ( ! AddLegalInst ( U ) ) return false ; } } if ( isSource ( V ) || shouldPromote ( V ) ) { for ( Use & U : V -> uses ( ) ) { if ( ! AddLegalInst ( U . getUser ( ) ) ) return false ; } } } LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ; for ( auto * I : CurrentVisited ) I -> dump ( ) ; ) ; unsigned ToPromote = <NUM_LIT> ; for ( auto * V : CurrentVisited ) { if ( Sources . count ( V ) ) continue ; if ( Sinks . count ( cast < Instruction > ( V ) ) ) continue ; ++ ToPromote ; } if ( ToPromote < <NUM_LIT> ) return false ; Promoter -> Mutate ( OrigTy , CurrentVisited , Sources , Sinks ) ;


<s> std :: vector < BasicBlockInfo > BBInfo ;

BBInfo . resize ( MF -> getNumBlockIDs ( ) ) ;


<s> std :: vector < BasicBlockInfo > computeAllBlockSizes ( MachineFunction * MF ) { std :: vector < BasicBlockInfo > BBInfo ; BBInfo . resize ( MF -> getNumBlockIDs ( ) ) ; for ( MachineBasicBlock & MBB : * MF ) computeBlockSize ( MF , & MBB , BBInfo [ MBB . getNumber ( ) ] ) ;


<s> const <ISA_LIT>BaseInstrInfo * TII = static_cast < const <ISA_LIT>BaseInstrInfo * > ( MF -> getSubtarget ( ) . getInstrInfo ( ) ) ; bool isThumb = MF -> getInfo < <ISA_LIT>FunctionInfo > ( ) -> isThumbFunction ( ) ; BBI . Size = <NUM_LIT> ; BBI . Unalign = <NUM_LIT> ; BBI . PostAlign = <NUM_LIT> ; for ( MachineInstr & I : * MBB ) { BBI . Size += TII -> getInstSizeInBytes ( I ) ; if ( I . isInlineAsm ( ) ) BBI . Unalign = isThumb ? <NUM_LIT> : <NUM_LIT> ; else if ( isThumb && mayOptimizeThumb2Instruction ( & I ) ) BBI . Unalign = <NUM_LIT> ; } if ( ! MBB -> empty ( ) && MBB -> back ( ) . getOpcode ( ) == <STR_LIT> ) { BBI . PostAlign = <NUM_LIT> ; MBB -> getParent ( ) -> ensureAlignment ( <NUM_LIT> ) ; }


<s> if ( I . isInlineAsm ( ) ) BBI . Unalign = isThumb ? <NUM_LIT> : <NUM_LIT> ; else if ( isThumb && mayOptimizeThumb2Instruction ( & I ) ) BBI . Unalign = <NUM_LIT> ; }

if ( ! MBB -> empty ( ) && MBB -> back ( ) . getOpcode ( ) == <STR_LIT> ) {


<s> static bool mayOptimizeThumb2Instruction ( const MachineInstr * MI ) { switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> for ( unsigned i = BBNum + <NUM_LIT> , e = MF -> getNumBlockIDs ( ) ; i < e ; ++ i ) { unsigned LogAlign = MF -> getBlockNumbered ( i ) -> getAlignment ( ) ;

unsigned Offset = BBInfo [ i - <NUM_LIT> ] . postOffset ( LogAlign ) ;


<s> unsigned KnownBits = BBInfo [ i - <NUM_LIT> ] . postKnownBits ( LogAlign ) ;

if ( i > BBNum + <NUM_LIT> && BBInfo [ i ] . Offset == Offset && BBInfo [ i ] . KnownBits == KnownBits ) break ;


<s> SmallVector < MachineOperand , <NUM_LIT> > Cond ; SmallVector < MachineOperand , <NUM_LIT> > CondPrior ; MachineFunction :: iterator BBi = BB -> getIterator ( ) ; MachineFunction :: iterator OldPrior = std :: prev ( BBi ) ; bool B = TII -> AnalyzeBranch ( * BB , TBB , FBB , Cond ) ; if ( ! B && Cond . empty ( ) && BB != MF -> begin ( ) && ! TII -> AnalyzeBranch ( * OldPrior , TBB , FBB , CondPrior ) ) { BB -> moveAfter ( JTBB ) ; OldPrior -> updateTerminator ( ) ; BB -> updateTerminator ( ) ; MF -> RenumberBlocks ( ) ; ++ NumJTMoved ; return nullptr ; } MachineBasicBlock * NewBB = MF -> CreateMachineBasicBlock ( JTBB -> getBasicBlock ( ) ) ;

MachineFunction :: iterator MBBI = ++ JTBB -> getIterator ( ) ;


<s> <ISA_LIT>ConstantIslands ( ) : MachineFunctionPass ( ID ) {


<s> if ( std :: find ( MBB -> succ_begin ( ) , MBB -> succ_end ( ) , NextBB ) == MBB -> succ_end ( ) ) return false ; MachineBasicBlock * TBB , * FBB ;

SmallVector < MachineOperand , <NUM_LIT> > Cond ;


<s> static bool BBIsJumpedOver ( MachineBasicBlock * MBB ) { if ( MBB -> pred_size ( ) != <NUM_LIT> || MBB -> succ_size ( ) != <NUM_LIT> ) return false ; MachineBasicBlock * Succ = * MBB -> succ_begin ( ) ;

MachineBasicBlock * Pred = * MBB -> pred_begin ( ) ;


<s> static bool BBIsJumpedOver ( MachineBasicBlock * MBB ) { if ( MBB -> pred_size ( ) != <NUM_LIT> || MBB -> succ_size ( ) != <NUM_LIT> ) return false ;

MachineBasicBlock * Succ = * MBB -> succ_begin ( ) ;


<s> static bool CompareMBBNumbers ( const MachineBasicBlock * LHS , const MachineBasicBlock * RHS ) {

return LHS -> getNumber ( ) < RHS -> getNumber ( ) ;


<s> static bool CompareMBBNumbers ( const MachineBasicBlock * LHS , const MachineBasicBlock * RHS ) { return LHS -> getNumber ( ) < RHS -> getNumber ( ) ;


<s> ++ I ) { BBI . Size += TII -> GetInstSizeInBytes ( I ) ; if ( I -> isInlineAsm ( ) ) BBI . Unalign = isThumb ? <NUM_LIT> : <NUM_LIT> ; else if ( isThumb && mayOptimizeThumb2Instruction ( I ) ) BBI . Unalign = <NUM_LIT> ; } if ( ! MBB -> empty ( ) && MBB -> back ( ) . getOpcode ( ) == <STR_LIT> ) { BBI . PostAlign = <NUM_LIT> ; MBB -> getParent ( ) -> ensureAlignment ( <NUM_LIT> ) ;


<s> CPEntry ( MachineInstr * cpemi , unsigned cpi , unsigned rc = <NUM_LIT> ) : CPEMI ( cpemi ) , CPI ( cpi ) , RefCount ( rc ) {


<s> CPUser ( MachineInstr * mi , MachineInstr * cpemi , unsigned maxdisp , bool neg , bool soimm ) : MI ( mi ) , CPEMI ( cpemi ) , MaxDisp ( maxdisp ) , NegOk ( neg ) , IsSoImm ( soimm ) , KnownAlignment ( false ) { HighWaterMark = CPEMI -> getParent ( ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>ConstantIslandPass ( ) { return new <ISA_LIT>ConstantIslands ( ) ;


<s> unsigned MaxDisp = getUnconditionalBrDisp ( UncondBr ) ; ImmBranches . push_back ( ImmBranch ( & UserMBB -> back ( ) , MaxDisp , false , UncondBr ) ) ; computeBlockSize ( UserMBB ) ; adjustBBOffsetsAfter ( UserMBB ) ; return ; } } unsigned LogAlign = MF -> getAlignment ( ) ; assert ( LogAlign >= CPELogAlign && <STR_LIT> ) ; unsigned KnownBits = UserBBI . internalKnownBits ( ) ; unsigned UPad = UnknownPadding ( LogAlign , KnownBits ) ; unsigned BaseInsertOffset = UserOffset + U . getMaxDisp ( ) - UPad ; DEBUG ( dbgs ( ) << format ( <STR_LIT> , BaseInsertOffset ) ) ; BaseInsertOffset -= <NUM_LIT> ; DEBUG ( dbgs ( ) << format ( <STR_LIT> , BaseInsertOffset ) << <STR_LIT> << LogAlign << <STR_LIT> << KnownBits << <STR_LIT> << UPad << '\n' ) ; if ( BaseInsertOffset + <NUM_LIT> >= UserBBI . postOffset ( ) ) { BaseInsertOffset = std :: max ( UserBBI . postOffset ( ) - UPad - <NUM_LIT> , UserOffset + TII -> GetInstSizeInBytes ( UserMI ) + <NUM_LIT> ) ; DEBUG ( dbgs ( ) << format ( <STR_LIT> , BaseInsertOffset ) ) ; }

unsigned EndInsertOffset = BaseInsertOffset + <NUM_LIT> + UPad + CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ;


<s> if ( -- CPE -> RefCount == <NUM_LIT> ) { removeDeadCPEMI ( CPEMI ) ; CPE -> CPEMI = nullptr ; -- NumCPEs ; return true ;


<s> MF -> push_back ( BB ) ; unsigned MaxAlign = Log2_32 ( MCP -> getConstantPoolAlignment ( ) ) ; BB -> setAlignment ( MaxAlign ) ; MF -> ensureAlignment ( BB -> getAlignment ( ) ) ; SmallVector < MachineBasicBlock :: iterator , <NUM_LIT> > InsPoint ( MaxAlign + <NUM_LIT> , BB -> end ( ) ) ; const std :: vector < MachineConstantPoolEntry > & CPs = MCP -> getConstants ( ) ; const DataLayout & TD = MF -> getDataLayout ( ) ; for ( unsigned i = <NUM_LIT> , e = CPs . size ( ) ; i != e ; ++ i ) { unsigned Size = TD . getTypeAllocSize ( CPs [ i ] . getType ( ) ) ; assert ( Size >= <NUM_LIT> && <STR_LIT> ) ; unsigned Align = CPs [ i ] . getAlignment ( ) ;

assert ( isPowerOf2_32 ( Align ) && <STR_LIT> ) ;


<s> for ( unsigned i = <NUM_LIT> , e = CPs . size ( ) ; i != e ; ++ i ) { unsigned Size = TD . getTypeAllocSize ( CPs [ i ] . getType ( ) ) ; assert ( Size >= <NUM_LIT> && <STR_LIT> ) ; unsigned Align = CPs [ i ] . getAlignment ( ) ; assert ( isPowerOf2_32 ( Align ) && <STR_LIT> ) ; assert ( ( Size % Align ) == <NUM_LIT> && <STR_LIT> ) ; unsigned LogAlign = Log2_32 ( Align ) ; MachineBasicBlock :: iterator InsAt = InsPoint [ LogAlign ] ; MachineInstr * CPEMI = BuildMI ( * BB , InsAt , DebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addImm ( i ) . addConstantPoolIndex ( i ) . addImm ( Size ) ; CPEMIs . push_back ( CPEMI ) ; for ( unsigned a = LogAlign + <NUM_LIT> ; a <= MaxAlign ; ++ a ) if ( InsPoint [ a ] == InsAt ) InsPoint [ a ] = CPEMI ; CPEntries . emplace_back ( <NUM_LIT> , CPEntry ( CPEMI , i ) ) ; ++ NumCPEs ; DEBUG ( dbgs ( ) << <STR_LIT> << i << <STR_LIT> << Size << <STR_LIT> << Align << '\n' ) ;


<s> if ( MI == MBB . end ( ) ) continue ; unsigned JTOpcode ; switch ( MI -> getOpcode ( ) ) { default : continue ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : JTOpcode = <STR_LIT> ; break ; case <STR_LIT> : JTOpcode = <STR_LIT> ; break ; case <STR_LIT> : JTOpcode = <STR_LIT> ; break ; case <STR_LIT> : JTOpcode = <STR_LIT> ; break ; } unsigned NumOps = MI -> getDesc ( ) . getNumOperands ( ) ; MachineOperand JTOp = MI -> getOperand ( NumOps - ( MI -> isPredicable ( ) ? <NUM_LIT> : <NUM_LIT> ) ) ; unsigned JTI = JTOp . getIndex ( ) ; unsigned Size = JT [ JTI ] . MBBs . size ( ) * sizeof ( uint32_t ) ; MachineBasicBlock * JumpTableBB = MF -> CreateMachineBasicBlock ( ) ;

MF -> insert ( std :: next ( MachineFunction :: iterator ( MBB ) ) , JumpTableBB ) ;


<s> DEBUG ( { for ( unsigned J = <NUM_LIT> , E = BBInfo . size ( ) ; J != E ; ++ J ) { const BasicBlockInfo & BBI = BBInfo [ J ] ; dbgs ( ) << format ( <STR_LIT> , BBI . Offset , J ) << <STR_LIT> << unsigned ( BBI . KnownBits ) << <STR_LIT> << unsigned ( BBI . Unalign ) << <STR_LIT> << unsigned ( BBI . PostAlign ) << format ( <STR_LIT> , BBInfo [ J ] . Size ) ;


<s> if ( isWaterInRange ( UserOffset , WaterBB , U , Growth ) && ( WaterBB -> getNumber ( ) < U . HighWaterMark -> getNumber ( ) || NewWaterList . count ( WaterBB ) || WaterBB == U . MI -> getParent ( ) ) && Growth < BestGrowth ) { BestGrowth = Growth ; WaterIter = IP ; DEBUG ( dbgs ( ) << <STR_LIT> << WaterBB -> getNumber ( ) << <STR_LIT> << Growth << '\n' ) ; if ( BestGrowth == <NUM_LIT> ) return true ;


<s> MachineBasicBlock * WaterBB = * IP ; unsigned Growth ; if ( isWaterInRange ( UserOffset , WaterBB , U , Growth ) && ( WaterBB -> getNumber ( ) < U . HighWaterMark -> getNumber ( ) || NewWaterList . count ( WaterBB ) || WaterBB == U . MI -> getParent ( ) ) && Growth < BestGrowth ) { BestGrowth = Growth ; WaterIter = IP ; DEBUG ( dbgs ( ) << <STR_LIT> << WaterBB -> getNumber ( ) << <STR_LIT> << Growth << '\n' ) ; if ( BestGrowth == <NUM_LIT> ) return true ; }


<s> std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) return & CPEs [ i ] ; } return nullptr ;


<s> DEBUG ( dbgs ( ) << <STR_LIT> ) ; return <NUM_LIT> ; } unsigned CPI = getCombinedIndex ( CPEMI ) ; std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) continue ; if ( CPEs [ i ] . CPEMI == nullptr ) continue ; if ( isCPEntryInRange ( UserMI , UserOffset , CPEs [ i ] . CPEMI , U . getMaxDisp ( ) , U . NegOk ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << CPI << <STR_LIT> << CPEs [ i ] . CPI << <STR_LIT> ) ; U . CPEMI = CPEs [ i ] . CPEMI ; for ( unsigned j = <NUM_LIT> , e = UserMI -> getNumOperands ( ) ; j != e ; ++ j ) if ( UserMI -> getOperand ( j ) . isCPI ( ) ) { UserMI -> getOperand ( j ) . setIndex ( CPEs [ i ] . CPI ) ; break ; } CPEs [ i ] . RefCount ++ ; return decrementCPEReferenceCount ( CPI , CPEMI ) ? <NUM_LIT> : <NUM_LIT> ; } }


<s> CC = <STR_LIT> ( CC ) ; unsigned CCReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineBasicBlock * MBB = MI -> getParent ( ) ; MachineInstr * BMI = & MBB -> back ( ) ; bool NeedSplit = ( BMI != MI ) || ! BBHasFallthrough ( MBB ) ; ++ NumCBrFixed ; if ( BMI != MI ) { if ( std :: next ( MachineBasicBlock :: iterator ( MI ) ) == std :: prev ( MBB -> end ( ) ) && BMI -> getOpcode ( ) == Br . UncondBr ) { MachineBasicBlock * NewDest = BMI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( isBBInRange ( MI , NewDest , Br . MaxDisp ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * BMI ) ; BMI -> getOperand ( <NUM_LIT> ) . setMBB ( DestBB ) ; MI -> getOperand ( <NUM_LIT> ) . setMBB ( NewDest ) ; MI -> getOperand ( <NUM_LIT> ) . setImm ( CC ) ; return true ; } } } if ( NeedSplit ) { splitBlockBeforeInstr ( MI ) ; int delta = TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= delta ; MBB -> back ( ) . eraseFromParent ( ) ; } MachineBasicBlock * NextBB = & * ++ MBB -> getIterator ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << DestBB -> getNumber ( ) << <STR_LIT> << NextBB -> getNumber ( ) << <STR_LIT> ) ; BuildMI ( MBB , DebugLoc ( ) , TII -> get ( MI -> getOpcode ( ) ) ) . addMBB ( NextBB ) . addImm ( CC ) . addReg ( CCReg ) ; Br . MI = & MBB -> back ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; if ( isThumb ) BuildMI ( MBB , DebugLoc ( ) , TII -> get ( Br . UncondBr ) ) . addMBB ( DestBB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; else BuildMI ( MBB , DebugLoc ( ) , TII -> get ( Br . UncondBr ) ) . addMBB ( DestBB ) ; BBInfo [ MBB -> getNumber ( ) ] . Size += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; unsigned MaxDisp = getUnconditionalBrDisp ( Br . UncondBr ) ; ImmBranches . push_back ( ImmBranch ( & MBB -> back ( ) , MaxDisp , false , Br . UncondBr ) ) ; BBInfo [ MI -> getParent ( ) -> getNumber ( ) ] . Size -= TII -> GetInstSizeInBytes ( MI ) ; MI -> eraseFromParent ( ) ; adjustBBOffsetsAfter ( MBB ) ;


MachineBasicBlock * DestBB = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ;


<s> bool <ISA_LIT>ConstantIslands :: fixupUnconditionalBr ( ImmBranch & Br ) { MachineInstr * MI = Br . MI ; MachineBasicBlock * MBB = MI -> getParent ( ) ;

if ( ! isThumb1 ) llvm_unreachable ( <STR_LIT> ) ;


<s> if ( CPEMI -> getOperand ( <NUM_LIT> ) . isCPI ( ) ) return CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ;

return JumpTableEntryIndices [ CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ] ;


<s> return <NUM_LIT> ; default : llvm_unreachable ( <STR_LIT> ) ; } unsigned CPI = getCombinedIndex ( CPEMI ) ; assert ( CPI < MCP -> getConstants ( ) . size ( ) && <STR_LIT> ) ;

unsigned Align = MCP -> getConstants ( ) [ CPI ] . getAlignment ( ) ;


<s> llvm_unreachable ( <STR_LIT> ) ; } unsigned CPI = getCombinedIndex ( CPEMI ) ; assert ( CPI < MCP -> getConstants ( ) . size ( ) && <STR_LIT> ) ; unsigned Align = MCP -> getConstants ( ) [ CPI ] . getAlignment ( ) ;


<s> unsigned getMaxDisp ( ) const { return ( KnownAlignment ? MaxDisp : MaxDisp - <NUM_LIT> ) - <NUM_LIT> ;


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


<s> static inline unsigned getUnconditionalBrDisp ( int Opc ) { switch ( Opc ) { case <STR_LIT> :

return ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ;


<s> unsigned KnownBits = BBI . internalKnownBits ( ) ; UserOffset += ( isThumb ? <NUM_LIT> : <NUM_LIT> ) ; U . KnownAlignment = ( KnownBits >= <NUM_LIT> ) ;

if ( isThumb && U . KnownAlignment ) UserOffset &= ~ <NUM_LIT> ;


<s> unsigned <ISA_LIT>ConstantIslands :: getUserOffset ( CPUser & U ) const { unsigned UserOffset = getOffsetOf ( U . MI ) ; const BasicBlockInfo & BBI = BBInfo [ U . MI -> getParent ( ) -> getNumber ( ) ] ; unsigned KnownBits = BBI . internalKnownBits ( ) ;

UserOffset += ( isThumb ? <NUM_LIT> : <NUM_LIT> ) ;


<s> updateForInsertedWaterBlock ( NewIsland ) ; U . HighWaterMark = NewIsland ; U . CPEMI = BuildMI ( NewIsland , DebugLoc ( ) , CPEMI -> getDesc ( ) ) . addImm ( ID ) . addOperand ( CPEMI -> getOperand ( <NUM_LIT> ) ) . addImm ( Size ) ; CPEntries [ CPI ] . push_back ( CPEntry ( U . CPEMI , ID , <NUM_LIT> ) ) ; ++ NumCPEs ; decrementCPEReferenceCount ( CPI , CPEMI ) ; NewIsland -> setAlignment ( getCPELogAlign ( U . CPEMI ) ) ; BBInfo [ NewIsland -> getNumber ( ) ] . Size += Size ; adjustBBOffsetsAfter ( & * -- NewIsland -> getIterator ( ) ) ; for ( unsigned i = <NUM_LIT> , e = UserMI -> getNumOperands ( ) ; i != e ; ++ i ) if ( UserMI -> getOperand ( i ) . isCPI ( ) ) {

UserMI -> getOperand ( i ) . setIndex ( ID ) ;


<s> ImmBranch ( MachineInstr * mi , unsigned maxdisp , bool cond , unsigned ubr ) : MI ( mi ) , MaxDisp ( maxdisp ) , isCond ( cond ) , UncondBr ( ubr ) {


<s> unsigned PCAdj = isThumb ? <NUM_LIT> : <NUM_LIT> ; unsigned BrOffset = getOffsetOf ( MI ) + PCAdj ; unsigned DestOffset = BBInfo [ DestBB -> getNumber ( ) ] . Offset ; DEBUG ( dbgs ( ) << <STR_LIT> << DestBB -> getNumber ( ) << <STR_LIT> << MI -> getParent ( ) -> getNumber ( ) << <STR_LIT> << MaxDisp << <STR_LIT> << getOffsetOf ( MI ) << <STR_LIT> << DestOffset << <STR_LIT> << int ( DestOffset - BrOffset ) << <STR_LIT> << * MI ) ; if ( BrOffset <= DestOffset ) { if ( DestOffset - BrOffset <= MaxDisp ) return true ;


<s> const BasicBlockInfo & BBI = BBInfo [ Block ] ;

dbgs ( ) << <STR_LIT> << CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) << <STR_LIT> << MaxDisp << format ( <STR_LIT> , UserOffset ) << <STR_LIT> << Block << <STR_LIT> << format ( <STR_LIT> , BBI . Offset , BBI . postOffset ( ) ) << * MI << format ( <STR_LIT> , CPEOffset , int ( CPEOffset - UserOffset ) ) ;


<s> if ( TrialOffset - UserOffset <= MaxDisp ) return true ; } else if ( NegativeOK ) { if ( UserOffset - TrialOffset <= MaxDisp ) return true ; }


<s> if ( I . getOperand ( <NUM_LIT> ) . getReg ( ) != EntryReg ) return false ;

if ( I . getOperand ( <NUM_LIT> ) . getReg ( ) != BaseReg ) return false ;


<s> unsigned NextBlockOffset , NextBlockAlignment ; MachineFunction :: const_iterator NextBlock = Water -> getIterator ( ) ; if ( ++ NextBlock == MF -> end ( ) ) { NextBlockOffset = BBInfo [ Water -> getNumber ( ) ] . postOffset ( ) ; NextBlockAlignment = <NUM_LIT> ; } else {

NextBlockOffset = BBInfo [ NextBlock -> getNumber ( ) ] . Offset ;


<s> static bool jumpTableFollowsTB ( MachineInstr * JTMI , MachineInstr * CPEMI ) { MachineFunction :: iterator MBB = JTMI -> getParent ( ) -> getIterator ( ) ;

MachineFunction * MF = MBB -> getParent ( ) ;


<s> static bool jumpTableFollowsTB ( MachineInstr * JTMI , MachineInstr * CPEMI ) { MachineFunction :: iterator MBB = JTMI -> getParent ( ) -> getIterator ( ) ; MachineFunction * MF = MBB -> getParent ( ) ; ++ MBB ;

return MBB != MF -> end ( ) && MBB -> begin ( ) != MBB -> end ( ) && & * MBB -> begin ( ) == CPEMI ;


<s> bool <ISA_LIT>ConstantIslands :: mayOptimizeThumb2Instruction ( const MachineInstr * MI ) const { switch ( MI -> getOpcode ( ) ) { case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : case <STR_LIT> :


<s> MachineBasicBlock * MBB = Br . MI -> getParent ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ; adjustBBOffsetsAfter ( MBB ) ; ++ NumT2BrShrunk ; MadeChange = true ; } } Opcode = Br . MI -> getOpcode ( ) ; if ( Opcode != <STR_LIT> ) continue ; if ( ! Br . MI -> killsRegister ( <STR_LIT> ) ) continue ; NewOpc = <NUM_LIT> ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( Br . MI , PredReg ) ; if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; if ( ! NewOpc ) continue ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned BrOffset = getOffsetOf ( Br . MI ) + <NUM_LIT> - <NUM_LIT> ; unsigned DestOffset = BBInfo [ DestBB -> getNumber ( ) ] . Offset ; if ( BrOffset < DestOffset && ( DestOffset - BrOffset ) <= <NUM_LIT> ) { MachineBasicBlock :: iterator CmpMI = Br . MI ; if ( CmpMI != Br . MI -> getParent ( ) -> begin ( ) ) { -- CmpMI ; if ( CmpMI -> getOpcode ( ) == <STR_LIT> ) { unsigned Reg = CmpMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Pred = getInstrPredicate ( CmpMI , PredReg ) ;

if ( Pred == <STR_LIT> && CmpMI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> && is<ISA_LIT>LowRegister ( Reg ) ) {


<s> } if ( NewOpc ) { unsigned MaxOffs = ( ( <NUM_LIT> << ( Bits - <NUM_LIT> ) ) - <NUM_LIT> ) * Scale ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( isBBInRange ( Br . MI , DestBB , MaxOffs ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * Br . MI ) ; Br . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = Br . MI -> getParent ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ; adjustBBOffsetsAfter ( MBB ) ; ++ NumT2BrShrunk ; MadeChange = true ; } } Opcode = Br . MI -> getOpcode ( ) ; if ( Opcode != <STR_LIT> ) continue ; if ( ! Br . MI -> killsRegister ( <STR_LIT> ) ) continue ; NewOpc = <NUM_LIT> ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( Br . MI , PredReg ) ; if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; if ( ! NewOpc ) continue ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned BrOffset = getOffsetOf ( Br . MI ) + <NUM_LIT> - <NUM_LIT> ;

unsigned DestOffset = BBInfo [ DestBB -> getNumber ( ) ] . Offset ;


<s> unsigned Opcode = U . MI -> getOpcode ( ) ; unsigned NewOpc = <NUM_LIT> ; unsigned Scale = <NUM_LIT> ; unsigned Bits = <NUM_LIT> ; switch ( Opcode ) { default : break ; case <STR_LIT> : if ( is<ISA_LIT>LowRegister ( U . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; } break ; case <STR_LIT> : if ( is<ISA_LIT>LowRegister ( U . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; } break ; } if ( ! NewOpc ) continue ; unsigned UserOffset = getUserOffset ( U ) ; unsigned MaxOffs = ( ( <NUM_LIT> << Bits ) - <NUM_LIT> ) * Scale ; if ( ! U . KnownAlignment ) MaxOffs -= <NUM_LIT> ; if ( isCPEntryInRange ( U . MI , UserOffset , U . CPEMI , MaxOffs , false , true ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * U . MI ) ; U . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = U . MI -> getParent ( ) ;

BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ;


<s> break ; case <STR_LIT> : if ( is<ISA_LIT>LowRegister ( U . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ) ) { NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; } break ; } if ( ! NewOpc ) continue ; unsigned UserOffset = getUserOffset ( U ) ; unsigned MaxOffs = ( ( <NUM_LIT> << Bits ) - <NUM_LIT> ) * Scale ; if ( ! U . KnownAlignment ) MaxOffs -= <NUM_LIT> ; if ( isCPEntryInRange ( U . MI , UserOffset , U . CPEMI , MaxOffs , false , true ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * U . MI ) ; U . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = U . MI -> getParent ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ; adjustBBOffsetsAfter ( MBB ) ; ++ NumT2CPShrunk ; MadeChange = true ;


<s> if ( HalfWordOk && ( DstOffset - JTOffset ) > TBHLimit ) HalfWordOk = false ; if ( ! ByteOk && ! HalfWordOk ) break ; } if ( ! ByteOk && ! HalfWordOk ) continue ; MachineBasicBlock * MBB = MI -> getParent ( ) ; if ( ! MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ) continue ; unsigned IdxReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IdxRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; CPUser & User = CPUsers [ JumpTableUserIndices [ JTI ] ] ; unsigned DeadSize = <NUM_LIT> ; bool CanDeleteLEA = false ; bool BaseRegKill = false ; bool PreservedBaseReg = preserveBaseRegister ( MI , User . MI , DeadSize , CanDeleteLEA , BaseRegKill ) ; if ( ! jumpTableFollowsTB ( MI , User . CPEMI ) && ! PreservedBaseReg ) continue ; DEBUG ( dbgs ( ) << <STR_LIT> << * MI ) ; MachineInstr * CPEMI = User . CPEMI ; unsigned Opc = ByteOk ? <STR_LIT> : <STR_LIT> ; MachineBasicBlock :: iterator MI_JT = MI ; MachineInstr * NewJTMI = BuildMI ( * MBB , MI_JT , MI -> getDebugLoc ( ) , TII -> get ( Opc ) ) . addReg ( User . MI -> getOperand ( <NUM_LIT> ) . getReg ( ) , getKillRegState ( BaseRegKill ) ) . addReg ( IdxReg , getKillRegState ( IdxRegKill ) ) . addJumpTableIndex ( JTI , JTOP . getTargetFlags ( ) ) . addImm ( CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << MBB -> getNumber ( ) << <STR_LIT> << * NewJTMI ) ; unsigned JTOpc = ByteOk ? <STR_LIT> : <STR_LIT> ; CPEMI -> setDesc ( TII -> get ( JTOpc ) ) ; if ( jumpTableFollowsTB ( MI , User . CPEMI ) ) { NewJTMI -> getOperand ( <NUM_LIT> ) . setReg ( <STR_LIT> ) ; NewJTMI -> getOperand ( <NUM_LIT> ) . setIsKill ( false ) ; if ( CanDeleteLEA ) {


<s> if ( isSimpleIndexCalc ( * I , EntryReg , BaseReg ) ) { RemovableAdd = & * I ; break ; } for ( unsigned K = <NUM_LIT> , E = I -> getNumOperands ( ) ; K != E ; ++ K ) { const MachineOperand & MO = I -> getOperand ( K ) ; if ( ! MO . isReg ( ) || ! MO . getReg ( ) ) continue ; if ( MO . isDef ( ) && MO . getReg ( ) == BaseReg ) return false ; if ( MO . isUse ( ) && MO . getReg ( ) == BaseReg ) { BaseRegKill = BaseRegKill || MO . isKill ( ) ; CanDeleteLEA = false ; } } } if ( ! RemovableAdd ) return true ; for ( ++ I ; & * I != JumpMI ; ++ I ) { for ( unsigned K = <NUM_LIT> , E = I -> getNumOperands ( ) ; K != E ; ++ K ) { const MachineOperand & MO = I -> getOperand ( K ) ;


<s> if ( JumpMI -> getParent ( ) != LEAMI -> getParent ( ) ) return false ; unsigned EntryReg = JumpMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; unsigned BaseReg = LEAMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; CanDeleteLEA = true ; BaseRegKill = false ; MachineInstr * RemovableAdd = nullptr ; MachineBasicBlock :: iterator I ( LEAMI ) ; for ( ++ I ; & * I != JumpMI ; ++ I ) { if ( isSimpleIndexCalc ( * I , EntryReg , BaseReg ) ) { RemovableAdd = & * I ; break ; } for ( unsigned K = <NUM_LIT> , E = I -> getNumOperands ( ) ; K != E ; ++ K ) { const MachineOperand & MO = I -> getOperand ( K ) ; if ( ! MO . isReg ( ) || ! MO . getReg ( ) ) continue ; if ( MO . isDef ( ) && MO . getReg ( ) == BaseReg ) return false ; if ( MO . isUse ( ) && MO . getReg ( ) == BaseReg ) { BaseRegKill = BaseRegKill || MO . isKill ( ) ; CanDeleteLEA = false ; } }


<s> unsigned Size = CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; CPEMI -> eraseFromParent ( ) ; BBInfo [ CPEBB -> getNumber ( ) ] . Size -= Size ; if ( CPEBB -> empty ( ) ) { BBInfo [ CPEBB -> getNumber ( ) ] . Size = <NUM_LIT> ; CPEBB -> setAlignment ( <NUM_LIT> ) ; } else CPEBB -> setAlignment ( getCPELogAlign ( CPEBB -> begin ( ) ) ) ; adjustBBOffsetsAfter ( CPEBB ) ; assert ( ! BBIsJumpedOver ( CPEBB ) && <STR_LIT> ) ;


<s> std :: vector < CPEntry > & CPEs = CPEntries [ i ] ; for ( unsigned j = <NUM_LIT> , ee = CPEs . size ( ) ; j != ee ; ++ j ) { if ( CPEs [ j ] . RefCount == <NUM_LIT> && CPEs [ j ] . CPEMI ) { removeDeadCPEMI ( CPEs [ j ] . CPEMI ) ; CPEs [ j ] . CPEMI = nullptr ; MadeChange = true ; }


<s> const std :: vector < MachineJumpTableEntry > & JT = MJTI -> getJumpTables ( ) ; for ( unsigned i = <NUM_LIT> , e = T2JumpTables . size ( ) ; i != e ; ++ i ) { MachineInstr * MI = T2JumpTables [ i ] ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; unsigned NumOps = MCID . getNumOperands ( ) ; unsigned JTOpIdx = NumOps - ( MI -> isPredicable ( ) ? <NUM_LIT> : <NUM_LIT> ) ; MachineOperand JTOP = MI -> getOperand ( JTOpIdx ) ; unsigned JTI = JTOP . getIndex ( ) ; assert ( JTI < JT . size ( ) ) ; int JTNumber = MI -> getParent ( ) -> getNumber ( ) ;

const std :: vector < MachineBasicBlock * > & JTBBs = JT [ JTI ] . MBBs ;


<s> } std :: vector < MachineInstr * > CPEMIs ; if ( ! MCP -> isEmpty ( ) ) doInitialConstPlacement ( CPEMIs ) ; if ( MF -> getJumpTableInfo ( ) ) doInitialJumpTablePlacement ( CPEMIs ) ; AFI -> initPICLabelUId ( CPEMIs . size ( ) ) ; initializeFunctionInfo ( CPEMIs ) ; CPEMIs . clear ( ) ; DEBUG ( dumpBBs ( ) ) ; if ( ! T2JumpTables . empty ( ) ) MF -> ensureAlignment ( <NUM_LIT> ) ; MadeChange |= removeUnusedCPEntries ( ) ; unsigned NoCPIters = <NUM_LIT> , NoBRIters = <NUM_LIT> ; while ( true ) { DEBUG ( dbgs ( ) << <STR_LIT> << NoCPIters << '\n' ) ; bool CPChange = false ; for ( unsigned i = <NUM_LIT> , e = CPUsers . size ( ) ; i != e ; ++ i ) CPChange |= handleConstantPoolUser ( i ) ; if ( CPChange && ++ NoCPIters > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; DEBUG ( dumpBBs ( ) ) ; NewWaterList . clear ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << NoBRIters << '\n' ) ; bool BRChange = false ; for ( unsigned i = <NUM_LIT> , e = ImmBranches . size ( ) ; i != e ; ++ i ) BRChange |= fixupImmediateBr ( ImmBranches [ i ] ) ; if ( BRChange && ++ NoBRIters > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; DEBUG ( dumpBBs ( ) ) ; if ( ! CPChange && ! BRChange ) break ; MadeChange = true ; } if ( isThumb2 && ! STI -> prefers32BitThumb ( ) ) MadeChange |= optimizeThumb2Instructions ( ) ; verify ( ) ; if ( isThumb && ! HasFarJump && AFI -> isLRSpilledForFarJump ( ) ) MadeChange |= undoLRSpillRestore ( ) ; for ( unsigned i = <NUM_LIT> , e = CPEntries . size ( ) ; i != e ; ++ i ) { for ( unsigned j = <NUM_LIT> , je = CPEntries [ i ] . size ( ) ; j != je ; ++ j ) { const CPEntry & CPE = CPEntries [ i ] [ j ] ; if ( CPE . CPEMI && CPE . CPEMI -> getOperand ( <NUM_LIT> ) . isCPI ( ) ) AFI -> recordCPEClone ( i , CPE . CPI ) ; } } DEBUG ( dbgs ( ) << '\n' ; dumpBBs ( ) ) ; BBInfo . clear ( ) ; WaterList . clear ( ) ;


<s> I != E ; ++ I ) if ( I -> isBranch ( ) && I -> getOpcode ( ) == <STR_LIT> ) T2JumpTables . push_back ( I ) ; }


<s> if ( ! isThumb ) BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) ; else BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; ++ NumSplit ; NewBB -> transferSuccessors ( OrigBB ) ; OrigBB -> addSuccessor ( NewBB ) ; MF -> RenumberBlocks ( NewBB ) ; BBInfo . insert ( BBInfo . begin ( ) + NewBB -> getNumber ( ) , BasicBlockInfo ( ) ) ; water_iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , OrigBB , CompareMBBNumbers ) ; MachineBasicBlock * WaterBB = * IP ; if ( WaterBB == OrigBB ) WaterList . insert ( std :: next ( IP ) , NewBB ) ; else WaterList . insert ( IP , OrigBB ) ; NewWaterList . insert ( OrigBB ) ;


<s> MachineBasicBlock * OrigBB = MI -> getParent ( ) ; MachineBasicBlock * NewBB = MF -> CreateMachineBasicBlock ( OrigBB -> getBasicBlock ( ) ) ; MachineFunction :: iterator MBBI = ++ OrigBB -> getIterator ( ) ; MF -> insert ( MBBI , NewBB ) ; NewBB -> splice ( NewBB -> end ( ) , OrigBB , MI , OrigBB -> end ( ) ) ; unsigned Opc = isThumb ? ( isThumb2 ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ; if ( ! isThumb ) BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) ; else BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; ++ NumSplit ; NewBB -> transferSuccessors ( OrigBB ) ; OrigBB -> addSuccessor ( NewBB ) ; MF -> RenumberBlocks ( NewBB ) ; BBInfo . insert ( BBInfo . begin ( ) + NewBB -> getNumber ( ) , BasicBlockInfo ( ) ) ;

water_iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , OrigBB , CompareMBBNumbers ) ;


<s> MachineInstr * MI = PushPopMIs [ i ] ; if ( MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == <STR_LIT> && MI -> getNumExplicitOperands ( ) == <NUM_LIT> ) { BuildMI ( MI -> getParent ( ) , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) . addOperand ( MI -> getOperand ( <NUM_LIT> ) ) ; MI -> eraseFromParent ( ) ; MadeChange = true ; } } return MadeChange ;


<s> if ( KnownBits < LogAlign ) return ( <NUM_LIT> << LogAlign ) - ( <NUM_LIT> << KnownBits ) ;


<s> if ( KnownBits < LogAlign ) return ( <NUM_LIT> << LogAlign ) - ( <NUM_LIT> << KnownBits ) ; return <NUM_LIT> ;


<s> NewBB -> getParent ( ) -> RenumberBlocks ( NewBB ) ; BBInfo . insert ( BBInfo . begin ( ) + NewBB -> getNumber ( ) , BasicBlockInfo ( ) ) ; water_iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , NewBB , CompareMBBNumbers ) ; WaterList . insert ( IP , NewBB ) ;


<s> water_iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , NewBB , CompareMBBNumbers ) ; WaterList . insert ( IP , NewBB ) ;


<s> MachineBasicBlock * MBB = & * MBBI ; unsigned MBBId = MBB -> getNumber ( ) ; assert ( ! MBBId || BBInfo [ MBBId - <NUM_LIT> ] . postOffset ( ) <= BBInfo [ MBBId ] . Offset ) ; } DEBUG ( dbgs ( ) << <STR_LIT> << CPUsers . size ( ) << <STR_LIT> ) ; for ( unsigned i = <NUM_LIT> , e = CPUsers . size ( ) ; i != e ; ++ i ) {


<s> return NULL ; } MachineBasicBlock * NewBB = MF -> CreateMachineBasicBlock ( JTBB -> getBasicBlock ( ) ) ; MachineFunction :: iterator MBBI = JTBB ; ++ MBBI ; MF -> insert ( MBBI , NewBB ) ; assert ( isThumb2 && <STR_LIT> ) ; BuildMI ( NewBB , DebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addMBB ( BB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; MF -> RenumberBlocks ( NewBB ) ; NewBB -> addSuccessor ( BB ) ; JTBB -> removeSuccessor ( BB ) ; JTBB -> addSuccessor ( NewBB ) ; ++ NumJTInserted ; return NewBB ;


<s> MachineBasicBlock * TBB = <NUM_LIT> , * FBB = <NUM_LIT> ; SmallVector < MachineOperand , <NUM_LIT> > Cond ; SmallVector < MachineOperand , <NUM_LIT> > CondPrior ; MachineFunction :: iterator BBi = BB ; MachineFunction :: iterator OldPrior = prior ( BBi ) ; bool B = TII -> AnalyzeBranch ( * BB , TBB , FBB , Cond ) ; if ( ! B && Cond . empty ( ) && BB != MF -> begin ( ) && ! TII -> AnalyzeBranch ( * OldPrior , TBB , FBB , CondPrior ) ) { BB -> moveAfter ( JTBB ) ; OldPrior -> updateTerminator ( ) ; BB -> updateTerminator ( ) ; MF -> RenumberBlocks ( ) ; ++ NumJTMoved ; return NULL ; } MachineBasicBlock * NewBB = MF -> CreateMachineBasicBlock ( JTBB -> getBasicBlock ( ) ) ; MachineFunction :: iterator MBBI = JTBB ; ++ MBBI ; MF -> insert ( MBBI , NewBB ) ; assert ( isThumb2 && <STR_LIT> ) ; BuildMI ( NewBB , DebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addMBB ( BB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; MF -> RenumberBlocks ( NewBB ) ; NewBB -> addSuccessor ( BB ) ;


<s> MachineFunction :: iterator MBBI = MBB ; if ( llvm :: next ( MBBI ) == MBB -> getParent ( ) -> end ( ) ) return false ; MachineBasicBlock * NextBB = llvm :: next ( MBBI ) ;

for ( MachineBasicBlock :: succ_iterator I = MBB -> succ_begin ( ) , E = MBB -> succ_end ( ) ; I != E ; ++ I ) if ( * I == NextBB ) return true ;


<s> static bool BBHasFallthrough ( MachineBasicBlock * MBB ) { MachineFunction :: iterator MBBI = MBB ;

if ( llvm :: next ( MBBI ) == MBB -> getParent ( ) -> end ( ) ) return false ;


<s> for ( MachineBasicBlock :: iterator I = MBB -> begin ( ) , E = MBB -> end ( ) ; I != E ; ++ I ) { BBI . Size += TII -> GetInstSizeInBytes ( I ) ; if ( I -> isInlineAsm ( ) ) BBI . Unalign = isThumb ? <NUM_LIT> : <NUM_LIT> ;

else if ( isThumb && mayOptimizeThumb2Instruction ( I ) ) BBI . Unalign = <NUM_LIT> ;


<s> BBI . Size += TII -> GetInstSizeInBytes ( I ) ; if ( I -> isInlineAsm ( ) ) BBI . Unalign = isThumb ? <NUM_LIT> : <NUM_LIT> ; else if ( isThumb && mayOptimizeThumb2Instruction ( I ) ) BBI . Unalign = <NUM_LIT> ; }

if ( ! MBB -> empty ( ) && MBB -> back ( ) . getOpcode ( ) == <STR_LIT> ) {


<s> unsigned BaseInsertOffset = UserOffset + U . getMaxDisp ( ) ; DEBUG ( dbgs ( ) << format ( <STR_LIT> , BaseInsertOffset ) ) ; BaseInsertOffset &= ~ ( ( <NUM_LIT> << LogAlign ) - <NUM_LIT> ) ; BaseInsertOffset -= UPad ; BaseInsertOffset -= <NUM_LIT> ; DEBUG ( dbgs ( ) << format ( <STR_LIT> , BaseInsertOffset ) << <STR_LIT> << LogAlign << <STR_LIT> << KnownBits << <STR_LIT> << UPad << '\n' ) ; if ( BaseInsertOffset >= BBInfo [ UserMBB -> getNumber ( ) + <NUM_LIT> ] . Offset ) BaseInsertOffset = BBInfo [ UserMBB -> getNumber ( ) + <NUM_LIT> ] . Offset - ( isThumb1 ? <NUM_LIT> : <NUM_LIT> ) ; unsigned EndInsertOffset = WorstCaseAlign ( BaseInsertOffset + <NUM_LIT> , LogAlign , KnownBits ) + CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; MachineBasicBlock :: iterator MI = UserMI ; ++ MI ; unsigned CPUIndex = CPUserIndex + <NUM_LIT> ; unsigned NumCPUsers = CPUsers . size ( ) ; MachineInstr * LastIT = <NUM_LIT> ; for ( unsigned Offset = UserOffset + TII -> GetInstSizeInBytes ( UserMI ) ; Offset < BaseInsertOffset ; Offset += TII -> GetInstSizeInBytes ( MI ) , MI = llvm :: next ( MI ) ) { if ( CPUIndex < NumCPUsers && CPUsers [ CPUIndex ] . MI == MI ) { CPUser & U = CPUsers [ CPUIndex ] ; if ( ! isOffsetInRange ( Offset , EndInsertOffset , U ) ) { BaseInsertOffset -= <NUM_LIT> << LogAlign ; EndInsertOffset -= <NUM_LIT> << LogAlign ; } EndInsertOffset = RoundUpToAlignment ( EndInsertOffset , <NUM_LIT> << getCPELogAlign ( U . CPEMI ) ) + U . CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; CPUIndex ++ ; } if ( MI -> getOpcode ( ) == <STR_LIT> ) LastIT = MI ; } -- MI ; if ( LastIT ) { unsigned PredReg = <NUM_LIT> ; <STR_LIT> CC = getITInstrPredicate ( MI , PredReg ) ; if ( CC != <STR_LIT> ) MI = LastIT ; }


<s> CPEntry * CPE = findConstPoolEntry ( CPI , CPEMI ) ; assert ( CPE && <STR_LIT> ) ; if ( -- CPE -> RefCount == <NUM_LIT> ) { removeDeadCPEMI ( CPEMI ) ; CPE -> CPEMI = NULL ; -- NumCPEs ; return true ; } return false ;


<s> assert ( CPE && <STR_LIT> ) ; if ( -- CPE -> RefCount == <NUM_LIT> ) { removeDeadCPEMI ( CPEMI ) ; CPE -> CPEMI = NULL ; -- NumCPEs ; return true ;


<s> assert ( ( Size % Align ) == <NUM_LIT> && <STR_LIT> ) ; unsigned LogAlign = Log2_32 ( Align ) ; MachineBasicBlock :: iterator InsAt = InsPoint [ LogAlign ] ; MachineInstr * CPEMI = BuildMI ( * BB , InsAt , DebugLoc ( ) , TII -> get ( <STR_LIT> ) ) . addImm ( i ) . addConstantPoolIndex ( i ) . addImm ( Size ) ; CPEMIs . push_back ( CPEMI ) ; for ( unsigned a = LogAlign + <NUM_LIT> ; a <= MaxAlign ; ++ a ) if ( InsPoint [ a ] == InsAt ) InsPoint [ a ] = CPEMI ; std :: vector < CPEntry > CPEs ; CPEs . push_back ( CPEntry ( CPEMI , i ) ) ; CPEntries . push_back ( CPEs ) ; ++ NumCPEs ;

DEBUG ( dbgs ( ) << <STR_LIT> << i << <STR_LIT> << Size << <STR_LIT> << Align << '\n' ) ;


<s> if ( isWaterInRange ( UserOffset , WaterBB , U , Growth ) && ( WaterBB -> getNumber ( ) < U . HighWaterMark -> getNumber ( ) || NewWaterList . count ( WaterBB ) ) && Growth < BestGrowth ) { BestGrowth = Growth ; WaterIter = IP ; DEBUG ( dbgs ( ) << <STR_LIT> << WaterBB -> getNumber ( ) << <STR_LIT> << Growth << '\n' ) ; if ( BestGrowth == <NUM_LIT> ) return true ; } if ( IP == B ) break ; }


<s> <ISA_LIT>ConstantIslands :: CPEntry * <ISA_LIT>ConstantIslands :: findConstPoolEntry ( unsigned CPI , const MachineInstr * CPEMI ) { std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) return & CPEs [ i ] ; }


<s> DEBUG ( dbgs ( ) << <STR_LIT> ) ; return <NUM_LIT> ; } unsigned CPI = CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) continue ; if ( CPEs [ i ] . CPEMI == NULL ) continue ; if ( isCPEntryInRange ( UserMI , UserOffset , CPEs [ i ] . CPEMI , U . getMaxDisp ( ) , U . NegOk ) ) {

DEBUG ( dbgs ( ) << <STR_LIT> << CPI << <STR_LIT> << CPEs [ i ] . CPI << <STR_LIT> ) ;


<s> bool NeedSplit = ( BMI != MI ) || ! BBHasFallthrough ( MBB ) ; ++ NumCBrFixed ; if ( BMI != MI ) { if ( llvm :: next ( MachineBasicBlock :: iterator ( MI ) ) == prior ( MBB -> end ( ) ) && BMI -> getOpcode ( ) == Br . UncondBr ) { MachineBasicBlock * NewDest = BMI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( isBBInRange ( MI , NewDest , Br . MaxDisp ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * BMI ) ; BMI -> getOperand ( <NUM_LIT> ) . setMBB ( DestBB ) ; MI -> getOperand ( <NUM_LIT> ) . setMBB ( NewDest ) ; MI -> getOperand ( <NUM_LIT> ) . setImm ( CC ) ; return true ; } } } if ( NeedSplit ) { splitBlockBeforeInstr ( MI ) ; int delta = TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= delta ; MBB -> back ( ) . eraseFromParent ( ) ; } MachineBasicBlock * NextBB = llvm :: next ( MachineFunction :: iterator ( MBB ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << DestBB -> getNumber ( ) << <STR_LIT> << NextBB -> getNumber ( ) << <STR_LIT> ) ; BuildMI ( MBB , DebugLoc ( ) , TII -> get ( MI -> getOpcode ( ) ) ) . addMBB ( NextBB ) . addImm ( CC ) . addReg ( CCReg ) ; Br . MI = & MBB -> back ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; if ( isThumb ) BuildMI ( MBB , DebugLoc ( ) , TII -> get ( Br . UncondBr ) ) . addMBB ( DestBB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; else BuildMI ( MBB , DebugLoc ( ) , TII -> get ( Br . UncondBr ) ) . addMBB ( DestBB ) ; BBInfo [ MBB -> getNumber ( ) ] . Size += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ;

unsigned MaxDisp = getUnconditionalBrDisp ( Br . UncondBr ) ;


<s> unsigned CCReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; MachineBasicBlock * MBB = MI -> getParent ( ) ; MachineInstr * BMI = & MBB -> back ( ) ; bool NeedSplit = ( BMI != MI ) || ! BBHasFallthrough ( MBB ) ; ++ NumCBrFixed ; if ( BMI != MI ) { if ( llvm :: next ( MachineBasicBlock :: iterator ( MI ) ) == prior ( MBB -> end ( ) ) && BMI -> getOpcode ( ) == Br . UncondBr ) { MachineBasicBlock * NewDest = BMI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( isBBInRange ( MI , NewDest , Br . MaxDisp ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * BMI ) ; BMI -> getOperand ( <NUM_LIT> ) . setMBB ( DestBB ) ; MI -> getOperand ( <NUM_LIT> ) . setMBB ( NewDest ) ; MI -> getOperand ( <NUM_LIT> ) . setImm ( CC ) ; return true ; } } } if ( NeedSplit ) { splitBlockBeforeInstr ( MI ) ; int delta = TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= delta ; MBB -> back ( ) . eraseFromParent ( ) ; } MachineBasicBlock * NextBB = llvm :: next ( MachineFunction :: iterator ( MBB ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << DestBB -> getNumber ( ) << <STR_LIT> << NextBB -> getNumber ( ) << <STR_LIT> ) ; BuildMI ( MBB , DebugLoc ( ) , TII -> get ( MI -> getOpcode ( ) ) ) . addMBB ( NextBB ) . addImm ( CC ) . addReg ( CCReg ) ;


<s> assert ( CPI < MCP -> getConstants ( ) . size ( ) && <STR_LIT> ) ; unsigned Align = MCP -> getConstants ( ) [ CPI ] . getAlignment ( ) ;

assert ( isPowerOf2_32 ( Align ) && <STR_LIT> ) ;


<s> virtual const char * getPassName ( ) const {


<s> int result = findInRangeCPEntry ( U , UserOffset ) ; if ( result == <NUM_LIT> ) return false ; else if ( result == <NUM_LIT> ) return true ; unsigned ID = AFI -> createPICLabelUId ( ) ; MachineBasicBlock * NewIsland = MF -> CreateMachineBasicBlock ( ) ; MachineBasicBlock * NewMBB ; water_iterator IP ; if ( findAvailableWater ( U , UserOffset , IP ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; MachineBasicBlock * WaterBB = * IP ; if ( NewWaterList . count ( WaterBB ) ) { NewWaterList . erase ( WaterBB ) ; NewWaterList . insert ( NewIsland ) ; } NewMBB = llvm :: next ( MachineFunction :: iterator ( WaterBB ) ) ; } else { DEBUG ( dbgs ( ) << <STR_LIT> ) ; createNewWater ( CPUserIndex , UserOffset , NewMBB ) ; MachineBasicBlock * WaterBB = prior ( MachineFunction :: iterator ( NewMBB ) ) ;

IP = std :: find ( WaterList . begin ( ) , WaterList . end ( ) , WaterBB ) ;


<s> ImmBranch ( MachineInstr * mi , unsigned maxdisp , bool cond , int ubr ) : MI ( mi ) , MaxDisp ( maxdisp ) , isCond ( cond ) , UncondBr ( ubr ) {


<s> if ( I -> isBranch ( ) ) { bool isCond = false ; unsigned Bits = <NUM_LIT> ; unsigned Scale = <NUM_LIT> ; int UOpc = Opc ; switch ( Opc ) { default : continue ; case <STR_LIT> : T2JumpTables . push_back ( I ) ; continue ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; } unsigned MaxOffs = ( ( <NUM_LIT> << ( Bits - <NUM_LIT> ) ) - <NUM_LIT> ) * Scale ; ImmBranches . push_back ( ImmBranch ( I , MaxOffs , isCond , UOpc ) ) ; } if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) PushPopMIs . push_back ( I ) ; if ( Opc == <STR_LIT> ) continue ; for ( unsigned op = <NUM_LIT> , e = I -> getNumOperands ( ) ; op != e ; ++ op ) if ( I -> getOperand ( op ) . isCPI ( ) ) { unsigned Bits = <NUM_LIT> ; unsigned Scale = <NUM_LIT> ; bool NegOk = false ;


<s> unsigned internalKnownBits ( ) const {


<s> DEBUG ( { unsigned Block = MI -> getParent ( ) -> getNumber ( ) ; const BasicBlockInfo & BBI = BBInfo [ Block ] ; dbgs ( ) << <STR_LIT> << CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) << <STR_LIT> << MaxDisp << format ( <STR_LIT> , UserOffset ) << <STR_LIT> << Block << <STR_LIT> << format ( <STR_LIT> , BBI . Offset , BBI . postOffset ( ) ) << * MI << format ( <STR_LIT> , CPEOffset , int ( CPEOffset - UserOffset ) ) ;


<s> } else { NextBlockOffset = BBInfo [ NextBlock -> getNumber ( ) ] . Offset ; NextBlockAlignment = NextBlock -> getAlignment ( ) ; } unsigned Size = U . CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; unsigned CPEEnd = CPEOffset + Size ; if ( CPEEnd > NextBlockOffset ) { Growth = CPEEnd - NextBlockOffset ; Growth += OffsetToAlignment ( CPEEnd , <NUM_LIT> << NextBlockAlignment ) ; if ( CPEOffset < UserOffset ) UserOffset += Growth + UnknownPadding ( MF -> getAlignment ( ) , CPELogAlign ) ; } else Growth = <NUM_LIT> ; return isOffsetInRange ( UserOffset , CPEOffset , U ) ;


<s> MachineBasicBlock * MBB = Br . MI -> getParent ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ; adjustBBOffsetsAfter ( MBB ) ; ++ NumT2BrShrunk ; MadeChange = true ; } } Opcode = Br . MI -> getOpcode ( ) ; if ( Opcode != <STR_LIT> ) continue ; if ( ! Br . MI -> killsRegister ( <STR_LIT> ) ) continue ; NewOpc = <NUM_LIT> ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( Br . MI , PredReg ) ; if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; else if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ; if ( ! NewOpc ) continue ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; unsigned BrOffset = getOffsetOf ( Br . MI ) + <NUM_LIT> - <NUM_LIT> ; unsigned DestOffset = BBInfo [ DestBB -> getNumber ( ) ] . Offset ; if ( BrOffset < DestOffset && ( DestOffset - BrOffset ) <= <NUM_LIT> ) { MachineBasicBlock :: iterator CmpMI = Br . MI ; if ( CmpMI != Br . MI -> getParent ( ) -> begin ( ) ) { -- CmpMI ; if ( CmpMI -> getOpcode ( ) == <STR_LIT> ) { unsigned Reg = CmpMI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; Pred = getInstrPredicate ( CmpMI , PredReg ) ; if ( Pred == <STR_LIT> && CmpMI -> getOperand ( <NUM_LIT> ) . getImm ( ) == <NUM_LIT> && is<ISA_LIT>LowRegister ( Reg ) ) { MachineBasicBlock * MBB = Br . MI -> getParent ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << * CmpMI << <STR_LIT> << * Br . MI ) ; MachineInstr * NewBR = BuildMI ( * MBB , CmpMI , Br . MI -> getDebugLoc ( ) , TII -> get ( NewOpc ) ) . addReg ( Reg ) . addMBB ( DestBB , Br . MI -> getOperand ( <NUM_LIT> ) . getTargetFlags ( ) ) ; CmpMI -> eraseFromParent ( ) ; Br . MI -> eraseFromParent ( ) ; Br . MI = NewBR ;


<s> bool MadeChange = false ; for ( unsigned i = <NUM_LIT> , e = ImmBranches . size ( ) ; i != e ; ++ i ) { ImmBranch & Br = ImmBranches [ i ] ; unsigned Opcode = Br . MI -> getOpcode ( ) ; unsigned NewOpc = <NUM_LIT> ; unsigned Scale = <NUM_LIT> ; unsigned Bits = <NUM_LIT> ; switch ( Opcode ) { default : break ; case <STR_LIT> : NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : { NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; } } if ( NewOpc ) { unsigned MaxOffs = ( ( <NUM_LIT> << ( Bits - <NUM_LIT> ) ) - <NUM_LIT> ) * Scale ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( isBBInRange ( Br . MI , DestBB , MaxOffs ) ) { DEBUG ( dbgs ( ) << <STR_LIT> << * Br . MI ) ; Br . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = Br . MI -> getParent ( ) ; BBInfo [ MBB -> getNumber ( ) ] . Size -= <NUM_LIT> ; adjustBBOffsetsAfter ( MBB ) ; ++ NumT2BrShrunk ; MadeChange = true ; } } Opcode = Br . MI -> getOpcode ( ) ; if ( Opcode != <STR_LIT> ) continue ; if ( ! Br . MI -> killsRegister ( <STR_LIT> ) ) continue ; NewOpc = <NUM_LIT> ; unsigned PredReg = <NUM_LIT> ; <STR_LIT> Pred = getInstrPredicate ( Br . MI , PredReg ) ;

if ( Pred == <STR_LIT> ) NewOpc = <STR_LIT> ;


<s> assert ( JTI < JT . size ( ) ) ; bool ByteOk = true ; bool HalfWordOk = true ; unsigned JTOffset = getOffsetOf ( MI ) + <NUM_LIT> ; const std :: vector < MachineBasicBlock * > & JTBBs = JT [ JTI ] . MBBs ; for ( unsigned j = <NUM_LIT> , ee = JTBBs . size ( ) ; j != ee ; ++ j ) { MachineBasicBlock * MBB = JTBBs [ j ] ; unsigned DstOffset = BBInfo [ MBB -> getNumber ( ) ] . Offset ; if ( ByteOk && ( DstOffset - JTOffset ) > ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ) ByteOk = false ; unsigned TBHLimit = ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ; if ( HalfWordOk && ( DstOffset - JTOffset ) > TBHLimit ) HalfWordOk = false ; if ( ! ByteOk && ! HalfWordOk ) break ; } if ( ByteOk || HalfWordOk ) { MachineBasicBlock * MBB = MI -> getParent ( ) ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool BaseRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( ! BaseRegKill ) continue ; unsigned IdxReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IdxRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; MachineBasicBlock :: iterator PrevI = MI ; MachineBasicBlock :: iterator B = MBB -> begin ( ) ; while ( PrevI != B && ! PrevI -> definesRegister ( BaseReg ) ) -- PrevI ; if ( ! PrevI -> definesRegister ( BaseReg ) ) continue ;


<s> unsigned TBHLimit = ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ; if ( HalfWordOk && ( DstOffset - JTOffset ) > TBHLimit ) HalfWordOk = false ; if ( ! ByteOk && ! HalfWordOk ) break ; } if ( ByteOk || HalfWordOk ) { MachineBasicBlock * MBB = MI -> getParent ( ) ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool BaseRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( ! BaseRegKill ) continue ; unsigned IdxReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IdxRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; MachineBasicBlock :: iterator PrevI = MI ; MachineBasicBlock :: iterator B = MBB -> begin ( ) ; while ( PrevI != B && ! PrevI -> definesRegister ( BaseReg ) ) -- PrevI ; if ( ! PrevI -> definesRegister ( BaseReg ) ) continue ; MachineInstr * AddrMI = PrevI ; bool OptOk = true ; for ( unsigned k = <NUM_LIT> , eee = AddrMI -> getNumOperands ( ) ; k != eee ; ++ k ) { const MachineOperand & MO = AddrMI -> getOperand ( k ) ; if ( ! MO . isReg ( ) || ! MO . getReg ( ) ) continue ; if ( MO . isDef ( ) && MO . getReg ( ) != BaseReg ) { OptOk = false ; break ; } if ( MO . isUse ( ) && ! MO . isKill ( ) && MO . getReg ( ) != IdxReg ) { OptOk = false ; break ; } } if ( ! OptOk ) continue ; for ( -- PrevI ; PrevI != B && ! PrevI -> definesRegister ( BaseReg ) ; -- PrevI ) ; MachineInstr * LeaMI = PrevI ; if ( ( LeaMI -> getOpcode ( ) != <STR_LIT> && LeaMI -> getOpcode ( ) != <STR_LIT> ) || LeaMI -> getOperand ( <NUM_LIT> ) . getReg ( ) != BaseReg ) OptOk = false ; if ( ! OptOk ) continue ; DEBUG ( dbgs ( ) << <STR_LIT> << * MI << <STR_LIT> << * AddrMI << <STR_LIT> << * LeaMI ) ; unsigned Opc = ByteOk ? <STR_LIT> : <STR_LIT> ; MachineInstr * NewJTMI = BuildMI ( MBB , MI -> getDebugLoc ( ) , TII -> get ( Opc ) ) . addReg ( IdxReg , getKillRegState ( IdxRegKill ) ) . addJumpTableIndex ( JTI , JTOP . getTargetFlags ( ) ) . addImm ( MI -> getOperand ( JTOpIdx + <NUM_LIT> ) . getImm ( ) ) ; DEBUG ( dbgs ( ) << <STR_LIT> << MBB -> getNumber ( ) << <STR_LIT> << * NewJTMI ) ;

unsigned NewSize = TII -> GetInstSizeInBytes ( NewJTMI ) ;


<s> unsigned PO = Offset + Size ; unsigned LA = std :: max ( unsigned ( PostAlign ) , LogAlign ) ;


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


<s> if ( CPEs [ j ] . RefCount == <NUM_LIT> && CPEs [ j ] . CPEMI ) { removeDeadCPEMI ( CPEs [ j ] . CPEMI ) ; CPEs [ j ] . CPEMI = NULL ; MadeChange = true ; } } }


<s> unsigned JTOpIdx = NumOps - ( MI -> isPredicable ( ) ? <NUM_LIT> : <NUM_LIT> ) ; MachineOperand JTOP = MI -> getOperand ( JTOpIdx ) ; unsigned JTI = JTOP . getIndex ( ) ; assert ( JTI < JT . size ( ) ) ; int JTNumber = MI -> getParent ( ) -> getNumber ( ) ; const std :: vector < MachineBasicBlock * > & JTBBs = JT [ JTI ] . MBBs ;

for ( unsigned j = <NUM_LIT> , ee = JTBBs . size ( ) ; j != ee ; ++ j ) {


<s> MachineInstr * MI = T2JumpTables [ i ] ; const MCInstrDesc & MCID = MI -> getDesc ( ) ; unsigned NumOps = MCID . getNumOperands ( ) ; unsigned JTOpIdx = NumOps - ( MI -> isPredicable ( ) ? <NUM_LIT> : <NUM_LIT> ) ; MachineOperand JTOP = MI -> getOperand ( JTOpIdx ) ; unsigned JTI = JTOP . getIndex ( ) ; assert ( JTI < JT . size ( ) ) ; int JTNumber = MI -> getParent ( ) -> getNumber ( ) ; const std :: vector < MachineBasicBlock * > & JTBBs = JT [ JTI ] . MBBs ; for ( unsigned j = <NUM_LIT> , ee = JTBBs . size ( ) ; j != ee ; ++ j ) {


<s> isThumb2 = AFI -> isThumb2Function ( ) ; HasFarJump = false ; MF -> getRegInfo ( ) . invalidateLiveness ( ) ; MF -> RenumberBlocks ( ) ; bool MadeChange = false ; if ( isThumb2 && AdjustJumpTableBlocks ) { scanFunctionJumpTables ( ) ; MadeChange |= reorderThumb2JumpTables ( ) ; T2JumpTables . clear ( ) ; MF -> RenumberBlocks ( ) ; } if ( ! isThumb1 ) MF -> EnsureAlignment ( <NUM_LIT> ) ; std :: vector < MachineInstr * > CPEMIs ; if ( ! MCP -> isEmpty ( ) ) doInitialPlacement ( CPEMIs ) ; AFI -> initPICLabelUId ( CPEMIs . size ( ) ) ; initializeFunctionInfo ( CPEMIs ) ; CPEMIs . clear ( ) ; DEBUG ( dumpBBs ( ) ) ; MadeChange |= removeUnusedCPEntries ( ) ; unsigned NoCPIters = <NUM_LIT> , NoBRIters = <NUM_LIT> ; while ( true ) { DEBUG ( dbgs ( ) << <STR_LIT> << NoCPIters << '\n' ) ; bool CPChange = false ; for ( unsigned i = <NUM_LIT> , e = CPUsers . size ( ) ; i != e ; ++ i ) CPChange |= handleConstantPoolUser ( i ) ; if ( CPChange && ++ NoCPIters > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; DEBUG ( dumpBBs ( ) ) ; NewWaterList . clear ( ) ; DEBUG ( dbgs ( ) << <STR_LIT> << NoBRIters << '\n' ) ; bool BRChange = false ; for ( unsigned i = <NUM_LIT> , e = ImmBranches . size ( ) ; i != e ; ++ i ) BRChange |= fixupImmediateBr ( ImmBranches [ i ] ) ; if ( BRChange && ++ NoBRIters > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; DEBUG ( dumpBBs ( ) ) ; if ( ! CPChange && ! BRChange ) break ; MadeChange = true ; } if ( isThumb2 && ! STI -> prefers32BitThumb ( ) ) MadeChange |= optimizeThumb2Instructions ( ) ; verify ( ) ; if ( isThumb && ! HasFarJump && AFI -> isLRSpilledForFarJump ( ) ) MadeChange |= undoLRSpillRestore ( ) ; for ( unsigned i = <NUM_LIT> , e = CPEntries . size ( ) ; i != e ; ++ i ) { for ( unsigned j = <NUM_LIT> , je = CPEntries [ i ] . size ( ) ; j != je ; ++ j ) { const CPEntry & CPE = CPEntries [ i ] [ j ] ; AFI -> recordCPEClone ( i , CPE . CPI ) ; } } DEBUG ( dbgs ( ) << '\n' ; dumpBBs ( ) ) ; BBInfo . clear ( ) ; WaterList . clear ( ) ; CPUsers . clear ( ) ; CPEntries . clear ( ) ; ImmBranches . clear ( ) ;


<s> MachineBasicBlock * NewBB = MF -> CreateMachineBasicBlock ( OrigBB -> getBasicBlock ( ) ) ; MachineFunction :: iterator MBBI = OrigBB ; ++ MBBI ; MF -> insert ( MBBI , NewBB ) ; NewBB -> splice ( NewBB -> end ( ) , OrigBB , MI , OrigBB -> end ( ) ) ; unsigned Opc = isThumb ? ( isThumb2 ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ; if ( ! isThumb ) BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) ; else BuildMI ( OrigBB , DebugLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) . addImm ( <STR_LIT> ) . addReg ( <NUM_LIT> ) ; ++ NumSplit ; NewBB -> transferSuccessors ( OrigBB ) ; OrigBB -> addSuccessor ( NewBB ) ; MF -> RenumberBlocks ( NewBB ) ; BBInfo . insert ( BBInfo . begin ( ) + NewBB -> getNumber ( ) , BasicBlockInfo ( ) ) ; water_iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , OrigBB , CompareMBBNumbers ) ;


<s> for ( unsigned i = <NUM_LIT> , e = CPUsers . size ( ) ; i != e ; ++ i ) { CPUser & U = CPUsers [ i ] ; unsigned UserOffset = getUserOffset ( U ) ; if ( isCPEntryInRange ( U . MI , UserOffset , U . CPEMI , U . getMaxDisp ( ) + <NUM_LIT> , U . NegOk , true ) ) { DEBUG ( dbgs ( ) << <STR_LIT> ) ; continue ; }


<s> static inline unsigned WorstCaseAlign ( unsigned Offset , unsigned LogAlign , unsigned KnownBits ) { Offset += UnknownPadding ( LogAlign , KnownBits ) ; return RoundUpToAlignment ( Offset , <NUM_LIT> << LogAlign ) ;


<s> WaterList . erase ( IP ) ; return next ( MachineFunction :: iterator ( WaterBB ) ) ;


<s> if ( MBB -> begin ( ) -> getOpcode ( ) == <STR_LIT> ) { unsigned OldOffset = BBOffsets [ i ] - delta ; if ( ( OldOffset % <NUM_LIT> ) == <NUM_LIT> && ( BBOffsets [ i ] % <NUM_LIT> ) != <NUM_LIT> ) { BBSizes [ i ] += <NUM_LIT> ; delta += <NUM_LIT> ; } else if ( ( OldOffset % <NUM_LIT> ) != <NUM_LIT> && ( BBOffsets [ i ] % <NUM_LIT> ) == <NUM_LIT> ) { BBSizes [ i ] -= <NUM_LIT> ; delta -= <NUM_LIT> ; } } MachineInstr * ThumbJTMI = prior ( MBB -> end ( ) ) ; if ( ThumbJTMI -> getOpcode ( ) == <STR_LIT> ) { unsigned NewMIOffset = GetOffsetOf ( ThumbJTMI ) ; unsigned OldMIOffset = NewMIOffset - delta ; if ( ( OldMIOffset % <NUM_LIT> ) == <NUM_LIT> && ( NewMIOffset % <NUM_LIT> ) != <NUM_LIT> ) { BBSizes [ i ] -= <NUM_LIT> ; delta -= <NUM_LIT> ; } else if ( ( OldMIOffset % <NUM_LIT> ) != <NUM_LIT> && ( NewMIOffset % <NUM_LIT> ) == <NUM_LIT> ) { BBSizes [ i ] += <NUM_LIT> ;


<s> <ISA_LIT>ConstantIslands ( ) : MachineFunctionPass ( & ID ) {


<s> if ( next ( MBBI ) == MBB -> getParent ( ) -> end ( ) ) return false ;

MachineBasicBlock * NextBB = next ( MBBI ) ;


DOUT << <STR_LIT> << CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) << <STR_LIT> << MaxDisp << <STR_LIT> << UserOffset << <STR_LIT> << CPEOffset << <STR_LIT> << int ( CPEOffset - UserOffset ) << <STR_LIT> << * MI ;


<s> CPUser ( MachineInstr * mi , MachineInstr * cpemi , unsigned maxdisp , bool neg , bool soimm ) : MI ( mi ) , CPEMI ( cpemi ) , MaxDisp ( maxdisp ) , NegOk ( neg ) , IsSoImm ( soimm ) {


<s> * NewMBB = next ( MachineFunction :: iterator ( UserMBB ) ) ; int UncondBr = isThumb ? ( ( isThumb2 ) ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ; BuildMI ( UserMBB , DebugLoc :: getUnknownLoc ( ) , TII -> get ( UncondBr ) ) . addMBB ( * NewMBB ) ; unsigned MaxDisp = getUnconditionalBrDisp ( UncondBr ) ; ImmBranches . push_back ( ImmBranch ( & UserMBB -> back ( ) , MaxDisp , false , UncondBr ) ) ; int delta = isThumb1 ? <NUM_LIT> : <NUM_LIT> ; BBSizes [ UserMBB -> getNumber ( ) ] += delta ; AdjustBBOffsetsAfter ( UserMBB , delta ) ; } else { unsigned BaseInsertOffset = UserOffset + U . MaxDisp - <NUM_LIT> ; if ( BaseInsertOffset >= BBOffsets [ UserMBB -> getNumber ( ) + <NUM_LIT> ] ) BaseInsertOffset = BBOffsets [ UserMBB -> getNumber ( ) + <NUM_LIT> ] - ( isThumb1 ? <NUM_LIT> : <NUM_LIT> ) ; unsigned EndInsertOffset = BaseInsertOffset + CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ;

MachineBasicBlock :: iterator MI = UserMI ;


<s> if ( -- CPE -> RefCount == <NUM_LIT> ) { RemoveDeadCPEMI ( CPEMI ) ;


<s> for ( unsigned i = <NUM_LIT> , e = CPs . size ( ) ; i != e ; ++ i ) { unsigned Size = TD . getTypeAllocSize ( CPs [ i ] . getType ( ) ) ; assert ( ( Size & <NUM_LIT> ) == <NUM_LIT> && <STR_LIT> ) ; MachineInstr * CPEMI = BuildMI ( BB , DebugLoc :: getUnknownLoc ( ) , TII -> get ( <STR_LIT> ) ) . addImm ( i ) . addConstantPoolIndex ( i ) . addImm ( Size ) ; CPEMIs . push_back ( CPEMI ) ;


<s> for ( unsigned J = <NUM_LIT> , E = BBOffsets . size ( ) ; J != E ; ++ J ) { DOUT << <STR_LIT> << J << <STR_LIT> << BBOffsets [ J ] << <STR_LIT> << BBSizes [ J ] << <STR_LIT> ; }


<s> int delta = TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; BBSizes [ MBB -> getNumber ( ) ] -= delta ; MachineBasicBlock * SplitBB = next ( MachineFunction :: iterator ( MBB ) ) ; AdjustBBOffsetsAfter ( SplitBB , - delta ) ; MBB -> back ( ) . eraseFromParent ( ) ; } MachineBasicBlock * NextBB = next ( MachineFunction :: iterator ( MBB ) ) ; DOUT << <STR_LIT> << DestBB -> getNumber ( ) << <STR_LIT> << NextBB -> getNumber ( ) << <STR_LIT> ; BuildMI ( MBB , DebugLoc :: getUnknownLoc ( ) , TII -> get ( MI -> getOpcode ( ) ) ) . addMBB ( NextBB ) . addImm ( CC ) . addReg ( CCReg ) ; Br . MI = & MBB -> back ( ) ; BBSizes [ MBB -> getNumber ( ) ] += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ; BuildMI ( MBB , DebugLoc :: getUnknownLoc ( ) , TII -> get ( Br . UncondBr ) ) . addMBB ( DestBB ) ; BBSizes [ MBB -> getNumber ( ) ] += TII -> GetInstSizeInBytes ( & MBB -> back ( ) ) ;


<s> MachineBasicBlock * DestBB = MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( BBIsInRange ( MI , DestBB , Br . MaxDisp ) ) return false ;

if ( ! Br . isCond ) return FixUpUnconditionalBr ( MF , Br ) ;


<s> MI -> setDesc ( TII -> get ( <STR_LIT> ) ) ; BBSizes [ MBB -> getNumber ( ) ] += <NUM_LIT> ; AdjustBBOffsetsAfter ( MBB , <NUM_LIT> ) ; HasFarJump = true ; NumUBrFixed ++ ; DOUT << <STR_LIT> << * MI ; return true ;


<s> unsigned Offset = BBOffsets [ MBB -> getNumber ( ) ] ; if ( isThumb && MI -> getOpcode ( ) == <STR_LIT> && Offset % <NUM_LIT> != <NUM_LIT> ) Offset += <NUM_LIT> ; for ( MachineBasicBlock :: iterator I = MBB -> begin ( ) ; ; ++ I ) {

assert ( I != MBB -> end ( ) && <STR_LIT> ) ;


<s> unsigned Offset = BBOffsets [ MBB -> getNumber ( ) ] ; if ( isThumb && MI -> getOpcode ( ) == <STR_LIT> && Offset % <NUM_LIT> != <NUM_LIT> ) Offset += <NUM_LIT> ; for ( MachineBasicBlock :: iterator I = MBB -> begin ( ) ; ; ++ I ) { assert ( I != MBB -> end ( ) && <STR_LIT> ) ; if ( & * I == MI ) return Offset ; Offset += TII -> GetInstSizeInBytes ( I ) ; }


<s> unsigned CPI = CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; unsigned Size = CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; MachineBasicBlock * NewMBB ; unsigned UserOffset = GetOffsetOf ( UserMI ) + ( isThumb ? <NUM_LIT> : <NUM_LIT> ) ; int result = LookForExistingCPEntry ( U , UserOffset ) ; if ( result == <NUM_LIT> ) return false ; else if ( result == <NUM_LIT> ) return true ; unsigned ID = AFI -> createConstPoolEntryUId ( ) ; if ( ! LookForWater ( U , UserOffset , & NewMBB ) ) { DOUT << <STR_LIT> ; CreateNewWater ( CPUserIndex , UserOffset , & NewMBB ) ; } MachineBasicBlock * NewIsland = MF . CreateMachineBasicBlock ( ) ; MF . insert ( NewMBB , NewIsland ) ; UpdateForInsertedWaterBlock ( NewIsland ) ; DecrementOldEntry ( CPI , CPEMI ) ; U . CPEMI = BuildMI ( NewIsland , DebugLoc :: getUnknownLoc ( ) , TII -> get ( <STR_LIT> ) ) . addImm ( ID ) . addConstantPoolIndex ( CPI ) . addImm ( Size ) ; CPEntries [ CPI ] . push_back ( CPEntry ( U . CPEMI , ID , <NUM_LIT> ) ) ; NumCPEs ++ ; BBOffsets [ NewIsland -> getNumber ( ) ] = BBOffsets [ NewMBB -> getNumber ( ) ] ;

if ( isThumb && BBOffsets [ NewIsland -> getNumber ( ) ] % <NUM_LIT> != <NUM_LIT> ) Size += <NUM_LIT> ;


<s> MachineInstr * CPEMI = U . CPEMI ; unsigned CPI = CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; unsigned Size = CPEMI -> getOperand ( <NUM_LIT> ) . getImm ( ) ; MachineBasicBlock * NewMBB ; unsigned UserOffset = GetOffsetOf ( UserMI ) + ( isThumb ? <NUM_LIT> : <NUM_LIT> ) ; int result = LookForExistingCPEntry ( U , UserOffset ) ; if ( result == <NUM_LIT> ) return false ; else if ( result == <NUM_LIT> ) return true ; unsigned ID = AFI -> createConstPoolEntryUId ( ) ; if ( ! LookForWater ( U , UserOffset , & NewMBB ) ) { DOUT << <STR_LIT> ; CreateNewWater ( CPUserIndex , UserOffset , & NewMBB ) ; } MachineBasicBlock * NewIsland = MF . CreateMachineBasicBlock ( ) ; MF . insert ( NewMBB , NewIsland ) ;

UpdateForInsertedWaterBlock ( NewIsland ) ;


<s> case <STR_LIT> : AFI -> setAlign ( <NUM_LIT> ) ; if ( ( Offset + MBBSize ) % <NUM_LIT> != <NUM_LIT> ) MBBSize += <NUM_LIT> ; continue ; case <STR_LIT> : T2JumpTables . push_back ( I ) ; continue ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : isCond = true ; UOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; } unsigned MaxOffs = ( ( <NUM_LIT> << ( Bits - <NUM_LIT> ) ) - <NUM_LIT> ) * Scale ; ImmBranches . push_back ( ImmBranch ( I , MaxOffs , isCond , UOpc ) ) ; } if ( Opc == <STR_LIT> || Opc == <STR_LIT> ) PushPopMIs . push_back ( I ) ; if ( Opc == <STR_LIT> ) continue ; for ( unsigned op = <NUM_LIT> , e = I -> getNumOperands ( ) ; op != e ; ++ op ) if ( I -> getOperand ( op ) . isCPI ( ) ) { unsigned Bits = <NUM_LIT> ; unsigned Scale = <NUM_LIT> ; bool NegOk = false ; bool IsSoImm = false ; switch ( Opc ) { default : llvm_unreachable ( <STR_LIT> ) ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; NegOk = true ; IsSoImm = true ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; NegOk = true ; break ; case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; NegOk = true ; break ; case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : case <STR_LIT> : Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; NegOk = true ; break ; } unsigned CPI = I -> getOperand ( op ) . getIndex ( ) ; MachineInstr * CPEMI = CPEMIs [ CPI ] ; unsigned MaxOffs = ( ( <NUM_LIT> << Bits ) - <NUM_LIT> ) * Scale ; CPUsers . push_back ( CPUser ( I , CPEMI , MaxOffs , NegOk , IsSoImm ) ) ; CPEntry * CPE = findConstPoolEntry ( CPI , CPEMI ) ; assert ( CPE && <STR_LIT> ) ; CPE -> RefCount ++ ; break ; } } if ( isThumb && ! MBB . empty ( ) && MBB . begin ( ) -> getOpcode ( ) == <STR_LIT> && ( Offset % <NUM_LIT> ) != <NUM_LIT> ) MBBSize += <NUM_LIT> ; BBSizes . push_back ( MBBSize ) ; BBOffsets . push_back ( Offset ) ; Offset += MBBSize ;


<s> MachineInstr * CPEMI = U . CPEMI ; if ( CPEIsInRange ( UserMI , UserOffset , CPEMI , U . MaxDisp , U . NegOk , true ) ) { DOUT << <STR_LIT> ; return <NUM_LIT> ; } unsigned CPI = CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) continue ; if ( CPEs [ i ] . CPEMI == NULL ) continue ;

if ( CPEIsInRange ( UserMI , UserOffset , CPEs [ i ] . CPEMI , U . MaxDisp , U . NegOk ) ) {


<s> return <NUM_LIT> ; } unsigned CPI = CPEMI -> getOperand ( <NUM_LIT> ) . getIndex ( ) ; std :: vector < CPEntry > & CPEs = CPEntries [ CPI ] ; for ( unsigned i = <NUM_LIT> , e = CPEs . size ( ) ; i != e ; ++ i ) { if ( CPEs [ i ] . CPEMI == CPEMI ) continue ; if ( CPEs [ i ] . CPEMI == NULL ) continue ; if ( CPEIsInRange ( UserMI , UserOffset , CPEs [ i ] . CPEMI , U . MaxDisp , U . NegOk ) ) { DOUT << <STR_LIT> << CPI << <STR_LIT> << CPEs [ i ] . CPI << <STR_LIT> ; U . CPEMI = CPEs [ i ] . CPEMI ; for ( unsigned j = <NUM_LIT> , e = UserMI -> getNumOperands ( ) ; j != e ; ++ j ) if ( UserMI -> getOperand ( j ) . isCPI ( ) ) { UserMI -> getOperand ( j ) . setIndex ( CPEs [ i ] . CPI ) ; break ; } CPEs [ i ] . RefCount ++ ; return DecrementOldEntry ( CPI , CPEMI ) ? <NUM_LIT> : <NUM_LIT> ; } }


<s> if ( ! WaterList . empty ( ) ) { for ( std :: vector < MachineBasicBlock * > :: iterator IP = prior ( WaterList . end ( ) ) , B = WaterList . begin ( ) ; ; -- IP ) { MachineBasicBlock * WaterBB = * IP ; if ( WaterIsInRange ( UserOffset , WaterBB , U ) ) { unsigned WBBId = WaterBB -> getNumber ( ) ; if ( isThumb && ( BBOffsets [ WBBId ] + BBSizes [ WBBId ] ) % <NUM_LIT> != <NUM_LIT> ) { if ( ! WaterBBThatWouldPad ) { WaterBBThatWouldPad = WaterBB ; IPThatWouldPad = IP ; } } else { * NewMBB = AcceptWater ( WaterBB , IP ) ; return true ; } } if ( IP == B ) break ; } } if ( isThumb && WaterBBThatWouldPad ) { * NewMBB = AcceptWater ( WaterBBThatWouldPad , IPThatWouldPad ) ; return true ; } return false ;


<s> if ( isThumb2 && TotalAdj != <NUM_LIT> ) MaxDisp -= ( <NUM_LIT> - TotalAdj ) ; if ( UserOffset <= TrialOffset ) { if ( TrialOffset - UserOffset <= MaxDisp ) return true ; } else if ( NegativeOK ) { if ( UserOffset - TrialOffset <= MaxDisp ) return true ; } return false ;


<s> UserOffset -= <NUM_LIT> ; TotalAdj = <NUM_LIT> ; } if ( isThumb && TrialOffset % <NUM_LIT> != <NUM_LIT> ) { TrialOffset += <NUM_LIT> ; TotalAdj += <NUM_LIT> ; } if ( isThumb2 && TotalAdj != <NUM_LIT> ) MaxDisp -= ( <NUM_LIT> - TotalAdj ) ; if ( UserOffset <= TrialOffset ) { if ( TrialOffset - UserOffset <= MaxDisp ) return true ; } else if ( NegativeOK ) { if ( UserOffset - TrialOffset <= MaxDisp ) return true ; }


<s> default : break ; case <STR_LIT> : NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; case <STR_LIT> : NewOpc = <STR_LIT> ; Bits = <NUM_LIT> ; Scale = <NUM_LIT> ; break ; } if ( ! NewOpc ) continue ; unsigned MaxOffs = ( ( <NUM_LIT> << ( Bits - <NUM_LIT> ) ) - <NUM_LIT> ) * Scale ; MachineBasicBlock * DestBB = Br . MI -> getOperand ( <NUM_LIT> ) . getMBB ( ) ; if ( BBIsInRange ( Br . MI , DestBB , MaxOffs ) ) { Br . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = Br . MI -> getParent ( ) ;

BBSizes [ MBB -> getNumber ( ) ] -= <NUM_LIT> ;


<s> if ( CPEIsInRange ( U . MI , UserOffset , U . CPEMI , MaxOffs , false , true ) ) { U . MI -> setDesc ( TII -> get ( NewOpc ) ) ; MachineBasicBlock * MBB = U . MI -> getParent ( ) ; BBSizes [ MBB -> getNumber ( ) ] -= <NUM_LIT> ; AdjustBBOffsetsAfter ( MBB , - <NUM_LIT> ) ; ++ NumT2CPShrunk ; MadeChange = true ; } } MadeChange |= OptimizeThumb2Branches ( MF ) ; MadeChange |= OptimizeThumb2JumpTables ( MF ) ; return MadeChange ;


<s> MachineOperand JTOP = MI -> getOperand ( JTOpIdx ) ; unsigned JTI = JTOP . getIndex ( ) ; assert ( JTI < JT . size ( ) ) ; bool ByteOk = true ; bool HalfWordOk = true ; unsigned JTOffset = GetOffsetOf ( MI ) + <NUM_LIT> ; const std :: vector < MachineBasicBlock * > & JTBBs = JT [ JTI ] . MBBs ; for ( unsigned j = <NUM_LIT> , ee = JTBBs . size ( ) ; j != ee ; ++ j ) { MachineBasicBlock * MBB = JTBBs [ j ] ; unsigned DstOffset = BBOffsets [ MBB -> getNumber ( ) ] ; if ( ByteOk && ( DstOffset - JTOffset ) > ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ) ByteOk = false ; unsigned TBHLimit = ( ( <NUM_LIT> << <NUM_LIT> ) - <NUM_LIT> ) * <NUM_LIT> ; if ( HalfWordOk && ( DstOffset - JTOffset ) > TBHLimit ) HalfWordOk = false ; if ( ! ByteOk && ! HalfWordOk ) break ; } if ( ByteOk || HalfWordOk ) { MachineBasicBlock * MBB = MI -> getParent ( ) ; unsigned BaseReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool BaseRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; if ( ! BaseRegKill ) continue ; unsigned IdxReg = MI -> getOperand ( <NUM_LIT> ) . getReg ( ) ; bool IdxRegKill = MI -> getOperand ( <NUM_LIT> ) . isKill ( ) ; MachineBasicBlock :: iterator PrevI = MI ; if ( PrevI == MBB -> begin ( ) ) continue ; MachineInstr * AddrMI = -- PrevI ; bool OptOk = true ; for ( unsigned k = <NUM_LIT> , eee = AddrMI -> getNumOperands ( ) ; k != eee ; ++ k ) { const MachineOperand & MO = AddrMI -> getOperand ( k ) ; if ( ! MO . isReg ( ) || ! MO . getReg ( ) ) continue ; if ( MO . isDef ( ) && MO . getReg ( ) != BaseReg ) { OptOk = false ; break ; } if ( MO . isUse ( ) && ! MO . isKill ( ) && MO . getReg ( ) != IdxReg ) { OptOk = false ; break ; } } if ( ! OptOk ) continue ; MachineInstr * LeaMI = -- PrevI ; if ( ( LeaMI -> getOpcode ( ) != <STR_LIT> && LeaMI -> getOpcode ( ) != <STR_LIT> ) || LeaMI -> getOperand ( <NUM_LIT> ) . getReg ( ) != BaseReg ) OptOk = false ;


<s> if ( CPEBB -> empty ( ) ) { if ( BBSizes [ CPEBB -> getNumber ( ) ] != <NUM_LIT> ) { Size += BBSizes [ CPEBB -> getNumber ( ) ] ; BBSizes [ CPEBB -> getNumber ( ) ] = <NUM_LIT> ; } }

AdjustBBOffsetsAfter ( CPEBB , - Size ) ;


<s> unsigned MadeChange = false ; for ( unsigned i = <NUM_LIT> , e = CPEntries . size ( ) ; i != e ; ++ i ) { std :: vector < CPEntry > & CPEs = CPEntries [ i ] ; for ( unsigned j = <NUM_LIT> , ee = CPEs . size ( ) ; j != ee ; ++ j ) { if ( CPEs [ j ] . RefCount == <NUM_LIT> && CPEs [ j ] . CPEMI ) {

RemoveDeadCPEMI ( CPEs [ j ] . CPEMI ) ;


<s> MachineBasicBlock * OrigBB = MI -> getParent ( ) ; MachineFunction & MF = * OrigBB -> getParent ( ) ; MachineBasicBlock * NewBB = MF . CreateMachineBasicBlock ( OrigBB -> getBasicBlock ( ) ) ; MachineFunction :: iterator MBBI = OrigBB ; ++ MBBI ; MF . insert ( MBBI , NewBB ) ; NewBB -> splice ( NewBB -> end ( ) , OrigBB , MI , OrigBB -> end ( ) ) ; unsigned Opc = isThumb ? ( isThumb2 ? <STR_LIT> : <STR_LIT> ) : <STR_LIT> ; BuildMI ( OrigBB , DebugLoc :: getUnknownLoc ( ) , TII -> get ( Opc ) ) . addMBB ( NewBB ) ; NumSplit ++ ; while ( ! OrigBB -> succ_empty ( ) ) { MachineBasicBlock * Succ = * OrigBB -> succ_begin ( ) ; OrigBB -> removeSuccessor ( Succ ) ; NewBB -> addSuccessor ( Succ ) ; assert ( ( Succ -> empty ( ) || Succ -> begin ( ) -> getOpcode ( ) != TargetInstrInfo :: PHI ) && <STR_LIT> ) ; } OrigBB -> addSuccessor ( NewBB ) ; MF . RenumberBlocks ( NewBB ) ; BBSizes . insert ( BBSizes . begin ( ) + NewBB -> getNumber ( ) , <NUM_LIT> ) ; BBOffsets . insert ( BBOffsets . begin ( ) + NewBB -> getNumber ( ) , <NUM_LIT> ) ; std :: vector < MachineBasicBlock * > :: iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , OrigBB , CompareMBBNumbers ) ; MachineBasicBlock * WaterBB = * IP ; if ( WaterBB == OrigBB ) WaterList . insert ( next ( IP ) , NewBB ) ; else WaterList . insert ( IP , OrigBB ) ; unsigned NewBBSize = <NUM_LIT> ; for ( MachineBasicBlock :: iterator I = NewBB -> begin ( ) , E = NewBB -> end ( ) ; I != E ; ++ I ) NewBBSize += TII -> GetInstSizeInBytes ( I ) ; unsigned OrigBBI = OrigBB -> getNumber ( ) ; unsigned NewBBI = NewBB -> getNumber ( ) ; BBSizes [ NewBBI ] = NewBBSize ; int delta = isThumb1 ? <NUM_LIT> : <NUM_LIT> ;

BBSizes [ OrigBBI ] -= NewBBSize - delta ;


<s> for ( unsigned i = <NUM_LIT> , e = PushPopMIs . size ( ) ; i != e ; ++ i ) { MachineInstr * MI = PushPopMIs [ i ] ; if ( MI -> getOpcode ( ) == <STR_LIT> && MI -> getOperand ( <NUM_LIT> ) . getReg ( ) == <STR_LIT> && MI -> getNumExplicitOperands ( ) == <NUM_LIT> ) { BuildMI ( MI -> getParent ( ) , MI -> getDebugLoc ( ) , TII -> get ( <STR_LIT> ) ) ;


<s> std :: vector < MachineBasicBlock * > :: iterator IP = std :: lower_bound ( WaterList . begin ( ) , WaterList . end ( ) , NewBB , CompareMBBNumbers ) ;