mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
[objc-arc] Track if we encountered an additive overflow while computing {TopDown,BottomUp}PathCounts and do nothing if it occurred.
I fixed the aforementioned problems that came up on some of the linux boxes. Major thanks to Nick Lewycky for his help debugging! rdar://14590914 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188122 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
835738ce54
commit
3ed7576a3b
@ -674,7 +674,9 @@ namespace {
|
|||||||
SmallVector<BasicBlock *, 2> Succs;
|
SmallVector<BasicBlock *, 2> Succs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BBState() : TopDownPathCount(0), BottomUpPathCount(0) {}
|
static const unsigned OverflowOccurredValue;
|
||||||
|
|
||||||
|
BBState() : TopDownPathCount(0), BottomUpPathCount(0) { }
|
||||||
|
|
||||||
typedef MapTy::iterator ptr_iterator;
|
typedef MapTy::iterator ptr_iterator;
|
||||||
typedef MapTy::const_iterator ptr_const_iterator;
|
typedef MapTy::const_iterator ptr_const_iterator;
|
||||||
@ -745,13 +747,15 @@ namespace {
|
|||||||
/// Returns true if overflow occured. Returns false if overflow did not
|
/// Returns true if overflow occured. Returns false if overflow did not
|
||||||
/// occur.
|
/// occur.
|
||||||
bool GetAllPathCountWithOverflow(unsigned &PathCount) const {
|
bool GetAllPathCountWithOverflow(unsigned &PathCount) const {
|
||||||
assert(TopDownPathCount != 0);
|
if (TopDownPathCount == OverflowOccurredValue ||
|
||||||
assert(BottomUpPathCount != 0);
|
BottomUpPathCount == OverflowOccurredValue)
|
||||||
|
return true;
|
||||||
unsigned long long Product =
|
unsigned long long Product =
|
||||||
(unsigned long long)TopDownPathCount*BottomUpPathCount;
|
(unsigned long long)TopDownPathCount*BottomUpPathCount;
|
||||||
PathCount = Product;
|
// Overflow occured if any of the upper bits of Product are set or if all
|
||||||
// Overflow occured if any of the upper bits of Product are set.
|
// the lower bits of Product are all set.
|
||||||
return Product >> 32;
|
return (Product >> 32) ||
|
||||||
|
((PathCount = Product) == OverflowOccurredValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized CFG utilities.
|
// Specialized CFG utilities.
|
||||||
@ -766,6 +770,8 @@ namespace {
|
|||||||
|
|
||||||
bool isExit() const { return Succs.empty(); }
|
bool isExit() const { return Succs.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const unsigned BBState::OverflowOccurredValue = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BBState::InitFromPred(const BBState &Other) {
|
void BBState::InitFromPred(const BBState &Other) {
|
||||||
@ -781,13 +787,25 @@ void BBState::InitFromSucc(const BBState &Other) {
|
|||||||
/// The top-down traversal uses this to merge information about predecessors to
|
/// The top-down traversal uses this to merge information about predecessors to
|
||||||
/// form the initial state for a new block.
|
/// form the initial state for a new block.
|
||||||
void BBState::MergePred(const BBState &Other) {
|
void BBState::MergePred(const BBState &Other) {
|
||||||
|
if (TopDownPathCount == OverflowOccurredValue)
|
||||||
|
return;
|
||||||
|
|
||||||
// Other.TopDownPathCount can be 0, in which case it is either dead or a
|
// Other.TopDownPathCount can be 0, in which case it is either dead or a
|
||||||
// loop backedge. Loop backedges are special.
|
// loop backedge. Loop backedges are special.
|
||||||
TopDownPathCount += Other.TopDownPathCount;
|
TopDownPathCount += Other.TopDownPathCount;
|
||||||
|
|
||||||
|
// In order to be consistent, we clear the top down pointers when by adding
|
||||||
|
// TopDownPathCount becomes OverflowOccurredValue even though "true" overflow
|
||||||
|
// has not occured.
|
||||||
|
if (TopDownPathCount == OverflowOccurredValue) {
|
||||||
|
clearTopDownPointers();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for overflow. If we have overflow, fall back to conservative
|
// Check for overflow. If we have overflow, fall back to conservative
|
||||||
// behavior.
|
// behavior.
|
||||||
if (TopDownPathCount < Other.TopDownPathCount) {
|
if (TopDownPathCount < Other.TopDownPathCount) {
|
||||||
|
TopDownPathCount = OverflowOccurredValue;
|
||||||
clearTopDownPointers();
|
clearTopDownPointers();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -813,13 +831,25 @@ void BBState::MergePred(const BBState &Other) {
|
|||||||
/// The bottom-up traversal uses this to merge information about successors to
|
/// The bottom-up traversal uses this to merge information about successors to
|
||||||
/// form the initial state for a new block.
|
/// form the initial state for a new block.
|
||||||
void BBState::MergeSucc(const BBState &Other) {
|
void BBState::MergeSucc(const BBState &Other) {
|
||||||
|
if (BottomUpPathCount == OverflowOccurredValue)
|
||||||
|
return;
|
||||||
|
|
||||||
// Other.BottomUpPathCount can be 0, in which case it is either dead or a
|
// Other.BottomUpPathCount can be 0, in which case it is either dead or a
|
||||||
// loop backedge. Loop backedges are special.
|
// loop backedge. Loop backedges are special.
|
||||||
BottomUpPathCount += Other.BottomUpPathCount;
|
BottomUpPathCount += Other.BottomUpPathCount;
|
||||||
|
|
||||||
|
// In order to be consistent, we clear the top down pointers when by adding
|
||||||
|
// BottomUpPathCount becomes OverflowOccurredValue even though "true" overflow
|
||||||
|
// has not occured.
|
||||||
|
if (BottomUpPathCount == OverflowOccurredValue) {
|
||||||
|
clearBottomUpPointers();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for overflow. If we have overflow, fall back to conservative
|
// Check for overflow. If we have overflow, fall back to conservative
|
||||||
// behavior.
|
// behavior.
|
||||||
if (BottomUpPathCount < Other.BottomUpPathCount) {
|
if (BottomUpPathCount < Other.BottomUpPathCount) {
|
||||||
|
BottomUpPathCount = OverflowOccurredValue;
|
||||||
clearBottomUpPointers();
|
clearBottomUpPointers();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2526,9 +2556,12 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
// If we overflow when we compute the path count, don't remove/move
|
// If we overflow when we compute the path count, don't remove/move
|
||||||
// anything.
|
// anything.
|
||||||
const BBState &NRRBBState = BBStates[NewRetainRelease->getParent()];
|
const BBState &NRRBBState = BBStates[NewRetainRelease->getParent()];
|
||||||
unsigned PathCount;
|
unsigned PathCount = BBState::OverflowOccurredValue;
|
||||||
if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
|
if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
|
||||||
return false;
|
return false;
|
||||||
|
assert(PathCount != BBState::OverflowOccurredValue &&
|
||||||
|
"PathCount at this point can not be "
|
||||||
|
"OverflowOccurredValue.");
|
||||||
OldDelta -= PathCount;
|
OldDelta -= PathCount;
|
||||||
|
|
||||||
// Merge the ReleaseMetadata and IsTailCallRelease values.
|
// Merge the ReleaseMetadata and IsTailCallRelease values.
|
||||||
@ -2558,8 +2591,12 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
// If we overflow when we compute the path count, don't
|
// If we overflow when we compute the path count, don't
|
||||||
// remove/move anything.
|
// remove/move anything.
|
||||||
const BBState &RIPBBState = BBStates[RIP->getParent()];
|
const BBState &RIPBBState = BBStates[RIP->getParent()];
|
||||||
|
PathCount = BBState::OverflowOccurredValue;
|
||||||
if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
|
if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
|
||||||
return false;
|
return false;
|
||||||
|
assert(PathCount != BBState::OverflowOccurredValue &&
|
||||||
|
"PathCount at this point can not be "
|
||||||
|
"OverflowOccurredValue.");
|
||||||
NewDelta -= PathCount;
|
NewDelta -= PathCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2595,9 +2632,12 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
// If we overflow when we compute the path count, don't remove/move
|
// If we overflow when we compute the path count, don't remove/move
|
||||||
// anything.
|
// anything.
|
||||||
const BBState &NRRBBState = BBStates[NewReleaseRetain->getParent()];
|
const BBState &NRRBBState = BBStates[NewReleaseRetain->getParent()];
|
||||||
unsigned PathCount;
|
unsigned PathCount = BBState::OverflowOccurredValue;
|
||||||
if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
|
if (NRRBBState.GetAllPathCountWithOverflow(PathCount))
|
||||||
return false;
|
return false;
|
||||||
|
assert(PathCount != BBState::OverflowOccurredValue &&
|
||||||
|
"PathCount at this point can not be "
|
||||||
|
"OverflowOccurredValue.");
|
||||||
OldDelta += PathCount;
|
OldDelta += PathCount;
|
||||||
OldCount += PathCount;
|
OldCount += PathCount;
|
||||||
|
|
||||||
@ -2612,8 +2652,13 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
// If we overflow when we compute the path count, don't
|
// If we overflow when we compute the path count, don't
|
||||||
// remove/move anything.
|
// remove/move anything.
|
||||||
const BBState &RIPBBState = BBStates[RIP->getParent()];
|
const BBState &RIPBBState = BBStates[RIP->getParent()];
|
||||||
|
|
||||||
|
PathCount = BBState::OverflowOccurredValue;
|
||||||
if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
|
if (RIPBBState.GetAllPathCountWithOverflow(PathCount))
|
||||||
return false;
|
return false;
|
||||||
|
assert(PathCount != BBState::OverflowOccurredValue &&
|
||||||
|
"PathCount at this point can not be "
|
||||||
|
"OverflowOccurredValue.");
|
||||||
NewDelta += PathCount;
|
NewDelta += PathCount;
|
||||||
NewCount += PathCount;
|
NewCount += PathCount;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user