summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorNirav Dave <niravd@google.com>2018-03-10 02:16:15 +0000
committerNirav Dave <niravd@google.com>2018-03-10 02:16:15 +0000
commit042678bd555dcd3231c363cbc77fee6082b0a0ba (patch)
treee26dd887af285949c0990ef1eb58103f86750aef /llvm/lib/Target
parent0b013e041ddb09e4bbb366bc0be247b39872ae0c (diff)
downloadbcm5719-llvm-042678bd555dcd3231c363cbc77fee6082b0a0ba.tar.gz
bcm5719-llvm-042678bd555dcd3231c363cbc77fee6082b0a0ba.zip
Revert: r327172 "Correct load-op-store cycle detection analysis"
r327171 "Improve Dependency analysis when doing multi-node Instruction Selection" r328170 "[DAG] Enforce stricter NodeId invariant during Instruction selection" Reverting patch as NodeId invariant change is causing pathological increases in compile time on PPC llvm-svn: 327197
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp5
-rw-r--r--llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp2
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp10
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp15
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp97
6 files changed, 52 insertions, 81 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 6a47a5ba50c..90cd4ffaf0b 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -766,11 +766,12 @@ void AMDGPUDAGToDAGISel::SelectADD_SUB_I64(SDNode *N) {
if (ProduceCarry) {
// Replace the carry-use
- ReplaceUses(SDValue(N, 1), SDValue(AddHi, 1));
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 1), SDValue(AddHi, 1));
}
// Replace the remaining uses.
- ReplaceNode(N, RegSequence);
+ CurDAG->ReplaceAllUsesWith(N, RegSequence);
+ CurDAG->RemoveDeadNode(N);
}
void AMDGPUDAGToDAGISel::SelectUADDO_USUBO(SDNode *N) {
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 0063303ac48..94fe84c8751 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -500,7 +500,7 @@ bool ARMDAGToDAGISel::canExtractShiftFromMul(const SDValue &N,
void ARMDAGToDAGISel::replaceDAGValue(const SDValue &N, SDValue M) {
CurDAG->RepositionNode(N.getNode()->getIterator(), M.getNode());
- ReplaceUses(N, M);
+ CurDAG->ReplaceAllUsesWith(N, M);
}
bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N,
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index fa992490f5d..3540cf06b9c 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -662,7 +662,7 @@ void HexagonDAGToDAGISel::SelectBitcast(SDNode *N) {
return;
}
- ReplaceUses(SDValue(N, 0), N->getOperand(0));
+ CurDAG->ReplaceAllUsesOfValueWith(SDValue(N,0), N->getOperand(0));
CurDAG->RemoveDeadNode(N);
}
@@ -726,6 +726,7 @@ void HexagonDAGToDAGISel::SelectTypecast(SDNode *N) {
SDNode *T = CurDAG->MorphNodeTo(N, N->getOpcode(),
CurDAG->getVTList(OpTy), {Op});
ReplaceNode(T, Op.getNode());
+ CurDAG->RemoveDeadNode(T);
}
void HexagonDAGToDAGISel::SelectP2D(SDNode *N) {
@@ -2184,3 +2185,4 @@ void HexagonDAGToDAGISel::rebalanceAddressTrees() {
RootHeights.clear();
RootWeights.clear();
}
+
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
index 285197a909e..46f5bb4de8a 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp
@@ -1953,6 +1953,7 @@ void HvxSelector::selectShuffle(SDNode *N) {
// If the mask is all -1's, generate "undef".
if (!UseLeft && !UseRight) {
ISel.ReplaceNode(N, ISel.selectUndef(SDLoc(SN), ResTy).getNode());
+ DAG.RemoveDeadNode(N);
return;
}
@@ -2008,6 +2009,7 @@ void HvxSelector::selectRor(SDNode *N) {
NewN = DAG.getMachineNode(Hexagon::V6_vror, dl, Ty, {VecV, RotV});
ISel.ReplaceNode(N, NewN);
+ DAG.RemoveDeadNode(N);
}
void HvxSelector::selectVAlign(SDNode *N) {
@@ -2068,7 +2070,8 @@ void HexagonDAGToDAGISel::SelectV65GatherPred(SDNode *N) {
MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
- ReplaceNode(N, Result);
+ ReplaceUses(N, Result);
+ CurDAG->RemoveDeadNode(N);
}
void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
@@ -2106,7 +2109,8 @@ void HexagonDAGToDAGISel::SelectV65Gather(SDNode *N) {
MemOp[0] = cast<MemIntrinsicSDNode>(N)->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
- ReplaceNode(N, Result);
+ ReplaceUses(N, Result);
+ CurDAG->RemoveDeadNode(N);
}
void HexagonDAGToDAGISel::SelectHVXDualOutput(SDNode *N) {
@@ -2149,3 +2153,5 @@ void HexagonDAGToDAGISel::SelectHVXDualOutput(SDNode *N) {
ReplaceUses(SDValue(N, 1), SDValue(Result, 1));
CurDAG->RemoveDeadNode(N);
}
+
+
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index 6e2130828bb..9bf2474915c 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -596,13 +596,7 @@ static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N) {
if (N.getNode()->getNodeId() == -1 ||
N.getNode()->getNodeId() > Pos->getNodeId()) {
DAG->RepositionNode(Pos->getIterator(), N.getNode());
- // Mark Node as invalid for pruning as after this it may be a successor to a
- // selected node but otherwise be in the same position of Pos.
- // Conservatively mark it with the same -abs(Id) to assure node id
- // invariant is preserved.
- int PId = Pos->getNodeId();
- int InvalidatedPId = -(PId + 1);
- N->setNodeId((PId > 0) ? InvalidatedPId : PId);
+ N.getNode()->setNodeId(Pos->getNodeId());
}
}
@@ -1033,7 +1027,8 @@ bool SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) {
};
SDValue New = convertTo(
DL, VT, SDValue(CurDAG->getMachineNode(Opcode, DL, OpcodeVT, Ops), 0));
- ReplaceNode(N, New.getNode());
+ ReplaceUses(N, New.getNode());
+ CurDAG->RemoveDeadNode(N);
return true;
}
@@ -1124,7 +1119,8 @@ void SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node,
SDValue Lower = CurDAG->getConstant(LowerVal, DL, VT);
SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower);
- ReplaceNode(Node, Or.getNode());
+ ReplaceUses(Node, Or.getNode());
+ CurDAG->RemoveDeadNode(Node);
SelectCode(Or.getNode());
}
@@ -1622,3 +1618,4 @@ void SystemZDAGToDAGISel::PreprocessISelDAG() {
if (MadeChange)
CurDAG->RemoveDeadNodes();
}
+
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index ebcd15230b9..bcac241bb3a 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2109,86 +2109,52 @@ static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode,
LoadNode->getOffset() != StoreNode->getOffset())
return false;
- bool FoundLoad = false;
- SmallVector<SDValue, 4> ChainOps;
- SmallVector<const SDNode *, 4> LoopWorklist;
- SmallPtrSet<const SDNode *, 16> Visited;
- const unsigned int Max = 1024;
-
- // Visualization of Load-Op-Store fusion:
- // -------------------------
- // Legend:
- // *-lines = Chain operand dependencies.
- // |-lines = Normal operand dependencies.
- // Dependencies flow down and right. n-suffix references multiple nodes.
- //
- // C Xn C
- // * * *
- // * * *
- // Xn A-LD Yn TF Yn
- // * * \ | * |
- // * * \ | * |
- // * * \ | => A--LD_OP_ST
- // * * \| \
- // TF OP \
- // * | \ Zn
- // * | \
- // A-ST Zn
- //
-
- // This merge induced dependences from: #1: Xn -> LD, OP, Zn
- // #2: Yn -> LD
- // #3: ST -> Zn
-
- // Ensure the transform is safe by checking for the dual
- // dependencies to make sure we do not induce a loop.
-
- // As LD is a predecessor to both OP and ST we can do this by checking:
- // a). if LD is a predecessor to a member of Xn or Yn.
- // b). if a Zn is a predecessor to ST.
-
- // However, (b) can only occur through being a chain predecessor to
- // ST, which is the same as Zn being a member or predecessor of Xn,
- // which is a subset of LD being a predecessor of Xn. So it's
- // subsumed by check (a).
-
+ // Check if the chain is produced by the load or is a TokenFactor with
+ // the load output chain as an operand. Return InputChain by reference.
SDValue Chain = StoreNode->getChain();
- // Gather X elements in ChainOps.
+ bool ChainCheck = false;
if (Chain == Load.getValue(1)) {
- FoundLoad = true;
- ChainOps.push_back(Load.getOperand(0));
+ ChainCheck = true;
+ InputChain = LoadNode->getChain();
} else if (Chain.getOpcode() == ISD::TokenFactor) {
+ SmallVector<SDValue, 4> ChainOps;
for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i) {
SDValue Op = Chain.getOperand(i);
if (Op == Load.getValue(1)) {
- FoundLoad = true;
+ ChainCheck = true;
// Drop Load, but keep its chain. No cycle check necessary.
ChainOps.push_back(Load.getOperand(0));
continue;
}
- LoopWorklist.push_back(Op.getNode());
- ChainOps.push_back(Op);
- }
- }
- if (!FoundLoad)
- return false;
+ // Make sure using Op as part of the chain would not cause a cycle here.
+ // In theory, we could check whether the chain node is a predecessor of
+ // the load. But that can be very expensive. Instead visit the uses and
+ // make sure they all have smaller node id than the load.
+ int LoadId = LoadNode->getNodeId();
+ for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
+ UE = UI->use_end(); UI != UE; ++UI) {
+ if (UI.getUse().getResNo() != 0)
+ continue;
+ if (UI->getNodeId() > LoadId)
+ return false;
+ }
- // Worklist is currently Xn. Add Yn to worklist.
- for (SDValue Op : StoredVal->ops())
- if (Op.getNode() != LoadNode)
- LoopWorklist.push_back(Op.getNode());
+ ChainOps.push_back(Op);
+ }
- // Check (a) if Load is a predecessor to Xn + Yn
- if (SDNode::hasPredecessorHelper(Load.getNode(), Visited, LoopWorklist, Max,
- true))
+ if (ChainCheck)
+ // Make a new TokenFactor with all the other input chains except
+ // for the load.
+ InputChain = CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain),
+ MVT::Other, ChainOps);
+ }
+ if (!ChainCheck)
return false;
- InputChain =
- CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ChainOps);
return true;
- }
+}
// Change a chain of {load; op; store} of the same value into a simple op
// through memory of that value, if the uses of the modified value and its
@@ -2417,8 +2383,6 @@ bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
MemOp[1] = LoadNode->getMemOperand();
Result->setMemRefs(MemOp, MemOp + 2);
- // Update Load Chain uses as well.
- ReplaceUses(SDValue(LoadNode, 1), SDValue(Result, 1));
ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
ReplaceUses(SDValue(StoredVal.getNode(), 1), SDValue(Result, 0));
CurDAG->RemoveDeadNode(Node);
@@ -3130,7 +3094,8 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
// Emit a testl or testw.
SDNode *NewNode = CurDAG->getMachineNode(Op, dl, MVT::i32, Reg, Imm);
// Replace CMP with TEST.
- ReplaceNode(Node, NewNode);
+ CurDAG->ReplaceAllUsesWith(Node, NewNode);
+ CurDAG->RemoveDeadNode(Node);
return;
}
break;
OpenPOWER on IntegriCloud