[llvm] [Attributor] New attribute to identify what byte ranges are alive for an allocation (PR #66148)
Vidhush Singhal via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 4 15:43:28 PDT 2023
================
@@ -12658,6 +12665,232 @@ struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
};
} // namespace
+/// ----------- Allocation Info ----------
+namespace {
+struct AAAllocationInfoImpl : public AAAllocationInfo {
+ AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
+ : AAAllocationInfo(IRP, A) {}
+
+ std::optional<TypeSize> getAllocatedSize() const override {
+ assert(isValidState() && "the AA is invalid");
+ return AssumedAllocatedSize;
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+
+ const IRPosition &IRP = getIRPosition();
+ Instruction *I = IRP.getCtxI();
+
+ /*TODO: update check for malloc like calls.*/
+ if (!isa<AllocaInst>(I))
+ return indicatePessimisticFixpoint();
+
+ bool IsKnownNoCapture;
+ if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
+ A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
+ return indicatePessimisticFixpoint();
+
+ if (IsKnownNoCapture)
+ return indicatePessimisticFixpoint();
+
+ const AAPointerInfo *PI =
+ A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
+
+ if (!PI)
+ return indicatePessimisticFixpoint();
+
+ if (!PI->getState().isValidState())
+ return indicatePessimisticFixpoint();
+
+ const DataLayout &DL = A.getDataLayout();
+ int64_t BinSize = PI->numOffsetBins();
+ switch (BinSize) {
+ case 0: {
+ switch (I->getOpcode()) {
+ /*TODO: add case for malloc like calls*/
+ case Instruction::Alloca: {
+ AllocaInst *AI = cast<AllocaInst>(I);
+ const auto AllocationSize = AI->getAllocationSize(DL);
+
+ if (!AllocationSize || *AllocationSize == 0)
+ return indicatePessimisticFixpoint();
+
+ break;
+ }
+ default:
+ return indicatePessimisticFixpoint();
+ }
+
+ auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false));
+
+ if (!changeAllocationSize(NewAllocationSize))
+ return ChangeStatus::UNCHANGED;
+ break;
+ }
+ case 1: {
+ const auto &It = PI->begin();
+ if (It->first.Offset == 0) {
+
+ uint64_t SizeOfBin = It->first.Offset + It->first.Size;
+ /*TODO: add case for malloc like calls*/
+ switch (I->getOpcode()) {
+ case Instruction::Alloca: {
+ AllocaInst *AI = cast<AllocaInst>(I);
+ const auto AllocationSize = AI->getAllocationSize(DL);
+
+ if (!AllocationSize || *AllocationSize == 0)
+ return indicatePessimisticFixpoint();
+
+ if (SizeOfBin == *AllocationSize)
+ return indicatePessimisticFixpoint();
+
+ break;
+ }
+ default:
+ return indicatePessimisticFixpoint();
+ }
+
+ auto NewAllocationSize =
+ std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false));
+
+ if (!changeAllocationSize(NewAllocationSize))
+ return ChangeStatus::UNCHANGED;
+ } else {
+ /*TODO: when access does not start at the 0th byte of the bin*/
+ return indicatePessimisticFixpoint();
+ }
+ break;
+ }
+ default: {
+ /*TODO: Handle for multiple Bins*/
+ return indicatePessimisticFixpoint();
+ }
+ }
+
+ return ChangeStatus::CHANGED;
+ }
+
+ /// See AbstractAttribute::manifest(...).
+ ChangeStatus manifest(Attributor &A) override {
+
+ assert(isValidState() &&
+ "Manifest should only be called if the state is valid.");
+
+ Instruction *I = getIRPosition().getCtxI();
+
+ auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
+
+ int NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
+
+ Type *CharType = Type::getInt8Ty(I->getContext());
+
+ auto *NumBytesToValue = llvm::ConstantInt::get(
+ I->getContext(), llvm::APInt(32, NumBytesToAllocate));
+
+ switch (I->getOpcode()) {
+ /*TODO: add case for malloc like calls*/
+ case Instruction::Alloca: {
+
+ AllocaInst *AI = cast<AllocaInst>(I);
+ AllocaInst *NewAllocaInst =
+ new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
+ AI->getAlign(), AI->getName(), AI->getNextNode());
+
+ if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
+ return ChangeStatus::CHANGED;
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ return llvm::ChangeStatus::UNCHANGED;
+ }
+
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr(Attributor *A) const override {
+ if (!isValidState())
+ return "allocationinfo(<invalid>)";
+ return "allocationinfo(" +
+ (AssumedAllocatedSize == HasNoAllocationSize
+ ? "none"
+ : std::to_string(AssumedAllocatedSize->getFixedValue())) +
+ ")";
+ }
+
+private:
+ std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
+
+ bool changeAllocationSize(std::optional<TypeSize> Size) {
+ if (AssumedAllocatedSize == HasNoAllocationSize ||
+ AssumedAllocatedSize != Size) {
----------------
vidsinghal wrote:
this only checks if the allocation size changed or not.
The return value is a bool signifying if the allocation size changed or not changed.
https://github.com/llvm/llvm-project/pull/66148
More information about the llvm-commits
mailing list