@@ -303,7 +303,10 @@ void MemoryAccess::updateDimensionality() {
303
303
auto DimsAccess = isl_space_dim (AccessSpace, isl_dim_set);
304
304
auto DimsMissing = DimsArray - DimsAccess;
305
305
306
+ auto *BB = getStatement ()->getParent ()->getRegion ().getEntry ();
307
+ auto &DL = BB->getModule ()->getDataLayout ();
306
308
unsigned ArrayElemSize = SAI->getElemSizeInBytes ();
309
+ unsigned ElemBytes = DL.getTypeAllocSize (getElementType ());
307
310
308
311
auto *Map = isl_map_from_domain_and_range (
309
312
isl_set_universe (AccessSpace),
@@ -612,10 +615,34 @@ void MemoryAccess::assumeNoOutOfBound() {
612
615
isl_space_free (Space);
613
616
}
614
617
618
+ void MemoryAccess::buildMemIntrinsicAccessRelation () {
619
+ auto MAI = MemAccInst (getAccessInstruction ());
620
+ assert (MAI.isMemIntrinsic ());
621
+ assert (Subscripts.size () == 2 && Sizes.size () == 0 );
622
+
623
+ auto *LengthPWA = Statement->getPwAff (Subscripts[1 ]);
624
+ auto *LengthMap = isl_map_from_pw_aff (LengthPWA);
625
+ auto *RangeSpace = isl_space_range (isl_map_get_space (LengthMap));
626
+ LengthMap = isl_map_apply_range (LengthMap, isl_map_lex_gt (RangeSpace));
627
+ LengthMap = isl_map_lower_bound_si (LengthMap, isl_dim_out, 0 , 0 );
628
+ auto *SubscriptPWA = Statement->getPwAff (Subscripts[0 ]);
629
+ auto *SubscriptMap = isl_map_from_pw_aff (SubscriptPWA);
630
+ SubscriptMap =
631
+ isl_map_align_params (SubscriptMap, isl_map_get_space (LengthMap));
632
+ LengthMap = isl_map_align_params (LengthMap, isl_map_get_space (SubscriptMap));
633
+ LengthMap = isl_map_sum (LengthMap, SubscriptMap);
634
+ AccessRelation = isl_map_set_tuple_id (LengthMap, isl_dim_in,
635
+ getStatement ()->getDomainId ());
636
+ }
637
+
615
638
void MemoryAccess::computeBoundsOnAccessRelation (unsigned ElementSize) {
616
639
ScalarEvolution *SE = Statement->getParent ()->getSE ();
617
640
618
- Value *Ptr = MemAccInst (getAccessInstruction ()).getPointerOperand ();
641
+ auto MAI = MemAccInst (getAccessInstruction ());
642
+ if (MAI.isMemIntrinsic ())
643
+ return ;
644
+
645
+ Value *Ptr = MAI.getPointerOperand ();
619
646
if (!Ptr || !SE->isSCEVable (Ptr ->getType ()))
620
647
return ;
621
648
@@ -731,11 +758,16 @@ void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
731
758
isl_id *BaseAddrId = SAI->getBasePtrId ();
732
759
733
760
if (!isAffine ()) {
761
+ if (isa<MemIntrinsic>(getAccessInstruction ()))
762
+ buildMemIntrinsicAccessRelation ();
763
+
734
764
// We overapproximate non-affine accesses with a possible access to the
735
765
// whole array. For read accesses it does not make a difference, if an
736
766
// access must or may happen. However, for write accesses it is important to
737
767
// differentiate between writes that must happen and writes that may happen.
738
- AccessRelation = isl_map_from_basic_map (createBasicAccessMap (Statement));
768
+ if (!AccessRelation)
769
+ AccessRelation = isl_map_from_basic_map (createBasicAccessMap (Statement));
770
+
739
771
AccessRelation =
740
772
isl_map_set_tuple_id (AccessRelation, isl_dim_out, BaseAddrId);
741
773
return ;
@@ -764,19 +796,19 @@ void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
764
796
}
765
797
766
798
MemoryAccess::MemoryAccess (ScopStmt *Stmt, Instruction *AccessInst,
767
- AccessType Type , Value *BaseAddress,
768
- unsigned ElemBytes , bool Affine,
799
+ AccessType AccType , Value *BaseAddress,
800
+ Type *ElementType , bool Affine,
769
801
ArrayRef<const SCEV *> Subscripts,
770
802
ArrayRef<const SCEV *> Sizes, Value *AccessValue,
771
803
ScopArrayInfo::MemoryKind Kind, StringRef BaseName)
772
- : Kind(Kind), AccType(Type ), RedType(RT_NONE), Statement(Stmt),
773
- BaseAddr(BaseAddress), BaseName(BaseName), ElemBytes(ElemBytes ),
804
+ : Kind(Kind), AccType(AccType ), RedType(RT_NONE), Statement(Stmt),
805
+ BaseAddr(BaseAddress), BaseName(BaseName), ElementType(ElementType ),
774
806
Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
775
807
AccessValue(AccessValue), IsAffine(Affine),
776
808
Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(nullptr ),
777
809
NewAccessRelation(nullptr ) {
778
810
static const std::string TypeStrings[] = {" " , " _Read" , " _Write" , " _MayWrite" };
779
- const std::string Access = TypeStrings[Type ] + utostr (Stmt->size ()) + " _" ;
811
+ const std::string Access = TypeStrings[AccType ] + utostr (Stmt->size ()) + " _" ;
780
812
781
813
std::string IdName =
782
814
getIslCompatibleName (Stmt->getBaseName (), Access, BaseName);
@@ -948,7 +980,7 @@ void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
948
980
void ScopStmt::buildAccessRelations () {
949
981
Scop &S = *getParent ();
950
982
for (MemoryAccess *Access : MemAccs) {
951
- Type *ElementType = Access->getAccessValue ()-> getType ();
983
+ Type *ElementType = Access->getElementType ();
952
984
953
985
ScopArrayInfo::MemoryKind Ty;
954
986
if (Access->isPHIKind ())
@@ -2566,7 +2598,10 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
2566
2598
if (!MA->isRead ())
2567
2599
HasWriteAccess.insert (MA->getBaseAddr ());
2568
2600
MemAccInst Acc (MA->getAccessInstruction ());
2569
- PtrToAcc[Acc.getPointerOperand ()] = MA;
2601
+ if (MA->isRead () && Acc.isMemTransferInst ())
2602
+ PtrToAcc[Acc.asMemTransferInst ()->getSource ()] = MA;
2603
+ else
2604
+ PtrToAcc[Acc.getPointerOperand ()] = MA;
2570
2605
AST.add (Acc);
2571
2606
}
2572
2607
}
@@ -2578,8 +2613,8 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
2578
2613
AliasGroupTy AG;
2579
2614
for (auto &PR : AS)
2580
2615
AG.push_back (PtrToAcc[PR.getValue ()]);
2581
- assert (AG.size () > 1 &&
2582
- " Alias groups should contain at least two accesses " ) ;
2616
+ if (AG.size () < 2 )
2617
+ continue ;
2583
2618
AliasGroups.push_back (std::move (AG));
2584
2619
}
2585
2620
@@ -3774,8 +3809,7 @@ bool ScopInfo::buildAccessMultiDimFixed(
3774
3809
const ScopDetection::BoxedLoopsSetTy *BoxedLoops,
3775
3810
const InvariantLoadsSetTy &ScopRIL) {
3776
3811
Value *Val = Inst.getValueOperand ();
3777
- Type *SizeType = Val->getType ();
3778
- unsigned ElementSize = DL->getTypeAllocSize (SizeType);
3812
+ Type *ElementType = Val->getType ();
3779
3813
Value *Address = Inst.getPointerOperand ();
3780
3814
const SCEV *AccessFunction = SE->getSCEVAtScope (Address, L);
3781
3815
const SCEVUnknown *BasePointer =
@@ -3816,7 +3850,7 @@ bool ScopInfo::buildAccessMultiDimFixed(
3816
3850
SizesSCEV.push_back (SE->getSCEV (ConstantInt::get (
3817
3851
IntegerType::getInt64Ty (BasePtr->getContext ()), V)));
3818
3852
3819
- addArrayAccess (Inst, Type, BasePointer->getValue (), ElementSize , true ,
3853
+ addArrayAccess (Inst, Type, BasePointer->getValue (), ElementType , true ,
3820
3854
Subscripts, SizesSCEV, Val);
3821
3855
return true ;
3822
3856
}
@@ -3831,8 +3865,8 @@ bool ScopInfo::buildAccessMultiDimParam(
3831
3865
const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) {
3832
3866
Value *Address = Inst.getPointerOperand ();
3833
3867
Value *Val = Inst.getValueOperand ();
3834
- Type *SizeType = Val->getType ();
3835
- unsigned ElementSize = DL->getTypeAllocSize (SizeType );
3868
+ Type *ElementType = Val->getType ();
3869
+ unsigned ElementSize = DL->getTypeAllocSize (ElementType );
3836
3870
enum MemoryAccess::AccessType Type =
3837
3871
Inst.isLoad () ? MemoryAccess::READ : MemoryAccess::MUST_WRITE;
3838
3872
@@ -3860,21 +3894,58 @@ bool ScopInfo::buildAccessMultiDimParam(
3860
3894
if (ElementSize != DelinearizedSize)
3861
3895
scop->invalidate (DELINEARIZATION, Inst.getDebugLoc ());
3862
3896
3863
- addArrayAccess (Inst, Type, BasePointer->getValue (), ElementSize , true ,
3897
+ addArrayAccess (Inst, Type, BasePointer->getValue (), ElementType , true ,
3864
3898
AccItr->second .DelinearizedSubscripts , Sizes, Val);
3865
3899
return true ;
3866
3900
}
3867
3901
return false ;
3868
3902
}
3869
3903
3904
+ bool ScopInfo::buildAccessMemIntrinsic (
3905
+ MemAccInst Inst, Loop *L, Region *R,
3906
+ const ScopDetection::BoxedLoopsSetTy *BoxedLoops,
3907
+ const InvariantLoadsSetTy &ScopRIL) {
3908
+ if (!Inst.isMemIntrinsic ())
3909
+ return false ;
3910
+
3911
+ auto *LengthVal = SE->getSCEVAtScope (Inst.asMemIntrinsic ()->getLength (), L);
3912
+ assert (LengthVal);
3913
+
3914
+ auto *DestPtrVal = Inst.asMemIntrinsic ()->getDest ();
3915
+ assert (DestPtrVal);
3916
+ auto *DestAccFunc = SE->getSCEVAtScope (DestPtrVal, L);
3917
+ assert (DestAccFunc);
3918
+ auto *DestPtrSCEV = dyn_cast<SCEVUnknown>(SE->getPointerBase (DestAccFunc));
3919
+ assert (DestPtrSCEV);
3920
+ DestAccFunc = SE->getMinusSCEV (DestAccFunc, DestPtrSCEV);
3921
+ addArrayAccess (Inst, MemoryAccess::MUST_WRITE, DestPtrSCEV->getValue (),
3922
+ IntegerType::getInt8Ty (DestPtrVal->getContext ()), false ,
3923
+ {DestAccFunc, LengthVal}, {}, Inst.getValueOperand ());
3924
+
3925
+ if (!Inst.isMemTransferInst ())
3926
+ return true ;
3927
+
3928
+ auto *SrcPtrVal = Inst.asMemTransferInst ()->getSource ();
3929
+ assert (SrcPtrVal);
3930
+ auto *SrcAccFunc = SE->getSCEVAtScope (SrcPtrVal, L);
3931
+ assert (SrcAccFunc);
3932
+ auto *SrcPtrSCEV = dyn_cast<SCEVUnknown>(SE->getPointerBase (SrcAccFunc));
3933
+ assert (SrcPtrSCEV);
3934
+ SrcAccFunc = SE->getMinusSCEV (SrcAccFunc, SrcPtrSCEV);
3935
+ addArrayAccess (Inst, MemoryAccess::READ, SrcPtrSCEV->getValue (),
3936
+ IntegerType::getInt8Ty (SrcPtrVal->getContext ()), false ,
3937
+ {SrcAccFunc, LengthVal}, {}, Inst.getValueOperand ());
3938
+
3939
+ return true ;
3940
+ }
3941
+
3870
3942
void ScopInfo::buildAccessSingleDim (
3871
3943
MemAccInst Inst, Loop *L, Region *R,
3872
3944
const ScopDetection::BoxedLoopsSetTy *BoxedLoops,
3873
3945
const InvariantLoadsSetTy &ScopRIL) {
3874
3946
Value *Address = Inst.getPointerOperand ();
3875
3947
Value *Val = Inst.getValueOperand ();
3876
- Type *SizeType = Val->getType ();
3877
- unsigned ElementSize = DL->getTypeAllocSize (SizeType);
3948
+ Type *ElementType = Val->getType ();
3878
3949
enum MemoryAccess::AccessType Type =
3879
3950
Inst.isLoad () ? MemoryAccess::READ : MemoryAccess::MUST_WRITE;
3880
3951
@@ -3907,7 +3978,7 @@ void ScopInfo::buildAccessSingleDim(
3907
3978
if (!IsAffine && Type == MemoryAccess::MUST_WRITE)
3908
3979
Type = MemoryAccess::MAY_WRITE;
3909
3980
3910
- addArrayAccess (Inst, Type, BasePointer->getValue (), ElementSize , IsAffine,
3981
+ addArrayAccess (Inst, Type, BasePointer->getValue (), ElementType , IsAffine,
3911
3982
{AccessFunction}, {}, Val);
3912
3983
}
3913
3984
@@ -3916,6 +3987,9 @@ void ScopInfo::buildMemoryAccess(
3916
3987
const ScopDetection::BoxedLoopsSetTy *BoxedLoops,
3917
3988
const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) {
3918
3989
3990
+ if (buildAccessMemIntrinsic (Inst, L, R, BoxedLoops, ScopRIL))
3991
+ return ;
3992
+
3919
3993
if (buildAccessMultiDimFixed (Inst, L, R, BoxedLoops, ScopRIL))
3920
3994
return ;
3921
3995
@@ -3999,8 +4073,8 @@ void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB,
3999
4073
}
4000
4074
4001
4075
MemoryAccess *ScopInfo::addMemoryAccess (BasicBlock *BB, Instruction *Inst,
4002
- MemoryAccess::AccessType Type ,
4003
- Value *BaseAddress, unsigned ElemBytes ,
4076
+ MemoryAccess::AccessType AccType ,
4077
+ Value *BaseAddress, Type *ElementType ,
4004
4078
bool Affine, Value *AccessValue,
4005
4079
ArrayRef<const SCEV *> Subscripts,
4006
4080
ArrayRef<const SCEV *> Sizes,
@@ -4037,24 +4111,23 @@ MemoryAccess *ScopInfo::addMemoryAccess(BasicBlock *BB, Instruction *Inst,
4037
4111
if (Kind == ScopArrayInfo::MK_PHI || Kind == ScopArrayInfo::MK_ExitPHI)
4038
4112
isKnownMustAccess = true ;
4039
4113
4040
- if (!isKnownMustAccess && Type == MemoryAccess::MUST_WRITE)
4041
- Type = MemoryAccess::MAY_WRITE;
4114
+ if (!isKnownMustAccess && AccType == MemoryAccess::MUST_WRITE)
4115
+ AccType = MemoryAccess::MAY_WRITE;
4042
4116
4043
- AccList.emplace_back (Stmt, Inst, Type , BaseAddress, ElemBytes , Affine,
4117
+ AccList.emplace_back (Stmt, Inst, AccType , BaseAddress, ElementType , Affine,
4044
4118
Subscripts, Sizes, AccessValue, Kind, BaseName);
4045
4119
Stmt->addAccess (&AccList.back ());
4046
4120
return &AccList.back ();
4047
4121
}
4048
4122
4049
4123
void ScopInfo::addArrayAccess (MemAccInst MemAccInst,
4050
- MemoryAccess::AccessType Type, Value *BaseAddress ,
4051
- unsigned ElemBytes, bool IsAffine ,
4052
- ArrayRef<const SCEV *> Subscripts,
4124
+ MemoryAccess::AccessType AccType ,
4125
+ Value *BaseAddress, Type *ElementType ,
4126
+ bool IsAffine, ArrayRef<const SCEV *> Subscripts,
4053
4127
ArrayRef<const SCEV *> Sizes,
4054
4128
Value *AccessValue) {
4055
- assert (MemAccInst.isLoad () == (Type == MemoryAccess::READ));
4056
- addMemoryAccess (MemAccInst.getParent (), MemAccInst, Type, BaseAddress,
4057
- ElemBytes, IsAffine, AccessValue, Subscripts, Sizes,
4129
+ addMemoryAccess (MemAccInst.getParent (), MemAccInst, AccType, BaseAddress,
4130
+ ElementType, IsAffine, AccessValue, Subscripts, Sizes,
4058
4131
ScopArrayInfo::MK_Array);
4059
4132
}
4060
4133
@@ -4069,8 +4142,8 @@ void ScopInfo::ensureValueWrite(Instruction *Inst) {
4069
4142
if (Stmt->lookupValueWriteOf (Inst))
4070
4143
return ;
4071
4144
4072
- addMemoryAccess (Inst->getParent (), Inst, MemoryAccess::MUST_WRITE, Inst, 1 ,
4073
- true , Inst, ArrayRef<const SCEV *>(),
4145
+ addMemoryAccess (Inst->getParent (), Inst, MemoryAccess::MUST_WRITE, Inst,
4146
+ Inst-> getType (), true , Inst, ArrayRef<const SCEV *>(),
4074
4147
ArrayRef<const SCEV *>(), ScopArrayInfo::MK_Value);
4075
4148
}
4076
4149
@@ -4119,7 +4192,7 @@ void ScopInfo::ensureValueRead(Value *V, BasicBlock *UserBB) {
4119
4192
if (UserStmt->lookupValueReadOf (V))
4120
4193
return ;
4121
4194
4122
- addMemoryAccess (UserBB, nullptr , MemoryAccess::READ, V, 1 , true , V,
4195
+ addMemoryAccess (UserBB, nullptr , MemoryAccess::READ, V, V-> getType () , true , V,
4123
4196
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
4124
4197
ScopArrayInfo::MK_Value);
4125
4198
if (ValueInst)
@@ -4149,17 +4222,17 @@ void ScopInfo::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock,
4149
4222
MemoryAccess *Acc = addMemoryAccess (
4150
4223
IncomingStmt->isBlockStmt () ? IncomingBlock
4151
4224
: IncomingStmt->getRegion ()->getEntry (),
4152
- PHI, MemoryAccess::MUST_WRITE, PHI, 1 , true , PHI,
4225
+ PHI, MemoryAccess::MUST_WRITE, PHI, PHI-> getType () , true , PHI,
4153
4226
ArrayRef<const SCEV *>(), ArrayRef<const SCEV *>(),
4154
4227
IsExitBlock ? ScopArrayInfo::MK_ExitPHI : ScopArrayInfo::MK_PHI);
4155
4228
assert (Acc);
4156
4229
Acc->addIncoming (IncomingBlock, IncomingValue);
4157
4230
}
4158
4231
4159
4232
void ScopInfo::addPHIReadAccess (PHINode *PHI) {
4160
- addMemoryAccess (PHI->getParent (), PHI, MemoryAccess::READ, PHI, 1 , true , PHI,
4161
- ArrayRef< const SCEV *>() , ArrayRef<const SCEV *>(),
4162
- ScopArrayInfo::MK_PHI);
4233
+ addMemoryAccess (PHI->getParent (), PHI, MemoryAccess::READ, PHI,
4234
+ PHI-> getType (), true , PHI , ArrayRef<const SCEV *>(),
4235
+ ArrayRef< const SCEV *>(), ScopArrayInfo::MK_PHI);
4163
4236
}
4164
4237
4165
4238
void ScopInfo::buildScop (Region &R, AssumptionCache &AC) {
0 commit comments