forked from OSchip/llvm-project
Added initial support for DEBUG_LABEL allowing debug specific labels to be
inserted in the code. llvm-svn: 25104
This commit is contained in:
parent
45e19098a6
commit
762e9ec06c
|
@ -550,8 +550,9 @@ namespace llvm {
|
||||||
///
|
///
|
||||||
void EmitInitial() const;
|
void EmitInitial() const;
|
||||||
|
|
||||||
/// ShouldEmitDwarf - Determine if dwarf declarations should be made.
|
/// ShouldEmitDwarf - Returns true if dwarf declarations should be made.
|
||||||
///
|
/// When called it also checks to see if debug info is newly available. if
|
||||||
|
/// so the initial dwarf headers are emitted.
|
||||||
bool ShouldEmitDwarf();
|
bool ShouldEmitDwarf();
|
||||||
|
|
||||||
/// BeginModule - Emit all dwarf sections that should come prior to the
|
/// BeginModule - Emit all dwarf sections that should come prior to the
|
||||||
|
|
|
@ -52,6 +52,13 @@ public:
|
||||||
///
|
///
|
||||||
unsigned getNextUniqueID() { return UniqueID++; }
|
unsigned getNextUniqueID() { return UniqueID++; }
|
||||||
|
|
||||||
|
/// RecordLabel - Records location information and associates it with a
|
||||||
|
/// debug label. Returns unique label id.
|
||||||
|
unsigned RecordLabel(unsigned Line, unsigned Col, unsigned SrcFile) {
|
||||||
|
// FIXME - actually record.
|
||||||
|
return getNextUniqueID();
|
||||||
|
}
|
||||||
|
|
||||||
bool doInitialization();
|
bool doInitialization();
|
||||||
bool doFinalization();
|
bool doFinalization();
|
||||||
|
|
||||||
|
|
|
@ -355,12 +355,17 @@ namespace ISD {
|
||||||
LOCATION,
|
LOCATION,
|
||||||
|
|
||||||
// DEBUG_LOC - This node is used to represent source line information
|
// DEBUG_LOC - This node is used to represent source line information
|
||||||
// embedded in the code. It takes token chain as input, then a line number,
|
// embedded in the code. It takes a token chain as input, then a line
|
||||||
// then a column then a file id (provided by MachineDebugInfo), then a
|
// number, then a column then a file id (provided by MachineDebugInfo.) It
|
||||||
// unique id (provided by MachineDebugInfo for label gen). It produces a
|
// produces a token chain as output.
|
||||||
// token chain as output.
|
|
||||||
DEBUG_LOC,
|
DEBUG_LOC,
|
||||||
|
|
||||||
|
// DEBUG_LABEL - This node is used to mark a location in the code where a
|
||||||
|
// label should be generated for use by the debug information. It takes a
|
||||||
|
// token chain as input, the a unique id (provided by MachineDebugInfo.) It
|
||||||
|
// produces a token chain as output.
|
||||||
|
DEBUG_LABEL,
|
||||||
|
|
||||||
// BUILTIN_OP_END - This must be the last enum value in this list.
|
// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||||
BUILTIN_OP_END,
|
BUILTIN_OP_END,
|
||||||
};
|
};
|
||||||
|
|
|
@ -2117,8 +2117,7 @@ SDOperand DAGCombiner::visitDEBUGLOC(SDNode *N) {
|
||||||
return DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Chain.getOperand(0),
|
return DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Chain.getOperand(0),
|
||||||
N->getOperand(1),
|
N->getOperand(1),
|
||||||
N->getOperand(2),
|
N->getOperand(2),
|
||||||
N->getOperand(3),
|
N->getOperand(3));
|
||||||
N->getOperand(4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
|
|
|
@ -619,20 +619,33 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
default: assert(0 && "This action is not supported yet!");
|
default: assert(0 && "This action is not supported yet!");
|
||||||
case TargetLowering::Expand: {
|
case TargetLowering::Expand: {
|
||||||
MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
|
MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
|
||||||
if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other) && DebugInfo) {
|
bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other);
|
||||||
|
bool useDEBUG_LABEL = TLI.isOperationLegal(ISD::DEBUG_LABEL, MVT::Other);
|
||||||
|
|
||||||
|
if (DebugInfo && (useDEBUG_LOC || useDEBUG_LABEL)) {
|
||||||
|
const std::string &FName =
|
||||||
|
cast<StringSDNode>(Node->getOperand(3))->getValue();
|
||||||
|
const std::string &DirName =
|
||||||
|
cast<StringSDNode>(Node->getOperand(4))->getValue();
|
||||||
|
unsigned SrcFile = DebugInfo->getUniqueSourceID(FName, DirName);
|
||||||
|
|
||||||
std::vector<SDOperand> Ops;
|
std::vector<SDOperand> Ops;
|
||||||
Ops.push_back(Tmp1); // chain
|
Ops.push_back(Tmp1); // chain
|
||||||
Ops.push_back(Node->getOperand(1)); // line #
|
SDOperand LineOp = Node->getOperand(1);
|
||||||
Ops.push_back(Node->getOperand(2)); // col #
|
SDOperand ColOp = Node->getOperand(2);
|
||||||
const std::string &fname =
|
|
||||||
cast<StringSDNode>(Node->getOperand(3))->getValue();
|
if (useDEBUG_LOC) {
|
||||||
const std::string &dirname =
|
Ops.push_back(LineOp); // line #
|
||||||
cast<StringSDNode>(Node->getOperand(4))->getValue();
|
Ops.push_back(ColOp); // col #
|
||||||
unsigned srcfile = DebugInfo->getUniqueSourceID(fname, dirname);
|
Ops.push_back(DAG.getConstant(SrcFile, MVT::i32)); // source file id
|
||||||
Ops.push_back(DAG.getConstant(srcfile, MVT::i32)); // source file id
|
Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops);
|
||||||
unsigned id = DebugInfo->getNextUniqueID();
|
} else {
|
||||||
Ops.push_back(DAG.getConstant(id, MVT::i32)); // label id
|
unsigned Line = dyn_cast<ConstantSDNode>(LineOp)->getValue();
|
||||||
Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops);
|
unsigned Col = dyn_cast<ConstantSDNode>(ColOp)->getValue();
|
||||||
|
unsigned ID = DebugInfo->RecordLabel(Line, Col, SrcFile);
|
||||||
|
Ops.push_back(DAG.getConstant(ID, MVT::i32));
|
||||||
|
Result = DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, Ops);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Result = Tmp1; // chain
|
Result = Tmp1; // chain
|
||||||
}
|
}
|
||||||
|
@ -661,27 +674,40 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::DEBUG_LOC:
|
case ISD::DEBUG_LOC:
|
||||||
assert(Node->getNumOperands() == 5 && "Invalid DEBUG_LOC node!");
|
assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!");
|
||||||
switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) {
|
switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) {
|
||||||
case TargetLowering::Promote:
|
case TargetLowering::Promote:
|
||||||
case TargetLowering::Expand:
|
case TargetLowering::Expand:
|
||||||
default: assert(0 && "This action is not supported yet!");
|
default: assert(0 && "This action is not supported yet!");
|
||||||
case TargetLowering::Legal: {
|
case TargetLowering::Legal:
|
||||||
SDOperand Tmp5;
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #.
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the line #.
|
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #.
|
||||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the col #.
|
Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id.
|
||||||
Tmp4 = LegalizeOp(Node->getOperand(3)); // Legalize the source file id.
|
|
||||||
Tmp5 = LegalizeOp(Node->getOperand(4)); // Legalize the label id.
|
if (Tmp1 != Node->getOperand(0) ||
|
||||||
|
Tmp2 != Node->getOperand(1) ||
|
||||||
if (Tmp1 != Node->getOperand(0) ||
|
Tmp3 != Node->getOperand(2) ||
|
||||||
Tmp2 != Node->getOperand(1) ||
|
Tmp4 != Node->getOperand(3)) {
|
||||||
Tmp3 != Node->getOperand(2) ||
|
Result = DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4);
|
||||||
Tmp4 != Node->getOperand(3) ||
|
}
|
||||||
Tmp5 != Node->getOperand(4)) {
|
break;
|
||||||
Result =
|
}
|
||||||
DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5);
|
break;
|
||||||
}
|
|
||||||
|
case ISD::DEBUG_LABEL:
|
||||||
|
assert(Node->getNumOperands() == 2 && "Invalid DEBUG_LABEL node!");
|
||||||
|
switch (TLI.getOperationAction(ISD::DEBUG_LABEL, MVT::Other)) {
|
||||||
|
case TargetLowering::Promote:
|
||||||
|
case TargetLowering::Expand:
|
||||||
|
default: assert(0 && "This action is not supported yet!");
|
||||||
|
case TargetLowering::Legal:
|
||||||
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||||
|
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the label id.
|
||||||
|
|
||||||
|
if (Tmp1 != Node->getOperand(0) ||
|
||||||
|
Tmp2 != Node->getOperand(1)) {
|
||||||
|
Result = DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, Tmp1, Tmp2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2005,6 +2005,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
||||||
// Debug info
|
// Debug info
|
||||||
case ISD::LOCATION: return "location";
|
case ISD::LOCATION: return "location";
|
||||||
case ISD::DEBUG_LOC: return "debug_loc";
|
case ISD::DEBUG_LOC: return "debug_loc";
|
||||||
|
case ISD::DEBUG_LABEL: return "debug_label";
|
||||||
|
|
||||||
case ISD::CONDCODE:
|
case ISD::CONDCODE:
|
||||||
switch (cast<CondCodeSDNode>(this)->get()) {
|
switch (cast<CondCodeSDNode>(this)->get()) {
|
||||||
|
|
|
@ -103,7 +103,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||||
|
|
||||||
// We don't have line number support yet.
|
// We don't have line number support yet.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
|
||||||
|
|
||||||
// We want to legalize GlobalAddress and ConstantPool and
|
// We want to legalize GlobalAddress and ConstantPool and
|
||||||
// ExternalSymbols nodes into the appropriate instructions to
|
// ExternalSymbols nodes into the appropriate instructions to
|
||||||
|
|
|
@ -74,7 +74,6 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
|
||||||
|
|
||||||
// We don't have line number support yet.
|
// We don't have line number support yet.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
|
||||||
|
|
||||||
//IA64 has these, but they are not implemented
|
//IA64 has these, but they are not implemented
|
||||||
setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
|
setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
|
||||||
|
|
|
@ -102,7 +102,6 @@ namespace {
|
||||||
|
|
||||||
// We don't have line number support yet.
|
// We don't have line number support yet.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
|
||||||
|
|
||||||
computeRegisterProperties();
|
computeRegisterProperties();
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,9 @@ namespace {
|
||||||
bool doFinalization(Module &M);
|
bool doFinalization(Module &M);
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.setPreservesAll();
|
||||||
AU.addRequired<MachineDebugInfo>();
|
AU.addRequired<MachineDebugInfo>();
|
||||||
|
PPCAsmPrinter::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -418,6 +420,9 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||||
/// method to print assembly for each instruction.
|
/// method to print assembly for each instruction.
|
||||||
///
|
///
|
||||||
bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
|
// FIXME - is this the earliest this can be set.
|
||||||
|
DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
|
||||||
|
|
||||||
SetupMachineFunction(MF);
|
SetupMachineFunction(MF);
|
||||||
O << "\n\n";
|
O << "\n\n";
|
||||||
|
|
||||||
|
@ -486,7 +491,6 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
|
||||||
Mang->setUseQuotes(true);
|
Mang->setUseQuotes(true);
|
||||||
|
|
||||||
// Emit initial debug information.
|
// Emit initial debug information.
|
||||||
DW.SetDebugInfo(getAnalysisToUpdate<MachineDebugInfo>());
|
|
||||||
DW.BeginModule();
|
DW.BeginModule();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,11 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||||
// PowerPC does not have truncstore for i1.
|
// PowerPC does not have truncstore for i1.
|
||||||
setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
|
setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
|
||||||
|
|
||||||
// PowerPC doesn't have line number support yet.
|
// Support label based line numbers.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
|
// FIXME - use subtarget debug flags
|
||||||
|
if (TM.getSubtarget<PPCSubtarget>().isDarwin())
|
||||||
|
setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
|
||||||
|
|
||||||
// We want to legalize GlobalAddress and ConstantPool nodes into the
|
// We want to legalize GlobalAddress and ConstantPool nodes into the
|
||||||
// appropriate instructions to materialize the address.
|
// appropriate instructions to materialize the address.
|
||||||
|
|
|
@ -955,11 +955,14 @@ def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD),
|
||||||
// DWARF Pseudo Instructions
|
// DWARF Pseudo Instructions
|
||||||
//
|
//
|
||||||
|
|
||||||
def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file,
|
def DWARF_LOC : Pseudo<(ops i32imm:$line, i32imm:$col, i32imm:$file),
|
||||||
i32imm:$id),
|
"; .loc $file, $line, $col",
|
||||||
"; .loc $file, $line, $col\nLdebug_loc$id:",
|
|
||||||
[(dwarf_loc (i32 imm:$line), (i32 imm:$col),
|
[(dwarf_loc (i32 imm:$line), (i32 imm:$col),
|
||||||
(i32 imm:$file), (i32 imm:$id))]>;
|
(i32 imm:$file))]>;
|
||||||
|
|
||||||
|
def DWARF_LABEL : Pseudo<(ops i32imm:$id),
|
||||||
|
"\nLdebug_loc$id:",
|
||||||
|
[(dwarf_label (i32 imm:$id))]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PowerPC Instruction Patterns
|
// PowerPC Instruction Patterns
|
||||||
|
|
|
@ -153,7 +153,6 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||||
|
|
||||||
// We don't have line number support yet.
|
// We don't have line number support yet.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
|
||||||
|
|
||||||
computeRegisterProperties();
|
computeRegisterProperties();
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,9 +440,12 @@ class ComplexPattern<ValueType ty, int numops, string fn, list<SDNode> roots = [
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Dwarf support.
|
// Dwarf support.
|
||||||
//
|
//
|
||||||
def SDT_dwarf_loc : SDTypeProfile<0, 4,
|
def SDT_dwarf_loc : SDTypeProfile<0, 3,
|
||||||
[SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>, SDTCisInt<3>]>;
|
[SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
|
||||||
def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
|
def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
|
||||||
|
|
||||||
|
def SDT_dwarf_label : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
||||||
|
def dwarf_label : SDNode<"ISD::DEBUG_LABEL", SDT_dwarf_label,[SDNPHasChain]>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||||
|
|
||||||
// We don't have line number support yet.
|
// We don't have line number support yet.
|
||||||
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
setOperationAction(ISD::LOCATION, MVT::Other, Expand);
|
||||||
setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
|
|
||||||
|
|
||||||
if (X86ScalarSSE) {
|
if (X86ScalarSSE) {
|
||||||
// Set up the FP register classes.
|
// Set up the FP register classes.
|
||||||
|
|
Loading…
Reference in New Issue