mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-27 04:18:42 +00:00
Debug Info: Simplify Frame Index handling in DBG_VALUE Machine Instructions
Rather than using the full power of target-specific addressing modes in DBG_VALUEs with Frame Indicies, simply use Frame Index + Offset. This reduces the complexity of debug info handling down to two representations of values (reg+offset and frame index+offset) rather than three or four. Ideally we could ensure that frame indicies had been eliminated by the time we reached an assembly or dwarf generation, but I haven't spent the time to figure out where the FIs are leaking through into that & whether there's a good place to convert them. Some FI+offset=>reg+offset conversion is done (see PrologEpilogInserter, for example) which is necessary for some SelectionDAG assumptions about registers, I believe, but it might be possible to make this a more thorough conversion & ensure there are no remaining FIs no matter how instruction selection is performed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184066 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
1 parent
b7770e0b85
commit
6d9dbd5526
14 files changed
+115
-139
No files matched your search
@@ -42,6 +42,7 @@
|
|||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/Timer.h"
|
#include "llvm/Support/Timer.h"
|
||||||
#include "llvm/Target/Mangler.h"
|
#include "llvm/Target/Mangler.h"
|
||||||
|
#include "llvm/Target/TargetFrameLowering.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetLowering.h"
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||||
@@ -591,8 +592,17 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
|
|||||||
} else if (MI->getOperand(0).isCImm()) {
|
} else if (MI->getOperand(0).isCImm()) {
|
||||||
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
|
MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
|
||||||
} else {
|
} else {
|
||||||
assert(MI->getOperand(0).isReg() && "Unknown operand type");
|
unsigned Reg;
|
||||||
unsigned Reg = MI->getOperand(0).getReg();
|
if (MI->getOperand(0).isReg()) {
|
||||||
|
Reg = MI->getOperand(0).getReg();
|
||||||
|
Deref = Offset != 0; // FIXME: use a better sentinel value so that deref
|
||||||
|
// of a reg with a zero offset is valid
|
||||||
|
} else {
|
||||||
|
assert(MI->getOperand(0).isFI() && "Unknown operand type");
|
||||||
|
const TargetFrameLowering *TFI = AP.TM.getFrameLowering();
|
||||||
|
Offset += TFI->getFrameIndexReference(*AP.MF, MI->getOperand(0).getIndex(), Reg);
|
||||||
|
Deref = true;
|
||||||
|
}
|
||||||
if (Reg == 0) {
|
if (Reg == 0) {
|
||||||
// Suppress offset, it is not meaningful here.
|
// Suppress offset, it is not meaningful here.
|
||||||
OS << "undef";
|
OS << "undef";
|
||||||
@@ -600,8 +610,6 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
|
|||||||
AP.OutStreamer.EmitRawText(OS.str());
|
AP.OutStreamer.EmitRawText(OS.str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Deref = Offset != 0; // FIXME: use a better sentinel value so that deref of
|
|
||||||
// a reg with a zero offset is valid
|
|
||||||
if (Deref)
|
if (Deref)
|
||||||
OS << '[';
|
OS << '[';
|
||||||
OS << AP.TM.getRegisterInfo()->getName(Reg);
|
OS << AP.TM.getRegisterInfo()->getName(Reg);
|
||||||
|
|||||||
@@ -1525,43 +1525,23 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
|
|||||||
// Check if variable is described by a DBG_VALUE instruction.
|
// Check if variable is described by a DBG_VALUE instruction.
|
||||||
if (const MachineInstr *DVInsn = DV->getMInsn()) {
|
if (const MachineInstr *DVInsn = DV->getMInsn()) {
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
if (DVInsn->getNumOperands() == 3) {
|
assert(DVInsn->getNumOperands() == 3);
|
||||||
if (DVInsn->getOperand(0).isReg()) {
|
if (DVInsn->getOperand(0).isReg()) {
|
||||||
const MachineOperand RegOp = DVInsn->getOperand(0);
|
const MachineOperand RegOp = DVInsn->getOperand(0);
|
||||||
const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
|
if (int64_t Offset = DVInsn->getOperand(1).getImm()) {
|
||||||
if (DVInsn->getOperand(1).isImm() &&
|
MachineLocation Location(RegOp.getReg(), Offset);
|
||||||
TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
|
addVariableAddress(DV, VariableDie, Location);
|
||||||
unsigned FrameReg = 0;
|
} else if (RegOp.getReg())
|
||||||
const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
|
addVariableAddress(DV, VariableDie, MachineLocation(RegOp.getReg()));
|
||||||
int Offset =
|
|
||||||
TFI->getFrameIndexReference(*Asm->MF,
|
|
||||||
DVInsn->getOperand(1).getImm(),
|
|
||||||
FrameReg);
|
|
||||||
MachineLocation Location(FrameReg, Offset);
|
|
||||||
addVariableAddress(DV, VariableDie, Location);
|
|
||||||
|
|
||||||
} else if (RegOp.getReg())
|
|
||||||
addVariableAddress(DV, VariableDie,
|
|
||||||
MachineLocation(RegOp.getReg()));
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
else if (DVInsn->getOperand(0).isImm())
|
|
||||||
updated =
|
|
||||||
addConstantValue(VariableDie, DVInsn->getOperand(0),
|
|
||||||
DV->getType());
|
|
||||||
else if (DVInsn->getOperand(0).isFPImm())
|
|
||||||
updated =
|
|
||||||
addConstantFPValue(VariableDie, DVInsn->getOperand(0));
|
|
||||||
else if (DVInsn->getOperand(0).isCImm())
|
|
||||||
updated =
|
|
||||||
addConstantValue(VariableDie,
|
|
||||||
DVInsn->getOperand(0).getCImm(),
|
|
||||||
DV->getType().isUnsignedDIType());
|
|
||||||
} else {
|
|
||||||
addVariableAddress(DV, VariableDie,
|
|
||||||
Asm->getDebugValueLocation(DVInsn));
|
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
} else if (DVInsn->getOperand(0).isImm())
|
||||||
|
updated =
|
||||||
|
addConstantValue(VariableDie, DVInsn->getOperand(0), DV->getType());
|
||||||
|
else if (DVInsn->getOperand(0).isFPImm())
|
||||||
|
updated = addConstantFPValue(VariableDie, DVInsn->getOperand(0));
|
||||||
|
else if (DVInsn->getOperand(0).isCImm())
|
||||||
|
updated = addConstantValue(VariableDie, DVInsn->getOperand(0).getCImm(),
|
||||||
|
DV->getType().isUnsignedDIType());
|
||||||
if (!updated) {
|
if (!updated) {
|
||||||
// If variableDie is not updated then DBG_VALUE instruction does not
|
// If variableDie is not updated then DBG_VALUE instruction does not
|
||||||
// have valid variable info.
|
// have valid variable info.
|
||||||
|
|||||||
@@ -1170,10 +1170,7 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
|
|||||||
const MachineInstr *MI) {
|
const MachineInstr *MI) {
|
||||||
const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata();
|
const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata();
|
||||||
|
|
||||||
if (MI->getNumOperands() != 3) {
|
assert(MI->getNumOperands() == 3);
|
||||||
MachineLocation MLoc = Asm->getDebugValueLocation(MI);
|
|
||||||
return DotDebugLocEntry(FLabel, SLabel, MLoc, Var);
|
|
||||||
}
|
|
||||||
if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) {
|
if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) {
|
||||||
MachineLocation MLoc;
|
MachineLocation MLoc;
|
||||||
// TODO: Currently an offset of 0 in a DBG_VALUE means
|
// TODO: Currently an offset of 0 in a DBG_VALUE means
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBundle.h"
|
#include "llvm/CodeGen/MachineInstrBundle.h"
|
||||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
@@ -1123,15 +1124,10 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {
|
|||||||
uint64_t Offset = MI->getOperand(1).getImm();
|
uint64_t Offset = MI->getOperand(1).getImm();
|
||||||
const MDNode *MDPtr = MI->getOperand(2).getMetadata();
|
const MDNode *MDPtr = MI->getOperand(2).getMetadata();
|
||||||
DebugLoc DL = MI->getDebugLoc();
|
DebugLoc DL = MI->getDebugLoc();
|
||||||
if (MachineInstr *NewDV = TII.emitFrameIndexDebugValue(MF, StackSlot,
|
DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);
|
||||||
Offset, MDPtr, DL)) {
|
MachineBasicBlock *MBB = MI->getParent();
|
||||||
DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);
|
BuildMI(*MBB, MBB->erase(MI), DL, TII.get(TargetOpcode::DBG_VALUE))
|
||||||
MachineBasicBlock *MBB = MI->getParent();
|
.addFrameIndex(StackSlot).addImm(Offset).addMetadata(MDPtr);
|
||||||
MBB->insert(MBB->erase(MI), NewDV);
|
|
||||||
} else {
|
|
||||||
DEBUG(dbgs() << "Removing debug info due to spill:" << "\t" << *MI);
|
|
||||||
MI->eraseFromParent();
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -921,17 +921,6 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
|
|||||||
MachineOperand &Loc = locations[LocNo];
|
MachineOperand &Loc = locations[LocNo];
|
||||||
++NumInsertedDebugValues;
|
++NumInsertedDebugValues;
|
||||||
|
|
||||||
// Frame index locations may require a target callback.
|
|
||||||
if (Loc.isFI()) {
|
|
||||||
MachineInstr *MI = TII.emitFrameIndexDebugValue(*MBB->getParent(),
|
|
||||||
Loc.getIndex(), offset, variable,
|
|
||||||
findDebugLoc());
|
|
||||||
if (MI) {
|
|
||||||
MBB->insert(I, MI);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This is not a frame index, or the target is happy with a standard FI.
|
|
||||||
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
|
BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
|
||||||
.addOperand(Loc).addImm(offset).addMetadata(variable);
|
.addOperand(Loc).addImm(offset).addMetadata(variable);
|
||||||
}
|
}
|
||||||
@@ -992,4 +981,3 @@ void LiveDebugVariables::dump() {
|
|||||||
static_cast<LDVImpl*>(pImpl)->print(dbgs());
|
static_cast<LDVImpl*>(pImpl)->print(dbgs());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -777,7 +777,22 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
|
|||||||
bool DoIncr = true;
|
bool DoIncr = true;
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
if (!MI->getOperand(i).isFI())
|
if (!MI->getOperand(i).isFI())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Frame indicies in debug values are encoded in a target independent
|
||||||
|
// way with simply the frame index and offset rather than any
|
||||||
|
// target-specific addressing mode.
|
||||||
|
if (MI->isDebugValue()) {
|
||||||
|
assert(i == 0 && "Frame indicies can only appear as the first "
|
||||||
|
"operand of a DBG_VALUE machine instruction");
|
||||||
|
unsigned Reg;
|
||||||
|
MachineOperand &Offset = MI->getOperand(1);
|
||||||
|
Offset.setImm(Offset.getImm() +
|
||||||
|
TFI->getFrameIndexReference(
|
||||||
|
Fn, MI->getOperand(0).getIndex(), Reg));
|
||||||
|
MI->getOperand(0).ChangeToRegister(Reg, false /*isDef*/);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Some instructions (e.g. inline asm instructions) can have
|
// Some instructions (e.g. inline asm instructions) can have
|
||||||
// multiple frame indices and/or cause eliminateFrameIndex
|
// multiple frame indices and/or cause eliminateFrameIndex
|
||||||
|
|||||||
@@ -297,25 +297,21 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,
|
|||||||
LiveDbgValueMap[LRI->VirtReg];
|
LiveDbgValueMap[LRI->VirtReg];
|
||||||
for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) {
|
for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) {
|
||||||
MachineInstr *DBG = LRIDbgValues[li];
|
MachineInstr *DBG = LRIDbgValues[li];
|
||||||
const MDNode *MDPtr =
|
const MDNode *MDPtr = DBG->getOperand(2).getMetadata();
|
||||||
DBG->getOperand(DBG->getNumOperands()-1).getMetadata();
|
int64_t Offset = DBG->getOperand(1).getImm();
|
||||||
int64_t Offset = 0;
|
|
||||||
if (DBG->getOperand(1).isImm())
|
|
||||||
Offset = DBG->getOperand(1).getImm();
|
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
if (MI == MBB->end()) {
|
if (MI == MBB->end()) {
|
||||||
// If MI is at basic block end then use last instruction's location.
|
// If MI is at basic block end then use last instruction's location.
|
||||||
MachineBasicBlock::iterator EI = MI;
|
MachineBasicBlock::iterator EI = MI;
|
||||||
DL = (--EI)->getDebugLoc();
|
DL = (--EI)->getDebugLoc();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
DL = MI->getDebugLoc();
|
DL = MI->getDebugLoc();
|
||||||
if (MachineInstr *NewDV =
|
MachineBasicBlock *MBB = DBG->getParent();
|
||||||
TII->emitFrameIndexDebugValue(*MF, FI, Offset, MDPtr, DL)) {
|
MachineInstr *NewDV =
|
||||||
MachineBasicBlock *MBB = DBG->getParent();
|
BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE))
|
||||||
MBB->insert(MI, NewDV);
|
.addFrameIndex(FI).addImm(Offset).addMetadata(MDPtr);
|
||||||
DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV);
|
(void)NewDV;
|
||||||
}
|
DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV);
|
||||||
}
|
}
|
||||||
// Now this register is spilled there is should not be any DBG_VALUE
|
// Now this register is spilled there is should not be any DBG_VALUE
|
||||||
// pointing to this register because they are all pointing to spilled value
|
// pointing to this register because they are all pointing to spilled value
|
||||||
@@ -863,21 +859,16 @@ void RAFast::AllocateBasicBlock() {
|
|||||||
const MDNode *MDPtr =
|
const MDNode *MDPtr =
|
||||||
MI->getOperand(MI->getNumOperands()-1).getMetadata();
|
MI->getOperand(MI->getNumOperands()-1).getMetadata();
|
||||||
DebugLoc DL = MI->getDebugLoc();
|
DebugLoc DL = MI->getDebugLoc();
|
||||||
if (MachineInstr *NewDV =
|
MachineBasicBlock *MBB = MI->getParent();
|
||||||
TII->emitFrameIndexDebugValue(*MF, SS, Offset, MDPtr, DL)) {
|
MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(MI), DL,
|
||||||
DEBUG(dbgs() << "Modifying debug info due to spill:" <<
|
TII->get(TargetOpcode::DBG_VALUE))
|
||||||
"\t" << *MI);
|
.addFrameIndex(SS).addImm(Offset).addMetadata(MDPtr);
|
||||||
MachineBasicBlock *MBB = MI->getParent();
|
DEBUG(dbgs() << "Modifying debug info due to spill:"
|
||||||
MBB->insert(MBB->erase(MI), NewDV);
|
<< "\t" << *NewDV);
|
||||||
// Scan NewDV operands from the beginning.
|
// Scan NewDV operands from the beginning.
|
||||||
MI = NewDV;
|
MI = NewDV;
|
||||||
ScanDbgValue = true;
|
ScanDbgValue = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
// We can't allocate a physreg for a DebugValue; sorry!
|
|
||||||
DEBUG(dbgs() << "Unable to allocate vreg used by DBG_VALUE");
|
|
||||||
MO.setReg(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LiveDbgValueMap[Reg].push_back(MI);
|
LiveDbgValueMap[Reg].push_back(MI);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "isel"
|
#define DEBUG_TYPE "isel"
|
||||||
#include "llvm/CodeGen/FastISel.h"
|
#include "llvm/CodeGen/FastISel.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Analysis/Loads.h"
|
#include "llvm/Analysis/Loads.h"
|
||||||
#include "llvm/CodeGen/Analysis.h"
|
#include "llvm/CodeGen/Analysis.h"
|
||||||
@@ -613,16 +614,14 @@ bool FastISel::SelectCall(const User *I) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Reg = 0;
|
Optional<MachineOperand> Op;
|
||||||
unsigned Offset = 0;
|
if (const Argument *Arg = dyn_cast<Argument>(Address))
|
||||||
if (const Argument *Arg = dyn_cast<Argument>(Address)) {
|
|
||||||
// Some arguments' frame index is recorded during argument lowering.
|
// Some arguments' frame index is recorded during argument lowering.
|
||||||
Offset = FuncInfo.getArgumentFrameIndex(Arg);
|
if (int FI = FuncInfo.getArgumentFrameIndex(Arg))
|
||||||
if (Offset)
|
Op = MachineOperand::CreateFI(FI);
|
||||||
Reg = TRI.getFrameRegister(*FuncInfo.MF);
|
if (!Op)
|
||||||
}
|
if (unsigned Reg = lookUpRegForValue(Address))
|
||||||
if (!Reg)
|
Op = MachineOperand::CreateReg(Reg, false);
|
||||||
Reg = lookUpRegForValue(Address);
|
|
||||||
|
|
||||||
// If we have a VLA that has a "use" in a metadata node that's then used
|
// If we have a VLA that has a "use" in a metadata node that's then used
|
||||||
// here but it has no other uses, then we have a problem. E.g.,
|
// here but it has no other uses, then we have a problem. E.g.,
|
||||||
@@ -635,16 +634,19 @@ bool FastISel::SelectCall(const User *I) {
|
|||||||
// If we assign 'a' a vreg and fast isel later on has to use the selection
|
// If we assign 'a' a vreg and fast isel later on has to use the selection
|
||||||
// DAG isel, it will want to copy the value to the vreg. However, there are
|
// DAG isel, it will want to copy the value to the vreg. However, there are
|
||||||
// no uses, which goes counter to what selection DAG isel expects.
|
// no uses, which goes counter to what selection DAG isel expects.
|
||||||
if (!Reg && !Address->use_empty() && isa<Instruction>(Address) &&
|
if (!Op && !Address->use_empty() && isa<Instruction>(Address) &&
|
||||||
(!isa<AllocaInst>(Address) ||
|
(!isa<AllocaInst>(Address) ||
|
||||||
!FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address))))
|
!FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address))))
|
||||||
Reg = FuncInfo.InitializeRegForValue(Address);
|
Op = MachineOperand::CreateReg(FuncInfo.InitializeRegForValue(Address),
|
||||||
|
false);
|
||||||
|
|
||||||
if (Reg)
|
if (Op && Op->isReg())
|
||||||
|
Op->setIsDebug(true);
|
||||||
|
|
||||||
|
if (Op)
|
||||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||||
TII.get(TargetOpcode::DBG_VALUE))
|
TII.get(TargetOpcode::DBG_VALUE)).addOperand(*Op).addImm(0)
|
||||||
.addReg(Reg, RegState::Debug).addImm(Offset)
|
.addMetadata(DI->getVariable());
|
||||||
.addMetadata(DI->getVariable());
|
|
||||||
else
|
else
|
||||||
// We can't yet handle anything else here because it would require
|
// We can't yet handle anything else here because it would require
|
||||||
// generating code, thus altering codegen because of debug info.
|
// generating code, thus altering codegen because of debug info.
|
||||||
|
|||||||
@@ -639,8 +639,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,
|
|||||||
if (SD->getKind() == SDDbgValue::FRAMEIX) {
|
if (SD->getKind() == SDDbgValue::FRAMEIX) {
|
||||||
// Stack address; this needs to be lowered in target-dependent fashion.
|
// Stack address; this needs to be lowered in target-dependent fashion.
|
||||||
// EmitTargetCodeForFrameDebugValue is responsible for allocation.
|
// EmitTargetCodeForFrameDebugValue is responsible for allocation.
|
||||||
unsigned FrameIx = SD->getFrameIx();
|
return BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
|
||||||
return TII->emitFrameIndexDebugValue(*MF, FrameIx, Offset, MDPtr, DL);
|
.addFrameIndex(SD->getFrameIx()).addImm(Offset).addMetadata(MDPtr);
|
||||||
}
|
}
|
||||||
// Otherwise, we're going to create an instruction here.
|
// Otherwise, we're going to create an instruction here.
|
||||||
const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
|
const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "SelectionDAGBuilder.h"
|
#include "SelectionDAGBuilder.h"
|
||||||
#include "SDNodeDbgValue.h"
|
#include "SDNodeDbgValue.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
||||||
@@ -4349,20 +4350,19 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
|
|||||||
|
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
const TargetInstrInfo *TII = DAG.getTarget().getInstrInfo();
|
const TargetInstrInfo *TII = DAG.getTarget().getInstrInfo();
|
||||||
const TargetRegisterInfo *TRI = DAG.getTarget().getRegisterInfo();
|
|
||||||
|
|
||||||
// Ignore inlined function arguments here.
|
// Ignore inlined function arguments here.
|
||||||
DIVariable DV(Variable);
|
DIVariable DV(Variable);
|
||||||
if (DV.isInlinedFnArgument(MF.getFunction()))
|
if (DV.isInlinedFnArgument(MF.getFunction()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned Reg = 0;
|
Optional<MachineOperand> Op;
|
||||||
// Some arguments' frame index is recorded during argument lowering.
|
// Some arguments' frame index is recorded during argument lowering.
|
||||||
Offset = FuncInfo.getArgumentFrameIndex(Arg);
|
if (int FI = FuncInfo.getArgumentFrameIndex(Arg))
|
||||||
if (Offset)
|
Op = MachineOperand::CreateFI(FI);
|
||||||
Reg = TRI->getFrameRegister(MF);
|
|
||||||
|
|
||||||
if (!Reg && N.getNode()) {
|
if (!Op && N.getNode()) {
|
||||||
|
unsigned Reg;
|
||||||
if (N.getOpcode() == ISD::CopyFromReg)
|
if (N.getOpcode() == ISD::CopyFromReg)
|
||||||
Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();
|
Reg = cast<RegisterSDNode>(N.getOperand(1))->getReg();
|
||||||
else
|
else
|
||||||
@@ -4373,32 +4373,33 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,
|
|||||||
if (PR)
|
if (PR)
|
||||||
Reg = PR;
|
Reg = PR;
|
||||||
}
|
}
|
||||||
|
if (Reg)
|
||||||
|
Op = MachineOperand::CreateReg(Reg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Reg) {
|
if (!Op) {
|
||||||
// Check if ValueMap has reg number.
|
// Check if ValueMap has reg number.
|
||||||
DenseMap<const Value *, unsigned>::iterator VMI = FuncInfo.ValueMap.find(V);
|
DenseMap<const Value *, unsigned>::iterator VMI = FuncInfo.ValueMap.find(V);
|
||||||
if (VMI != FuncInfo.ValueMap.end())
|
if (VMI != FuncInfo.ValueMap.end())
|
||||||
Reg = VMI->second;
|
Op = MachineOperand::CreateReg(VMI->second, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Reg && N.getNode()) {
|
if (!Op && N.getNode())
|
||||||
// Check if frame index is available.
|
// Check if frame index is available.
|
||||||
if (LoadSDNode *LNode = dyn_cast<LoadSDNode>(N.getNode()))
|
if (LoadSDNode *LNode = dyn_cast<LoadSDNode>(N.getNode()))
|
||||||
if (FrameIndexSDNode *FINode =
|
if (FrameIndexSDNode *FINode =
|
||||||
dyn_cast<FrameIndexSDNode>(LNode->getBasePtr().getNode())) {
|
dyn_cast<FrameIndexSDNode>(LNode->getBasePtr().getNode()))
|
||||||
Reg = TRI->getFrameRegister(MF);
|
Op = MachineOperand::CreateFI(FINode->getIndex());
|
||||||
Offset = FINode->getIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Reg)
|
if (!Op)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MachineInstrBuilder MIB = BuildMI(MF, getCurDebugLoc(),
|
if (Op->isReg())
|
||||||
TII->get(TargetOpcode::DBG_VALUE))
|
Op->setIsDebug();
|
||||||
.addReg(Reg, RegState::Debug).addImm(Offset).addMetadata(Variable);
|
|
||||||
FuncInfo.ArgDbgValues.push_back(&*MIB);
|
FuncInfo.ArgDbgValues.push_back(
|
||||||
|
BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE))
|
||||||
|
.addOperand(*Op).addImm(Offset).addMetadata(Variable));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -401,7 +401,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
// Insert DBG_VALUE instructions for function arguments to the entry block.
|
// Insert DBG_VALUE instructions for function arguments to the entry block.
|
||||||
for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
|
for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
|
||||||
MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1];
|
MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1];
|
||||||
unsigned Reg = MI->getOperand(0).getReg();
|
bool hasFI = MI->getOperand(0).isFI();
|
||||||
|
unsigned Reg = hasFI ? TRI.getFrameRegister(*MF) : MI->getOperand(0).getReg();
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||||
EntryMBB->insert(EntryMBB->begin(), MI);
|
EntryMBB->insert(EntryMBB->begin(), MI);
|
||||||
else {
|
else {
|
||||||
@@ -414,6 +415,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
// If Reg is live-in then update debug info to track its copy in a vreg.
|
// If Reg is live-in then update debug info to track its copy in a vreg.
|
||||||
DenseMap<unsigned, unsigned>::iterator LDI = LiveInMap.find(Reg);
|
DenseMap<unsigned, unsigned>::iterator LDI = LiveInMap.find(Reg);
|
||||||
if (LDI != LiveInMap.end()) {
|
if (LDI != LiveInMap.end()) {
|
||||||
|
assert(!hasFI && "There's no handling of frame pointer updating here yet "
|
||||||
|
"- add if needed");
|
||||||
MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
|
MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
|
||||||
MachineBasicBlock::iterator InsertPos = Def;
|
MachineBasicBlock::iterator InsertPos = Def;
|
||||||
const MDNode *Variable =
|
const MDNode *Variable =
|
||||||
|
|||||||
@@ -702,12 +702,7 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
}
|
}
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
|
|
||||||
// Special handling of dbg_value instructions.
|
assert(!MI.isDebugValue() && "DBG_VALUEs should be handled in target-independent code");
|
||||||
if (MI.isDebugValue()) {
|
|
||||||
MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg, false /*isDef*/);
|
|
||||||
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modify MI as necessary to handle as much of 'Offset' as possible
|
// Modify MI as necessary to handle as much of 'Offset' as possible
|
||||||
bool Done = false;
|
bool Done = false;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ define void @foo(%struct.tag_s* nocapture %this, %struct.tag_s* %c, i64 %x, i64
|
|||||||
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %c}, i64 0, metadata !13), !dbg !21
|
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %c}, i64 0, metadata !13), !dbg !21
|
||||||
tail call void @llvm.dbg.value(metadata !{i64 %x}, i64 0, metadata !14), !dbg !22
|
tail call void @llvm.dbg.value(metadata !{i64 %x}, i64 0, metadata !14), !dbg !22
|
||||||
tail call void @llvm.dbg.value(metadata !{i64 %y}, i64 0, metadata !17), !dbg !23
|
tail call void @llvm.dbg.value(metadata !{i64 %y}, i64 0, metadata !17), !dbg !23
|
||||||
;CHECK: @DEBUG_VALUE: foo:y <- [R7+4294967295]
|
;CHECK: @DEBUG_VALUE: foo:y <- [R7+8]
|
||||||
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr1}, i64 0, metadata !18), !dbg !24
|
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr1}, i64 0, metadata !18), !dbg !24
|
||||||
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr2}, i64 0, metadata !19), !dbg !25
|
tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr2}, i64 0, metadata !19), !dbg !25
|
||||||
%1 = icmp eq %struct.tag_s* %c, null, !dbg !26
|
%1 = icmp eq %struct.tag_s* %c, null, !dbg !26
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
; RUN: llc -O0 < %s | FileCheck %s
|
; RUN: llc -O0 < %s | FileCheck %s
|
||||||
; CHECK: @DEBUG_VALUE: mydata <- [sp+#{{[0-9]+}}]+#0
|
; CHECK: @DEBUG_VALUE: mydata <- [SP+{{[0-9]+}}]
|
||||||
; Radar 9331779
|
; Radar 9331779
|
||||||
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
|
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
|
||||||
target triple = "thumbv7-apple-ios"
|
target triple = "thumbv7-apple-ios"
|
||||||
|
|||||||
Reference in new issue
Block a user