Revert "r306529 - [X86] Correct dwarf unwind information in function epilogue"
I am 99% sure that this breaks the PPC ASAN build bot: http://lab.llvm.org:8011/builders/sanitizer-ppc64be-linux/builds/3112/steps/64-bit%20check-asan/logs/stdio If it doesn't go back to green, we can recommit (and fix the original commit message at the same time :) ). llvm-svn: 306676
This commit is contained in:
@@ -35,8 +35,6 @@
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "codegen"
|
||||
@@ -1345,228 +1343,3 @@ MachineBasicBlock::livein_iterator MachineBasicBlock::livein_begin() const {
|
||||
"Liveness information is accurate");
|
||||
return LiveIns.begin();
|
||||
}
|
||||
|
||||
void MachineBasicBlock::updateCFIInfo(MachineBasicBlock::iterator Pos) {
|
||||
// Used for calculating outgoing cfa offset when CFI instruction added at Pos
|
||||
// is def_cfa or def_cfa_offset.
|
||||
/* For example:
|
||||
...
|
||||
.cfi_adjust_cfa_offset 4
|
||||
...
|
||||
.cfi_adjust_cfa_offset 4
|
||||
...
|
||||
.cfi_def_cfa_offset 16 <---- newly added CFI instruction at Pos
|
||||
...
|
||||
.cfi_adjust_cfa_offset 4
|
||||
...
|
||||
Once def_cfa_offset is inserted, outgoing cfa offset is no longer
|
||||
calculated as incoming offset incremented by the sum of all adjustments
|
||||
(12). It becomes equal to the offset set by the added CFI instruction (16)
|
||||
incremented by the sum of adjustments below it (4). Adjustments above the
|
||||
added def_cfa_offset directive don't have effect below it anymore and
|
||||
therefore don't affect the value of outgoing cfa offset.
|
||||
*/
|
||||
int AdjustAmount = 0;
|
||||
// Used to check if outgoing cfa offset should be updated or not (when def_cfa
|
||||
// is inserted).
|
||||
bool ShouldSetOffset = true;
|
||||
// Used to check if outgoing cfa register should be updated or not (when
|
||||
// def_cfa is inserted).
|
||||
bool ShouldSetRegister = true;
|
||||
const std::vector<MCCFIInstruction> CFIInstructions =
|
||||
getParent()->getFrameInstructions();
|
||||
MCCFIInstruction CFI = CFIInstructions[Pos->getOperand(0).getCFIIndex()];
|
||||
// Type of the CFI instruction that was inserted.
|
||||
MCCFIInstruction::OpType CFIType = CFI.getOperation();
|
||||
|
||||
// Check if there are already existing CFI instructions below Pos and see if
|
||||
// outgoing CFI info should be updated or not.
|
||||
for (MachineBasicBlock::reverse_iterator RI = rbegin();
|
||||
RI != Pos.getReverse(); ++RI) {
|
||||
if (RI->isCFIInstruction()) {
|
||||
MCCFIInstruction::OpType RIType =
|
||||
CFIInstructions[RI->getOperand(0).getCFIIndex()].getOperation();
|
||||
switch (RIType) {
|
||||
case MCCFIInstruction::OpAdjustCfaOffset:
|
||||
AdjustAmount +=
|
||||
CFIInstructions[RI->getOperand(0).getCFIIndex()].getOffset();
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfaOffset:
|
||||
// CFI instruction doesn't affect outgoing cfa offset if there is
|
||||
// already a def_cfa_offset instruction below it.
|
||||
if (CFIType == MCCFIInstruction::OpDefCfaOffset ||
|
||||
CFIType == MCCFIInstruction::OpAdjustCfaOffset)
|
||||
return;
|
||||
if (CFIType == MCCFIInstruction::OpDefCfa) {
|
||||
// CFI instruction doesn't affect outgoing cfa offset and register
|
||||
// if there are both def_cfa_offset and def_cfa_register
|
||||
// instructions below it.
|
||||
if (!ShouldSetRegister) return;
|
||||
ShouldSetOffset = false;
|
||||
}
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfaRegister:
|
||||
// CFI instruction doesn't affect outgoing cfa register if there is
|
||||
// already a def_cfa_register instruction below it.
|
||||
if (CFIType == MCCFIInstruction::OpDefCfaRegister) return;
|
||||
if (CFIType == MCCFIInstruction::OpDefCfa) {
|
||||
// CFI instruction doesn't affect outgoing cfa offset and register
|
||||
// if there are both def_cfa_offset and def_cfa_register
|
||||
// instructions below it.
|
||||
if (!ShouldSetOffset) return;
|
||||
ShouldSetRegister = false;
|
||||
}
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfa:
|
||||
// CFI instruction doesn't affect outgoing cfa offset and register if
|
||||
// there is already a def_cfa instruction below it.
|
||||
if (CFIType == MCCFIInstruction::OpDefCfaRegister ||
|
||||
CFIType == MCCFIInstruction::OpDefCfaOffset ||
|
||||
CFIType == MCCFIInstruction::OpDefCfa ||
|
||||
CFIType == MCCFIInstruction::OpAdjustCfaOffset)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the outgoing CFI info based on the added CFI instruction.
|
||||
switch (CFIType) {
|
||||
case MCCFIInstruction::OpAdjustCfaOffset:
|
||||
setOutgoingCFAOffset(getOutgoingCFAOffset() + CFI.getOffset());
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfaOffset:
|
||||
setOutgoingCFAOffset(CFI.getOffset() + AdjustAmount);
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfaRegister:
|
||||
setOutgoingCFARegister(CFI.getRegister());
|
||||
break;
|
||||
case MCCFIInstruction::OpDefCfa:
|
||||
if (ShouldSetOffset) setOutgoingCFAOffset(CFI.getOffset() + AdjustAmount);
|
||||
if (ShouldSetRegister) setOutgoingCFARegister(CFI.getRegister());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MachineBasicBlock::updateCFIInfoSucc() {
|
||||
// Blocks whose successors' CFI info should be updated.
|
||||
std::queue<MachineBasicBlock *> Successors;
|
||||
// Keep track of basic blocks that have already been put in the Successors
|
||||
// queue.
|
||||
std::set<MachineBasicBlock *> ProcessedMBBs;
|
||||
// Start with updating CFI info for direct successors of this block.
|
||||
Successors.push(this);
|
||||
ProcessedMBBs.insert(this);
|
||||
|
||||
// Go through the successors and update their CFI info if needed.
|
||||
while (!Successors.empty()) {
|
||||
MachineBasicBlock *CurrSucc = Successors.front();
|
||||
Successors.pop();
|
||||
|
||||
// Update CFI info for CurrSucc's successors.
|
||||
for (auto Succ : CurrSucc->successors()) {
|
||||
if (ProcessedMBBs.find(Succ) != ProcessedMBBs.end()) continue;
|
||||
if (Succ->getIncomingCFAOffset() == CurrSucc->getOutgoingCFAOffset() &&
|
||||
Succ->getIncomingCFARegister() == CurrSucc->getOutgoingCFARegister())
|
||||
continue;
|
||||
bool ChangedOutgoingInfo = false;
|
||||
// Do not update cfa offset if the existing value matches the new.
|
||||
if (Succ->getIncomingCFAOffset() != CurrSucc->getOutgoingCFAOffset()) {
|
||||
// If the block doesn't have a def_cfa_offset or def_cfa directive,
|
||||
// update its outgoing offset.
|
||||
if (!Succ->hasDefOffset()) {
|
||||
// Succ block doesn't set absolute offset, so the difference between
|
||||
// outgoing and incoming offset remains the same. This difference is
|
||||
// the sum of offsets set by adjust_cfa_offset directives.
|
||||
int AdjustAmount =
|
||||
Succ->getOutgoingCFAOffset() - Succ->getIncomingCFAOffset();
|
||||
Succ->setOutgoingCFAOffset(CurrSucc->getOutgoingCFAOffset() +
|
||||
AdjustAmount);
|
||||
ChangedOutgoingInfo = true;
|
||||
}
|
||||
Succ->setIncomingCFAOffset(CurrSucc->getOutgoingCFAOffset());
|
||||
}
|
||||
// Do not update cfa register if the existing value matches the new.
|
||||
if (Succ->getIncomingCFARegister() !=
|
||||
CurrSucc->getOutgoingCFARegister()) {
|
||||
Succ->setIncomingCFARegister(CurrSucc->getOutgoingCFARegister());
|
||||
// If the block doesn't have a def_cfa_register or def_cfa directive,
|
||||
// update its outgoing register.
|
||||
if (!Succ->hasDefRegister()) {
|
||||
Succ->setOutgoingCFARegister(Succ->getIncomingCFARegister());
|
||||
ChangedOutgoingInfo = true;
|
||||
}
|
||||
}
|
||||
// If Succ's outgoing CFI info has been changed, it's successors should be
|
||||
// updated as well.
|
||||
if (ChangedOutgoingInfo) {
|
||||
Successors.push(Succ);
|
||||
ProcessedMBBs.insert(Succ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MachineBasicBlock::recalculateCFIInfo(bool UseExistingIncoming,
|
||||
int NewIncomingOffset,
|
||||
unsigned NewIncomingRegister) {
|
||||
// Outgoing cfa offset set by the block.
|
||||
int SetOffset;
|
||||
// Outgoing cfa register set by the block.
|
||||
unsigned SetRegister;
|
||||
const std::vector<MCCFIInstruction> &Instrs =
|
||||
getParent()->getFrameInstructions();
|
||||
|
||||
// Set initial values to SetOffset and SetRegister. Use existing incoming
|
||||
// values or values passed as arguments.
|
||||
if (!UseExistingIncoming) {
|
||||
// Set new incoming cfa offset and register values.
|
||||
setIncomingCFAOffset(NewIncomingOffset);
|
||||
setIncomingCFARegister(NewIncomingRegister);
|
||||
}
|
||||
|
||||
SetOffset = getIncomingCFAOffset();
|
||||
SetRegister = getIncomingCFARegister();
|
||||
|
||||
setDefOffset(false);
|
||||
setDefRegister(false);
|
||||
|
||||
// Determine cfa offset and register set by the block.
|
||||
for (MachineBasicBlock::iterator MI = begin(); MI != end(); ++MI) {
|
||||
if (MI->isCFIInstruction()) {
|
||||
unsigned CFIIndex = MI->getOperand(0).getCFIIndex();
|
||||
const MCCFIInstruction &CFI = Instrs[CFIIndex];
|
||||
if (CFI.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
|
||||
SetRegister = CFI.getRegister();
|
||||
setDefRegister(true);
|
||||
} else if (CFI.getOperation() == MCCFIInstruction::OpDefCfaOffset) {
|
||||
SetOffset = CFI.getOffset();
|
||||
setDefOffset(true);
|
||||
} else if (CFI.getOperation() == MCCFIInstruction::OpAdjustCfaOffset) {
|
||||
SetOffset = SetOffset + CFI.getOffset();
|
||||
} else if (CFI.getOperation() == MCCFIInstruction::OpDefCfa) {
|
||||
SetRegister = CFI.getRegister();
|
||||
SetOffset = CFI.getOffset();
|
||||
setDefOffset(true);
|
||||
setDefRegister(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update outgoing CFI info.
|
||||
setOutgoingCFAOffset(SetOffset);
|
||||
setOutgoingCFARegister(SetRegister);
|
||||
}
|
||||
|
||||
void MachineBasicBlock::mergeCFIInfo(MachineBasicBlock *MBB) {
|
||||
// Update CFI info. This basic block acquires MBB's outgoing cfa offset and
|
||||
// register values.
|
||||
setOutgoingCFAOffset(MBB->getOutgoingCFAOffset());
|
||||
setOutgoingCFARegister(MBB->getOutgoingCFARegister());
|
||||
setDefOffset(hasDefOffset() || MBB->hasDefOffset());
|
||||
setDefRegister(hasDefRegister() || MBB->hasDefRegister());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user