mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-15 05:24:01 +00:00
Add DBG_VALUE handling for byval parameters; this
produces a comment on targets that support it, but the Dwarf writer is not hooked up yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102372 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -62,8 +62,15 @@ private:
|
|||||||
/// instead the info is kept off to the side in this structure. Each SDNode may
|
/// instead the info is kept off to the side in this structure. Each SDNode may
|
||||||
/// have one or more associated dbg_value entries. This information is kept in
|
/// have one or more associated dbg_value entries. This information is kept in
|
||||||
/// DbgValMap.
|
/// DbgValMap.
|
||||||
|
/// Byval parameters are handled separately because they don't use alloca's,
|
||||||
|
/// which busts the normal mechanism. There is good reason for handling all
|
||||||
|
/// parameters separately: they may not have code generated for them, they
|
||||||
|
/// should always go at the beginning of the function regardless of other code
|
||||||
|
/// motion, and debug info for them is potentially useful even if the parameter
|
||||||
|
/// is unused. Right now only byval parameters are handled separately.
|
||||||
class SDDbgInfo {
|
class SDDbgInfo {
|
||||||
SmallVector<SDDbgValue*, 32> DbgValues;
|
SmallVector<SDDbgValue*, 32> DbgValues;
|
||||||
|
SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
|
||||||
DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
|
DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
|
||||||
|
|
||||||
void operator=(const SDDbgInfo&); // Do not implement.
|
void operator=(const SDDbgInfo&); // Do not implement.
|
||||||
@ -71,19 +78,22 @@ class SDDbgInfo {
|
|||||||
public:
|
public:
|
||||||
SDDbgInfo() {}
|
SDDbgInfo() {}
|
||||||
|
|
||||||
void add(SDDbgValue *V, const SDNode *Node = 0) {
|
void add(SDDbgValue *V, const SDNode *Node, bool isParameter) {
|
||||||
|
if (isParameter) {
|
||||||
|
ByvalParmDbgValues.push_back(V);
|
||||||
|
} else DbgValues.push_back(V);
|
||||||
if (Node)
|
if (Node)
|
||||||
DbgValMap[Node].push_back(V);
|
DbgValMap[Node].push_back(V);
|
||||||
DbgValues.push_back(V);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
DbgValMap.clear();
|
DbgValMap.clear();
|
||||||
DbgValues.clear();
|
DbgValues.clear();
|
||||||
|
ByvalParmDbgValues.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return DbgValues.empty();
|
return DbgValues.empty() && ByvalParmDbgValues.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) {
|
SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) {
|
||||||
@ -93,6 +103,8 @@ public:
|
|||||||
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
|
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
|
||||||
DbgIterator DbgBegin() { return DbgValues.begin(); }
|
DbgIterator DbgBegin() { return DbgValues.begin(); }
|
||||||
DbgIterator DbgEnd() { return DbgValues.end(); }
|
DbgIterator DbgEnd() { return DbgValues.end(); }
|
||||||
|
DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
|
||||||
|
DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CombineLevel {
|
enum CombineLevel {
|
||||||
@ -877,7 +889,7 @@ public:
|
|||||||
|
|
||||||
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
|
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
|
||||||
/// value is produced by SD.
|
/// value is produced by SD.
|
||||||
void AddDbgValue(SDDbgValue *DB, SDNode *SD = 0);
|
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
|
||||||
|
|
||||||
/// GetDbgValues - Get the debug values which reference the given SDNode.
|
/// GetDbgValues - Get the debug values which reference the given SDNode.
|
||||||
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
|
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
|
||||||
@ -890,6 +902,12 @@ public:
|
|||||||
|
|
||||||
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
|
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
|
||||||
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
|
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
|
||||||
|
SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
|
||||||
|
return DbgInfo->ByvalParmDbgBegin();
|
||||||
|
}
|
||||||
|
SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
|
||||||
|
return DbgInfo->ByvalParmDbgEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
|
@ -470,6 +470,17 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
|||||||
SmallSet<unsigned, 8> Seen;
|
SmallSet<unsigned, 8> Seen;
|
||||||
bool HasDbg = DAG->hasDebugValues();
|
bool HasDbg = DAG->hasDebugValues();
|
||||||
|
|
||||||
|
// If this is the first BB, emit byval parameter dbg_value's.
|
||||||
|
if (HasDbg && BB->getParent()->begin() == MachineFunction::iterator(BB)) {
|
||||||
|
SDDbgInfo::DbgIterator PDI = DAG->ByvalParmDbgBegin();
|
||||||
|
SDDbgInfo::DbgIterator PDE = DAG->ByvalParmDbgEnd();
|
||||||
|
for (; PDI != PDE; ++PDI) {
|
||||||
|
MachineInstr *DbgMI= Emitter.EmitDbgValue(*PDI, VRBaseMap, EM);
|
||||||
|
if (DbgMI)
|
||||||
|
BB->insert(BB->end(), DbgMI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||||
SUnit *SU = Sequence[i];
|
SUnit *SU = Sequence[i];
|
||||||
if (!SU) {
|
if (!SU) {
|
||||||
@ -494,20 +505,20 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
|||||||
SDNode *N = FlaggedNodes.back();
|
SDNode *N = FlaggedNodes.back();
|
||||||
Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,
|
Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,
|
||||||
VRBaseMap, EM);
|
VRBaseMap, EM);
|
||||||
// Remember the the source order of the inserted instruction.
|
// Remember the source order of the inserted instruction.
|
||||||
if (HasDbg)
|
if (HasDbg)
|
||||||
ProcessSourceNode(N, DAG, Emitter, EM, VRBaseMap, Orders, Seen);
|
ProcessSourceNode(N, DAG, Emitter, EM, VRBaseMap, Orders, Seen);
|
||||||
FlaggedNodes.pop_back();
|
FlaggedNodes.pop_back();
|
||||||
}
|
}
|
||||||
Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
|
Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
|
||||||
VRBaseMap, EM);
|
VRBaseMap, EM);
|
||||||
// Remember the the source order of the inserted instruction.
|
// Remember the source order of the inserted instruction.
|
||||||
if (HasDbg)
|
if (HasDbg)
|
||||||
ProcessSourceNode(SU->getNode(), DAG, Emitter, EM, VRBaseMap, Orders,
|
ProcessSourceNode(SU->getNode(), DAG, Emitter, EM, VRBaseMap, Orders,
|
||||||
Seen);
|
Seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert all the dbg_value which have not already been inserted in source
|
// Insert all the dbg_values which have not already been inserted in source
|
||||||
// order sequence.
|
// order sequence.
|
||||||
if (HasDbg) {
|
if (HasDbg) {
|
||||||
MachineBasicBlock::iterator BBBegin = BB->empty() ? BB->end() : BB->begin();
|
MachineBasicBlock::iterator BBBegin = BB->empty() ? BB->end() : BB->begin();
|
||||||
|
@ -5341,8 +5341,8 @@ unsigned SelectionDAG::GetOrdering(const SDNode *SD) const {
|
|||||||
|
|
||||||
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
|
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
|
||||||
/// value is produced by SD.
|
/// value is produced by SD.
|
||||||
void SelectionDAG::AddDbgValue(SDDbgValue *DB, SDNode *SD) {
|
void SelectionDAG::AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter) {
|
||||||
DbgInfo->add(DB, SD);
|
DbgInfo->add(DB, SD, isParameter);
|
||||||
if (SD)
|
if (SD)
|
||||||
SD->setHasDebugValue(true);
|
SD->setHasDebugValue(true);
|
||||||
}
|
}
|
||||||
|
@ -3775,32 +3775,75 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||||||
case Intrinsic::dbg_declare: {
|
case Intrinsic::dbg_declare: {
|
||||||
// FIXME: currently, we get here only if OptLevel != CodeGenOpt::None.
|
// FIXME: currently, we get here only if OptLevel != CodeGenOpt::None.
|
||||||
// The real handling of this intrinsic is in FastISel.
|
// The real handling of this intrinsic is in FastISel.
|
||||||
if (OptLevel != CodeGenOpt::None)
|
// if (OptLevel != CodeGenOpt::None)
|
||||||
// FIXME: Variable debug info is not supported here.
|
// FIXME: Variable debug info is not supported here.
|
||||||
return 0;
|
// return 0;
|
||||||
const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
|
const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
|
||||||
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
|
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MDNode *Variable = DI.getVariable();
|
MDNode *Variable = DI.getVariable();
|
||||||
|
// Parameters are handled specially.
|
||||||
|
bool isParameter = false;
|
||||||
|
ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Variable->getOperand(0));
|
||||||
|
if (CI) {
|
||||||
|
unsigned Val = CI->getZExtValue();
|
||||||
|
unsigned Tag = Val & ~LLVMDebugVersionMask;
|
||||||
|
if (Tag == dwarf::DW_TAG_arg_variable)
|
||||||
|
isParameter = true;
|
||||||
|
}
|
||||||
const Value *Address = DI.getAddress();
|
const Value *Address = DI.getAddress();
|
||||||
if (!Address)
|
if (!Address)
|
||||||
return 0;
|
return 0;
|
||||||
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
|
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
|
||||||
Address = BCI->getOperand(0);
|
Address = BCI->getOperand(0);
|
||||||
const AllocaInst *AI = dyn_cast<AllocaInst>(Address);
|
const AllocaInst *AI = dyn_cast<AllocaInst>(Address);
|
||||||
// Don't handle byval struct arguments or VLAs, for example.
|
if (AI) {
|
||||||
if (!AI)
|
// Don't handle byval arguments or VLAs, for example.
|
||||||
return 0;
|
// Non-byval arguments are handled here (they refer to the stack temporary
|
||||||
DenseMap<const AllocaInst*, int>::iterator SI =
|
// alloca at this point).
|
||||||
FuncInfo.StaticAllocaMap.find(AI);
|
DenseMap<const AllocaInst*, int>::iterator SI =
|
||||||
if (SI == FuncInfo.StaticAllocaMap.end())
|
FuncInfo.StaticAllocaMap.find(AI);
|
||||||
return 0; // VLAs.
|
if (SI == FuncInfo.StaticAllocaMap.end())
|
||||||
int FI = SI->second;
|
return 0; // VLAs.
|
||||||
|
int FI = SI->second;
|
||||||
|
|
||||||
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
||||||
if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
|
if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
|
||||||
MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
|
MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build an entry in DbgOrdering. Debug info input nodes get an SDNodeOrder
|
||||||
|
// but do not always have a corresponding SDNode built. The SDNodeOrder
|
||||||
|
// absolute, but not relative, values are different depending on whether
|
||||||
|
// debug info exists.
|
||||||
|
++SDNodeOrder;
|
||||||
|
SDValue &N = NodeMap[Address];
|
||||||
|
SDDbgValue *SDV;
|
||||||
|
if (N.getNode()) {
|
||||||
|
if (isParameter && !AI) {
|
||||||
|
FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N.getNode());
|
||||||
|
if (FINode)
|
||||||
|
// Byval parameter. We have a frame index at this point.
|
||||||
|
SDV = DAG.getDbgValue(Variable, FINode->getIndex(),
|
||||||
|
0, dl, SDNodeOrder);
|
||||||
|
else
|
||||||
|
// Can't do anything with other non-AI cases yet. This might be a
|
||||||
|
// parameter of a callee function that got inlined, for example.
|
||||||
|
return 0;
|
||||||
|
} else if (AI)
|
||||||
|
SDV = DAG.getDbgValue(Variable, N.getNode(), N.getResNo(),
|
||||||
|
0, dl, SDNodeOrder);
|
||||||
|
else
|
||||||
|
// Can't do anything with other non-AI cases yet.
|
||||||
|
return 0;
|
||||||
|
DAG.AddDbgValue(SDV, N.getNode(), isParameter);
|
||||||
|
} else {
|
||||||
|
// This isn't useful, but it shows what we're missing.
|
||||||
|
SDV = DAG.getDbgValue(Variable, UndefValue::get(Address->getType()),
|
||||||
|
0, dl, SDNodeOrder);
|
||||||
|
DAG.AddDbgValue(SDV, 0, isParameter);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case Intrinsic::dbg_value: {
|
case Intrinsic::dbg_value: {
|
||||||
@ -3819,20 +3862,23 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||||||
// absolute, but not relative, values are different depending on whether
|
// absolute, but not relative, values are different depending on whether
|
||||||
// debug info exists.
|
// debug info exists.
|
||||||
++SDNodeOrder;
|
++SDNodeOrder;
|
||||||
|
SDDbgValue *SDV;
|
||||||
if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) {
|
if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) {
|
||||||
DAG.AddDbgValue(DAG.getDbgValue(Variable, V, Offset, dl, SDNodeOrder));
|
SDV = DAG.getDbgValue(Variable, V, Offset, dl, SDNodeOrder);
|
||||||
|
DAG.AddDbgValue(SDV, 0, false);
|
||||||
} else {
|
} else {
|
||||||
SDValue &N = NodeMap[V];
|
SDValue &N = NodeMap[V];
|
||||||
if (N.getNode())
|
if (N.getNode()) {
|
||||||
DAG.AddDbgValue(DAG.getDbgValue(Variable, N.getNode(),
|
SDV = DAG.getDbgValue(Variable, N.getNode(),
|
||||||
N.getResNo(), Offset, dl, SDNodeOrder),
|
N.getResNo(), Offset, dl, SDNodeOrder);
|
||||||
N.getNode());
|
DAG.AddDbgValue(SDV, N.getNode(), false);
|
||||||
else
|
} else {
|
||||||
// We may expand this to cover more cases. One case where we have no
|
// We may expand this to cover more cases. One case where we have no
|
||||||
// data available is an unreferenced parameter; we need this fallback.
|
// data available is an unreferenced parameter; we need this fallback.
|
||||||
DAG.AddDbgValue(DAG.getDbgValue(Variable,
|
SDV = DAG.getDbgValue(Variable, UndefValue::get(V->getType()),
|
||||||
UndefValue::get(V->getType()),
|
Offset, dl, SDNodeOrder);
|
||||||
Offset, dl, SDNodeOrder));
|
DAG.AddDbgValue(SDV, 0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a debug info table entry.
|
// Build a debug info table entry.
|
||||||
|
Reference in New Issue
Block a user