@@ -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";
@@ -6969,10 +6974,9 @@ ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6969
6974
if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
6970
6975
Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
6971
6976
if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
6972
- LLVM_DEBUG(
6973
- dbgs()
6974
- << "[H2S] unique free call might not be executed with the allocation "
6975
- << *UniqueFree << "\n");
6977
+ LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
6978
+ "with the allocation "
6979
+ << *UniqueFree << "\n");
6976
6980
return false;
6977
6981
}
6978
6982
}
@@ -10425,11 +10429,12 @@ struct AANoFPClassFloating : public AANoFPClassImpl {
10425
10429
10426
10430
struct AANoFPClassReturned final
10427
10431
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10428
- AANoFPClassImpl::StateType, false, Attribute::None, false> {
10432
+ AANoFPClassImpl::StateType, false,
10433
+ Attribute::None, false> {
10429
10434
AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10430
10435
: AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10431
- AANoFPClassImpl::StateType, false, Attribute::None, false>(
10432
- IRP, A) {}
10436
+ AANoFPClassImpl::StateType, false,
10437
+ Attribute::None, false>( IRP, A) {}
10433
10438
10434
10439
/// See AbstractAttribute::trackStatistics()
10435
10440
void trackStatistics() const override {
@@ -12686,6 +12691,11 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12686
12691
return AssumedAllocatedSize;
12687
12692
}
12688
12693
12694
+ const NewOffsetsTy &getNewOffsets() const override {
12695
+ assert(isValidState() && "the AA is invalid");
12696
+ return NewComputedOffsets;
12697
+ }
12698
+
12689
12699
std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
12690
12700
const DataLayout &DL) {
12691
12701
@@ -12735,37 +12745,42 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12735
12745
if (*AllocationSize == 0)
12736
12746
return indicatePessimisticFixpoint();
12737
12747
12738
- int64_t BinSize = PI->numOffsetBins();
12739
-
12740
- // TODO: implement for multiple bins
12741
- if (BinSize > 1)
12742
- return indicatePessimisticFixpoint();
12748
+ int64_t NumBins = PI->numOffsetBins();
12743
12749
12744
- if (BinSize == 0) {
12750
+ if (NumBins == 0) {
12745
12751
auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false));
12746
12752
if (!changeAllocationSize(NewAllocationSize))
12747
12753
return ChangeStatus::UNCHANGED;
12748
12754
return ChangeStatus::CHANGED;
12749
12755
}
12750
12756
12751
- // TODO: refactor this to be part of multiple bin case
12752
- const auto &It = PI->begin();
12757
+ // For each access bin
12758
+ // Compute its new start Offset and store the results in a new map
12759
+ // (NewOffsetBins).
12760
+ int64_t PrevBinEndOffset = 0;
12761
+ bool ChangedOffsets = false;
12762
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin();
12763
+ It != PI->end(); It++) {
12764
+ const AA::RangeTy &OldRange = It->getFirst();
12765
+ int64_t NewStartOffset = PrevBinEndOffset;
12766
+ int64_t NewEndOffset = NewStartOffset + OldRange.Size;
12767
+ PrevBinEndOffset = NewEndOffset;
12753
12768
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();
12769
+ ChangedOffsets |= setNewOffsets(OldRange, OldRange.Offset, NewStartOffset,
12770
+ OldRange.Size);
12771
+ }
12762
12772
12773
+ // Set the new size of the allocation, the new size of the Allocation should
12774
+ // be the size of NewEndOffset * 8, in bits.
12763
12775
auto NewAllocationSize =
12764
- std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false));
12776
+ std::optional<TypeSize>(TypeSize(PrevBinEndOffset * 8, false));
12765
12777
12766
12778
if (!changeAllocationSize(NewAllocationSize))
12767
12779
return ChangeStatus::UNCHANGED;
12768
12780
12781
+ if (!ChangedOffsets)
12782
+ return ChangeStatus::UNCHANGED;
12783
+
12769
12784
return ChangeStatus::CHANGED;
12770
12785
}
12771
12786
@@ -12775,12 +12790,13 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12775
12790
assert(isValidState() &&
12776
12791
"Manifest should only be called if the state is valid.");
12777
12792
12778
- Instruction *I = getIRPosition().getCtxI();
12793
+ bool Changed = false;
12794
+ const IRPosition &IRP = getIRPosition();
12795
+ Instruction *I = IRP.getCtxI();
12779
12796
12780
12797
auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
12781
12798
12782
12799
unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
12783
-
12784
12800
switch (I->getOpcode()) {
12785
12801
// TODO: add case for malloc like calls
12786
12802
case Instruction::Alloca: {
@@ -12789,25 +12805,100 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12789
12805
12790
12806
Type *CharType = Type::getInt8Ty(I->getContext());
12791
12807
12792
- auto *NumBytesToValue =
12793
- ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
12808
+ Type *CharArrayType = ArrayType::get(CharType, NumBytesToAllocate);
12794
12809
12795
12810
BasicBlock::iterator insertPt = AI->getIterator();
12796
12811
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;
12812
+ AllocaInst *NewAllocaInst = new AllocaInst(
12813
+ CharArrayType, AI->getAddressSpace(), AI->getName(), insertPt);
12803
12814
12815
+ Changed |= A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst);
12804
12816
break;
12805
12817
}
12806
12818
default:
12807
12819
break;
12808
12820
}
12809
12821
12810
- return ChangeStatus::UNCHANGED;
12822
+ const AAPointerInfo *PI =
12823
+ A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
12824
+
12825
+ if (!PI)
12826
+ return ChangeStatus::UNCHANGED;
12827
+
12828
+ if (!PI->getState().isValidState())
12829
+ return ChangeStatus::UNCHANGED;
12830
+
12831
+ const auto &NewOffsetsMap = getNewOffsets();
12832
+ for (AAPointerInfo::OffsetBinsTy::const_iterator It = PI->begin();
12833
+ It != PI->end(); It++) {
12834
+
12835
+ const auto &OldOffsetRange = It->getFirst();
12836
+
12837
+ // If the OldOffsetRange is not in the map, offsets for that bin did not
12838
+ // change We should just continue and skip changing the offsets in that
12839
+ // case
12840
+ if (!NewOffsetsMap.contains(OldOffsetRange))
12841
+ continue;
12842
+
12843
+ const auto &NewOffsetRange = NewOffsetsMap.lookup(OldOffsetRange);
12844
+ int64_t ShiftValue = NewOffsetRange.Offset - OldOffsetRange.Offset;
12845
+ for (const auto AccIndex : It->getSecond()) {
12846
+
12847
+ const auto &AccessInstruction = PI->getBinAccess(AccIndex);
12848
+ auto *LocalInst = AccessInstruction.getLocalInst();
12849
+
12850
+ switch (LocalInst->getOpcode()) {
12851
+ case Instruction::Load: {
12852
+ LoadInst *OldLoadInst = cast<LoadInst>(LocalInst);
12853
+ Value *PointerOperand = OldLoadInst->getPointerOperand();
12854
+ Type *PointeeTy = OldLoadInst->getPointerOperandType();
12855
+
12856
+ IntegerType *Int64TyInteger =
12857
+ IntegerType::get(LocalInst->getContext(), 64);
12858
+
12859
+ Value *IndexList[1] = {ConstantInt::get(Int64TyInteger, ShiftValue)};
12860
+ Value *GepToNewAddress = GetElementPtrInst::Create(
12861
+ PointeeTy, PointerOperand, IndexList, "NewGep", OldLoadInst);
12862
+
12863
+ LoadInst *NewLoadInst = new LoadInst(
12864
+ OldLoadInst->getType(), GepToNewAddress, OldLoadInst->getName(),
12865
+ false, OldLoadInst->getAlign(), OldLoadInst);
12866
+
12867
+ Changed |= A.changeAfterManifest(IRPosition::inst(*OldLoadInst),
12868
+ *NewLoadInst);
12869
+
12870
+ A.deleteAfterManifest(*OldLoadInst);
12871
+ break;
12872
+ }
12873
+ case Instruction::Store: {
12874
+ StoreInst *OldStoreInst = cast<StoreInst>(LocalInst);
12875
+ Value *PointerOperand = OldStoreInst->getPointerOperand();
12876
+ Type *PointeeTy = OldStoreInst->getPointerOperandType();
12877
+
12878
+ IntegerType *Int64TyInteger =
12879
+ IntegerType::get(LocalInst->getContext(), 64);
12880
+
12881
+ Value *IndexList[1] = {ConstantInt::get(Int64TyInteger, ShiftValue)};
12882
+ Value *GepToNewAddress = GetElementPtrInst::Create(
12883
+ PointeeTy, PointerOperand, IndexList, "NewGep", OldStoreInst);
12884
+
12885
+ StoreInst *NewStoreInst =
12886
+ new StoreInst(OldStoreInst->getValueOperand(), GepToNewAddress,
12887
+ false, OldStoreInst->getAlign(), OldStoreInst);
12888
+
12889
+ Changed |= A.changeAfterManifest(IRPosition::inst(*OldStoreInst),
12890
+ *NewStoreInst);
12891
+
12892
+ A.deleteAfterManifest(*OldStoreInst);
12893
+ break;
12894
+ }
12895
+ }
12896
+ }
12897
+ }
12898
+
12899
+ if (!Changed)
12900
+ return ChangeStatus::UNCHANGED;
12901
+ return ChangeStatus::CHANGED;
12811
12902
}
12812
12903
12813
12904
/// See AbstractAttribute::getAsStr().
@@ -12821,8 +12912,28 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12821
12912
")";
12822
12913
}
12823
12914
12915
+ void dumpNewOffsetBins(raw_ostream &O) {
12916
+
12917
+ O << "Printing Map from [OldOffsetsRange] : [NewOffsetsRange] if the "
12918
+ "offsets changed."
12919
+ << "\n";
12920
+ const auto &NewOffsetsMap = getNewOffsets();
12921
+ for (auto It = NewOffsetsMap.begin(); It != NewOffsetsMap.end(); It++) {
12922
+
12923
+ const auto &OldRange = It->getFirst();
12924
+ const auto &NewRange = It->getSecond();
12925
+
12926
+ O << "[" << OldRange.Offset << "," << OldRange.Offset + OldRange.Size
12927
+ << "] : ";
12928
+ O << "[" << NewRange.Offset << "," << NewRange.Offset + NewRange.Size
12929
+ << "]";
12930
+ O << "\n";
12931
+ }
12932
+ }
12933
+
12824
12934
private:
12825
12935
std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
12936
+ NewOffsetsTy NewComputedOffsets;
12826
12937
12827
12938
// Maintain the computed allocation size of the object.
12828
12939
// Returns (bool) weather the size of the allocation was modified or not.
@@ -12834,6 +12945,21 @@ struct AAAllocationInfoImpl : public AAAllocationInfo {
12834
12945
}
12835
12946
return false;
12836
12947
}
12948
+
12949
+ // Maps an old byte range to its new Offset range in the new allocation.
12950
+ // Returns (bool) weather the old byte range's offsets changed or not.
12951
+ bool setNewOffsets(const AA::RangeTy &OldRange, int64_t OldOffset,
12952
+ int64_t NewComputedOffset, int64_t Size) {
12953
+
12954
+ if (OldOffset == NewComputedOffset)
12955
+ return false;
12956
+
12957
+ AA::RangeTy &NewRange = NewComputedOffsets.getOrInsertDefault(OldRange);
12958
+ NewRange.Offset = NewComputedOffset;
12959
+ NewRange.Size = Size;
12960
+
12961
+ return true;
12962
+ }
12837
12963
};
12838
12964
12839
12965
struct AAAllocationInfoFloating : AAAllocationInfoImpl {
0 commit comments