Page MenuHomePhabricator

D61181.diff
No OneTemporary

File Metadata

Created
Fri, Nov 15, 10:24 AM

D61181.diff

Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -423,6 +423,8 @@
LLVMContext *Context;
+ DenseMap<const Value *, SDValue> ExportedMap;
+
SelectionDAGBuilder(SelectionDAG &dag, FunctionLoweringInfo &funcinfo,
SwiftErrorValueTracking &swifterror, CodeGenOpt::Level ol)
: SDNodeOrder(LowestSDNodeOrder), TM(dag.getTarget()), DAG(dag),
@@ -867,7 +869,7 @@
/// updates them for the output Chain/Flag. If the Flag pointer is nullptr, no
/// flag is used. If V is not nullptr, then it is used in printing better
/// diagnostic messages on error.
- void getCopyToRegs(SDValue Val, SelectionDAG &DAG, const SDLoc &dl,
+ SDValue getCopyToRegs(SDValue Val, SelectionDAG &DAG, const SDLoc &dl,
SDValue &Chain, SDValue *Flag, const Value *V = nullptr,
ISD::NodeType PreferredExtendType = ISD::ANY_EXTEND) const;
Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -883,7 +883,7 @@
return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(ValueVTs), Values);
}
-void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
+SDValue RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
const SDLoc &dl, SDValue &Chain, SDValue *Flag,
const Value *V,
ISD::NodeType PreferredExtendType) const {
@@ -911,8 +911,8 @@
// Copy the parts into the registers.
SmallVector<SDValue, 8> Chains(NumRegs);
+ SDValue Part;
for (unsigned i = 0; i != NumRegs; ++i) {
- SDValue Part;
if (!Flag) {
Part = DAG.getCopyToReg(Chain, dl, Regs[i], Parts[i]);
} else {
@@ -937,6 +937,8 @@
Chain = Chains[NumRegs-1];
else
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
+
+ return Part;
}
void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching,
@@ -1026,6 +1028,7 @@
HasTailCall = false;
SDNodeOrder = LowestSDNodeOrder;
StatepointLowering.clear();
+ ExportedMap.clear();
}
void SelectionDAGBuilder::clearDanglingDebugInfo() {
@@ -1266,6 +1269,50 @@
<< "\n");
}
+/// Helper for handleDebugValue to deal with dbg.value intrinsics that refer
+/// to a virtual register. If the original IR type was not a primitive, the
+/// variable location may have been split over several machine vregs, meaning
+/// the dbg.value must decompose into several DBG_VALUE insts and fragment
+/// expressions.
+static void handleVRegDebugValue(const Value *V, DILocalVariable *Var,
+ DIExpression *Expr, DebugLoc dl,
+ DebugLoc InstDL, unsigned Order, unsigned Reg,
+ SDNode *Node, const TargetLowering &TLI,
+ SelectionDAG &DAG) {
+ SDDbgValue *SDV;
+ // If this is a PHI node, it may be split up into several MI PHI nodes
+ // (in FunctionLoweringInfo::set).
+ RegsForValue RFV(V->getContext(), TLI, DAG.getDataLayout(), Reg, V->getType(),
+ None);
+ if (!RFV.occupiesMultipleRegs()) {
+ // Simple case: the value resides in one virtual register.
+ SDV = DAG.getVRegDbgValue(Var, Expr, Reg, false, dl, Order);
+ DAG.AddDbgValue(SDV, Node, false);
+ return;
+ }
+
+ // Hard case: split variable location into multiple vregs and fragments.
+ unsigned Offset = 0;
+ unsigned BitsToDescribe = Var->getSizeInBits().getValueOr(0);
+ for (auto RegAndSize : RFV.getRegsAndSizes()) {
+ unsigned RegisterSize = RegAndSize.second;
+ // Bail out if all bits are described already.
+ if (Offset >= BitsToDescribe)
+ break;
+ unsigned FragmentSize = (Offset + RegisterSize > BitsToDescribe)
+ ? BitsToDescribe - Offset
+ : RegisterSize;
+ auto FragmentExpr =
+ DIExpression::createFragmentExpression(Expr, Offset, FragmentSize);
+ if (!FragmentExpr)
+ continue;
+ SDV = DAG.getVRegDbgValue(Var, *FragmentExpr, RegAndSize.first, false, dl,
+ Order);
+ DAG.AddDbgValue(SDV, Node, false);
+ Offset += RegisterSize;
+ }
+}
+
bool SelectionDAGBuilder::handleDebugValue(const Value *V, DILocalVariable *Var,
DIExpression *Expr, DebugLoc dl,
DebugLoc InstDL, unsigned Order) {
@@ -1301,6 +1348,18 @@
if (N.getNode()) {
if (EmitFuncArgumentDbgValue(V, Var, Expr, dl, false, N))
return true;
+
+ // If this Value is exported from the current block, attach our debug
+ // record to the exporting CopyToReg, to avoid liveness issues.
+ if (ExportedMap.count(V)) {
+ SDValue &TheVal = ExportedMap.find(V)->second;
+ unsigned Reg = FuncInfo.ValueMap[V];
+
+ handleVRegDebugValue(V, Var, Expr, dl, InstDL, SDNodeOrder, Reg,
+ TheVal.getNode(), TLI, DAG);
+ return true;
+ }
+
SDV = getDbgValue(N, Var, Expr, dl, SDNodeOrder);
DAG.AddDbgValue(SDV, N.getNode(), false);
return true;
@@ -1319,38 +1378,8 @@
auto VMI = FuncInfo.ValueMap.find(V);
if (VMI != FuncInfo.ValueMap.end()) {
unsigned Reg = VMI->second;
- // If this is a PHI node, it may be split up into several MI PHI nodes
- // (in FunctionLoweringInfo::set).
- RegsForValue RFV(V->getContext(), TLI, DAG.getDataLayout(), Reg,
- V->getType(), None);
- if (RFV.occupiesMultipleRegs()) {
- unsigned Offset = 0;
- unsigned BitsToDescribe = 0;
- if (auto VarSize = Var->getSizeInBits())
- BitsToDescribe = *VarSize;
- if (auto Fragment = Expr->getFragmentInfo())
- BitsToDescribe = Fragment->SizeInBits;
- for (auto RegAndSize : RFV.getRegsAndSizes()) {
- unsigned RegisterSize = RegAndSize.second;
- // Bail out if all bits are described already.
- if (Offset >= BitsToDescribe)
- break;
- unsigned FragmentSize = (Offset + RegisterSize > BitsToDescribe)
- ? BitsToDescribe - Offset
- : RegisterSize;
- auto FragmentExpr = DIExpression::createFragmentExpression(
- Expr, Offset, FragmentSize);
- if (!FragmentExpr)
- continue;
- SDV = DAG.getVRegDbgValue(Var, *FragmentExpr, RegAndSize.first,
- false, dl, SDNodeOrder);
- DAG.AddDbgValue(SDV, nullptr, false);
- Offset += RegisterSize;
- }
- } else {
- SDV = DAG.getVRegDbgValue(Var, Expr, Reg, false, dl, SDNodeOrder);
- DAG.AddDbgValue(SDV, nullptr, false);
- }
+ handleVRegDebugValue(V, Var, Expr, dl, InstDL, SDNodeOrder, Reg, nullptr,
+ TLI, DAG);
return true;
}
}
@@ -9266,8 +9295,10 @@
FuncInfo.PreferredExtendType.end())
? ISD::ANY_EXTEND
: FuncInfo.PreferredExtendType[V];
- RFV.getCopyToRegs(Op, DAG, getCurSDLoc(), Chain, nullptr, V, ExtendType);
+ SDValue CopyNode =
+ RFV.getCopyToRegs(Op, DAG, getCurSDLoc(), Chain, nullptr, V, ExtendType);
PendingExports.push_back(Chain);
+ ExportedMap.insert(std::make_pair(V, CopyNode));
}
#include "llvm/CodeGen/SelectionDAGISel.h"

Event Timeline