<s> StringRef ValueStr = DA -> getAsString ( ) ; size_t Separator = ValueStr . find_first_of ( ':' ) ; StringRef EnumeratorStr = ValueStr . substr ( <NUM_LIT> , Separator ) ; DIType * BaseTy = stripQualifiers ( Ty , true ) ; const auto * CTy = cast < DICompositeType > ( BaseTy ) ; assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_enumeration_type ) ; int EnumIndex = <NUM_LIT> ; for ( const auto Element : CTy -> getElements ( ) ) { const auto * Enum = cast < DIEnumerator > ( Element ) ; if ( Enum -> getName ( ) == EnumeratorStr ) { AccessStr = std :: to_string ( EnumIndex ) ; break ;


<s> if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlignment ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlignment ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ;


<s> if ( ! Call ) return false ; const auto * GV = dyn_cast < GlobalValue > ( Call -> getCalledValue ( ) ) ; if ( ! GV ) return false ; if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveArrayAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlignment ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlignment ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ;


<s> BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , LDInst ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ; Call -> replaceAllUsesWith ( BCInst2 ) ; Call -> eraseFromParent ( ) ; return true ;


<s> if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) VarType = Type :: getInt32Ty ( BB -> getContext ( ) ) ; else VarType = Type :: getInt64Ty ( BB -> getContext ( ) ) ; GV = new GlobalVariable ( M , VarType , false , GlobalVariable :: ExternalLinkage , NULL , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { auto * LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , LDInst ) ; Call -> replaceAllUsesWith ( LDInst ) ; Call -> eraseFromParent ( ) ; return true ; }

auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV ) ;


<s> auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; if ( ! MemberTy -> isBitField ( ) ) { PatchImm += MemberTy -> getOffsetInBits ( ) >> <NUM_LIT> ; } else { unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; PatchImm += SBitOffset >> <NUM_LIT> ; } } return PatchImm ; } if ( InfoKind == <STR_LIT> ) { if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; return calcArraySize ( CTy , <NUM_LIT> ) * ( EltTy -> getSizeInBits ( ) >> <NUM_LIT> ) ; } else { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; uint32_t SizeInBits = MemberTy -> getSizeInBits ( ) ; if ( ! MemberTy -> isBitField ( ) ) return SizeInBits >> <NUM_LIT> ; unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; SizeInBits = NextSBitOffset - SBitOffset ; if ( SizeInBits & ( SizeInBits - <NUM_LIT> ) ) report_fatal_error ( <STR_LIT> ) ; return SizeInBits >> <NUM_LIT> ; } } if ( InfoKind == <STR_LIT> ) { const DIType * BaseTy ; if ( Tag == dwarf :: DW_TAG_array_type ) { if ( CTy -> getElements ( ) . size ( ) != <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; } else { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; BaseTy = stripQualifiers ( MemberTy -> getBaseType ( ) ) ; } const auto * BTy = dyn_cast < DIBasicType > ( BaseTy ) ; while ( ! BTy ) { const auto * CompTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CompTy || CompTy -> getTag ( ) != dwarf :: DW_TAG_enumeration_type ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CompTy -> getBaseType ( ) ) ; BTy = dyn_cast < DIBasicType > ( BaseTy ) ; } uint32_t Encoding = BTy -> getEncoding ( ) ; return ( Encoding == dwarf :: DW_ATE_signed || Encoding == dwarf :: DW_ATE_signed_char ) ;


<s> if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = nullptr ; uint64_t InfoKind = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( InfoKind >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = InfoKind ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ;


<s> if ( ! Base ) return false ; } BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { IntegerType * VarType ; if ( IsInt32Ret ) VarType = Type :: getInt32Ty ( BB -> getContext ( ) ) ; else VarType = Type :: getInt64Ty ( BB -> getContext ( ) ) ; GV = new GlobalVariable ( M , VarType , false , GlobalVariable :: ExternalLinkage , NULL , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { LoadInst * LDInst ; if ( IsInt32Ret ) LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; else LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; Call -> replaceAllUsesWith ( LDInst ) ; Call -> eraseFromParent ( ) ; return true ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ; Call -> replaceAllUsesWith ( BCInst2 ) ; Call -> eraseFromParent ( ) ;


<s> if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( getBaseElementType ( Call ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = nullptr ; uint64_t InfoKind = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( InfoKind >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = InfoKind ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; uint64_t Flag = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( Flag >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; if ( Flag == <STR_LIT> ) CInfo . AccessIndex = <STR_LIT> ; else CInfo . AccessIndex = <STR_LIT> ; return true ; }


<s> return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; uint64_t Flag = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( Flag >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; if ( Flag == <STR_LIT> ) CInfo . AccessIndex = <STR_LIT> ; else CInfo . AccessIndex = <STR_LIT> ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; uint64_t Flag = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( Flag >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; if ( Flag == <STR_LIT> ) CInfo . AccessIndex = <STR_LIT> ; else CInfo . AccessIndex = <STR_LIT> ; return true ;


<s> if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { LoadInst * LDInst ; if ( IsInt32Ret ) LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; else LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; Instruction * PassThroughInst = <STR_LIT> ( M , BB , LDInst , Call ) ; Call -> replaceAllUsesWith ( PassThroughInst ) ; Call -> eraseFromParent ( ) ; return true ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ;

BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ;


<s> while ( auto * DTy = dyn_cast < DIDerivedType > ( Ty ) ) { if ( ! SkipDIDerivedTag ( DTy -> getTag ( ) ) ) break ;


<s> <ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM = nullptr ) : FunctionPass ( ID ) , TM ( TM ) {


<s> FunctionPass * llvm :: create<ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM ) {

return new <ISA_LIT>AbstractMemberAccess ( TM ) ;


<s> M = F . getParent ( ) ; if ( ! M ) return false ; if ( M -> debug_compile_units ( ) . empty ( ) ) return false ; DL = & M -> getDataLayout ( ) ; return doTransformation ( F ) ;


<s> <ISA_LIT>AbstractMemberAccess ( ) : ModulePass ( ID ) {


<s> uint32_t Kind ; auto * Call = dyn_cast < CallInst > ( & I ) ;

if ( ! IsPreserveDIAccessIndexCall ( Call , Kind ) || AIChain . find ( Call ) != AIChain . end ( ) ) continue ;


<s> AIChain . clear ( ) ; BaseAICalls . clear ( ) ; for ( auto & BB : F ) for ( auto & I : BB ) { uint32_t Kind ; auto * Call = dyn_cast < CallInst > ( & I ) ;


<s> if ( ! Ty ) return nullptr ; TypeName = Ty -> getName ( ) ; } uint64_t AccessIndex ; uint32_t ArgIndex = ( Kind == <ISA_LIT>PreserveUnionAI ) ? <NUM_LIT> : <NUM_LIT> ; if ( ! getAccessIndex ( Call -> getArgOperand ( ArgIndex ) , AccessIndex ) ) return nullptr ; AccessIndices . push_back ( AccessIndex ) ; if ( TypeName . size ( ) ) { TypeNameIndex = AccessIndices . size ( ) - <NUM_LIT> ; LastTypeName = TypeName ; TypeMeta = MDN ; } Kind = AIChain [ Call ] . second ; Call = AIChain [ Call ] . first ;


<s> Value * <ISA_LIT>AbstractMemberAccess :: computeBaseAndAccessKey ( CallInst * Call , std :: string & AccessKey , uint32_t Kind , MDNode * & TypeMeta ) { Value * Base = nullptr ; std :: vector < uint64_t > AccessIndices ; uint64_t TypeNameIndex = <NUM_LIT> ; std :: string LastTypeName ; while ( Call ) { Base = Call -> getArgOperand ( <NUM_LIT> ) ; std :: string TypeName ; MDNode * MDN ; if ( Kind == <ISA_LIT>PreserveUnionAI || Kind == <ISA_LIT>PreserveStructAI ) { MDN = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ;


<s> return new <ISA_LIT>AbstractMemberAccess ( ) ;


<s> const ConstantInt * CV = dyn_cast < ConstantInt > ( IndexValue ) ; if ( ! CV ) return false ; AccessIndex = CV -> getValue ( ) . getZExtValue ( ) ; return true ;


AccessIndex = CV -> getValue ( ) . getZExtValue ( ) ;


<s> if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { Kind = <ISA_LIT>PreserveArrayAI ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { Kind = <ISA_LIT>PreserveUnionAI ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { Kind = <ISA_LIT>PreserveStructAI ; return true ;


<s> bool <ISA_LIT>AbstractMemberAccess :: IsPreserveDIAccessIndexCall ( const CallInst * Call , uint32_t & Kind ) { if ( ! Call ) return false ; const auto * GV = dyn_cast < GlobalValue > ( Call -> getCalledValue ( ) ) ; if ( ! GV ) return false ; if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { Kind = <ISA_LIT>PreserveArrayAI ; return true ; }


<s> Found = true ; if ( Kind == <ISA_LIT>PreserveArrayAI ) PreserveArrayIndexCalls . push_back ( Call ) ; else if ( Kind == <ISA_LIT>PreserveUnionAI ) PreserveUnionIndexCalls . push_back ( Call ) ; else PreserveStructIndexCalls . push_back ( Call ) ; } replaceWithGEP ( PreserveArrayIndexCalls , <NUM_LIT> , <NUM_LIT> ) ; replaceWithGEP ( PreserveStructIndexCalls , <NUM_LIT> , <NUM_LIT> ) ; for ( auto Call : PreserveUnionIndexCalls ) { Call -> replaceAllUsesWith ( Call -> getArgOperand ( <NUM_LIT> ) ) ; Call -> eraseFromParent ( ) ;


<s> bool <ISA_LIT>AbstractMemberAccess :: removePreserveAccessIndexIntrinsic ( Module & M ) { std :: vector < CallInst * > PreserveArrayIndexCalls ; std :: vector < CallInst * > PreserveUnionIndexCalls ; std :: vector < CallInst * > PreserveStructIndexCalls ; bool Found = false ; for ( Function & F : M ) for ( auto & BB : F ) for ( auto & I : BB ) { auto * Call = dyn_cast < CallInst > ( & I ) ; uint32_t Kind ; if ( ! IsPreserveDIAccessIndexCall ( Call , Kind ) ) continue ; Found = true ; if ( Kind == <ISA_LIT>PreserveArrayAI ) PreserveArrayIndexCalls . push_back ( Call ) ; else if ( Kind == <ISA_LIT>PreserveUnionAI ) PreserveUnionIndexCalls . push_back ( Call ) ;

else PreserveStructIndexCalls . push_back ( Call ) ;


<s> void <ISA_LIT>AbstractMemberAccess :: replaceWithGEP ( std :: vector < CallInst * > & CallList , uint32_t DimensionIndex , uint32_t GEPIndex ) { for ( auto Call : CallList ) { uint32_t Dimension = <NUM_LIT> ; if ( DimensionIndex > <NUM_LIT> ) Dimension = cast < ConstantInt > ( Call -> getArgOperand ( DimensionIndex ) ) -> getZExtValue ( ) ; Constant * Zero = ConstantInt :: get ( Type :: getInt32Ty ( Call -> getParent ( ) -> getContext ( ) ) , <NUM_LIT> ) ; SmallVector < Value * , <NUM_LIT> > IdxList ; for ( unsigned I = <NUM_LIT> ; I < Dimension ; ++ I ) IdxList . push_back ( Zero ) ; IdxList . push_back ( Call -> getArgOperand ( GEPIndex ) ) ;

auto * GEP = GetElementPtrInst :: CreateInBounds ( Call -> getArgOperand ( <NUM_LIT> ) , IdxList , <STR_LIT> , Call ) ;


<s> uint32_t Dimension = <NUM_LIT> ; if ( DimensionIndex > <NUM_LIT> ) Dimension = cast < ConstantInt > ( Call -> getArgOperand ( DimensionIndex ) ) -> getZExtValue ( ) ; Constant * Zero = ConstantInt :: get ( Type :: getInt32Ty ( Call -> getParent ( ) -> getContext ( ) ) , <NUM_LIT> ) ; SmallVector < Value * , <NUM_LIT> > IdxList ; for ( unsigned I = <NUM_LIT> ; I < Dimension ; ++ I ) IdxList . push_back ( Zero ) ; IdxList . push_back ( Call -> getArgOperand ( GEPIndex ) ) ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ; if ( empty ( M . debug_compile_units ( ) ) ) return false ; return doTransformation ( M ) ;


<s> void <ISA_LIT>AbstractMemberAccess :: traceAICall ( CallInst * Call , uint32_t Kind ) { for ( User * U : Call -> users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Call , Kind ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ;

if ( IsPreserveDIAccessIndexCall ( CI , CIKind ) ) {


<s> } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind ) ) { AIChain [ CI ] = std :: make_pair ( Call , Kind ) ; traceAICall ( CI , CIKind ) ; } else { BaseAICalls [ Call ] = Kind ; } } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { if ( GI -> hasAllZeroIndices ( ) ) traceGEP ( GI , Call , Kind ) ;


<s> if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , Kind ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind ) ; } else { BaseAICalls [ Parent ] = Kind ;


<s> void <ISA_LIT>AbstractMemberAccess :: traceGEP ( GetElementPtrInst * GEP , CallInst * Parent , uint32_t Kind ) { for ( User * U : GEP -> users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , Kind ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind ) ; } else {


<s> } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind ) ; } else { BaseAICalls [ Parent ] = Kind ;


<s> std :: string AccessKey ; MDNode * TypeMeta = nullptr ; Value * Base = computeBaseAndAccessKey ( Call , AccessKey , Kind , TypeMeta ) ; if ( ! Base ) return false ; BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { GV = new GlobalVariable ( M , Type :: getInt64Ty ( BB -> getContext ( ) ) , false , GlobalVariable :: ExternalLinkage , NULL , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; if ( TypeMeta ) GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else {


<s> for ( auto & BB : F ) for ( auto & I : BB ) { uint32_t Kind ; const MDNode * TypeMeta ; uint32_t AccessIndex ; auto * Call = dyn_cast < CallInst > ( & I ) ; if ( ! IsPreserveDIAccessIndexCall ( Call , Kind , TypeMeta , AccessIndex ) || AIChain . find ( Call ) != AIChain . end ( ) ) continue ; traceAICall ( Call , Kind , TypeMeta , AccessIndex ) ; }


<s> if ( ! GV ) return false ; if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { Kind = <ISA_LIT>PreserveArrayAI ; TypeMeta = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! TypeMeta ) report_fatal_error ( <STR_LIT> ) ; AccessIndex = cast < ConstantInt > ( Call -> getArgOperand ( <NUM_LIT> ) ) -> getZExtValue ( ) ; return true ; }


<s> const DIType * PType = stripQualifiers ( cast < DIType > ( ParentType ) ) ; const DIType * CType = stripQualifiers ( cast < DIType > ( ChildType ) ) ; if ( isa < DIDerivedType > ( CType ) ) return false ; if ( const auto * PtrTy = dyn_cast < DIDerivedType > ( PType ) ) { if ( PtrTy -> getTag ( ) != dwarf :: DW_TAG_pointer_type ) return false ; return stripQualifiers ( PtrTy -> getBaseType ( ) ) == CType ; } const auto * PTy = dyn_cast < DICompositeType > ( PType ) ; const auto * CTy = dyn_cast < DICompositeType > ( CType ) ; assert ( PTy && CTy && <STR_LIT> ) ;


<s> } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; const MDNode * ChildMeta ; uint32_t ChildAI ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind , ChildMeta , ChildAI ) && IsValidAIChain ( ParentMeta , ParentAI , ChildMeta ) ) { AIChain [ CI ] = std :: make_pair ( Call , Kind ) ; traceAICall ( CI , CIKind , ChildMeta , ChildAI ) ; } else { BaseAICalls [ Call ] = Kind ; }

} else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) {


<s> for ( User * U : Call -> users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Call , Kind , ParentMeta , ParentAI ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; const MDNode * ChildMeta ; uint32_t ChildAI ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind , ChildMeta , ChildAI ) && IsValidAIChain ( ParentMeta , ParentAI , ChildMeta ) ) { AIChain [ CI ] = std :: make_pair ( Call , Kind ) ; traceAICall ( CI , CIKind , ChildMeta , ChildAI ) ; } else { BaseAICalls [ Call ] = Kind ; }


<s> uint32_t ChildAI ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind , ChildMeta , ChildAI ) && IsValidAIChain ( ParentMeta , ParentAI , ChildMeta ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind , ChildMeta , ChildAI ) ; } else { BaseAICalls [ Parent ] = Kind ; } } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { if ( GI -> hasAllZeroIndices ( ) ) traceGEP ( GI , Parent , Kind , ParentMeta , ParentAI ) ; else BaseAICalls [ Parent ] = Kind ; }


<s> if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , Kind , ParentMeta , ParentAI ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; const MDNode * ChildMeta ; uint32_t ChildAI ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind , ChildMeta , ChildAI ) && IsValidAIChain ( ParentMeta , ParentAI , ChildMeta ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind , ChildMeta , ChildAI ) ; } else { BaseAICalls [ Parent ] = Kind ; } } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { if ( GI -> hasAllZeroIndices ( ) ) traceGEP ( GI , Parent , Kind , ParentMeta , ParentAI ) ; else BaseAICalls [ Parent ] = Kind ; } }


<s> } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { uint32_t CIKind ; const MDNode * ChildMeta ; uint32_t ChildAI ; if ( IsPreserveDIAccessIndexCall ( CI , CIKind , ChildMeta , ChildAI ) && IsValidAIChain ( ParentMeta , ParentAI , ChildMeta ) ) { AIChain [ CI ] = std :: make_pair ( Parent , Kind ) ; traceAICall ( CI , CIKind , ChildMeta , ChildAI ) ; } else { BaseAICalls [ Parent ] = Kind ; }


<s> Value * Base = computeBaseAndAccessKey ( Call , AccessKey , Kind , TypeMeta ) ; if ( ! Base ) return false ; BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { GV = new GlobalVariable ( M , Type :: getInt64Ty ( BB -> getContext ( ) ) , false , GlobalVariable :: ExternalLinkage , NULL , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , LDInst ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ;

Call -> replaceAllUsesWith ( BCInst2 ) ;


<s> <ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM ) : TM ( TM ) {


<s> <ISA_LIT>AbstractMemberAccessLegacyPass ( <ISA_LIT>TargetMachine * TM = nullptr ) : FunctionPass ( ID ) , TM ( TM ) {


<s> AIChain . clear ( ) ; BaseAICalls . clear ( ) ; for ( auto & BB : F ) for ( auto & I : BB ) { CallInfo CInfo ; auto * Call = dyn_cast < CallInst > ( & I ) ; if ( ! IsPreserveDIAccessIndexCall ( Call , CInfo ) || AIChain . find ( Call ) != AIChain . end ( ) ) continue ; traceAICall ( Call , CInfo ) ; }


<s> IsInt32Ret = false ; const auto * CE = cast < ConstantExpr > ( Call -> getArgOperand ( <NUM_LIT> ) ) ; const GlobalVariable * GV = cast < GlobalVariable > ( CE -> getOperand ( <NUM_LIT> ) ) ; assert ( GV -> hasInitializer ( ) ) ; const ConstantDataArray * DA = cast < ConstantDataArray > ( GV -> getInitializer ( ) ) ; assert ( DA -> isString ( ) ) ; StringRef ValueStr = DA -> getAsString ( ) ; size_t Separator = ValueStr . find_first_of ( ':' ) ; StringRef EnumeratorStr = ValueStr . substr ( <NUM_LIT> , Separator ) ; DIType * BaseTy = stripQualifiers ( Ty , true ) ; const auto * CTy = cast < DICompositeType > ( BaseTy ) ; assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_enumeration_type ) ; int EnumIndex = <NUM_LIT> ; for ( const auto Element : CTy -> getElements ( ) ) { const auto * Enum = cast < DIEnumerator > ( Element ) ; if ( Enum -> getName ( ) == EnumeratorStr ) { AccessStr = std :: to_string ( EnumIndex ) ; break ; } EnumIndex ++ ; } if ( CInfo . AccessIndex == <STR_LIT> ) { StringRef EValueStr = ValueStr . substr ( Separator + <NUM_LIT> ) ; PatchImm = std :: stoll ( std :: string ( EValueStr ) ) ; } else { PatchImm = <NUM_LIT> ; } } AccessKey = <STR_LIT> + Ty -> getName ( ) . str ( ) + <STR_LIT> + std :: to_string ( CInfo . AccessIndex ) + std :: string ( <STR_LIT> ) + std :: to_string ( PatchImm ) + std :: string ( <STR_LIT> ) + AccessStr ;


<s> CallInfoStack CallStack ; while ( Call ) { CallStack . push ( std :: make_pair ( Call , CInfo ) ) ; CInfo = AIChain [ Call ] . second ; Call = AIChain [ Call ] . first ; } uint32_t FirstIndex = <NUM_LIT> ; uint32_t PatchImm = <NUM_LIT> ; uint32_t InfoKind = <STR_LIT> ; while ( CallStack . size ( ) ) { auto StackElem = CallStack . top ( ) ; Call = StackElem . first ; CInfo = StackElem . second ; if ( ! Base ) Base = CInfo . Base ; DIType * PossibleTypeDef = stripQualifiers ( cast < DIType > ( CInfo . Metadata ) , false ) ; DIType * Ty = stripQualifiers ( PossibleTypeDef ) ; if ( CInfo . Kind == <ISA_LIT>PreserveUnionAI || CInfo . Kind == <ISA_LIT>PreserveStructAI ) { TypeName = std :: string ( PossibleTypeDef -> getName ( ) ) ; TypeMeta = PossibleTypeDef ; PatchImm += FirstIndex * ( Ty -> getSizeInBits ( ) >> <NUM_LIT> ) ; break ; } assert ( CInfo . Kind == <ISA_LIT>PreserveArrayAI ) ; CallStack . pop ( ) ; uint64_t AccessIndex = CInfo . AccessIndex ; DIType * BaseTy = nullptr ; bool CheckElemType = false ; if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) { assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_array_type ) ; FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; CheckElemType = CTy -> getElements ( ) . size ( ) == <NUM_LIT> ; } else { auto * DTy = cast < DIDerivedType > ( Ty ) ; assert ( DTy -> getTag ( ) == dwarf :: DW_TAG_pointer_type ) ; BaseTy = stripQualifiers ( DTy -> getBaseType ( ) ) ; CTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CTy ) { CheckElemType = true ; } else if ( CTy -> getTag ( ) != dwarf :: DW_TAG_array_type ) { FirstIndex += AccessIndex ; CheckElemType = true ;


<s> Value * Base = nullptr ; std :: string TypeName ; CallInfoStack CallStack ; while ( Call ) { CallStack . push ( std :: make_pair ( Call , CInfo ) ) ; CInfo = AIChain [ Call ] . second ; Call = AIChain [ Call ] . first ; } uint32_t FirstIndex = <NUM_LIT> ; uint32_t PatchImm = <NUM_LIT> ; uint32_t InfoKind = <STR_LIT> ; while ( CallStack . size ( ) ) { auto StackElem = CallStack . top ( ) ; Call = StackElem . first ; CInfo = StackElem . second ; if ( ! Base ) Base = CInfo . Base ; DIType * PossibleTypeDef = stripQualifiers ( cast < DIType > ( CInfo . Metadata ) , false ) ; DIType * Ty = stripQualifiers ( PossibleTypeDef ) ; if ( CInfo . Kind == <ISA_LIT>PreserveUnionAI || CInfo . Kind == <ISA_LIT>PreserveStructAI ) { TypeName = std :: string ( PossibleTypeDef -> getName ( ) ) ; TypeMeta = PossibleTypeDef ; PatchImm += FirstIndex * ( Ty -> getSizeInBits ( ) >> <NUM_LIT> ) ; break ; } assert ( CInfo . Kind == <ISA_LIT>PreserveArrayAI ) ; CallStack . pop ( ) ; uint64_t AccessIndex = CInfo . AccessIndex ; DIType * BaseTy = nullptr ; bool CheckElemType = false ; if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) { assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_array_type ) ; FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; CheckElemType = CTy -> getElements ( ) . size ( ) == <NUM_LIT> ; } else {

auto * DTy = cast < DIDerivedType > ( Ty ) ;


<s> FunctionPass * llvm :: create<ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM ) { return new <ISA_LIT>AbstractMemberAccessLegacyPass ( TM ) ;


<s> return new <ISA_LIT>AbstractMemberAccessLegacyPass ( TM ) ;


<s> collectAICallChains ( F ) ; for ( auto & C : BaseAICalls ) Transformed = transformGEPChain ( C . first , C . second ) || Transformed ; return removePreserveAccessIndexIntrinsic ( F ) || Transformed ;


<s> } uint32_t AlignBits = RecordAlignment . value ( ) * <NUM_LIT> ; if ( MemberBitSize > AlignBits ) report_fatal_error ( <STR_LIT> <STR_LIT> ) ; StartBitOffset = MemberBitOffset & ~ ( AlignBits - <NUM_LIT> ) ;

if ( ( StartBitOffset + AlignBits ) < ( MemberBitOffset + MemberBitSize ) ) report_fatal_error ( <STR_LIT> <STR_LIT> ) ;


<s> Constant * SeqNumVal = ConstantInt :: get ( Type :: getInt32Ty ( BB -> getContext ( ) ) , <STR_LIT> ++ ) ; auto * NewInst = CallInst :: Create ( Fn , { SeqNumVal , Input } ) ;

BB -> getInstList ( ) . insert ( Before -> getIterator ( ) , NewInst ) ;


<s> Function * Fn = <STR_LIT> ( M , <STR_LIT> , { Input -> getType ( ) , Input -> getType ( ) } ) ;

Constant * SeqNumVal = ConstantInt :: get ( Type :: getInt32Ty ( BB -> getContext ( ) ) , <STR_LIT> ++ ) ;


<s> return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; uint64_t Flag = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( Flag >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; if ( Flag == <STR_LIT> ) CInfo . AccessIndex = <STR_LIT> ; else CInfo . AccessIndex = <STR_LIT> ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; uint64_t Flag = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( Flag >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; if ( Flag == <STR_LIT> ) CInfo . AccessIndex = <STR_LIT> ; else CInfo . AccessIndex = <STR_LIT> ; return true ; } return false ;


<s> const auto * GV = dyn_cast < GlobalValue > ( Call -> getCalledOperand ( ) ) ; if ( ! GV ) return false ; if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveArrayAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( getBaseElementType ( Call ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( getBaseElementType ( Call ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = nullptr ; uint64_t InfoKind = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; if ( InfoKind >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = InfoKind ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ;


<s> std :: vector < CallInst * > PreserveArrayIndexCalls ; std :: vector < CallInst * > PreserveUnionIndexCalls ; std :: vector < CallInst * > PreserveStructIndexCalls ; bool Found = false ; for ( auto & BB : F ) for ( auto & I : BB ) { auto * Call = dyn_cast < CallInst > ( & I ) ; CallInfo CInfo ; if ( ! IsPreserveDIAccessIndexCall ( Call , CInfo ) ) continue ;


<s> PreservedAnalyses <ISA_LIT>AbstractMemberAccessPass :: run ( Function & F , FunctionAnalysisManager & AM ) {

return <ISA_LIT>AbstractMemberAccess ( TM ) . run ( F ) ? PreservedAnalyses :: none ( ) : PreservedAnalyses :: all ( ) ;


<s> bool runOnFunction ( Function & F ) override {

return <ISA_LIT>AbstractMemberAccess ( TM ) . run ( F ) ;


<s> GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { LoadInst * LDInst ; if ( IsInt32Ret ) LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; else LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; Instruction * PassThroughInst = <STR_LIT> ( M , BB , LDInst , Call ) ; Call -> replaceAllUsesWith ( PassThroughInst ) ; Call -> eraseFromParent ( ) ; return true ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ;

BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ;


<s> } BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { IntegerType * VarType ; if ( IsInt32Ret ) VarType = Type :: getInt32Ty ( BB -> getContext ( ) ) ; else VarType = Type :: getInt64Ty ( BB -> getContext ( ) ) ; GV = new GlobalVariable ( * M , VarType , false , GlobalVariable :: ExternalLinkage , nullptr , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { LoadInst * LDInst ; if ( IsInt32Ret ) LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; else LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; Instruction * PassThroughInst = <STR_LIT> ( M , BB , LDInst , Call ) ; Call -> replaceAllUsesWith ( PassThroughInst ) ; Call -> eraseFromParent ( ) ; return true ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ;

auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ;


<s> } assert ( CInfo . Kind == <ISA_LIT>PreserveArrayAI ) ; CallStack . pop ( ) ; uint64_t AccessIndex = CInfo . AccessIndex ; DIType * BaseTy = nullptr ; bool CheckElemType = false ; if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) { assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_array_type ) ; FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; CheckElemType = CTy -> getElements ( ) . size ( ) == <NUM_LIT> ; } else { auto * DTy = cast < DIDerivedType > ( Ty ) ; assert ( DTy -> getTag ( ) == dwarf :: DW_TAG_pointer_type ) ; BaseTy = stripQualifiers ( DTy -> getBaseType ( ) ) ; CTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CTy ) { CheckElemType = true ; } else if ( CTy -> getTag ( ) != dwarf :: DW_TAG_array_type ) { FirstIndex += AccessIndex ; CheckElemType = true ; } else { FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; } } if ( CheckElemType ) { auto * CTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CTy ) { if ( HasPreserveFieldInfoCall ( CallStack ) ) report_fatal_error ( <STR_LIT> ) ; return nullptr ; }


<s> } if ( InfoKind == <STR_LIT> ) { const DIType * BaseTy ; if ( Tag == dwarf :: DW_TAG_array_type ) { if ( CTy -> getElements ( ) . size ( ) != <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; } else { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; BaseTy = stripQualifiers ( MemberTy -> getBaseType ( ) ) ; } const auto * BTy = dyn_cast < DIBasicType > ( BaseTy ) ; while ( ! BTy ) { const auto * CompTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CompTy || CompTy -> getTag ( ) != dwarf :: DW_TAG_enumeration_type ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CompTy -> getBaseType ( ) ) ; BTy = dyn_cast < DIBasicType > ( BaseTy ) ; } uint32_t Encoding = BTy -> getEncoding ( ) ; return ( Encoding == dwarf :: DW_ATE_signed || Encoding == dwarf :: DW_ATE_signed_char ) ; } if ( InfoKind == <STR_LIT> ) { const Triple & Triple = TM -> getTargetTriple ( ) ; DIDerivedType * MemberTy = nullptr ; bool IsBitField = false ; uint32_t SizeInBits ; if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; SizeInBits = calcArraySize ( CTy , <NUM_LIT> ) * EltTy -> getSizeInBits ( ) ; } else { MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; SizeInBits = MemberTy -> getSizeInBits ( ) ; IsBitField = MemberTy -> isBitField ( ) ; } if ( ! IsBitField ) { if ( SizeInBits > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; return <NUM_LIT> - SizeInBits ; } unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( CTy , MemberTy , AccessIndex , SBitOffset , NextSBitOffset ) ; if ( NextSBitOffset - SBitOffset > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; unsigned OffsetInBits = MemberTy -> getOffsetInBits ( ) ; if ( Triple . getArch ( ) == Triple :: bpfel ) return SBitOffset + <NUM_LIT> - OffsetInBits - SizeInBits ; else return OffsetInBits + <NUM_LIT> - NextSBitOffset ; } if ( InfoKind == <STR_LIT> ) { DIDerivedType * MemberTy = nullptr ; bool IsBitField = false ; uint32_t SizeInBits ; if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; SizeInBits = calcArraySize ( CTy , <NUM_LIT> ) * EltTy -> getSizeInBits ( ) ; } else { MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; SizeInBits = MemberTy -> getSizeInBits ( ) ; IsBitField = MemberTy -> isBitField ( ) ; } if ( ! IsBitField ) {


<s> uint32_t Index = AccessIndex + <NUM_LIT> ; for ( ; Index < CTy -> getElements ( ) . size ( ) ; ++ Index ) { auto Member = cast < DIDerivedType > ( CTy -> getElements ( ) [ Index ] ) ; if ( ! Member -> getStorageOffsetInBits ( ) ) { EndBitOffset = Member -> getOffsetInBits ( ) ; break ; } SOff = dyn_cast < ConstantInt > ( Member -> getStorageOffsetInBits ( ) ) ; assert ( SOff ) ;

unsigned BitOffset = SOff -> getZExtValue ( ) ;


<s> if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = nullptr ; uint64_t InfoKind = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ;

if ( InfoKind >= <STR_LIT> ) report_fatal_error ( <STR_LIT> ) ;


<s> LLVM_DEBUG ( dbgs ( ) << <STR_LIT> ) ;

if ( M . debug_compile_units ( ) . empty ( ) ) return false ;


<s> if ( M . debug_compile_units ( ) . empty ( ) ) return false ;


<s> Base = Call -> getArgOperand ( <NUM_LIT> ) ; std :: string TypeName ; MDNode * MDN ; if ( Kind == <ISA_LIT>PreserveUnionAI || Kind == <ISA_LIT>PreserveStructAI ) { MDN = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! MDN ) return nullptr ; DIType * Ty = dyn_cast < DIType > ( MDN ) ; if ( ! Ty ) return nullptr ; TypeName = Ty -> getName ( ) ; } uint64_t AccessIndex ; uint32_t ArgIndex = ( Kind == <ISA_LIT>PreserveUnionAI ) ? <NUM_LIT> : <NUM_LIT> ; if ( ! getAccessIndex ( Call -> getArgOperand ( ArgIndex ) , AccessIndex ) ) return nullptr ; AccessIndices . push_back ( AccessIndex ) ; if ( TypeName . size ( ) ) { TypeNameIndex = AccessIndices . size ( ) - <NUM_LIT> ; LastTypeName = TypeName ; TypeMeta = MDN ;


<s> uint64_t TypeNameIndex = <NUM_LIT> ; std :: string LastTypeName ; while ( Call ) { Base = Call -> getArgOperand ( <NUM_LIT> ) ; std :: string TypeName ; MDNode * MDN ; if ( Kind == <ISA_LIT>PreserveUnionAI || Kind == <ISA_LIT>PreserveStructAI ) { MDN = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! MDN ) return nullptr ; DIType * Ty = dyn_cast < DIType > ( MDN ) ; if ( ! Ty ) return nullptr ; TypeName = Ty -> getName ( ) ; } uint64_t AccessIndex ;

uint32_t ArgIndex = ( Kind == <ISA_LIT>PreserveUnionAI ) ? <NUM_LIT> : <NUM_LIT> ;


<s> bool <ISA_LIT>AbstractMemberAccess :: transformGEPChain ( Module & M , CallInst * Call , uint32_t Kind ) { std :: string AccessStr , AccessKey ; MDNode * TypeMeta = nullptr ; Value * Base = computeBaseAndAccessStr ( Call , AccessStr , AccessKey , Kind , TypeMeta ) ; if ( ! Base ) return false ; BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { GV = new GlobalVariable ( M , Type :: getInt64Ty ( BB -> getContext ( ) ) , false , GlobalVariable :: ExternalLinkage , NULL , AccessStr ) ; GV -> addAttribute ( <STR_LIT> ) ; if ( TypeMeta ) GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , LDInst ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ;


<s> MDNode * TypeMeta = nullptr ; Value * Base = computeBaseAndAccessStr ( Call , AccessStr , AccessKey , Kind , TypeMeta ) ; if ( ! Base ) return false ; BasicBlock * BB = Call -> getParent ( ) ; GlobalVariable * GV ; if ( GEPGlobals . find ( AccessKey ) == GEPGlobals . end ( ) ) { GV = new GlobalVariable ( M , Type :: getInt64Ty ( BB -> getContext ( ) ) , false , GlobalVariable :: ExternalLinkage , NULL , AccessStr ) ; GV -> addAttribute ( <STR_LIT> ) ; if ( TypeMeta ) GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , LDInst ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ;

BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ;


<s> auto Member = cast < DIDerivedType > ( CTy -> getElements ( ) [ Index ] ) ; if ( ! Member -> isBitField ( ) ) { EndBitOffset = Member -> getOffsetInBits ( ) ; break ; } SOff = dyn_cast < ConstantInt > ( Member -> getStorageOffsetInBits ( ) ) ; assert ( SOff ) ; unsigned BitOffset = SOff -> getZExtValue ( ) ; if ( BitOffset != StartBitOffset ) { EndBitOffset = BitOffset ; break ; } }


<s> if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveArrayAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveFieldInfoAI ; CInfo . Metadata = nullptr ; uint64_t InfoKind = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ;


<s> if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlign ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ;


<s> <ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM = nullptr ) : ModulePass ( ID ) , TM ( TM ) {


<s> if ( ! IsPreserveDIAccessIndexCall ( Call , CInfo ) || AIChain . find ( Call ) != AIChain . end ( ) ) continue ;


<s> for ( auto & BB : F ) for ( auto & I : BB ) { CallInfo CInfo ; auto * Call = dyn_cast < CallInst > ( & I ) ; if ( ! IsPreserveDIAccessIndexCall ( Call , CInfo ) || AIChain . find ( Call ) != AIChain . end ( ) ) continue ; traceAICall ( Call , CInfo ) ; }


<s> DIType * BaseTy = nullptr ; bool CheckElemType = false ; if ( const auto * CTy = dyn_cast < DICompositeType > ( Ty ) ) { assert ( CTy -> getTag ( ) == dwarf :: DW_TAG_array_type ) ; FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; CheckElemType = CTy -> getElements ( ) . size ( ) == <NUM_LIT> ; } else { auto * DTy = cast < DIDerivedType > ( Ty ) ; assert ( DTy -> getTag ( ) == dwarf :: DW_TAG_pointer_type ) ; BaseTy = stripQualifiers ( DTy -> getBaseType ( ) ) ; CTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CTy ) { CheckElemType = true ; } else if ( CTy -> getTag ( ) != dwarf :: DW_TAG_array_type ) { FirstIndex += AccessIndex ; CheckElemType = true ; } else { FirstIndex += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) ; } } if ( CheckElemType ) { auto * CTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CTy ) { if ( HasPreserveFieldInfoCall ( CallStack ) ) report_fatal_error ( <STR_LIT> ) ; return nullptr ; } unsigned CTag = CTy -> getTag ( ) ; if ( CTag == dwarf :: DW_TAG_structure_type || CTag == dwarf :: DW_TAG_union_type ) { TypeName = std :: string ( CTy -> getName ( ) ) ; } else { if ( HasPreserveFieldInfoCall ( CallStack ) ) report_fatal_error ( <STR_LIT> ) ; return nullptr ;


<s> ModulePass * llvm :: create<ISA_LIT>AbstractMemberAccess ( <ISA_LIT>TargetMachine * TM ) {

return new <ISA_LIT>AbstractMemberAccess ( TM ) ;


<s> for ( auto & C : BaseAICalls ) Transformed = transformGEPChain ( M , C . first , C . second ) || Transformed ;


<s> for ( auto & C : BaseAICalls ) Transformed = transformGEPChain ( M , C . first , C . second ) || Transformed ; } return removePreserveAccessIndexIntrinsic ( M ) || Transformed ;


<s> uint32_t Encoding = BTy -> getEncoding ( ) ; return ( Encoding == dwarf :: DW_ATE_signed || Encoding == dwarf :: DW_ATE_signed_char ) ; } if ( InfoKind == <STR_LIT> ) { const Triple & Triple = TM -> getTargetTriple ( ) ; DIDerivedType * MemberTy = nullptr ; bool IsBitField = false ; uint32_t SizeInBits ; if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; SizeInBits = calcArraySize ( CTy , <NUM_LIT> ) * EltTy -> getSizeInBits ( ) ; } else { MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; SizeInBits = MemberTy -> getSizeInBits ( ) ; IsBitField = MemberTy -> isBitField ( ) ; } if ( ! IsBitField ) { if ( SizeInBits > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; return <NUM_LIT> - SizeInBits ; } unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; if ( NextSBitOffset - SBitOffset > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; unsigned OffsetInBits = MemberTy -> getOffsetInBits ( ) ; if ( Triple . getArch ( ) == Triple :: bpfel ) return SBitOffset + <NUM_LIT> - OffsetInBits - SizeInBits ; else return OffsetInBits + <NUM_LIT> - NextSBitOffset ; } if ( InfoKind == <STR_LIT> ) { DIDerivedType * MemberTy = nullptr ; bool IsBitField = false ; uint32_t SizeInBits ; if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; SizeInBits = calcArraySize ( CTy , <NUM_LIT> ) * EltTy -> getSizeInBits ( ) ; } else { MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; SizeInBits = MemberTy -> getSizeInBits ( ) ; IsBitField = MemberTy -> isBitField ( ) ; } if ( ! IsBitField ) { if ( SizeInBits > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; return <NUM_LIT> - SizeInBits ; } unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; if ( NextSBitOffset - SBitOffset > <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; return <NUM_LIT> - SizeInBits ;


<s> if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; PatchImm += AccessIndex * calcArraySize ( CTy , <NUM_LIT> ) * ( EltTy -> getSizeInBits ( ) >> <NUM_LIT> ) ; } else if ( Tag == dwarf :: DW_TAG_structure_type ) { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; if ( ! MemberTy -> isBitField ( ) ) { PatchImm += MemberTy -> getOffsetInBits ( ) >> <NUM_LIT> ; } else { unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; PatchImm += SBitOffset >> <NUM_LIT> ; } } return PatchImm ; } if ( InfoKind == <STR_LIT> ) { if ( Tag == dwarf :: DW_TAG_array_type ) { auto * EltTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; return calcArraySize ( CTy , <NUM_LIT> ) * ( EltTy -> getSizeInBits ( ) >> <NUM_LIT> ) ; } else { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; uint32_t SizeInBits = MemberTy -> getSizeInBits ( ) ; if ( ! MemberTy -> isBitField ( ) ) return SizeInBits >> <NUM_LIT> ; unsigned SBitOffset , NextSBitOffset ; GetStorageBitRange ( MemberTy , RecordAlignment , SBitOffset , NextSBitOffset ) ; SizeInBits = NextSBitOffset - SBitOffset ; if ( SizeInBits & ( SizeInBits - <NUM_LIT> ) ) report_fatal_error ( <STR_LIT> ) ; return SizeInBits >> <NUM_LIT> ; } } if ( InfoKind == <STR_LIT> ) { const DIType * BaseTy ; if ( Tag == dwarf :: DW_TAG_array_type ) { if ( CTy -> getElements ( ) . size ( ) != <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CTy -> getBaseType ( ) ) ; } else { auto * MemberTy = cast < DIDerivedType > ( CTy -> getElements ( ) [ AccessIndex ] ) ; BaseTy = stripQualifiers ( MemberTy -> getBaseType ( ) ) ; } const auto * BTy = dyn_cast < DIBasicType > ( BaseTy ) ; while ( ! BTy ) { const auto * CompTy = dyn_cast < DICompositeType > ( BaseTy ) ; if ( ! CompTy || CompTy -> getTag ( ) != dwarf :: DW_TAG_enumeration_type ) report_fatal_error ( <STR_LIT> ) ; BaseTy = stripQualifiers ( CompTy -> getBaseType ( ) ) ; BTy = dyn_cast < DIBasicType > ( BaseTy ) ; } uint32_t Encoding = BTy -> getEncoding ( ) ;

return ( Encoding == dwarf :: DW_ATE_signed || Encoding == dwarf :: DW_ATE_signed_char ) ;


<s> StringRef getPassName ( ) const override {


<s> uint32_t AlignBits = RecordAlignment * <NUM_LIT> ; if ( RecordAlignment > <NUM_LIT> || MemberBitSize > AlignBits ) report_fatal_error ( <STR_LIT> <STR_LIT> ) ; StartBitOffset = MemberBitOffset & ~ ( AlignBits - <NUM_LIT> ) ;

if ( ( StartBitOffset + AlignBits ) < ( MemberBitOffset + MemberBitSize ) ) report_fatal_error ( <STR_LIT> <STR_LIT> ) ;


<s> auto StackElem = CallStack . top ( ) ; if ( StackElem . second . Kind == <ISA_LIT>PreserveFieldInfoAI ) return true ; CallStack . pop ( ) ; }


<s> while ( CallStack . size ( ) ) { auto StackElem = CallStack . top ( ) ; if ( StackElem . second . Kind == <ISA_LIT>PreserveFieldInfoAI ) return true ; CallStack . pop ( ) ; } return false ;


<s> } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveUnionAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ; CInfo . AccessIndex = getConstant ( Call -> getArgOperand ( <NUM_LIT> ) ) ; CInfo . Base = Call -> getArgOperand ( <NUM_LIT> ) ; CInfo . RecordAlignment = DL -> getABITypeAlignment ( CInfo . Base -> getType ( ) -> getPointerElementType ( ) ) ; return true ; } if ( GV -> getName ( ) . startswith ( <STR_LIT> ) ) { CInfo . Kind = <ISA_LIT>PreserveStructAI ; CInfo . Metadata = Call -> getMetadata ( LLVMContext :: MD_preserve_access_index ) ; if ( ! CInfo . Metadata ) report_fatal_error ( <STR_LIT> ) ;


<s> if ( isa < DIDerivedType > ( CType ) ) return false ; if ( const auto * PtrTy = dyn_cast < DIDerivedType > ( PType ) ) { if ( PtrTy -> getTag ( ) != dwarf :: DW_TAG_pointer_type ) return false ; return stripQualifiers ( PtrTy -> getBaseType ( ) ) == CType ; } const auto * PTy = dyn_cast < DICompositeType > ( PType ) ; const auto * CTy = dyn_cast < DICompositeType > ( CType ) ; assert ( PTy && CTy && <STR_LIT> ) ; uint32_t PTyTag = PTy -> getTag ( ) ; assert ( PTyTag == dwarf :: DW_TAG_array_type || PTyTag == dwarf :: DW_TAG_structure_type || PTyTag == dwarf :: DW_TAG_union_type ) ; uint32_t CTyTag = CTy -> getTag ( ) ; assert ( CTyTag == dwarf :: DW_TAG_array_type || CTyTag == dwarf :: DW_TAG_structure_type || CTyTag == dwarf :: DW_TAG_union_type ) ; if ( PTyTag == dwarf :: DW_TAG_array_type && PTyTag == CTyTag ) return PTy -> getBaseType ( ) == CTy -> getBaseType ( ) ; DIType * Ty ; if ( PTyTag == dwarf :: DW_TAG_array_type ) Ty = PTy -> getBaseType ( ) ;

else Ty = dyn_cast < DIType > ( PTy -> getElements ( ) [ ParentAI ] ) ;


<s> bool <ISA_LIT>AbstractMemberAccess :: IsValidAIChain ( const MDNode * ParentType , uint32_t ParentAI , const MDNode * ChildType ) { if ( ! ChildType ) return true ; const DIType * PType = stripQualifiers ( cast < DIType > ( ParentType ) ) ; const DIType * CType = stripQualifiers ( cast < DIType > ( ChildType ) ) ; if ( isa < DIDerivedType > ( CType ) ) return false ; if ( const auto * PtrTy = dyn_cast < DIDerivedType > ( PType ) ) { if ( PtrTy -> getTag ( ) != dwarf :: DW_TAG_pointer_type ) return false ; return stripQualifiers ( PtrTy -> getBaseType ( ) ) == CType ; } const auto * PTy = dyn_cast < DICompositeType > ( PType ) ; const auto * CTy = dyn_cast < DICompositeType > ( CType ) ; assert ( PTy && CTy && <STR_LIT> ) ; uint32_t PTyTag = PTy -> getTag ( ) ; assert ( PTyTag == dwarf :: DW_TAG_array_type || PTyTag == dwarf :: DW_TAG_structure_type || PTyTag == dwarf :: DW_TAG_union_type ) ; uint32_t CTyTag = CTy -> getTag ( ) ; assert ( CTyTag == dwarf :: DW_TAG_array_type || CTyTag == dwarf :: DW_TAG_structure_type || CTyTag == dwarf :: DW_TAG_union_type ) ; if ( PTyTag == dwarf :: DW_TAG_array_type && PTyTag == CTyTag ) return PTy -> getBaseType ( ) == CTy -> getBaseType ( ) ; DIType * Ty ;

if ( PTyTag == dwarf :: DW_TAG_array_type ) Ty = PTy -> getBaseType ( ) ;


<s> Found = true ; if ( CInfo . Kind == <ISA_LIT>PreserveArrayAI ) PreserveArrayIndexCalls . push_back ( Call ) ; else if ( CInfo . Kind == <ISA_LIT>PreserveUnionAI ) PreserveUnionIndexCalls . push_back ( Call ) ; else PreserveStructIndexCalls . push_back ( Call ) ; } replaceWithGEP ( PreserveArrayIndexCalls , <NUM_LIT> , <NUM_LIT> ) ; replaceWithGEP ( PreserveStructIndexCalls , <NUM_LIT> , <NUM_LIT> ) ; for ( auto Call : PreserveUnionIndexCalls ) { Call -> replaceAllUsesWith ( Call -> getArgOperand ( <NUM_LIT> ) ) ; Call -> eraseFromParent ( ) ; } return Found ;


<s> uint32_t Dimension = <NUM_LIT> ; if ( DimensionIndex > <NUM_LIT> ) Dimension = getConstant ( Call -> getArgOperand ( DimensionIndex ) ) ; Constant * Zero = ConstantInt :: get ( Type :: getInt32Ty ( Call -> getParent ( ) -> getContext ( ) ) , <NUM_LIT> ) ; SmallVector < Value * , <NUM_LIT> > IdxList ; for ( unsigned I = <NUM_LIT> ; I < Dimension ; ++ I ) IdxList . push_back ( Zero ) ; IdxList . push_back ( Call -> getArgOperand ( GEPIndex ) ) ; auto * GEP = GetElementPtrInst :: CreateInBounds ( Call -> getArgOperand ( <NUM_LIT> ) , IdxList , <STR_LIT> , Call ) ; Call -> replaceAllUsesWith ( GEP ) ; Call -> eraseFromParent ( ) ; }


<s> for ( unsigned I = <NUM_LIT> ; I < Dimension ; ++ I ) IdxList . push_back ( Zero ) ; IdxList . push_back ( Call -> getArgOperand ( GEPIndex ) ) ; auto * GEP = GetElementPtrInst :: CreateInBounds ( Call -> getArgOperand ( <NUM_LIT> ) , IdxList , <STR_LIT> , Call ) ; Call -> replaceAllUsesWith ( GEP ) ; Call -> eraseFromParent ( ) ; }


<s> bool <ISA_LIT>AbstractMemberAccess :: runOnModule ( Module & M ) {


<s> } else { BaseAICalls [ Parent ] = ParentInfo ; } } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { if ( GI -> hasAllZeroIndices ( ) ) traceGEP ( GI , Parent , ParentInfo ) ; else BaseAICalls [ Parent ] = ParentInfo ; } else { BaseAICalls [ Parent ] = ParentInfo ;


<s> Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , ParentInfo ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { CallInfo ChildInfo ; if ( IsPreserveDIAccessIndexCall ( CI , ChildInfo ) && IsValidAIChain ( ParentInfo . Metadata , ParentInfo . AccessIndex , ChildInfo . Metadata ) ) { AIChain [ CI ] = std :: make_pair ( Parent , ParentInfo ) ; traceAICall ( CI , ChildInfo ) ; } else { BaseAICalls [ Parent ] = ParentInfo ; }

} else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) {


<s> if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , ParentInfo ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { CallInfo ChildInfo ; if ( IsPreserveDIAccessIndexCall ( CI , ChildInfo ) && IsValidAIChain ( ParentInfo . Metadata , ParentInfo . AccessIndex , ChildInfo . Metadata ) ) { AIChain [ CI ] = std :: make_pair ( Parent , ParentInfo ) ; traceAICall ( CI , ChildInfo ) ; } else { BaseAICalls [ Parent ] = ParentInfo ; } } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { if ( GI -> hasAllZeroIndices ( ) ) traceGEP ( GI , Parent , ParentInfo ) ; else BaseAICalls [ Parent ] = ParentInfo ; } else {


<s> for ( User * U : GEP -> users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * BI = dyn_cast < BitCastInst > ( Inst ) ) { traceBitCast ( BI , Parent , ParentInfo ) ; } else if ( auto * CI = dyn_cast < CallInst > ( Inst ) ) { CallInfo ChildInfo ; if ( IsPreserveDIAccessIndexCall ( CI , ChildInfo ) && IsValidAIChain ( ParentInfo . Metadata , ParentInfo . AccessIndex , ChildInfo . Metadata ) ) {

AIChain [ CI ] = std :: make_pair ( Parent , ParentInfo ) ;


<s> else VarType = Type :: getInt64Ty ( BB -> getContext ( ) ) ; GV = new GlobalVariable ( M , VarType , false , GlobalVariable :: ExternalLinkage , NULL , AccessKey ) ; GV -> addAttribute ( <STR_LIT> ) ; GV -> setMetadata ( LLVMContext :: MD_preserve_access_index , TypeMeta ) ; GEPGlobals [ AccessKey ] = GV ; } else { GV = GEPGlobals [ AccessKey ] ; } if ( CInfo . Kind == <ISA_LIT>PreserveFieldInfoAI ) { auto * LDInst = new LoadInst ( Type :: getInt32Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; Call -> replaceAllUsesWith ( LDInst ) ; Call -> eraseFromParent ( ) ; return true ; } auto * LDInst = new LoadInst ( Type :: getInt64Ty ( BB -> getContext ( ) ) , GV , <STR_LIT> , Call ) ; auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ;

Call -> replaceAllUsesWith ( BCInst2 ) ;


<s> auto * BCInst = new BitCastInst ( Base , Type :: getInt8PtrTy ( BB -> getContext ( ) ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst ) ; auto * GEP = GetElementPtrInst :: Create ( Type :: getInt8Ty ( BB -> getContext ( ) ) , BCInst , LDInst ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , GEP ) ; auto * BCInst2 = new BitCastInst ( GEP , Call -> getType ( ) ) ; BB -> getInstList ( ) . insert ( Call -> getIterator ( ) , BCInst2 ) ;


<s> bool <ISA_LIT>AdjustOptImpl :: run ( ) { for ( Function & F : * M ) for ( auto & BB : F ) { adjustBasicBlock ( BB ) ; for ( auto & I : BB ) adjustInst ( I ) ; } return insertPassThrough ( ) ;


<s> bool <ISA_LIT>AdjustOptImpl :: run ( ) { for ( Function & F : * M ) for ( auto & BB : F ) { adjustBasicBlock ( BB ) ; for ( auto & I : BB ) adjustInst ( I ) ; }


<s> if ( ! BI || ! BI -> isConditional ( ) ) return false ; auto * Cond = dyn_cast < ICmpInst > ( BI -> getCondition ( ) ) ; if ( ! Cond || B2 -> getFirstNonPHI ( ) != Cond ) return false ; Value * B2Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond2Op = Cond -> getPredicate ( ) ; TI = B1 -> getTerminator ( ) ; BI = dyn_cast < BranchInst > ( TI ) ; if ( ! BI || ! BI -> isConditional ( ) ) return false ; Cond = dyn_cast < ICmpInst > ( BI -> getCondition ( ) ) ; if ( ! Cond ) return false ; Value * B1Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond1Op = Cond -> getPredicate ( ) ; if ( B1Op0 != B2Op0 ) return false ; if ( Cond1Op == ICmpInst :: ICMP_SGT || Cond1Op == ICmpInst :: ICMP_SGE ) { if ( Cond2Op != ICmpInst :: ICMP_SLT && Cond1Op != ICmpInst :: ICMP_SLE ) return false ; } else if ( Cond1Op == ICmpInst :: ICMP_SLT || Cond1Op == ICmpInst :: ICMP_SLE ) { if ( Cond2Op != ICmpInst :: ICMP_SGT && Cond1Op != ICmpInst :: ICMP_SGE ) return false ; } else { return false ;


<s> if ( ! isa < Constant > ( Icmp1Op1 ) ) return false ; isCandidate = true ; continue ; } if ( Inst -> getParent ( ) == I . getParent ( ) ) continue ; for ( auto & I2 : * Inst -> getParent ( ) ) { if ( dyn_cast < CallInst > ( & I2 ) ) return false ; if ( dyn_cast < LoadInst > ( & I2 ) || dyn_cast < StoreInst > ( & I2 ) ) return false ; if ( & I2 == Inst ) break ; } if ( Inst -> getOpcode ( ) == Instruction :: ZExt || Inst -> getOpcode ( ) == Instruction :: SExt ) {

PassThroughInfo Info ( & I , Inst , <NUM_LIT> ) ;


<s> if ( auto * GV = dyn_cast < GlobalVariable > ( LdInst -> getOperand ( <NUM_LIT> ) ) ) { if ( GV -> hasAttribute ( <STR_LIT> ) || GV -> hasAttribute ( <STR_LIT> ) ) return false ; } } if ( ! isa < LoadInst > ( & I ) && ! isa < CallInst > ( & I ) ) return false ; bool isCandidate = false ; SmallVector < PassThroughInfo , <NUM_LIT> > Candidates ; for ( User * U : I . users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * Icmp1 = dyn_cast < ICmpInst > ( Inst ) ) { Value * Icmp1Op1 = Icmp1 -> getOperand ( <NUM_LIT> ) ; if ( ! isa < Constant > ( Icmp1Op1 ) ) return false ; isCandidate = true ; continue ; } if ( Inst -> getParent ( ) == I . getParent ( ) ) continue ; for ( auto & I2 : * Inst -> getParent ( ) ) { if ( dyn_cast < CallInst > ( & I2 ) ) return false ; if ( dyn_cast < LoadInst > ( & I2 ) || dyn_cast < StoreInst > ( & I2 ) ) return false ; if ( & I2 == Inst ) break ; } if ( Inst -> getOpcode ( ) == Instruction :: ZExt || Inst -> getOpcode ( ) == Instruction :: SExt ) { PassThroughInfo Info ( & I , Inst , <NUM_LIT> ) ; Candidates . push_back ( Info ) ; } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { unsigned i , e ; for ( i = <NUM_LIT> , e = GI -> getNumOperands ( ) ; i != e ; ++ i ) { Value * V = GI -> getOperand ( i ) ; if ( V == & I ) break ; } if ( i == e ) continue ; PassThroughInfo Info ( & I , GI , i ) ; Candidates . push_back ( Info ) ; } } if ( ! isCandidate || Candidates . empty ( ) ) return false ;

llvm :: append_range ( PassThroughs , Candidates ) ;


<s> bool <ISA_LIT>AdjustOptImpl :: serializeICMPInBB ( Instruction & I ) { if ( I . getOpcode ( ) != Instruction :: Or ) return false ; auto * Icmp1 = dyn_cast < ICmpInst > ( I . getOperand ( <NUM_LIT> ) ) ; if ( ! Icmp1 ) return false ; auto * Icmp2 = dyn_cast < ICmpInst > ( I . getOperand ( <NUM_LIT> ) ) ; if ( ! Icmp2 ) return false ;

Value * Icmp1Op0 = Icmp1 -> getOperand ( <NUM_LIT> ) ;


<s> } if ( ! dyn_cast < LoadInst > ( & I ) && ! dyn_cast < CallInst > ( & I ) ) return false ; bool isCandidate = false ; SmallVector < PassThroughInfo , <NUM_LIT> > Candidates ; for ( User * U : I . users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * Icmp1 = dyn_cast < ICmpInst > ( Inst ) ) { Value * Icmp1Op1 = Icmp1 -> getOperand ( <NUM_LIT> ) ; if ( ! isa < Constant > ( Icmp1Op1 ) ) return false ; isCandidate = true ; continue ; } if ( Inst -> getParent ( ) == I . getParent ( ) ) continue ; for ( auto & I2 : * Inst -> getParent ( ) ) { if ( dyn_cast < CallInst > ( & I2 ) ) return false ; if ( dyn_cast < LoadInst > ( & I2 ) || dyn_cast < StoreInst > ( & I2 ) ) return false ; if ( & I2 == Inst ) break ; } if ( Inst -> getOpcode ( ) == Instruction :: ZExt || Inst -> getOpcode ( ) == Instruction :: SExt ) {


<s> void <ISA_LIT>AdjustOpt :: adjustBasicBlock ( BasicBlock & BB ) { if ( ! Disable<ISA_LIT>serializeICMP && serializeICMPCrossBB ( BB ) ) return ;


<s> if ( ! Disable<ISA_LIT>avoidSpeculation && avoidSpeculation ( I ) ) return ;


<s> if ( ! Disable<ISA_LIT>serializeICMP && serializeICMPInBB ( I ) ) return ; if ( ! Disable<ISA_LIT>avoidSpeculation && avoidSpeculation ( I ) ) return ;


<s> if ( auto * Icmp1 = dyn_cast < ICmpInst > ( Inst ) ) { Value * Icmp1Op1 = Icmp1 -> getOperand ( <NUM_LIT> ) ; if ( ! isa < Constant > ( Icmp1Op1 ) ) return false ; isCandidate = true ; continue ; } if ( Inst -> getParent ( ) == I . getParent ( ) ) continue ; for ( auto & I2 : * Inst -> getParent ( ) ) { if ( dyn_cast < CallInst > ( & I2 ) ) return false ; if ( dyn_cast < LoadInst > ( & I2 ) || dyn_cast < StoreInst > ( & I2 ) ) return false ; if ( & I2 == Inst ) break ; } if ( Inst -> getOpcode ( ) == Instruction :: ZExt || Inst -> getOpcode ( ) == Instruction :: SExt ) { PassThroughInfo Info ( & I , Inst , <NUM_LIT> ) ; Candidates . push_back ( Info ) ; } else if ( auto * GI = dyn_cast < GetElementPtrInst > ( Inst ) ) { unsigned i , e ; for ( i = <NUM_LIT> , e = GI -> getNumOperands ( ) ; i != e ; ++ i ) { Value * V = GI -> getOperand ( i ) ; if ( V == & I ) break ; } if ( i == e ) continue ; PassThroughInfo Info ( & I , GI , i ) ; Candidates . push_back ( Info ) ; }


<s> auto * CI = <STR_LIT> ( Mod , Info . UsedInst -> getParent ( ) , Info . Input , Info . UsedInst ) ; Info . UsedInst -> setOperand ( Info . OpIdx , CI ) ;


<s> Mod = & M ; for ( Function & F : M ) for ( auto & BB : F ) { adjustBasicBlock ( BB ) ; for ( auto & I : BB ) adjustInst ( I ) ; } return insertPassThrough ( ) ;


<s> if ( ! BI || ! BI -> isConditional ( ) ) return false ; Cond = dyn_cast < ICmpInst > ( BI -> getCondition ( ) ) ; if ( ! Cond ) return false ; Value * B1Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond1Op = Cond -> getPredicate ( ) ; if ( B1Op0 != B2Op0 ) return false ; if ( Cond1Op == ICmpInst :: ICMP_SGT || Cond1Op == ICmpInst :: ICMP_SGE ) { if ( Cond2Op != ICmpInst :: ICMP_SLT && Cond1Op != ICmpInst :: ICMP_SLE ) return false ; } else if ( Cond1Op == ICmpInst :: ICMP_SLT || Cond1Op == ICmpInst :: ICMP_SLE ) { if ( Cond2Op != ICmpInst :: ICMP_SGT && Cond1Op != ICmpInst :: ICMP_SGE ) return false ; } else { return false ;


<s> Value * B1Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond1Op = Cond -> getPredicate ( ) ; if ( B1Op0 != B2Op0 ) return false ; if ( Cond1Op == ICmpInst :: ICMP_SGT || Cond1Op == ICmpInst :: ICMP_SGE ) { if ( Cond2Op != ICmpInst :: ICMP_SLT && Cond1Op != ICmpInst :: ICMP_SLE ) return false ; } else if ( Cond1Op == ICmpInst :: ICMP_SLT || Cond1Op == ICmpInst :: ICMP_SLE ) { if ( Cond2Op != ICmpInst :: ICMP_SGT && Cond1Op != ICmpInst :: ICMP_SGE ) return false ; } else { return false ; } PassThroughInfo Info ( Cond , BI , <NUM_LIT> ) ; PassThroughs . push_back ( Info ) ; return true ;


<s> if ( ! Icmp1 ) return false ; auto * Icmp2 = dyn_cast < ICmpInst > ( I . getOperand ( <NUM_LIT> ) ) ; if ( ! Icmp2 ) return false ; Value * Icmp1Op0 = Icmp1 -> getOperand ( <NUM_LIT> ) ; Value * Icmp2Op0 = Icmp2 -> getOperand ( <NUM_LIT> ) ; if ( Icmp1Op0 != Icmp2Op0 ) return false ; PassThroughInfo Info ( Icmp1 , & I , <NUM_LIT> ) ; PassThroughs . push_back ( Info ) ;


<s> auto * Icmp1 = dyn_cast < ICmpInst > ( I . getOperand ( <NUM_LIT> ) ) ; if ( ! Icmp1 ) return false ; auto * Icmp2 = dyn_cast < ICmpInst > ( I . getOperand ( <NUM_LIT> ) ) ; if ( ! Icmp2 ) return false ; Value * Icmp1Op0 = Icmp1 -> getOperand ( <NUM_LIT> ) ; Value * Icmp2Op0 = Icmp2 -> getOperand ( <NUM_LIT> ) ; if ( Icmp1Op0 != Icmp2Op0 ) return false ; PassThroughInfo Info ( Icmp1 , & I , <NUM_LIT> ) ;


<s> void <ISA_LIT>AdjustOptImpl :: adjustBasicBlock ( BasicBlock & BB ) { if ( ! Disable<ISA_LIT>serializeICMP && serializeICMPCrossBB ( BB ) ) return ;


<s> ToBeDeleted = nullptr ; } auto * Icmp = dyn_cast < ICmpInst > ( & I ) ; if ( ! Icmp ) continue ; Value * Op0 = Icmp -> getOperand ( <NUM_LIT> ) ; if ( ! isa < TruncInst > ( Op0 ) ) continue ; auto ConstOp1 = dyn_cast < ConstantInt > ( Icmp -> getOperand ( <NUM_LIT> ) ) ; if ( ! ConstOp1 ) continue ; auto ConstOp1Val = ConstOp1 -> getValue ( ) . getZExtValue ( ) ; auto Op = Icmp -> getPredicate ( ) ; if ( Op == ICmpInst :: ICMP_ULT || Op == ICmpInst :: ICMP_UGE ) { if ( ( ConstOp1Val - <NUM_LIT> ) & ConstOp1Val ) continue ; } else if ( Op == ICmpInst :: ICMP_ULE || Op == ICmpInst :: ICMP_UGT ) { if ( ConstOp1Val & ( ConstOp1Val + <NUM_LIT> ) ) continue ; } else { continue ; } Constant * Opcode = ConstantInt :: get ( Type :: getInt32Ty ( BB . getContext ( ) ) , Op ) ; Function * Fn = <STR_LIT> ( M , <STR_LIT> , { Op0 -> getType ( ) , ConstOp1 -> getType ( ) } ) ; auto * NewInst = CallInst :: Create ( Fn , { Opcode , Op0 , ConstOp1 } ) ; BB . getInstList ( ) . insert ( I . getIterator ( ) , NewInst ) ;

Icmp -> replaceAllUsesWith ( NewInst ) ;


<s> void <ISA_LIT>AdjustOptImpl :: adjustInst ( Instruction & I ) { if ( ! Disable<ISA_LIT>serializeICMP && serializeICMPInBB ( I ) ) return ;

if ( ! Disable<ISA_LIT>avoidSpeculation && avoidSpeculation ( I ) ) return ;


<s> if ( ! Disable<ISA_LIT>serializeICMP && serializeICMPInBB ( I ) ) return ;


<s> } } if ( ! isa < LoadInst > ( & I ) && ! isa < CallInst > ( & I ) ) return false ; bool isCandidate = false ; SmallVector < PassThroughInfo , <NUM_LIT> > Candidates ; for ( User * U : I . users ( ) ) { Instruction * Inst = dyn_cast < Instruction > ( U ) ; if ( ! Inst ) continue ; if ( auto * Icmp1 = dyn_cast < ICmpInst > ( Inst ) ) { Value * Icmp1Op1 = Icmp1 -> getOperand ( <NUM_LIT> ) ; if ( ! isa < Constant > ( Icmp1Op1 ) ) return false ; isCandidate = true ; continue ; } if ( Inst -> getParent ( ) == I . getParent ( ) ) continue ; for ( auto & I2 : * Inst -> getParent ( ) ) { if ( isa < CallInst > ( & I2 ) ) return false ; if ( isa < LoadInst > ( & I2 ) || isa < StoreInst > ( & I2 ) ) return false ; if ( & I2 == Inst ) break ; }

if ( Inst -> getOpcode ( ) == Instruction :: ZExt || Inst -> getOpcode ( ) == Instruction :: SExt ) {


<s> <ISA_LIT>AdjustOpt ( ) : ModulePass ( ID ) {


<s> <ISA_LIT>AdjustOptImpl ( Module * M ) : M ( M ) {


<s> ModulePass * llvm :: create<ISA_LIT>AdjustOpt ( ) { return new <ISA_LIT>AdjustOpt ( ) ;


<s> for ( auto & Info : PassThroughs ) {

auto * CI = <STR_LIT> ( M , Info . UsedInst -> getParent ( ) , Info . Input , Info . UsedInst ) ;


<s> for ( auto & Info : PassThroughs ) { auto * CI = <STR_LIT> ( M , Info . UsedInst -> getParent ( ) , Info . Input , Info . UsedInst ) ;

Info . UsedInst -> setOperand ( Info . OpIdx , CI ) ;


<s> PassThroughInfo ( Instruction * I , Instruction * U , uint32_t Idx ) : Input ( I ) , UsedInst ( U ) , OpIdx ( Idx ) {


<s> PreservedAnalyses <ISA_LIT>AdjustOptPass :: run ( Module & M , ModuleAnalysisManager & AM ) {

return <ISA_LIT>AdjustOptImpl ( & M ) . run ( ) ? PreservedAnalyses :: none ( ) : PreservedAnalyses :: all ( ) ;


<s> bool <ISA_LIT>AdjustOpt :: runOnModule ( Module & M ) { return <ISA_LIT>AdjustOptImpl ( & M ) . run ( ) ;


<s> if ( ! Cond || B2 -> getFirstNonPHI ( ) != Cond ) return false ; Value * B2Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond2Op = Cond -> getPredicate ( ) ; TI = B1 -> getTerminator ( ) ; BI = dyn_cast < BranchInst > ( TI ) ; if ( ! BI || ! BI -> isConditional ( ) ) return false ; Cond = dyn_cast < ICmpInst > ( BI -> getCondition ( ) ) ; if ( ! Cond ) return false ; Value * B1Op0 = Cond -> getOperand ( <NUM_LIT> ) ; auto Cond1Op = Cond -> getPredicate ( ) ; if ( B1Op0 != B2Op0 ) return false ; if ( Cond1Op == ICmpInst :: ICMP_SGT || Cond1Op == ICmpInst :: ICMP_SGE ) { if ( Cond2Op != ICmpInst :: ICMP_SLT && Cond2Op != ICmpInst :: ICMP_SLE ) return false ; } else if ( Cond1Op == ICmpInst :: ICMP_SLT || Cond1Op == ICmpInst :: ICMP_SLE ) { if ( Cond2Op != ICmpInst :: ICMP_SGT && Cond2Op != ICmpInst :: ICMP_SGE ) return false ;

} else if ( Cond1Op == ICmpInst :: ICMP_ULT || Cond1Op == ICmpInst :: ICMP_ULE ) {


<s> Value * Icmp2Op0 = Icmp2 -> getOperand ( <NUM_LIT> ) ; if ( Icmp1Op0 != Icmp2Op0 ) return false ; PassThroughInfo Info ( Icmp1 , & I , <NUM_LIT> ) ; PassThroughs . push_back ( Info ) ; return true ;


<s> <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_8 ) { <STR_LIT> :: write < uint64_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; int64_t ByteOff = ( int64_t ) Value - <NUM_LIT> ; if ( ByteOff > INT16_MAX * <NUM_LIT> || ByteOff < INT16_MIN * <NUM_LIT> ) report_fatal_error ( <STR_LIT> ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; <STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ;


<s> <ISA_LIT>AsmBackend ( <STR_LIT> Endian ) : MCAsmBackend ( Endian ) {


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCSubtargetInfo & STI , const MCRegisterInfo & MRI , const MCTargetOptions & ) {

return new <ISA_LIT>AsmBackend ( <STR_LIT> ) ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCSubtargetInfo & STI , const MCRegisterInfo & MRI , const MCTargetOptions & ) { return new <ISA_LIT>AsmBackend ( <STR_LIT> ) ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>beAsmBackend ( const Target & T , const MCSubtargetInfo & STI , const MCRegisterInfo & MRI , const MCTargetOptions & ) {


<s> std :: unique_ptr < MCObjectTargetWriter > <ISA_LIT>AsmBackend :: createObjectTargetWriter ( ) const { return create<ISA_LIT>ELFObjectWriter ( <NUM_LIT> ) ;


<s> return create<ISA_LIT>ELFObjectWriter ( <NUM_LIT> ) ;


<s> bool fixupNeedsRelaxation ( const MCFixup & Fixup , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout ) const override { return false ;


<s> bool fixupNeedsRelaxation ( const MCFixup & Fixup , uint64_t Value , const MCRelaxableFragment * DF , const MCAsmLayout & Layout ) const override {


<s> unsigned getNumFixupKinds ( ) const override { return <NUM_LIT> ;


<s> if ( ( Count % <NUM_LIT> ) != <NUM_LIT> ) return false ; for ( uint64_t i = <NUM_LIT> ; i < Count ; i += <NUM_LIT> ) <STR_LIT> :: write < uint64_t > ( OS , <NUM_LIT> , Endian ) ; return true ;


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value == <NUM_LIT> ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ;


<s> } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; }


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value == <NUM_LIT> ) ; return ;


<s> assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; * ( uint16_t * ) & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> <ISA_LIT>AsmBackend ( ) : MCAsmBackend ( ) {


<s> MCObjectWriter * <ISA_LIT>AsmBackend :: createObjectWriter ( raw_ostream & OS ) const { return create<ISA_LIT>ELFObjectWriter ( OS , <NUM_LIT> ) ;


<s> bool <ISA_LIT>AsmBackend :: writeNopData ( uint64_t Count , MCObjectWriter * OW ) const { if ( ( Count % <NUM_LIT> ) != <NUM_LIT> ) return false ; for ( uint64_t i = <NUM_LIT> ; i < Count ; i += <NUM_LIT> ) OW -> Write64 ( <NUM_LIT> ) ; return true ;


<s> for ( uint64_t i = <NUM_LIT> ; i < Count ; i += <NUM_LIT> ) OW -> Write64 ( <NUM_LIT> ) ;


<s> assert ( Value == <NUM_LIT> ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 ) { <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_8 ) { <STR_LIT> :: write < uint64_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; <STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ; }


<s> bool mayNeedRelaxation ( const MCInst & Inst , const MCSubtargetInfo & STI ) const override {


<s> if ( ( Count % <NUM_LIT> ) != <NUM_LIT> ) return false ; for ( uint64_t i = <NUM_LIT> ; i < Count ; i += <NUM_LIT> ) <STR_LIT> :: write < uint64_t > ( OS , <NUM_LIT> , Endian ) ;


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value <= UINT32_MAX ) ; <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , static_cast < uint32_t > ( Value ) , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 ) { <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_8 ) { <STR_LIT> :: write < uint64_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else {

assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ;


<s> <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , static_cast < uint32_t > ( Value ) , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 ) { <STR_LIT> :: write < uint32_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_Data_8 ) { <STR_LIT> :: write < uint64_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;

<STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ;


<s> } else if ( Fixup . getKind ( ) == FK_Data_8 ) { <STR_LIT> :: write < uint64_t > ( & Data [ Fixup . getOffset ( ) ] , Value , Endian ) ; } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; <STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ;


<s> } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i - <NUM_LIT> ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else if ( Fixup . getKind ( ) == FK_PCRel_4 ) { Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) {

Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ;


<s> assert ( Value == <NUM_LIT> ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i - <NUM_LIT> ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value & <NUM_LIT> ; Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ; Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value & <NUM_LIT> ; }


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value == <NUM_LIT> ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i - <NUM_LIT> ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value & <NUM_LIT> ; Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ; } else {


<s> assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value & <NUM_LIT> ; Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU , const MCTargetOptions & ) { return new <ISA_LIT>AsmBackend ( true ) ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>beAsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU , const MCTargetOptions & ) { return new <ISA_LIT>AsmBackend ( false ) ;


<s> void relaxInstruction ( const MCInst & Inst , const MCSubtargetInfo & STI , MCInst & Res ) const override {


<s> MCAsmBackend * llvm :: create<ISA_LIT>beAsmBackend ( const Target & T , const MCRegisterInfo & MRI , StringRef TT , StringRef CPU ) { return new <ISA_LIT>AsmBackend ( false ) ;


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value == <NUM_LIT> ) ; } else if ( Fixup . getKind ( ) == FK_Data_4 || Fixup . getKind ( ) == FK_Data_8 ) { unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) {


<s> if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; <STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ;


<s> <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> return ; } assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; * ( uint16_t * ) & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ;

* ( uint16_t * ) & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> <ISA_LIT>AsmBackend ( ) : MCAsmBackend ( ) {


<s> unsigned getNumFixupKinds ( ) const { return <NUM_LIT> ;


<s> void relaxInstruction ( const MCInst & Inst , MCInst & Res ) const {


<s> return create<ISA_LIT>ELFObjectWriter ( OS , <NUM_LIT> ) ;


<s> unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i - <NUM_LIT> ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> unsigned Size = Fixup . getKind ( ) == FK_Data_4 ? <NUM_LIT> : <NUM_LIT> ; for ( unsigned i = <NUM_LIT> ; i != Size ; ++ i ) { unsigned Idx = IsLittleEndian ? i : Size - i - <NUM_LIT> ; Data [ Fixup . getOffset ( ) + Idx ] = uint8_t ( Value >> ( i * <NUM_LIT> ) ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( IsLittleEndian ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value & <NUM_LIT> ; Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = Value >> <NUM_LIT> ; } else {


<s> Value = ( uint32_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; if ( Endian == <STR_LIT> ) { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32le ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } else { Data [ Fixup . getOffset ( ) + <NUM_LIT> ] = <NUM_LIT> ; <STR_LIT> :: write32be ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value ) ; } } else { assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ; Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ; <STR_LIT> :: write < uint16_t > ( & Data [ Fixup . getOffset ( ) + <NUM_LIT> ] , Value , Endian ) ; }


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCSubtargetInfo & STI , const MCRegisterInfo & MRI , const MCTargetOptions & ) { return new <ISA_LIT>AsmBackend ( true ) ;


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCSubtargetInfo & STI , const MCRegisterInfo & MRI , const MCTargetOptions & ) {

return new <ISA_LIT>AsmBackend ( true ) ;


<s> if ( Fixup . getKind ( ) == FK_SecRel_4 || Fixup . getKind ( ) == FK_SecRel_8 ) { assert ( Value == <NUM_LIT> ) ; return ; } assert ( Fixup . getKind ( ) == FK_PCRel_2 ) ;

Value = ( uint16_t ) ( ( Value - <NUM_LIT> ) / <NUM_LIT> ) ;


<s> <ISA_LIT>AsmBackend ( bool IsLittleEndian ) : MCAsmBackend ( ) , IsLittleEndian ( IsLittleEndian ) {


<s> MCAsmBackend * llvm :: create<ISA_LIT>AsmBackend ( const Target & T , const MCRegisterInfo & MRI , const Triple & TT , StringRef CPU ) { return new <ISA_LIT>AsmBackend ( true ) ;


<s> bool mayNeedRelaxation ( const MCInst & Inst ) const override {


<s> void relaxInstruction ( const MCInst & Inst , MCInst & Res ) const override {


<s> for ( uint64_t i = <NUM_LIT> ; i < Count ; i += <NUM_LIT> ) OW -> write64 ( <NUM_LIT> ) ;


<s> ~ <ISA_LIT>AsmBackend ( ) override {


<s> return isImm ( ) && dyn_cast < MCConstantExpr > ( getImm ( ) ) ;


<s> unsigned RegNo = MatchRegisterName ( Name ) ; if ( RegNo != <NUM_LIT> ) { SMLoc E = SMLoc :: getFromPointer ( NameLoc . getPointer ( ) - <NUM_LIT> ) ; Operands . push_back ( <STR_LIT> ( RegNo , NameLoc , E ) ) ; } else if ( <STR_LIT> ( Name ) ) Operands . push_back ( <STR_LIT> ( Name , NameLoc ) ) ; else return true ; while ( ! getLexer ( ) . is ( AsmToken :: EndOfStatement ) ) { if ( parseOperandAsOperator ( Operands ) == MatchOperand_Success ) continue ; if ( parseRegister ( Operands ) == MatchOperand_Success ) continue ; if ( parseImmediate ( Operands ) != MatchOperand_Success ) return true ; } if ( getLexer ( ) . isNot ( AsmToken :: EndOfStatement ) ) { SMLoc Loc = getLexer ( ) . getLoc ( ) ; getParser ( ) . eatToEndOfStatement ( ) ; return Error ( Loc , <STR_LIT> ) ; } getParser ( ) . Lex ( ) ; return false ;


<s> if ( parseOperandAsOperator ( Operands ) == MatchOperand_Success ) continue ; if ( parseRegister ( Operands ) == MatchOperand_Success ) continue ; if ( parseImmediate ( Operands ) != MatchOperand_Success ) return true ; } if ( getLexer ( ) . isNot ( AsmToken :: EndOfStatement ) ) { SMLoc Loc = getLexer ( ) . getLoc ( ) ; getParser ( ) . eatToEndOfStatement ( ) ;


<s> getLexer ( ) . Lex ( ) ; Operands . push_back ( <STR_LIT> ( Name , S ) ) ; return MatchOperand_Success ; } case AsmToken :: EqualEqual : case AsmToken :: ExclaimEqual : case AsmToken :: GreaterEqual : case AsmToken :: GreaterGreater : case AsmToken :: LessEqual : case AsmToken :: LessLess : { Operands . push_back ( <STR_LIT> ( getLexer ( ) . getTok ( ) . getString ( ) . substr ( <NUM_LIT> , <NUM_LIT> ) , S ) ) ; Operands . push_back ( <STR_LIT> ( getLexer ( ) . getTok ( ) . getString ( ) . substr ( <NUM_LIT> , <NUM_LIT> ) , S ) ) ; getLexer ( ) . Lex ( ) ; return MatchOperand_Success ; } default : break ;


<s> <ISA_LIT>Operand ( KindTy K ) : Kind ( K ) {


<s> static std :: unique_ptr < <ISA_LIT>Operand > createImm ( const MCExpr * Val , SMLoc S , SMLoc E ) {

auto Op = std :: make_unique < <ISA_LIT>Operand > ( Immediate ) ;


<s> Op -> Imm . Val = Val ; Op -> StartLoc = S ; Op -> EndLoc = E ;


<s> Op -> Reg . RegNum = RegNo ; Op -> StartLoc = S ; Op -> EndLoc = E ;


<s> Op -> Reg . RegNum = RegNo ; Op -> StartLoc = S ;


<s> static std :: unique_ptr < <ISA_LIT>Operand > createToken ( StringRef Str , SMLoc S ) { auto Op = std :: make_unique < <ISA_LIT>Operand > ( Token ) ;


<s> LLVM_EXTERNAL_VISIBILITY void LLVMInitialize<ISA_LIT>AsmParser ( ) { RegisterMCAsmParser < <ISA_LIT>AsmParser > X ( getThe<ISA_LIT>Target ( ) ) ; RegisterMCAsmParser < <ISA_LIT>AsmParser > Y ( getThe<ISA_LIT>leTarget ( ) ) ; RegisterMCAsmParser < <ISA_LIT>AsmParser > Z ( getThe<ISA_LIT>beTarget ( ) ) ;


<s> RegisterMCAsmParser < <ISA_LIT>AsmParser > X ( getThe<ISA_LIT>Target ( ) ) ;

RegisterMCAsmParser < <ISA_LIT>AsmParser > Y ( getThe<ISA_LIT>leTarget ( ) ) ;


<s> if ( tryParseRegister ( RegNo , StartLoc , EndLoc ) != MatchOperand_Success ) return Error ( StartLoc , <STR_LIT> ) ;


<s> StartLoc = Tok . getLoc ( ) ; EndLoc = Tok . getEndLoc ( ) ; RegNo = <NUM_LIT> ; StringRef Name = getLexer ( ) . getTok ( ) . getIdentifier ( ) ; if ( ! MatchRegisterName ( Name ) ) { getParser ( ) . Lex ( ) ; return MatchOperand_Success ; } return MatchOperand_NoMatch ;


<s> StringRef Name = getLexer ( ) . getTok ( ) . getIdentifier ( ) ; if ( ! MatchRegisterName ( Name ) ) { getParser ( ) . Lex ( ) ; return MatchOperand_Success ;


<s> void addExpr ( MCInst & Inst , const MCExpr * Expr ) const { assert ( Expr && <STR_LIT> ) ; if ( auto * CE = dyn_cast < MCConstantExpr > ( Expr ) ) Inst . addOperand ( MCOperand :: createImm ( CE -> getValue ( ) ) ) ;

else Inst . addOperand ( MCOperand :: createExpr ( Expr ) ) ;


<s> assert ( N == <NUM_LIT> && <STR_LIT> ) ;


<s> assert ( N == <NUM_LIT> && <STR_LIT> ) ; addExpr ( Inst , getImm ( ) ) ;


<s> Inst . addOperand ( MCOperand :: createReg ( getReg ( ) ) ) ;


Inst . addOperand ( MCOperand :: createReg ( getReg ( ) ) ) ;


<s> <ISA_LIT>AsmParser ( const MCSubtargetInfo & STI , MCAsmParser & Parser , const MCInstrInfo & MII , const MCTargetOptions & Options ) : MCTargetAsmParser ( Options , STI , MII ) {

setAvailableFeatures ( ComputeAvailableFeatures ( STI . getFeatureBits ( ) ) ) ;


<s> <ISA_LIT>Operand ( const <ISA_LIT>Operand & o ) : MCParsedAsmOperand ( ) { Kind = o . Kind ; StartLoc = o . StartLoc ; EndLoc = o . EndLoc ; switch ( Kind ) { case Register : Reg = o . Reg ; break ;


<s> EndLoc = o . EndLoc ; switch ( Kind ) { case Register : Reg = o . Reg ; break ; case Immediate :


<s> auto Op = make_unique < <ISA_LIT>Operand > ( Immediate ) ; Op -> Imm . Val = Val ; Op -> StartLoc = S ;


<s> static std :: unique_ptr < <ISA_LIT>Operand > createImm ( const MCExpr * Val , SMLoc S , SMLoc E ) { auto Op = make_unique < <ISA_LIT>Operand > ( Immediate ) ; Op -> Imm . Val = Val ; Op -> StartLoc = S ;


<s> static std :: unique_ptr < <ISA_LIT>Operand > createReg ( unsigned RegNo , SMLoc S , SMLoc E ) { auto Op = make_unique < <ISA_LIT>Operand > ( Register ) ;


<s> auto Op = make_unique < <ISA_LIT>Operand > ( Register ) ; Op -> Reg . RegNum = RegNo ; Op -> StartLoc = S ;