forked from OSchip/llvm-project
[BOLT] Fix frameopt=all for gcc
Summary: Fix two bugs. First, stack pointer tracking, the dataflow analysis, was converging to the "superposition" state (meaning that at this point there are multiple and conflicting states) too early in case the entry state in the BB was "empty" AND there was an SP computation in the block. In these cases, we need to propagate an "empty" value as well and wait for an iteration where the input is not empty (only entry BBs start with a non-empty well-defined value). Previously, it was propagating "superposition", meaning there is a conflict of states in this block, which is not true, since the input is empty and, therefore, there is no preceding state to justify a collision of states. Second, if SPT failed and has no idea about the stack values in a block (if it is in the superposition state at a given point in a BB), shrink wrapping should not attempt to insert computation into those blocks that we do not understand what is happening. Fix it to bail on those cases. (cherry picked from FBD5858402)
This commit is contained in:
parent
9df155ce11
commit
ef0ec9edf9
|
@ -696,6 +696,7 @@ void ShrinkWrapping::computeSaveLocations() {
|
|||
SavePos = std::vector<SmallPtrSet<MCInst *, 4>>(BC.MRI->getNumRegs());
|
||||
auto &RI = Info.getReachingInsnsBackwards();
|
||||
auto &DA = Info.getDominatorAnalysis();
|
||||
auto &SPT = Info.getStackPointerTracking();
|
||||
|
||||
DEBUG(dbgs() << "Checking save/restore possibilities\n");
|
||||
for (auto &BB : BF) {
|
||||
|
@ -710,6 +711,12 @@ void ShrinkWrapping::computeSaveLocations() {
|
|||
if (RI.isInLoop(BB))
|
||||
continue;
|
||||
|
||||
const auto SPFP = *SPT.getStateBefore(*First);
|
||||
// If we don't know stack state at this point, bail
|
||||
if ((SPFP.first == SPT.SUPERPOSITION || SPFP.first == SPT.EMPTY) &&
|
||||
(SPFP.second == SPT.SUPERPOSITION || SPFP.second == SPT.EMPTY))
|
||||
continue;
|
||||
|
||||
for (unsigned I = 0, E = BC.MRI->getNumRegs(); I != E; ++I) {
|
||||
if (!CSA.CalleeSaved[I])
|
||||
continue;
|
||||
|
@ -1144,9 +1151,15 @@ void ShrinkWrapping::moveSaveRestores() {
|
|||
auto FIELoad = CSA.LoadFIEByReg[I];
|
||||
assert(FIESave && FIELoad);
|
||||
auto &SPT = Info.getStackPointerTracking();
|
||||
auto SaveOffset = SPT.getStateBefore(*BestPosSave)->first;
|
||||
const auto SPFP = *SPT.getStateBefore(*BestPosSave);
|
||||
auto SaveOffset = SPFP.first;
|
||||
auto SaveSize = FIESave->Size;
|
||||
|
||||
// If we don't know stack state at this point, bail
|
||||
if ((SPFP.first == SPT.SUPERPOSITION || SPFP.first == SPT.EMPTY) &&
|
||||
(SPFP.second == SPT.SUPERPOSITION || SPFP.second == SPT.EMPTY))
|
||||
continue;
|
||||
|
||||
// Operation mode: if true, will insert push/pops instead of loads/restores
|
||||
bool UsePushPops = validatePushPopsMode(I, BestPosSave, SaveOffset);
|
||||
|
||||
|
|
|
@ -123,8 +123,11 @@ protected:
|
|||
else
|
||||
FP = std::make_pair(0, 0);
|
||||
int64_t Output;
|
||||
if (!MIA->evaluateSimple(Point, Output, SP, FP))
|
||||
if (!MIA->evaluateSimple(Point, Output, SP, FP)) {
|
||||
if (SPVal == EMPTY && FPVal == EMPTY)
|
||||
return SPVal;
|
||||
return SUPERPOSITION;
|
||||
}
|
||||
|
||||
return static_cast<int>(Output);
|
||||
}
|
||||
|
@ -155,8 +158,11 @@ protected:
|
|||
else
|
||||
SP = std::make_pair(0, 0);
|
||||
int64_t Output;
|
||||
if (!MIA->evaluateSimple(Point, Output, SP, FP))
|
||||
if (!MIA->evaluateSimple(Point, Output, SP, FP)) {
|
||||
if (SPVal == EMPTY && FPVal == EMPTY)
|
||||
return FPVal;
|
||||
return SUPERPOSITION;
|
||||
}
|
||||
|
||||
if (!HasFramePointer) {
|
||||
if (MIA->escapesVariable(Point, *this->BC.MRI, false)) {
|
||||
|
|
Loading…
Reference in New Issue