diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 458e865a6b3..ac4e7091052 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -701,6 +701,7 @@ void SelectionDAGBuilder::clear() { UnusedArgNodeMap.clear(); PendingLoads.clear(); PendingExports.clear(); + DanglingDebugInfoMap.clear(); CurDebugLoc = DebugLoc(); HasTailCall = false; } @@ -805,6 +806,33 @@ void SelectionDAGBuilder::visit(unsigned Opcode, const User &I) { } } +// resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V, +// generate the debug data structures now that we've seen its definition. +void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, + SDValue Val) { + DanglingDebugInfo &DDI = DanglingDebugInfoMap[V]; + if (DDI.getDI()) { + const DbgValueInst *DI = DDI.getDI(); + DebugLoc dl = DDI.getdl(); + unsigned DbgSDNodeOrder = DDI.getSDNodeOrder(); + MDNode *Variable = DI->getVariable(); + uint64_t Offset = DI->getOffset(); + SDDbgValue *SDV; + if (Val.getNode()) { + if (!EmitFuncArgumentDbgValue(*DI, V, Variable, Offset, Val)) { + SDV = DAG.getDbgValue(Variable, Val.getNode(), + Val.getResNo(), Offset, dl, DbgSDNodeOrder); + DAG.AddDbgValue(SDV, Val.getNode(), false); + } + } else { + SDV = DAG.getDbgValue(Variable, UndefValue::get(V->getType()), + Offset, dl, SDNodeOrder); + DAG.AddDbgValue(SDV, 0, false); + } + DanglingDebugInfoMap[V] = DanglingDebugInfo(); + } +} + // getValue - Return an SDValue for the given Value. SDValue SelectionDAGBuilder::getValue(const Value *V) { // If we already have an SDValue for this value, use it. It's important @@ -826,6 +854,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { // Otherwise create a new SDValue and remember it. SDValue Val = getValueImpl(V); NodeMap[V] = Val; + resolveDanglingDebugInfo(V, Val); return Val; } @@ -839,10 +868,11 @@ SDValue SelectionDAGBuilder::getNonRegisterValue(const Value *V) { // Otherwise create a new SDValue and remember it. SDValue Val = getValueImpl(V); NodeMap[V] = Val; + resolveDanglingDebugInfo(V, Val); return Val; } -/// getValueImpl - Helper function for getValue and getMaterializedValue. +/// getValueImpl - Helper function for getValue and getNonRegisterValue. /// Create an SDValue for the given value. SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { if (const Constant *C = dyn_cast(V)) { @@ -4049,7 +4079,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { DAG.AddDbgValue(SDV, 0, false); } else { bool createUndef = false; - // FIXME : Why not use getValue() directly ? + // Do not use getValue() in here; we don't want to generate code at + // this point if it hasn't been done yet. SDValue N = NodeMap[V]; if (!N.getNode() && isa(V)) // Check unused arguments map. @@ -4060,16 +4091,11 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { N.getResNo(), Offset, dl, SDNodeOrder); DAG.AddDbgValue(SDV, N.getNode(), false); } - } else if (isa(V) && !V->use_empty()) { - SDValue N = getValue(V); - if (N.getNode()) { - if (!EmitFuncArgumentDbgValue(DI, V, Variable, Offset, N)) { - SDV = DAG.getDbgValue(Variable, N.getNode(), - N.getResNo(), Offset, dl, SDNodeOrder); - DAG.AddDbgValue(SDV, N.getNode(), false); - } - } else - createUndef = true; + } else if (isa(V) && !V->use_empty() ) { + // Do not call getValue(V) yet, as we don't want to generate code. + // Remember it for later. + DanglingDebugInfo DDI(&DI, dl, SDNodeOrder); + DanglingDebugInfoMap[V] = DDI; } else createUndef = true; if (createUndef) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 46733d6db12..bc3fd62c3f2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -64,6 +64,7 @@ class PHINode; class PtrToIntInst; class ReturnInst; class SDISelAsmOperandInfo; +class SDDbgValue; class SExtInst; class SelectInst; class ShuffleVectorInst; @@ -93,6 +94,24 @@ class SelectionDAGBuilder { /// to preserve debug information for incoming arguments. DenseMap UnusedArgNodeMap; + /// DanglingDebugInfo - Helper type for DanglingDebugInfoMap. + class DanglingDebugInfo { + const DbgValueInst* DI; + DebugLoc dl; + unsigned SDNodeOrder; + public: + DanglingDebugInfo() : DI(0), dl(DebugLoc()), SDNodeOrder(0) { } + DanglingDebugInfo(const DbgValueInst *di, DebugLoc DL, unsigned SDNO) : + DI(di), dl(DL), SDNodeOrder(SDNO) { } + const DbgValueInst* getDI() { return DI; } + DebugLoc getdl() { return dl; } + unsigned getSDNodeOrder() { return SDNodeOrder; } + }; + + /// DanglingDebugInfoMap - Keeps track of dbg_values for which we have not + /// yet seen the referent. We defer handling these until we do see it. + DenseMap DanglingDebugInfoMap; + public: /// PendingLoads - Loads are not emitted to the program immediately. We bunch /// them up and then emit token factor nodes when possible. This allows us to @@ -345,6 +364,9 @@ public: void visit(unsigned Opcode, const User &I); + // resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V, + // generate the debug data structures now that we've seen its definition. + void resolveDanglingDebugInfo(const Value *V, SDValue Val); SDValue getValue(const Value *V); SDValue getNonRegisterValue(const Value *V); SDValue getValueImpl(const Value *V); diff --git a/test/CodeGen/Thumb/2010-07-15-debugOrdering.ll b/test/CodeGen/Thumb/2010-07-15-debugOrdering.ll new file mode 100644 index 00000000000..e9f7ad3f4e3 --- /dev/null +++ b/test/CodeGen/Thumb/2010-07-15-debugOrdering.ll @@ -0,0 +1,147 @@ +; RUN: llc -mtriple=thumbv6-apple-darwin10 %s -o - | FileCheck %s +; RUN: opt -strip-debug < %s -o - | llc -mtriple=thumbv6-apple-darwin10 %s -o - | FileCheck %s +; Stripping out debug info formerly caused the last two multiplies to be emitted in +; the other order. 7797940 (part of it dated 6/29/2010..7/15/2010). + +%0 = type { [3 x double] } + +@llvm.used = appending global [1 x i8*] [i8* bitcast (void (%0*, i32, i32)* @_Z19getClosestDiagonal3ii to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define void @_Z19getClosestDiagonal3ii(%0* noalias sret, i32, i32) nounwind { +; CHECK: blx ___muldf3 +; CHECK: blx ___muldf3 +; CHECK: beq LBB0_8 +; CHECK: blx ___muldf3 +;