@@ -1083,6 +1083,10 @@ struct AAPointerInfoImpl
10831083 return State::numOffsetBins ();
10841084 }
10851085
1086+ virtual const Access &getBinAccess (unsigned Index) const override {
1087+ return getAccess (Index);
1088+ }
1089+
10861090 bool forallInterferingAccesses (
10871091 AA::RangeTy Range,
10881092 function_ref<bool (const AAPointerInfo::Access &, bool )> CB)
@@ -1429,7 +1433,7 @@ struct AAPointerInfoImpl
14291433 void trackPointerInfoStatistics (const IRPosition &IRP) const {}
14301434
14311435 // / Dump the state into \p O.
1432- void dumpState (raw_ostream &O) {
1436+ virtual void dumpState (raw_ostream &O) const override {
14331437 for (auto &It : OffsetBins) {
14341438 O << " [" << It.first .Offset << " -" << It.first .Offset + It.first .Size
14351439 << " ] : " << It.getSecond ().size () << " \n " ;
@@ -12686,6 +12690,11 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1268612690 return AssumedAllocatedSize;
1268712691 }
1268812692
12693+ const NewOffsetsTy &getNewOffsets () const override {
12694+ assert (isValidState () && " the AA is invalid" );
12695+ return NewComputedOffsets;
12696+ }
12697+
1268912698 std::optional<TypeSize> findInitialAllocationSize (Instruction *I,
1269012699 const DataLayout &DL) {
1269112700
@@ -12735,37 +12744,42 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1273512744 if (*AllocationSize == 0 )
1273612745 return indicatePessimisticFixpoint ();
1273712746
12738- int64_t BinSize = PI->numOffsetBins ();
12739-
12740- // TODO: implement for multiple bins
12741- if (BinSize > 1 )
12742- return indicatePessimisticFixpoint ();
12747+ int64_t NumBins = PI->numOffsetBins ();
1274312748
12744- if (BinSize == 0 ) {
12749+ if (NumBins == 0 ) {
1274512750 auto NewAllocationSize = std::optional<TypeSize>(TypeSize (0 , false ));
1274612751 if (!changeAllocationSize (NewAllocationSize))
1274712752 return ChangeStatus::UNCHANGED;
1274812753 return ChangeStatus::CHANGED;
1274912754 }
1275012755
12751- // TODO: refactor this to be part of multiple bin case
12752- const auto &It = PI->begin ();
12756+ // For each access bin
12757+ // Compute its new start Offset and store the results in a new map
12758+ // (NewOffsetBins).
12759+ int64_t PrevBinEndOffset = 0 ;
12760+ bool ChangedOffsets = false ;
12761+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin ();
12762+ It != PI->end (); It++) {
12763+ const AA::RangeTy &OldRange = It->getFirst ();
12764+ int64_t NewStartOffset = PrevBinEndOffset;
12765+ int64_t NewEndOffset = NewStartOffset + OldRange.Size ;
12766+ PrevBinEndOffset = NewEndOffset;
1275312767
12754- // TODO: handle if Offset is not zero
12755- if (It->first .Offset != 0 )
12756- return indicatePessimisticFixpoint ();
12757-
12758- uint64_t SizeOfBin = It->first .Offset + It->first .Size ;
12759-
12760- if (SizeOfBin >= *AllocationSize)
12761- return indicatePessimisticFixpoint ();
12768+ ChangedOffsets |= setNewOffsets (OldRange, OldRange.Offset , NewStartOffset,
12769+ OldRange.Size );
12770+ }
1276212771
12772+ // Set the new size of the allocation, the new size of the Allocation should
12773+ // be the size of NewEndOffset * 8, in bits.
1276312774 auto NewAllocationSize =
12764- std::optional<TypeSize>(TypeSize (SizeOfBin * 8 , false ));
12775+ std::optional<TypeSize>(TypeSize (PrevBinEndOffset * 8 , false ));
1276512776
1276612777 if (!changeAllocationSize (NewAllocationSize))
1276712778 return ChangeStatus::UNCHANGED;
1276812779
12780+ if (!ChangedOffsets)
12781+ return ChangeStatus::UNCHANGED;
12782+
1276912783 return ChangeStatus::CHANGED;
1277012784 }
1277112785
@@ -12775,12 +12789,13 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1277512789 assert (isValidState () &&
1277612790 " Manifest should only be called if the state is valid." );
1277712791
12778- Instruction *I = getIRPosition ().getCtxI ();
12792+ bool Changed = false ;
12793+ const IRPosition &IRP = getIRPosition ();
12794+ Instruction *I = IRP.getCtxI ();
1277912795
1278012796 auto FixedAllocatedSizeInBits = getAllocatedSize ()->getFixedValue ();
1278112797
1278212798 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7 ) / 8 ;
12783-
1278412799 switch (I->getOpcode ()) {
1278512800 // TODO: add case for malloc like calls
1278612801 case Instruction::Alloca: {
@@ -12789,25 +12804,98 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1278912804
1279012805 Type *CharType = Type::getInt8Ty (I->getContext ());
1279112806
12792- auto *NumBytesToValue =
12793- ConstantInt::get (I->getContext (), APInt (32 , NumBytesToAllocate));
12807+ Type *CharArrayType = ArrayType::get (CharType, NumBytesToAllocate);
1279412808
1279512809 BasicBlock::iterator insertPt = AI->getIterator ();
1279612810 insertPt = std::next (insertPt);
12797- AllocaInst *NewAllocaInst =
12798- new AllocaInst (CharType, AI->getAddressSpace (), NumBytesToValue,
12799- AI->getAlign (), AI->getName (), insertPt);
12800-
12801- if (A.changeAfterManifest (IRPosition::inst (*AI), *NewAllocaInst))
12802- return ChangeStatus::CHANGED;
12811+ AllocaInst *NewAllocaInst = new AllocaInst (
12812+ CharArrayType, AI->getAddressSpace (), AI->getName (), insertPt);
1280312813
12814+ Changed |= A.changeAfterManifest (IRPosition::inst (*AI), *NewAllocaInst);
1280412815 break ;
1280512816 }
1280612817 default :
1280712818 break ;
1280812819 }
1280912820
12810- return ChangeStatus::UNCHANGED;
12821+ const AAPointerInfo *PI =
12822+ A.getOrCreateAAFor <AAPointerInfo>(IRP, *this , DepClassTy::REQUIRED);
12823+
12824+ if (!PI)
12825+ return ChangeStatus::UNCHANGED;
12826+
12827+ if (!PI->getState ().isValidState ())
12828+ return ChangeStatus::UNCHANGED;
12829+
12830+ const auto &NewOffsetsMap = getNewOffsets ();
12831+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin ();
12832+ It != PI->end (); It++) {
12833+
12834+ const auto &OldOffsetRange = It->getFirst ();
12835+
12836+ // If the OldOffsetRange is not in the map, offsets for that bin did not
12837+ // change We should just continue and skip changing the offsets in that
12838+ // case
12839+ if (!NewOffsetsMap.contains (OldOffsetRange))
12840+ continue ;
12841+
12842+ const auto &NewOffsetRange = NewOffsetsMap.lookup (OldOffsetRange);
12843+ for (const auto AccIndex : It->getSecond ()) {
12844+
12845+ const auto &AccessInstruction = PI->getBinAccess (AccIndex);
12846+ auto *LocalInst = AccessInstruction.getLocalInst ();
12847+
12848+ switch (LocalInst->getOpcode ()) {
12849+ case Instruction::Load: {
12850+ LoadInst *OldLoadInst = cast<LoadInst>(LocalInst);
12851+ Value *PointerOperand = OldLoadInst->getPointerOperand ();
12852+
12853+ IntegerType *Int8TyInteger =
12854+ IntegerType::get (LocalInst->getContext (), 8 );
12855+ IntegerType *Int64TyInteger =
12856+ IntegerType::get (LocalInst->getContext (), 64 );
12857+ Value *indexList[2 ] = {
12858+ ConstantInt::get (Int64TyInteger, 0 ),
12859+ ConstantInt::get (Int64TyInteger,
12860+ NewOffsetRange.Offset - OldOffsetRange.Offset )};
12861+ Value *GepToNewAddress = GetElementPtrInst::Create (
12862+ Int8TyInteger, PointerOperand, indexList, " NewGep" , OldLoadInst);
12863+
12864+ LoadInst *NewLoadInst =
12865+ new LoadInst (OldLoadInst->getType (), GepToNewAddress,
12866+ OldLoadInst->getName (), OldLoadInst);
12867+ Changed |= A.changeAfterManifest (IRPosition::inst (*OldLoadInst),
12868+ *NewLoadInst);
12869+ break ;
12870+ }
12871+ case Instruction::Store: {
12872+ StoreInst *OldStoreInst = cast<StoreInst>(LocalInst);
12873+ Value *PointerOperand = OldStoreInst->getPointerOperand ();
12874+
12875+ IntegerType *Int8TyInteger =
12876+ IntegerType::get (LocalInst->getContext (), 8 );
12877+ IntegerType *Int64TyInteger =
12878+ IntegerType::get (LocalInst->getContext (), 64 );
12879+ Value *indexList[2 ] = {
12880+ ConstantInt::get (Int64TyInteger, 0 ),
12881+ ConstantInt::get (Int64TyInteger,
12882+ NewOffsetRange.Offset - OldOffsetRange.Offset )};
12883+ Value *GepToNewAddress = GetElementPtrInst::Create (
12884+ Int8TyInteger, PointerOperand, indexList, " NewGep" , OldStoreInst);
12885+
12886+ StoreInst *NewStoreInst = new StoreInst (
12887+ OldStoreInst->getValueOperand (), GepToNewAddress, OldStoreInst);
12888+ Changed |= A.changeAfterManifest (IRPosition::inst (*OldStoreInst),
12889+ *NewStoreInst);
12890+ break ;
12891+ }
12892+ }
12893+ }
12894+ }
12895+
12896+ if (!Changed)
12897+ return ChangeStatus::UNCHANGED;
12898+ return ChangeStatus::CHANGED;
1281112899 }
1281212900
1281312901 // / See AbstractAttribute::getAsStr().
@@ -12821,8 +12909,28 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1282112909 " )" ;
1282212910 }
1282312911
12912+ void dumpNewOffsetBins (raw_ostream &O) {
12913+
12914+ O << " Printing Map from [OldOffsetsRange] : [NewOffsetsRange] if the "
12915+ " offsets changed."
12916+ << " \n " ;
12917+ const auto &NewOffsetsMap = getNewOffsets ();
12918+ for (auto It = NewOffsetsMap.begin (); It != NewOffsetsMap.end (); It++) {
12919+
12920+ const auto &OldRange = It->getFirst ();
12921+ const auto &NewRange = It->getSecond ();
12922+
12923+ O << " [" << OldRange.Offset << " ," << OldRange.Offset + OldRange.Size
12924+ << " ] : " ;
12925+ O << " [" << NewRange.Offset << " ," << NewRange.Offset + NewRange.Size
12926+ << " ]" ;
12927+ O << " \n " ;
12928+ }
12929+ }
12930+
1282412931private:
1282512932 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
12933+ NewOffsetsTy NewComputedOffsets;
1282612934
1282712935 // Maintain the computed allocation size of the object.
1282812936 // Returns (bool) weather the size of the allocation was modified or not.
@@ -12834,6 +12942,21 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
1283412942 }
1283512943 return false ;
1283612944 }
12945+
12946+ // Maps an old byte range to its new Offset range in the new allocation.
12947+ // Returns (bool) weather the old byte range's offsets changed or not.
12948+ bool setNewOffsets (const AA::RangeTy &OldRange, int64_t OldOffset,
12949+ int64_t NewComputedOffset, int64_t Size) {
12950+
12951+ if (OldOffset == NewComputedOffset)
12952+ return false ;
12953+
12954+ AA::RangeTy &NewRange = NewComputedOffsets.getOrInsertDefault (OldRange);
12955+ NewRange.Offset = NewComputedOffset;
12956+ NewRange.Size = Size;
12957+
12958+ return true ;
12959+ }
1283712960};
1283812961
1283912962struct AAAllocationInfoFloating : AAAllocationInfoImpl {
0 commit comments