[llvm] [DSE] Split memory intrinsics if they are dead in the middle (PR #75478)
Felipe de Azevedo Piovezan via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 14 08:43:41 PST 2023
================
@@ -554,6 +555,80 @@ static void shortenAssignment(Instruction *Inst, Value *OriginalDest,
}
}
+static bool tryToSplitMiddle(Instruction *DeadI,
+ OverlapIntervalsTy &IntervalMap,
+ int64_t &DeadStart, uint64_t &DeadSize,
+ const TargetTransformInfo &TTI) {
+ if (IntervalMap.empty() || !isShortenableAtTheEnd(DeadI))
+ return false;
+
+ OverlapIntervalsTy::iterator OII = IntervalMap.begin();
+ int64_t KillingStart = OII->second;
+ uint64_t KillingSize = OII->first - KillingStart;
+
+ assert(OII->first - KillingStart >= 0 && "Size expected to be positive");
+
+ uint64_t Threshold = TTI.getMaxMemIntrinsicInlineSizeThreshold();
+
+ // __Front__ ___Rear___
+ // | ------------- Dead ------------- |
+ // | --- Killing --- |
+
+ if (KillingStart < DeadStart ||
+ uint64_t(KillingStart + KillingSize) > uint64_t(DeadStart + DeadSize))
+ return false;
+
+ auto *DeadIntrinsic = cast<AnyMemIntrinsic>(DeadI);
+ Align PrefAlign = DeadIntrinsic->getDestAlign().valueOrOne();
+
+ // Assume Front is already correctly aligned.
+ uint64_t FrontSize = KillingStart - DeadStart;
+
+ int64_t RearStart =
+ alignDown(uint64_t(KillingStart + KillingSize), PrefAlign.value());
+ uint64_t RearSize = (DeadStart + DeadSize) - RearStart;
+
+ // If Front and Rear are both bigger than the threshold they won't be inlined
+ // so this seems like a bad idea. If Dead is smaller than the threshold it
+ // will be inlined so this isn't a good idea.
+ if ((FrontSize > Threshold && RearSize > Threshold) || DeadSize < Threshold)
+ return false;
+
+ Value *DeadWriteLength = DeadIntrinsic->getLength();
+ Value *DeadDest = DeadIntrinsic->getRawDest();
+
+ LLVM_DEBUG(dbgs() << "DSE: Split and shortened partially dead store: ["
+ << DeadStart << ", " << DeadSize + DeadStart
+ << "]\nInto: Front: [" << DeadStart << ", "
+ << DeadStart + FrontSize << "], Rear: [" << RearStart
+ << ", " << RearStart + RearSize << "]\n"
+ << "Killer: [" << KillingStart << ", "
+ << KillingSize + KillingStart << "]\n");
+
+ // Dead is now Front.
+ DeadIntrinsic->setLength(
+ ConstantInt::get(DeadWriteLength->getType(), FrontSize));
+ DeadIntrinsic->addDereferenceableParamAttr(0, FrontSize);
+
+ Value *Indices[1] = {ConstantInt::get(DeadWriteLength->getType(), RearStart)};
----------------
felipepiovezan wrote:
IIUC we have an array here for the conversion to ArrayRef later? There is an implicit conversion from `T` to `ArrayRef<T>`, so we probably don't need this
https://github.com/llvm/llvm-project/pull/75478
More information about the llvm-commits
mailing list