mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-21 02:24:22 +00:00
Dont emit 'DBG_VALUE %noreg, ...' to terminate user variable ranges.
These ranges get completely jumbled by the post-ra scheduler, and it is not really reasonable to expect it to make sense of them. Instead, teach DwarfDebug to notice when user variables in registers are clobbered, and terminate the ranges there. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128045 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -2424,8 +2424,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
ME = DbgValues.end(); MI != ME; ++MI) {
|
||||
const MDNode *Var =
|
||||
(*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();
|
||||
if (Var == DV &&
|
||||
!PrevMI->isIdenticalTo(*MI))
|
||||
if (Var == DV && !PrevMI->isIdenticalTo(*MI))
|
||||
MultipleValues.push_back(*MI);
|
||||
PrevMI = *MI;
|
||||
}
|
||||
@ -2448,7 +2447,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
DbgVariableToDbgInstMap[AbsVar] = MInsn;
|
||||
VarToAbstractVarMap[RegVar] = AbsVar;
|
||||
}
|
||||
if (MultipleValues.size() <= 1) {
|
||||
if (MultipleValues.size() <= 1 && !RegClobberInsn.count(MInsn)) {
|
||||
DbgVariableToDbgInstMap[RegVar] = MInsn;
|
||||
continue;
|
||||
}
|
||||
@ -2458,16 +2457,11 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
RegVar->setDotDebugLocOffset(0);
|
||||
else
|
||||
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());
|
||||
const MachineInstr *Begin = NULL;
|
||||
const MachineInstr *End = NULL;
|
||||
|
||||
for (SmallVector<const MachineInstr *, 4>::iterator
|
||||
MVI = MultipleValues.begin(), MVE = MultipleValues.end();
|
||||
MVI != MVE; ++MVI) {
|
||||
if (!Begin) {
|
||||
Begin = *MVI;
|
||||
continue;
|
||||
}
|
||||
End = *MVI;
|
||||
const MachineInstr *Begin = *MVI;
|
||||
MachineLocation MLoc;
|
||||
if (Begin->getNumOperands() == 3) {
|
||||
if (Begin->getOperand(0).isReg() && Begin->getOperand(1).isImm())
|
||||
@ -2475,25 +2469,25 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
} else
|
||||
MLoc = Asm->getDebugValueLocation(Begin);
|
||||
|
||||
const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
|
||||
const MCSymbol *SLabel = getLabelBeforeInsn(End);
|
||||
if (MLoc.getReg())
|
||||
DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
|
||||
if (!MLoc.getReg())
|
||||
continue;
|
||||
|
||||
Begin = End;
|
||||
if (MVI + 1 == MVE) {
|
||||
// If End is the last instruction then its value is valid
|
||||
// Compute the range for a register location.
|
||||
const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
|
||||
const MCSymbol *SLabel = 0;
|
||||
|
||||
if (const MachineInstr *ClobberMI = RegClobberInsn.lookup(Begin))
|
||||
// The register range starting at Begin may be clobbered.
|
||||
SLabel = getLabelAfterInsn(ClobberMI);
|
||||
else if (MVI + 1 == MVE)
|
||||
// If Begin is the last instruction then its value is valid
|
||||
// until the end of the funtion.
|
||||
MachineLocation EMLoc;
|
||||
if (End->getNumOperands() == 3) {
|
||||
if (End->getOperand(0).isReg() && Begin->getOperand(1).isImm())
|
||||
EMLoc.set(Begin->getOperand(0).getReg(), Begin->getOperand(1).getImm());
|
||||
} else
|
||||
EMLoc = Asm->getDebugValueLocation(End);
|
||||
if (EMLoc.getReg())
|
||||
DotDebugLocEntries.
|
||||
push_back(DotDebugLocEntry(SLabel, FunctionEndSym, EMLoc));
|
||||
}
|
||||
SLabel = FunctionEndSym;
|
||||
else
|
||||
// The value is valid until the next DBG_VALUE.
|
||||
SLabel = getLabelBeforeInsn(MVI[1]);
|
||||
|
||||
DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel, SLabel, MLoc));
|
||||
}
|
||||
DotDebugLocEntries.push_back(DotDebugLocEntry());
|
||||
}
|
||||
@ -2568,7 +2562,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
|
||||
|
||||
/// endInstruction - Process end of an instruction.
|
||||
void DwarfDebug::endInstruction(const MachineInstr *MI) {
|
||||
if (InsnsEndScopeSet.count(MI) != 0) {
|
||||
if (InsnsNeedsLabelAfter.count(MI) != 0) {
|
||||
// Emit a label if this instruction ends a scope.
|
||||
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
|
||||
Asm->OutStreamer.EmitLabel(Label);
|
||||
@ -2833,7 +2827,7 @@ void DwarfDebug::identifyScopeMarkers() {
|
||||
RE = Ranges.end(); RI != RE; ++RI) {
|
||||
assert(RI->first && "DbgRange does not have first instruction!");
|
||||
assert(RI->second && "DbgRange does not have second instruction!");
|
||||
InsnsEndScopeSet.insert(RI->second);
|
||||
InsnsNeedsLabelAfter.insert(RI->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2914,6 +2908,14 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
/// ProcessedArgs - Collection of arguments already processed.
|
||||
SmallPtrSet<const MDNode *, 8> ProcessedArgs;
|
||||
|
||||
/// LastDbgValue - Refer back to the last DBG_VALUE instruction to mention MD.
|
||||
DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;
|
||||
|
||||
const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
|
||||
|
||||
/// LiveUserVar - Map physreg numbers to the MDNode they contain.
|
||||
std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());
|
||||
|
||||
DebugLoc PrevLoc;
|
||||
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
|
||||
I != E; ++I)
|
||||
@ -2923,7 +2925,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
if (MI->isDebugValue()) {
|
||||
assert (MI->getNumOperands() > 1 && "Invalid machine instruction!");
|
||||
DIVariable DV(MI->getOperand(MI->getNumOperands() - 1).getMetadata());
|
||||
|
||||
// Keep track of variables in registers.
|
||||
const MDNode *Var =
|
||||
MI->getOperand(MI->getNumOperands() - 1).getMetadata();
|
||||
LastDbgValue[Var] = MI;
|
||||
if (isDbgValueInDefinedReg(MI))
|
||||
LiveUserVar[MI->getOperand(0).getReg()] = Var;
|
||||
|
||||
DIVariable DV(Var);
|
||||
if (!DV.Verify()) continue;
|
||||
// If DBG_VALUE is for a local variable then it needs a label.
|
||||
if (DV.getTag() != dwarf::DW_TAG_arg_variable)
|
||||
@ -2944,6 +2954,32 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
} else if (DL != PrevLoc)
|
||||
// Otherwise, instruction needs a location only if it is new location.
|
||||
InsnNeedsLabel.insert(MI);
|
||||
|
||||
// Check if the instruction clobbers any registers with debug vars.
|
||||
for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
|
||||
MOE = MI->operands_end(); MOI != MOE; ++MOI) {
|
||||
if (!MOI->isReg() || !MOI->isDef() || !MOI->getReg())
|
||||
continue;
|
||||
for (const unsigned *AI = TRI->getOverlaps(MOI->getReg());
|
||||
unsigned Reg = *AI; ++AI) {
|
||||
const MDNode *Var = LiveUserVar[Reg];
|
||||
if (!Var)
|
||||
continue;
|
||||
// Reg is now clobbered.
|
||||
LiveUserVar[Reg] = 0;
|
||||
|
||||
// Was MD last defined by a DBG_VALUE referring to Reg?
|
||||
const MachineInstr *Last = LastDbgValue.lookup(Var);
|
||||
if (!Last || Last->getParent() != MI->getParent())
|
||||
continue;
|
||||
if (!isDbgValueInDefinedReg(Last) ||
|
||||
Last->getOperand(0).getReg() != Reg)
|
||||
continue;
|
||||
// MD is clobbered. Make sure the next instruction gets a label.
|
||||
InsnsNeedsLabelAfter.insert(MI);
|
||||
RegClobberInsn[Last] = MI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DL.isUnknown() || UnknownLocations)
|
||||
@ -3013,7 +3049,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
||||
VarToAbstractVarMap.clear();
|
||||
DbgVariableToDbgInstMap.clear();
|
||||
DeleteContainerSeconds(DbgScopeMap);
|
||||
InsnsEndScopeSet.clear();
|
||||
InsnsNeedsLabelAfter.clear();
|
||||
ConcreteScopes.clear();
|
||||
DeleteContainerSeconds(AbstractScopes);
|
||||
AbstractScopesList.clear();
|
||||
|
Reference in New Issue
Block a user