From 304877e5ecec06fad0a8063566c2b6d6aaf6094d Mon Sep 17 00:00:00 2001 From: Bjorn Pettersson Date: Thu, 3 May 2018 17:04:16 +0000 Subject: Reapply "[SelectionDAG] Selection of DBG_VALUE using a PHI node result (pt 2)" Summary: This reverts SVN r331441 (reapplies r331337), together with a fix in to handle an already existing fragment expression in the dbg.value that must be fragmented due to a split PHI node. This should solve the problem seen in PR37321, which was the reason for the revert of r331337. The situation in PR37321 is that we have a PHI node like this %u.sroa = phi i80 [ %u.sroa.x, %if.x ], [ %u.sroa.y, %if.y ], [ %u.sroa.z, %if.z ] and a dbg.value like this call void @llvm.dbg.value(metadata i80 %u.sroa, metadata !13, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)) The phi node is split into three 32-bit PHI nodes %30:gr32 = PHI %11:gr32, %bb.4, %14:gr32, %bb.5, %27:gr32, %bb.8 %31:gr32 = PHI %12:gr32, %bb.4, %15:gr32, %bb.5, %28:gr32, %bb.8 %32:gr32 = PHI %13:gr32, %bb.4, %16:gr32, %bb.5, %29:gr32, %bb.8 but since the original value only is 80 bits we need to adjust the size of the last fragment expression, and with this patch we get DBG_VALUE debug-use %30:gr32, debug-use $noreg, !"u", !DIExpression(DW_OP_LLVM_fragment, 0, 32) DBG_VALUE debug-use %31:gr32, debug-use $noreg, !"u", !DIExpression(DW_OP_LLVM_fragment, 32, 32) DBG_VALUE debug-use %32:gr32, debug-use $noreg, !"u", !DIExpression(DW_OP_LLVM_fragment, 64, 16) Reviewers: vsk, aprantl, mstorsjo Reviewed By: aprantl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D46384 llvm-svn: 331464 --- .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 48 +++++++++++++++++++--- .../lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 5 +++ 2 files changed, 47 insertions(+), 6 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 58d323a3e5f..59a1d6e9753 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5257,12 +5257,48 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { // PHI nodes have already been selected, so we should know which VReg that // is assigns to already. if (isa(V)) { - auto It = FuncInfo.ValueMap.find(V); - if (It != FuncInfo.ValueMap.end()) { - unsigned Reg = It->second; - SDV = DAG.getVRegDbgValue(Variable, Expression, Reg, false, dl, - SDNodeOrder); - DAG.AddDbgValue(SDV, nullptr, false); + auto VMI = FuncInfo.ValueMap.find(V); + if (VMI != FuncInfo.ValueMap.end()) { + unsigned Reg = VMI->second; + // The PHI node may be split up into several MI PHI nodes (in + // FunctionLoweringInfo::set). + RegsForValue RFV(V->getContext(), TLI, DAG.getDataLayout(), Reg, + V->getType(), false); + if (RFV.occupiesMultipleRegs()) { + unsigned I = 0; + unsigned Offset = 0; + unsigned BitsToDescribe = 0; + if (auto VarSize = Variable->getSizeInBits()) + BitsToDescribe = *VarSize; + if (auto Fragment = Expression->getFragmentInfo()) + BitsToDescribe = Fragment->SizeInBits; + for (auto CountAndVT : zip_first(RFV.RegCount, RFV.RegVTs)) { + unsigned RegCount = std::get<0>(CountAndVT); + MVT RegisterVT = std::get<1>(CountAndVT); + unsigned RegisterSize = RegisterVT.getSizeInBits(); + for (unsigned E = I + RegCount; I != E; ++I) { + // Bail out if all bits already are described. + if (Offset >= BitsToDescribe) + break; + unsigned FragmentSize = (Offset + RegisterSize > BitsToDescribe) + ? BitsToDescribe - Offset + : RegisterSize; + auto FragmentExpr = DIExpression::createFragmentExpression( + Expression, Offset, FragmentSize); + if (!FragmentExpr) + continue; + // The vregs are guaranteed to be allocated in sequence. + SDV = DAG.getVRegDbgValue(Variable, *FragmentExpr, Reg + I, + false, dl, SDNodeOrder); + DAG.AddDbgValue(SDV, nullptr, false); + Offset += RegisterSize; + } + } + } else { + SDV = DAG.getVRegDbgValue(Variable, Expression, Reg, false, dl, + SDNodeOrder); + DAG.AddDbgValue(SDV, nullptr, false); + } return nullptr; } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index af094e4ab1c..7ed61c64bf5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -1048,6 +1048,11 @@ struct RegsForValue { void AddInlineAsmOperands(unsigned Kind, bool HasMatching, unsigned MatchingIdx, const SDLoc &dl, SelectionDAG &DAG, std::vector &Ops) const; + + /// Check if the total RegCount is greater than one. + bool occupiesMultipleRegs() const { + return std::accumulate(RegCount.begin(), RegCount.end(), 0) > 1; + } }; } // end namespace llvm -- cgit v1.2.3