@@ -419,7 +419,8 @@ struct AAReturnedFromReturnedValues : public BaseType {
419
419
// / See AbstractAttribute::updateImpl(...).
420
420
ChangeStatus updateImpl (Attributor &A) override {
421
421
StateType S (StateType::getBestState (this ->getState ()));
422
- clampReturnedValueStates<AAType, StateType, IRAttributeKind, RecurseForSelectAndPHI>(
422
+ clampReturnedValueStates<AAType, StateType, IRAttributeKind,
423
+ RecurseForSelectAndPHI>(
423
424
A, *this , S,
424
425
PropagateCallBaseContext ? this ->getCallBaseContext () : nullptr );
425
426
// TODO: If we know we visited all returned values, thus no are assumed
@@ -1083,6 +1084,10 @@ struct AAPointerInfoImpl
1083
1084
return State::numOffsetBins ();
1084
1085
}
1085
1086
1087
+ virtual const Access &getBinAccess (unsigned Index) const override {
1088
+ return getAccess (Index);
1089
+ }
1090
+
1086
1091
bool forallInterferingAccesses (
1087
1092
AA::RangeTy Range,
1088
1093
function_ref<bool (const AAPointerInfo::Access &, bool )> CB)
@@ -1429,7 +1434,7 @@ struct AAPointerInfoImpl
1429
1434
void trackPointerInfoStatistics (const IRPosition &IRP) const {}
1430
1435
1431
1436
// / Dump the state into \p O.
1432
- void dumpState (raw_ostream &O) {
1437
+ virtual void dumpState (raw_ostream &O) const override {
1433
1438
for (auto &It : OffsetBins) {
1434
1439
O << " [" << It.first .Offset << " -" << It.first .Offset + It.first .Size
1435
1440
<< " ] : " << It.getSecond ().size () << " \n " ;
@@ -6975,10 +6980,9 @@ ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6975
6980
if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
6976
6981
Instruction *CtxI = isa<InvokeInst>(AI.CB ) ? AI.CB : AI.CB ->getNextNode ();
6977
6982
if (!Explorer || !Explorer->findInContextOf (UniqueFree, CtxI)) {
6978
- LLVM_DEBUG (
6979
- dbgs ()
6980
- << " [H2S] unique free call might not be executed with the allocation "
6981
- << *UniqueFree << " \n " );
6983
+ LLVM_DEBUG (dbgs () << " [H2S] unique free call might not be executed "
6984
+ " with the allocation "
6985
+ << *UniqueFree << " \n " );
6982
6986
return false ;
6983
6987
}
6984
6988
}
@@ -10431,11 +10435,12 @@ struct AANoFPClassFloating : public AANoFPClassImpl {
10431
10435
10432
10436
struct AANoFPClassReturned final
10433
10437
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10434
- AANoFPClassImpl::StateType, false , Attribute::None, false > {
10438
+ AANoFPClassImpl::StateType, false ,
10439
+ Attribute::None, false > {
10435
10440
AANoFPClassReturned (const IRPosition &IRP, Attributor &A)
10436
10441
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10437
- AANoFPClassImpl::StateType, false , Attribute::None, false >(
10438
- IRP, A) {}
10442
+ AANoFPClassImpl::StateType, false ,
10443
+ Attribute::None, false >( IRP, A) {}
10439
10444
10440
10445
// / See AbstractAttribute::trackStatistics()
10441
10446
void trackStatistics () const override {
@@ -12692,6 +12697,11 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12692
12697
return AssumedAllocatedSize;
12693
12698
}
12694
12699
12700
+ const NewOffsetsTy &getNewOffsets () const override {
12701
+ assert (isValidState () && " the AA is invalid" );
12702
+ return NewComputedOffsets;
12703
+ }
12704
+
12695
12705
std::optional<TypeSize> findInitialAllocationSize (Instruction *I,
12696
12706
const DataLayout &DL) {
12697
12707
@@ -12741,37 +12751,42 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12741
12751
if (*AllocationSize == 0 )
12742
12752
return indicatePessimisticFixpoint ();
12743
12753
12744
- int64_t BinSize = PI->numOffsetBins ();
12745
-
12746
- // TODO: implement for multiple bins
12747
- if (BinSize > 1 )
12748
- return indicatePessimisticFixpoint ();
12754
+ int64_t NumBins = PI->numOffsetBins ();
12749
12755
12750
- if (BinSize == 0 ) {
12756
+ if (NumBins == 0 ) {
12751
12757
auto NewAllocationSize = std::optional<TypeSize>(TypeSize (0 , false ));
12752
12758
if (!changeAllocationSize (NewAllocationSize))
12753
12759
return ChangeStatus::UNCHANGED;
12754
12760
return ChangeStatus::CHANGED;
12755
12761
}
12756
12762
12757
- // TODO: refactor this to be part of multiple bin case
12758
- const auto &It = PI->begin ();
12763
+ // For each access bin
12764
+ // Compute its new start Offset and store the results in a new map
12765
+ // (NewOffsetBins).
12766
+ int64_t PrevBinEndOffset = 0 ;
12767
+ bool ChangedOffsets = false ;
12768
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin ();
12769
+ It != PI->end (); It++) {
12770
+ const AA::RangeTy &OldRange = It->getFirst ();
12771
+ int64_t NewStartOffset = PrevBinEndOffset;
12772
+ int64_t NewEndOffset = NewStartOffset + OldRange.Size ;
12773
+ PrevBinEndOffset = NewEndOffset;
12759
12774
12760
- // TODO: handle if Offset is not zero
12761
- if (It->first .Offset != 0 )
12762
- return indicatePessimisticFixpoint ();
12763
-
12764
- uint64_t SizeOfBin = It->first .Offset + It->first .Size ;
12765
-
12766
- if (SizeOfBin >= *AllocationSize)
12767
- return indicatePessimisticFixpoint ();
12775
+ ChangedOffsets |= setNewOffsets (OldRange, OldRange.Offset , NewStartOffset,
12776
+ OldRange.Size );
12777
+ }
12768
12778
12779
+ // Set the new size of the allocation, the new size of the Allocation should
12780
+ // be the size of NewEndOffset * 8, in bits.
12769
12781
auto NewAllocationSize =
12770
- std::optional<TypeSize>(TypeSize (SizeOfBin * 8 , false ));
12782
+ std::optional<TypeSize>(TypeSize (PrevBinEndOffset * 8 , false ));
12771
12783
12772
12784
if (!changeAllocationSize (NewAllocationSize))
12773
12785
return ChangeStatus::UNCHANGED;
12774
12786
12787
+ if (!ChangedOffsets)
12788
+ return ChangeStatus::UNCHANGED;
12789
+
12775
12790
return ChangeStatus::CHANGED;
12776
12791
}
12777
12792
@@ -12781,12 +12796,13 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12781
12796
assert (isValidState () &&
12782
12797
" Manifest should only be called if the state is valid." );
12783
12798
12784
- Instruction *I = getIRPosition ().getCtxI ();
12799
+ bool Changed = false ;
12800
+ const IRPosition &IRP = getIRPosition ();
12801
+ Instruction *I = IRP.getCtxI ();
12785
12802
12786
12803
auto FixedAllocatedSizeInBits = getAllocatedSize ()->getFixedValue ();
12787
12804
12788
- unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7 ) / 8 ;
12789
-
12805
+ long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7 ) / 8 ;
12790
12806
switch (I->getOpcode ()) {
12791
12807
// TODO: add case for malloc like calls
12792
12808
case Instruction::Alloca: {
@@ -12795,25 +12811,100 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12795
12811
12796
12812
Type *CharType = Type::getInt8Ty (I->getContext ());
12797
12813
12798
- auto *NumBytesToValue =
12799
- ConstantInt::get (I->getContext (), APInt (32 , NumBytesToAllocate));
12814
+ Type *CharArrayType = ArrayType::get (CharType, NumBytesToAllocate);
12800
12815
12801
12816
BasicBlock::iterator insertPt = AI->getIterator ();
12802
12817
insertPt = std::next (insertPt);
12803
- AllocaInst *NewAllocaInst =
12804
- new AllocaInst (CharType, AI->getAddressSpace (), NumBytesToValue,
12805
- AI->getAlign (), AI->getName (), insertPt);
12806
-
12807
- if (A.changeAfterManifest (IRPosition::inst (*AI), *NewAllocaInst))
12808
- return ChangeStatus::CHANGED;
12818
+ AllocaInst *NewAllocaInst = new AllocaInst (
12819
+ CharArrayType, AI->getAddressSpace (), AI->getName (), insertPt);
12809
12820
12821
+ Changed |= A.changeAfterManifest (IRPosition::inst (*AI), *NewAllocaInst);
12810
12822
break ;
12811
12823
}
12812
12824
default :
12813
12825
break ;
12814
12826
}
12815
12827
12816
- return ChangeStatus::UNCHANGED;
12828
+ const AAPointerInfo *PI =
12829
+ A.getOrCreateAAFor <AAPointerInfo>(IRP, *this , DepClassTy::REQUIRED);
12830
+
12831
+ if (!PI)
12832
+ return ChangeStatus::UNCHANGED;
12833
+
12834
+ if (!PI->getState ().isValidState ())
12835
+ return ChangeStatus::UNCHANGED;
12836
+
12837
+ const auto &NewOffsetsMap = getNewOffsets ();
12838
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin ();
12839
+ It != PI->end (); It++) {
12840
+
12841
+ const auto &OldOffsetRange = It->getFirst ();
12842
+
12843
+ // If the OldOffsetRange is not in the map, offsets for that bin did not
12844
+ // change We should just continue and skip changing the offsets in that
12845
+ // case
12846
+ if (!NewOffsetsMap.contains (OldOffsetRange))
12847
+ continue ;
12848
+
12849
+ const auto &NewOffsetRange = NewOffsetsMap.lookup (OldOffsetRange);
12850
+ int64_t ShiftValue = NewOffsetRange.Offset - OldOffsetRange.Offset ;
12851
+ for (const auto AccIndex : It->getSecond ()) {
12852
+
12853
+ const auto &AccessInstruction = PI->getBinAccess (AccIndex);
12854
+ auto *LocalInst = AccessInstruction.getLocalInst ();
12855
+
12856
+ switch (LocalInst->getOpcode ()) {
12857
+ case Instruction::Load: {
12858
+ LoadInst *OldLoadInst = cast<LoadInst>(LocalInst);
12859
+ Value *PointerOperand = OldLoadInst->getPointerOperand ();
12860
+ Type *PointeeTy = OldLoadInst->getPointerOperandType ();
12861
+
12862
+ IntegerType *Int64TyInteger =
12863
+ IntegerType::get (LocalInst->getContext (), 64 );
12864
+
12865
+ Value *IndexList[1 ] = {ConstantInt::get (Int64TyInteger, ShiftValue)};
12866
+ Value *GepToNewAddress = GetElementPtrInst::Create (
12867
+ PointeeTy, PointerOperand, IndexList, " NewGep" , OldLoadInst);
12868
+
12869
+ LoadInst *NewLoadInst = new LoadInst (
12870
+ OldLoadInst->getType (), GepToNewAddress, OldLoadInst->getName (),
12871
+ false , OldLoadInst->getAlign (), OldLoadInst);
12872
+
12873
+ Changed |= A.changeAfterManifest (IRPosition::inst (*OldLoadInst),
12874
+ *NewLoadInst);
12875
+
12876
+ A.deleteAfterManifest (*OldLoadInst);
12877
+ break ;
12878
+ }
12879
+ case Instruction::Store: {
12880
+ StoreInst *OldStoreInst = cast<StoreInst>(LocalInst);
12881
+ Value *PointerOperand = OldStoreInst->getPointerOperand ();
12882
+ Type *PointeeTy = OldStoreInst->getPointerOperandType ();
12883
+
12884
+ IntegerType *Int64TyInteger =
12885
+ IntegerType::get (LocalInst->getContext (), 64 );
12886
+
12887
+ Value *IndexList[1 ] = {ConstantInt::get (Int64TyInteger, ShiftValue)};
12888
+ Value *GepToNewAddress = GetElementPtrInst::Create (
12889
+ PointeeTy, PointerOperand, IndexList, " NewGep" , OldStoreInst);
12890
+
12891
+ StoreInst *NewStoreInst =
12892
+ new StoreInst (OldStoreInst->getValueOperand (), GepToNewAddress,
12893
+ false , OldStoreInst->getAlign (), OldStoreInst);
12894
+
12895
+ Changed |= A.changeAfterManifest (IRPosition::inst (*OldStoreInst),
12896
+ *NewStoreInst);
12897
+
12898
+ A.deleteAfterManifest (*OldStoreInst);
12899
+ break ;
12900
+ }
12901
+ }
12902
+ }
12903
+ }
12904
+
12905
+ if (!Changed)
12906
+ return ChangeStatus::UNCHANGED;
12907
+ return ChangeStatus::CHANGED;
12817
12908
}
12818
12909
12819
12910
// / See AbstractAttribute::getAsStr().
@@ -12827,8 +12918,28 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12827
12918
" )" ;
12828
12919
}
12829
12920
12921
+ void dumpNewOffsetBins (raw_ostream &O) {
12922
+
12923
+ O << " Printing Map from [OldOffsetsRange] : [NewOffsetsRange] if the "
12924
+ " offsets changed."
12925
+ << " \n " ;
12926
+ const auto &NewOffsetsMap = getNewOffsets ();
12927
+ for (auto It = NewOffsetsMap.begin (); It != NewOffsetsMap.end (); It++) {
12928
+
12929
+ const auto &OldRange = It->getFirst ();
12930
+ const auto &NewRange = It->getSecond ();
12931
+
12932
+ O << " [" << OldRange.Offset << " ," << OldRange.Offset + OldRange.Size
12933
+ << " ] : " ;
12934
+ O << " [" << NewRange.Offset << " ," << NewRange.Offset + NewRange.Size
12935
+ << " ]" ;
12936
+ O << " \n " ;
12937
+ }
12938
+ }
12939
+
12830
12940
private:
12831
12941
std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
12942
+ NewOffsetsTy NewComputedOffsets;
12832
12943
12833
12944
// Maintain the computed allocation size of the object.
12834
12945
// Returns (bool) weather the size of the allocation was modified or not.
@@ -12840,6 +12951,21 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12840
12951
}
12841
12952
return false ;
12842
12953
}
12954
+
12955
+ // Maps an old byte range to its new Offset range in the new allocation.
12956
+ // Returns (bool) weather the old byte range's offsets changed or not.
12957
+ bool setNewOffsets (const AA::RangeTy &OldRange, int64_t OldOffset,
12958
+ int64_t NewComputedOffset, int64_t Size ) {
12959
+
12960
+ if (OldOffset == NewComputedOffset)
12961
+ return false ;
12962
+
12963
+ AA::RangeTy &NewRange = NewComputedOffsets.getOrInsertDefault (OldRange);
12964
+ NewRange.Offset = NewComputedOffset;
12965
+ NewRange.Size = Size ;
12966
+
12967
+ return true ;
12968
+ }
12843
12969
};
12844
12970
12845
12971
struct AAAllocationInfoFloating : AAAllocationInfoImpl {
0 commit comments