mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Progress towards shepherding debug info through SelectionDAG.
No functional effect yet. This is still evolving and should not be viewed as final. llvm-svn: 98195
This commit is contained in:
parent
d14ff9f87b
commit
987770c05d
@ -227,6 +227,7 @@ namespace llvm {
|
||||
private:
|
||||
SDNode *Node; // Representative node.
|
||||
MachineInstr *Instr; // Alternatively, a MachineInstr.
|
||||
MachineInstr *DbgInstr; // A dbg_value referencing this.
|
||||
public:
|
||||
SUnit *OrigNode; // If not this, the node from which
|
||||
// this node was cloned.
|
||||
@ -269,10 +270,10 @@ namespace llvm {
|
||||
/// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
|
||||
/// an SDNode and any nodes flagged to it.
|
||||
SUnit(SDNode *node, unsigned nodenum)
|
||||
: Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
|
||||
Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false),
|
||||
: Node(node), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(nodenum),
|
||||
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||
isPending(false), isAvailable(false), isScheduled(false),
|
||||
isScheduleHigh(false), isCloned(false),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
@ -281,10 +282,10 @@ namespace llvm {
|
||||
/// SUnit - Construct an SUnit for post-regalloc scheduling to represent
|
||||
/// a MachineInstr.
|
||||
SUnit(MachineInstr *instr, unsigned nodenum)
|
||||
: Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0),
|
||||
Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false),
|
||||
: Node(0), Instr(instr), DbgInstr(0), OrigNode(0), NodeNum(nodenum),
|
||||
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||
isPending(false), isAvailable(false), isScheduled(false),
|
||||
isScheduleHigh(false), isCloned(false),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
@ -292,10 +293,10 @@ namespace llvm {
|
||||
|
||||
/// SUnit - Construct a placeholder SUnit.
|
||||
SUnit()
|
||||
: Node(0), Instr(0), OrigNode(0), NodeNum(~0u), NodeQueueId(0),
|
||||
Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
|
||||
isTwoAddress(false), isCommutable(false), hasPhysRegDefs(false),
|
||||
hasPhysRegClobbers(false),
|
||||
: Node(0), Instr(0), DbgInstr(0), OrigNode(0), NodeNum(~0u),
|
||||
NodeQueueId(0), Latency(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
|
||||
NumSuccsLeft(0), isTwoAddress(false), isCommutable(false),
|
||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||
isPending(false), isAvailable(false), isScheduled(false),
|
||||
isScheduleHigh(false), isCloned(false),
|
||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||
@ -329,6 +330,20 @@ namespace llvm {
|
||||
return Instr;
|
||||
}
|
||||
|
||||
/// setDbgInstr - Assign the debug instruction for the SUnit.
|
||||
/// This may be used during post-regalloc scheduling.
|
||||
void setDbgInstr(MachineInstr *MI) {
|
||||
assert(!Node && "Setting debug MachineInstr of SUnit with SDNode!");
|
||||
DbgInstr = MI;
|
||||
}
|
||||
|
||||
/// getDbgInstr - Return the debug MachineInstr for this SUnit.
|
||||
/// This may be used during post-regalloc scheduling.
|
||||
MachineInstr *getDbgInstr() const {
|
||||
assert(!Node && "Reading debug MachineInstr of SUnit with SDNode!");
|
||||
return DbgInstr;
|
||||
}
|
||||
|
||||
/// addPred - This adds the specified edge as a pred of the current node if
|
||||
/// not already. It also adds the current node as a successor of the
|
||||
/// specified node.
|
||||
|
@ -35,6 +35,7 @@ class MachineConstantPoolValue;
|
||||
class MachineFunction;
|
||||
class MachineModuleInfo;
|
||||
class SDNodeOrdering;
|
||||
class SDDbgValue;
|
||||
class TargetLowering;
|
||||
|
||||
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
|
||||
@ -57,6 +58,46 @@ private:
|
||||
static void createNode(const SDNode &);
|
||||
};
|
||||
|
||||
/// SDDbgInfo - Keeps track of dbg_value information through SDISel. We do
|
||||
/// not build SDNodes for these so as not to perturb the generated code;
|
||||
/// instead the info is kept off to the side in this structure. SDNodes may
|
||||
/// have an associated dbg_value entry in DbgValMap. Debug info that is not
|
||||
/// associated with any SDNode is held in DbgConstMap. It is possible for
|
||||
/// optimizations to change a variable to a constant, in which case the
|
||||
/// corresponding debug info is moved from the variable to the constant table
|
||||
/// (NYI).
|
||||
class SDDbgInfo {
|
||||
DenseMap<const SDNode*, SDDbgValue*> DbgVblMap;
|
||||
SmallVector<SDDbgValue*, 4> DbgConstMap;
|
||||
|
||||
void operator=(const SDDbgInfo&); // Do not implement.
|
||||
SDDbgInfo(const SDDbgInfo&); // Do not implement.
|
||||
public:
|
||||
SDDbgInfo() {}
|
||||
|
||||
void add(const SDNode *Node, SDDbgValue *V) {
|
||||
DbgVblMap[Node] = V;
|
||||
}
|
||||
void add(SDDbgValue *V) { DbgConstMap.push_back(V); }
|
||||
void remove(const SDNode *Node) {
|
||||
DenseMap<const SDNode*, SDDbgValue*>::iterator Itr =
|
||||
DbgVblMap.find(Node);
|
||||
if (Itr != DbgVblMap.end())
|
||||
DbgVblMap.erase(Itr);
|
||||
}
|
||||
// No need to remove a constant.
|
||||
void clear() {
|
||||
DbgVblMap.clear();
|
||||
DbgConstMap.clear();
|
||||
}
|
||||
SDDbgValue *getSDDbgValue(const SDNode *Node) {
|
||||
return DbgVblMap[Node];
|
||||
}
|
||||
typedef SmallVector<SDDbgValue*, 4>::iterator ConstDbgIterator;
|
||||
ConstDbgIterator DbgConstBegin() { return DbgConstMap.begin(); }
|
||||
ConstDbgIterator DbgConstEnd() { return DbgConstMap.end(); }
|
||||
};
|
||||
|
||||
enum CombineLevel {
|
||||
Unrestricted, // Combine may create illegal operations and illegal types.
|
||||
NoIllegalTypes, // Combine may create illegal operations but no illegal types.
|
||||
@ -119,6 +160,9 @@ class SelectionDAG {
|
||||
/// the ordering of the original LLVM instructions.
|
||||
SDNodeOrdering *Ordering;
|
||||
|
||||
/// DbgInfo - Tracks dbg_value information through SDISel.
|
||||
SDDbgInfo *DbgInfo;
|
||||
|
||||
/// VerifyNode - Sanity check the given node. Aborts if it is invalid.
|
||||
void VerifyNode(SDNode *N);
|
||||
|
||||
@ -828,6 +872,20 @@ public:
|
||||
/// GetOrdering - Get the order for the SDNode.
|
||||
unsigned GetOrdering(const SDNode *SD) const;
|
||||
|
||||
/// AssignDbgInfo - Assign debug info to the SDNode.
|
||||
void AssignDbgInfo(SDNode *SD, SDDbgValue *db);
|
||||
|
||||
/// RememberDbgInfo - Remember debug info with no associated SDNode.
|
||||
void RememberDbgInfo(SDDbgValue *db);
|
||||
|
||||
/// GetDbgInfo - Get the debug info for the SDNode.
|
||||
SDDbgValue *GetDbgInfo(const SDNode* SD);
|
||||
|
||||
SDDbgInfo::ConstDbgIterator DbgConstBegin() {
|
||||
return DbgInfo->DbgConstBegin();
|
||||
}
|
||||
SDDbgInfo::ConstDbgIterator DbgConstEnd() { return DbgInfo->DbgConstEnd(); }
|
||||
|
||||
void dump() const;
|
||||
|
||||
/// CreateStackTemporary - Create a stack temporary, suitable for holding the
|
||||
|
@ -34,6 +34,7 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
|
||||
const MachineDominatorTree &mdt)
|
||||
: ScheduleDAG(mf), MLI(mli), MDT(mdt), LoopRegs(MLI, MDT) {
|
||||
MFI = mf.getFrameInfo();
|
||||
DbgValueVec.clear();
|
||||
}
|
||||
|
||||
/// Run - perform scheduling.
|
||||
@ -157,6 +158,10 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
||||
std::map<const Value *, SUnit *> AliasMemDefs, NonAliasMemDefs;
|
||||
std::map<const Value *, std::vector<SUnit *> > AliasMemUses, NonAliasMemUses;
|
||||
|
||||
// Keep track of dangling debug references to registers.
|
||||
std::pair<MachineInstr*, unsigned>
|
||||
DanglingDebugValue[TargetRegisterInfo::FirstVirtualRegister];
|
||||
|
||||
// Check to see if the scheduler cares about latencies.
|
||||
bool UnitLatencies = ForceUnitLatencies();
|
||||
|
||||
@ -164,10 +169,25 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
||||
const TargetSubtarget &ST = TM.getSubtarget<TargetSubtarget>();
|
||||
unsigned SpecialAddressLatency = ST.getSpecialAddressLatency();
|
||||
|
||||
// Remove any stale debug info; sometimes BuildSchedGraph is called again
|
||||
// without emitting the info from the previous call.
|
||||
DbgValueVec.clear();
|
||||
std::memset(DanglingDebugValue, 0, sizeof(DanglingDebugValue));
|
||||
|
||||
// Walk the list of instructions, from bottom moving up.
|
||||
for (MachineBasicBlock::iterator MII = InsertPos, MIE = Begin;
|
||||
MII != MIE; --MII) {
|
||||
MachineInstr *MI = prior(MII);
|
||||
// DBG_VALUE does not have SUnit's built, so just remember these for later
|
||||
// reinsertion.
|
||||
if (MI->isDebugValue()) {
|
||||
if (MI->getNumOperands()==3 && MI->getOperand(0).isReg() &&
|
||||
MI->getOperand(0).getReg())
|
||||
DanglingDebugValue[MI->getOperand(0).getReg()] =
|
||||
std::make_pair(MI, DbgValueVec.size());
|
||||
DbgValueVec.push_back(MI);
|
||||
continue;
|
||||
}
|
||||
const TargetInstrDesc &TID = MI->getDesc();
|
||||
assert(!TID.isTerminator() && !MI->isLabel() &&
|
||||
"Cannot schedule terminators or labels!");
|
||||
@ -188,6 +208,13 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
||||
if (Reg == 0) continue;
|
||||
|
||||
assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
|
||||
|
||||
if (MO.isDef() && DanglingDebugValue[Reg].first!=0) {
|
||||
SU->setDbgInstr(DanglingDebugValue[Reg].first);
|
||||
DbgValueVec[DanglingDebugValue[Reg].second] = 0;
|
||||
DanglingDebugValue[Reg] = std::make_pair((MachineInstr*)0, 0);
|
||||
}
|
||||
|
||||
std::vector<SUnit *> &UseList = Uses[Reg];
|
||||
std::vector<SUnit *> &DefList = Defs[Reg];
|
||||
// Optionally add output and anti dependencies. For anti
|
||||
@ -555,6 +582,14 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
||||
BB->remove(I);
|
||||
}
|
||||
|
||||
// First reinsert any remaining debug_values; these are either constants,
|
||||
// or refer to live-in registers. The beginning of the block is the right
|
||||
// place for the latter. The former might reasonably be placed elsewhere
|
||||
// using some kind of ordering algorithm, but right now it doesn't matter.
|
||||
for (int i = DbgValueVec.size()-1; i>=0; --i)
|
||||
if (DbgValueVec[i])
|
||||
BB->insert(InsertPos, DbgValueVec[i]);
|
||||
|
||||
// Then re-insert them according to the given schedule.
|
||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||
SUnit *SU = Sequence[i];
|
||||
@ -565,12 +600,21 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
||||
}
|
||||
|
||||
BB->insert(InsertPos, SU->getInstr());
|
||||
if (SU->getDbgInstr())
|
||||
BB->insert(InsertPos, SU->getDbgInstr());
|
||||
}
|
||||
|
||||
// Update the Begin iterator, as the first instruction in the block
|
||||
// may have been scheduled later.
|
||||
if (!Sequence.empty())
|
||||
if (!DbgValueVec.empty()) {
|
||||
for (int i = DbgValueVec.size()-1; i>=0; --i)
|
||||
if (DbgValueVec[i]!=0) {
|
||||
Begin = DbgValueVec[DbgValueVec.size()-1];
|
||||
break;
|
||||
}
|
||||
} else if (!Sequence.empty())
|
||||
Begin = Sequence[0]->getInstr();
|
||||
|
||||
DbgValueVec.clear();
|
||||
return BB;
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ namespace llvm {
|
||||
/// initialized and destructed for each block.
|
||||
std::vector<SUnit *> Defs[TargetRegisterInfo::FirstVirtualRegister];
|
||||
std::vector<SUnit *> Uses[TargetRegisterInfo::FirstVirtualRegister];
|
||||
|
||||
/// DbgValueVec - Remember DBG_VALUEs that refer to a particular
|
||||
/// register.
|
||||
std::vector<MachineInstr *>DbgValueVec;
|
||||
|
||||
/// PendingLoads - Remember where unknown loads are after the most recent
|
||||
/// unknown store, as we iterate. As with Defs and Uses, this is here
|
||||
|
@ -508,6 +508,7 @@ InstrEmitter::EmitDbgValue(SDNode *Node,
|
||||
return;
|
||||
if (!sd)
|
||||
return;
|
||||
assert(sd->getKind() == SDDbgValue::SD);
|
||||
unsigned VReg = getVR(SDValue(sd->getSDNode(), sd->getResNo()), VRBaseMap);
|
||||
const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
|
||||
DebugLoc DL = sd->getDebugLoc();
|
||||
@ -524,26 +525,46 @@ InstrEmitter::EmitDbgValue(SDNode *Node,
|
||||
MBB->insert(InsertPos, MI);
|
||||
}
|
||||
|
||||
/// EmitDbgValue - Generate constant debug info. No SDNode is involved.
|
||||
/// EmitDbgValue - Generate debug info that does not refer to a SDNode.
|
||||
void
|
||||
InstrEmitter::EmitDbgValue(SDDbgValue *sd) {
|
||||
InstrEmitter::EmitDbgValue(SDDbgValue *sd,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
||||
if (!sd)
|
||||
return;
|
||||
const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
|
||||
uint64_t Offset = sd->getOffset();
|
||||
MDNode* mdPtr = sd->getMDPtr();
|
||||
SDDbgValue::DbgValueKind kind = sd->getKind();
|
||||
DebugLoc DL = sd->getDebugLoc();
|
||||
MachineInstr *MI;
|
||||
Value *V = sd->getConst();
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
|
||||
addImm(sd->getOffset()).
|
||||
addMetadata(sd->getMDPtr());
|
||||
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
||||
MI = BuildMI(*MF, DL, II).addFPImm(CF).addImm(sd->getOffset()).
|
||||
addMetadata(sd->getMDPtr());
|
||||
MachineInstr* MI;
|
||||
if (kind == SDDbgValue::CNST) {
|
||||
Value *V = sd->getConst();
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
|
||||
addImm(Offset).addMetadata(mdPtr);
|
||||
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
||||
MI = BuildMI(*MF, DL, II).addFPImm(CF).
|
||||
addImm(Offset).addMetadata(mdPtr);
|
||||
} else {
|
||||
// Could be an Undef. In any case insert an Undef so we can see what we
|
||||
// dropped.
|
||||
MI = BuildMI(*MF, DL, II).addReg(0U).
|
||||
addImm(Offset).addMetadata(mdPtr);
|
||||
}
|
||||
} else if (kind == SDDbgValue::FX) {
|
||||
unsigned FrameIx = sd->getFrameIx();
|
||||
// Stack address; this needs to be lowered in target-dependent fashion.
|
||||
// FIXME test that the target supports this somehow; if not emit Undef.
|
||||
// Create a pseudo for EmitInstrWithCustomInserter's consumption.
|
||||
MI = BuildMI(*MF, DL, II).addImm(FrameIx).
|
||||
addImm(Offset).addMetadata(mdPtr);
|
||||
MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM);
|
||||
InsertPos = MBB->end();
|
||||
return;
|
||||
} else {
|
||||
// Insert an Undef so we can see what we dropped.
|
||||
MI = BuildMI(*MF, DL, II).addReg(0U).addImm(sd->getOffset()).
|
||||
addMetadata(sd->getMDPtr());
|
||||
MI = BuildMI(*MF, DL, II).addReg(0U).
|
||||
addImm(Offset).addMetadata(mdPtr);
|
||||
}
|
||||
MBB->insert(InsertPos, MI);
|
||||
}
|
||||
|
@ -106,7 +106,8 @@ public:
|
||||
|
||||
|
||||
/// EmitDbgValue - Generate a constant DBG_VALUE. No node is involved.
|
||||
void EmitDbgValue(SDDbgValue* sd);
|
||||
void EmitDbgValue(SDDbgValue* sd,
|
||||
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
|
||||
|
||||
/// EmitNode - Generate machine code for a node and needed dependencies.
|
||||
///
|
||||
|
@ -28,9 +28,22 @@ class Value;
|
||||
/// We do not use SDValue here to avoid including its header.
|
||||
|
||||
class SDDbgValue {
|
||||
SDNode *Node; // valid for non-constants
|
||||
unsigned ResNo; // valid for non-constants
|
||||
Value *Const; // valid for constants
|
||||
public:
|
||||
enum DbgValueKind {
|
||||
SD = 0,
|
||||
CNST = 1,
|
||||
FX = 2
|
||||
};
|
||||
private:
|
||||
enum DbgValueKind kind;
|
||||
union {
|
||||
struct {
|
||||
SDNode *Node; // valid for non-constants
|
||||
unsigned ResNo; // valid for non-constants
|
||||
} s;
|
||||
Value *Const; // valid for constants
|
||||
unsigned FrameIx; // valid for stack objects
|
||||
} u;
|
||||
MDNode *mdPtr;
|
||||
uint64_t Offset;
|
||||
DebugLoc DL;
|
||||
@ -38,24 +51,43 @@ class SDDbgValue {
|
||||
public:
|
||||
// Constructor for non-constants.
|
||||
SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl,
|
||||
unsigned O) :
|
||||
Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
|
||||
unsigned O) : mdPtr(mdP), Offset(off), DL(dl), Order(O) {
|
||||
kind = SD;
|
||||
u.s.Node = N;
|
||||
u.s.ResNo = R;
|
||||
}
|
||||
|
||||
// Constructor for constants.
|
||||
SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl, unsigned O) :
|
||||
Node(0), ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl), Order(O) {}
|
||||
mdPtr(mdP), Offset(off), DL(dl), Order(O) {
|
||||
kind = CNST;
|
||||
u.Const = C;
|
||||
}
|
||||
|
||||
// Constructor for frame indices.
|
||||
SDDbgValue(MDNode *mdP, unsigned FI, uint64_t off, DebugLoc dl, unsigned O) :
|
||||
mdPtr(mdP), Offset(off), DL(dl), Order(O) {
|
||||
kind = FX;
|
||||
u.FrameIx = FI;
|
||||
}
|
||||
|
||||
// Returns the kind.
|
||||
DbgValueKind getKind() { return kind; }
|
||||
|
||||
// Returns the MDNode pointer.
|
||||
MDNode *getMDPtr() { return mdPtr; }
|
||||
|
||||
// Returns the SDNode* (valid for non-constants only).
|
||||
SDNode *getSDNode() { assert (!Const); return Node; }
|
||||
// Returns the SDNode* for a register ref
|
||||
SDNode *getSDNode() { assert (kind==SD); return u.s.Node; }
|
||||
|
||||
// Returns the ResNo (valid for non-constants only).
|
||||
unsigned getResNo() { assert (!Const); return ResNo; }
|
||||
// Returns the ResNo for a register ref
|
||||
unsigned getResNo() { assert (kind==SD); return u.s.ResNo; }
|
||||
|
||||
// Returns the Value* for a constant (invalid for non-constants).
|
||||
Value *getConst() { assert (!Node); return Const; }
|
||||
// Returns the Value* for a constant
|
||||
Value *getConst() { assert (kind==CNST); return u.Const; }
|
||||
|
||||
// Returns the FrameIx for a stack object
|
||||
unsigned getFrameIx() { assert (kind==FX); return u.FrameIx; }
|
||||
|
||||
// Returns the offset.
|
||||
uint64_t getOffset() { return Offset; }
|
||||
|
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "pre-RA-sched"
|
||||
#include "SDDbgValue.h"
|
||||
#include "ScheduleDAGSDNodes.h"
|
||||
#include "InstrEmitter.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
@ -412,6 +413,14 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
||||
InstrEmitter Emitter(BB, InsertPos);
|
||||
DenseMap<SDValue, unsigned> VRBaseMap;
|
||||
DenseMap<SUnit*, unsigned> CopyVRBaseMap;
|
||||
|
||||
// For now, any constant debug info nodes go at the beginning.
|
||||
for (SDDbgInfo::ConstDbgIterator I = DAG->DbgConstBegin(),
|
||||
E = DAG->DbgConstEnd(); I!=E; I++) {
|
||||
Emitter.EmitDbgValue(*I, EM);
|
||||
delete *I;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
|
||||
SUnit *SU = Sequence[i];
|
||||
if (!SU) {
|
||||
@ -435,10 +444,20 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
|
||||
while (!FlaggedNodes.empty()) {
|
||||
Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,
|
||||
VRBaseMap, EM);
|
||||
if (FlaggedNodes.back()->getHasDebugValue())
|
||||
if (SDDbgValue *sd = DAG->GetDbgInfo(FlaggedNodes.back())) {
|
||||
Emitter.EmitDbgValue(FlaggedNodes.back(), VRBaseMap, sd);
|
||||
delete sd;
|
||||
}
|
||||
FlaggedNodes.pop_back();
|
||||
}
|
||||
Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
|
||||
VRBaseMap, EM);
|
||||
if (SU->getNode()->getHasDebugValue())
|
||||
if (SDDbgValue *sd = DAG->GetDbgInfo(SU->getNode())) {
|
||||
Emitter.EmitDbgValue(SU->getNode(), VRBaseMap, sd);
|
||||
delete sd;
|
||||
}
|
||||
}
|
||||
|
||||
BB = Emitter.getBlock();
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "SDNodeOrdering.h"
|
||||
#include "SDDbgValue.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Function.h"
|
||||
@ -596,6 +597,9 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
|
||||
|
||||
// Remove the ordering of this node.
|
||||
Ordering->remove(N);
|
||||
|
||||
// And its entry in the debug info table, if any.
|
||||
DbgInfo->remove(N);
|
||||
}
|
||||
|
||||
/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
|
||||
@ -793,6 +797,7 @@ SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
|
||||
Root(getEntryNode()), Ordering(0) {
|
||||
AllNodes.push_back(&EntryNode);
|
||||
Ordering = new SDNodeOrdering();
|
||||
DbgInfo = new SDDbgInfo();
|
||||
}
|
||||
|
||||
void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
|
||||
@ -806,6 +811,7 @@ void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
|
||||
SelectionDAG::~SelectionDAG() {
|
||||
allnodes_clear();
|
||||
delete Ordering;
|
||||
delete DbgInfo;
|
||||
}
|
||||
|
||||
void SelectionDAG::allnodes_clear() {
|
||||
@ -833,6 +839,8 @@ void SelectionDAG::clear() {
|
||||
Root = getEntryNode();
|
||||
delete Ordering;
|
||||
Ordering = new SDNodeOrdering();
|
||||
delete DbgInfo;
|
||||
DbgInfo = new SDDbgInfo();
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) {
|
||||
@ -5264,6 +5272,25 @@ unsigned SelectionDAG::GetOrdering(const SDNode *SD) const {
|
||||
return Ordering->getOrder(SD);
|
||||
}
|
||||
|
||||
/// AssignDbgInfo - Assign debug info to the SDNode.
|
||||
void SelectionDAG::AssignDbgInfo(SDNode* SD, SDDbgValue* db) {
|
||||
assert(SD && "Trying to assign dbg info to a null node!");
|
||||
DbgInfo->add(SD, db);
|
||||
SD->setHasDebugValue(true);
|
||||
}
|
||||
|
||||
/// RememberDbgInfo - Remember debug info which is not assigned to an SDNode.
|
||||
void SelectionDAG::RememberDbgInfo(SDDbgValue* db) {
|
||||
DbgInfo->add(db);
|
||||
}
|
||||
|
||||
/// GetDbgInfo - Get the debug info, if any, for the SDNode.
|
||||
SDDbgValue* SelectionDAG::GetDbgInfo(const SDNode *SD) {
|
||||
assert(SD && "Trying to get the order of a null node!");
|
||||
if (SD->getHasDebugValue())
|
||||
return DbgInfo->getSDDbgValue(SD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SDNode Class
|
||||
@ -5911,7 +5938,7 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
|
||||
if (G)
|
||||
if (unsigned Order = G->GetOrdering(this))
|
||||
OS << " [ORD=" << Order << ']';
|
||||
|
||||
|
||||
if (getNodeId() != -1)
|
||||
OS << " [ID=" << getNodeId() << ']';
|
||||
}
|
||||
|
@ -8521,6 +8521,21 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
// DBG_VALUE. Only the frame index case is done here.
|
||||
case X86::DBG_VALUE: {
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
X86AddressMode AM;
|
||||
MachineFunction *F = BB->getParent();
|
||||
AM.BaseType = X86AddressMode::FrameIndexBase;
|
||||
AM.Base.FrameIndex = MI->getOperand(0).getImm();
|
||||
addFullAddress(BuildMI(BB, DL, TII->get(X86::DBG_VALUE)), AM).
|
||||
addImm(MI->getOperand(1).getImm()).
|
||||
addMetadata(MI->getOperand(2).getMetadata());
|
||||
F->DeleteMachineInstr(MI); // Remove pseudo.
|
||||
return BB;
|
||||
}
|
||||
|
||||
// String/text processing lowering.
|
||||
case X86::PCMPISTRM128REG:
|
||||
return EmitPCMP(MI, BB, 3, false /* in-mem */);
|
||||
|
Loading…
Reference in New Issue
Block a user