aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/StackLifetime.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/StackLifetime.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/Analysis/StackLifetime.cpp')
-rw-r--r--llvm/lib/Analysis/StackLifetime.cpp68
1 files changed, 42 insertions, 26 deletions
diff --git a/llvm/lib/Analysis/StackLifetime.cpp b/llvm/lib/Analysis/StackLifetime.cpp
index 162fd75c73e0..ee77e81fc978 100644
--- a/llvm/lib/Analysis/StackLifetime.cpp
+++ b/llvm/lib/Analysis/StackLifetime.cpp
@@ -67,17 +67,16 @@ static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II,
if (!AI)
return nullptr;
- auto AllocaSizeInBits = AI->getAllocationSizeInBits(DL);
- if (!AllocaSizeInBits)
+ auto AllocaSize = AI->getAllocationSize(DL);
+ if (!AllocaSize)
return nullptr;
- int64_t AllocaSize = *AllocaSizeInBits / 8;
auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
if (!Size)
return nullptr;
int64_t LifetimeSize = Size->getSExtValue();
- if (LifetimeSize != -1 && LifetimeSize != AllocaSize)
+ if (LifetimeSize != -1 && uint64_t(LifetimeSize) != *AllocaSize)
return nullptr;
return AI;
@@ -174,30 +173,35 @@ void StackLifetime::collectMarkers() {
void StackLifetime::calculateLocalLiveness() {
bool Changed = true;
+
+ // LiveIn, LiveOut and BitsIn have a different meaning deppends on type.
+ // ::Maybe true bits represent "may be alive" allocas, ::Must true bits
+ // represent "may be dead". After the loop we will convert ::Must bits from
+ // "may be dead" to "must be alive".
while (Changed) {
+ // TODO: Consider switching to worklist instead of traversing entire graph.
Changed = false;
for (const BasicBlock *BB : depth_first(&F)) {
BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
- // Compute LiveIn by unioning together the LiveOut sets of all preds.
- BitVector LocalLiveIn;
+ // Compute BitsIn by unioning together the LiveOut sets of all preds.
+ BitVector BitsIn;
for (const auto *PredBB : predecessors(BB)) {
LivenessMap::const_iterator I = BlockLiveness.find(PredBB);
// If a predecessor is unreachable, ignore it.
if (I == BlockLiveness.end())
continue;
- switch (Type) {
- case LivenessType::May:
- LocalLiveIn |= I->second.LiveOut;
- break;
- case LivenessType::Must:
- if (LocalLiveIn.empty())
- LocalLiveIn = I->second.LiveOut;
- else
- LocalLiveIn &= I->second.LiveOut;
- break;
- }
+ BitsIn |= I->second.LiveOut;
+ }
+
+ // Everything is "may be dead" for entry without predecessors.
+ if (Type == LivenessType::Must && BitsIn.empty())
+ BitsIn.resize(NumAllocas, true);
+
+ // Update block LiveIn set, noting whether it has changed.
+ if (BitsIn.test(BlockInfo.LiveIn)) {
+ BlockInfo.LiveIn |= BitsIn;
}
// Compute LiveOut by subtracting out lifetimes that end in this
@@ -207,22 +211,34 @@ void StackLifetime::calculateLocalLiveness() {
// because we already handle the case where the BEGIN comes
// before the END when collecting the markers (and building the
// BEGIN/END vectors).
- BitVector LocalLiveOut = LocalLiveIn;
- LocalLiveOut.reset(BlockInfo.End);
- LocalLiveOut |= BlockInfo.Begin;
-
- // Update block LiveIn set, noting whether it has changed.
- if (LocalLiveIn.test(BlockInfo.LiveIn)) {
- BlockInfo.LiveIn |= LocalLiveIn;
+ switch (Type) {
+ case LivenessType::May:
+ BitsIn.reset(BlockInfo.End);
+ // "may be alive" is set by lifetime start.
+ BitsIn |= BlockInfo.Begin;
+ break;
+ case LivenessType::Must:
+ BitsIn.reset(BlockInfo.Begin);
+ // "may be dead" is set by lifetime end.
+ BitsIn |= BlockInfo.End;
+ break;
}
// Update block LiveOut set, noting whether it has changed.
- if (LocalLiveOut.test(BlockInfo.LiveOut)) {
+ if (BitsIn.test(BlockInfo.LiveOut)) {
Changed = true;
- BlockInfo.LiveOut |= LocalLiveOut;
+ BlockInfo.LiveOut |= BitsIn;
}
}
} // while changed.
+
+ if (Type == LivenessType::Must) {
+ // Convert from "may be dead" to "must be alive".
+ for (auto &[BB, BlockInfo] : BlockLiveness) {
+ BlockInfo.LiveIn.flip();
+ BlockInfo.LiveOut.flip();
+ }
+ }
}
void StackLifetime::calculateLiveIntervals() {