aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-11 00:39:41 +0000
committerChris Lattner <sabre@nondot.org>2006-11-11 00:39:41 +0000
commit448f219fedf4f2d119599952b6229f11ed11b035 (patch)
treed1f3ffacc88e808d6302723b98fa7158dd2f924c /lib/CodeGen
parentab4b7b4e5291a79f2e621fbab4f01c5a2704c51b (diff)
downloadexternal_llvm-448f219fedf4f2d119599952b6229f11ed11b035.zip
external_llvm-448f219fedf4f2d119599952b6229f11ed11b035.tar.gz
external_llvm-448f219fedf4f2d119599952b6229f11ed11b035.tar.bz2
move big chunks of code out-of-line, no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31658 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp476
1 files changed, 241 insertions, 235 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b91d946..c7da77c 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -178,241 +178,10 @@ namespace {
return true;
}
- /// CombineToPreIndexedLoadStore - Try turning a load / store and a
- /// pre-indexed load / store when the base pointer is a add or subtract
- /// and it has other uses besides the load / store. After the
- /// transformation, the new indexed load / store has effectively folded
- /// the add / subtract in and all of its other uses are redirected to the
- /// new load / store.
- bool CombineToPreIndexedLoadStore(SDNode *N) {
- if (!AfterLegalize)
- return false;
-
- bool isLoad = true;
- SDOperand Ptr;
- MVT::ValueType VT;
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
- VT = LD->getLoadedVT();
- if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
- !TLI.isIndexedLoadLegal(ISD::PRE_DEC, VT))
- return false;
- Ptr = LD->getBasePtr();
- } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- VT = ST->getStoredVT();
- if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
- !TLI.isIndexedStoreLegal(ISD::PRE_DEC, VT))
- return false;
- Ptr = ST->getBasePtr();
- isLoad = false;
- } else
- return false;
-
- if ((Ptr.getOpcode() == ISD::ADD || Ptr.getOpcode() == ISD::SUB) &&
- Ptr.Val->use_size() > 1) {
- SDOperand BasePtr;
- SDOperand Offset;
- ISD::MemIndexedMode AM = ISD::UNINDEXED;
- if (TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG)) {
- // Try turning it into a pre-indexed load / store except when
- // 1) If N is a store and the ptr is either the same as or is a
- // predecessor of the value being stored.
- // 2) Another use of base ptr is a predecessor of N. If ptr is folded
- // that would create a cycle.
- // 3) All uses are load / store ops that use it as base ptr.
-
- // Checking #1.
- if (!isLoad) {
- SDOperand Val = cast<StoreSDNode>(N)->getValue();
- if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
- return false;
- }
-
- // Now check for #2 and #3.
- bool RealUse = false;
- for (SDNode::use_iterator I = Ptr.Val->use_begin(),
- E = Ptr.Val->use_end(); I != E; ++I) {
- SDNode *Use = *I;
- if (Use == N)
- continue;
- if (Use->isPredecessor(N))
- return false;
-
- if (!((Use->getOpcode() == ISD::LOAD &&
- cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
- (Use->getOpcode() == ISD::STORE) &&
- cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
- RealUse = true;
- }
- if (!RealUse)
- return false;
-
- SDOperand Result = isLoad
- ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
- : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
- ++PreIndexedNodes;
- ++NodesCombined;
- DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
- std::cerr << "\nWith: "; Result.Val->dump(&DAG);
- std::cerr << '\n');
- std::vector<SDNode*> NowDead;
- if (isLoad) {
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
- NowDead);
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
- NowDead);
- } else {
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
- NowDead);
- }
-
- // Nodes can end up on the worklist more than once. Make sure we do
- // not process a node that has been replaced.
- for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
- removeFromWorkList(NowDead[i]);
- // Finally, since the node is now dead, remove it from the graph.
- DAG.DeleteNode(N);
-
- // Replace the uses of Ptr with uses of the updated base value.
- DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
- NowDead);
- removeFromWorkList(Ptr.Val);
- for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
- removeFromWorkList(NowDead[i]);
- DAG.DeleteNode(Ptr.Val);
-
- return true;
- }
- }
- return false;
- }
-
- /// CombineToPostIndexedLoadStore - Try combine a load / store with a
- /// add / sub of the base pointer node into a post-indexed load / store.
- /// The transformation folded the add / subtract into the new indexed
- /// load / store effectively and all of its uses are redirected to the
- /// new load / store.
- bool CombineToPostIndexedLoadStore(SDNode *N) {
- if (!AfterLegalize)
- return false;
-
- bool isLoad = true;
- SDOperand Ptr;
- MVT::ValueType VT;
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
- VT = LD->getLoadedVT();
- if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
- !TLI.isIndexedLoadLegal(ISD::POST_DEC, VT))
- return false;
- Ptr = LD->getBasePtr();
- } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- VT = ST->getStoredVT();
- if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
- !TLI.isIndexedStoreLegal(ISD::POST_DEC, VT))
- return false;
- Ptr = ST->getBasePtr();
- isLoad = false;
- } else
- return false;
-
- if (Ptr.Val->use_size() > 1) {
- for (SDNode::use_iterator I = Ptr.Val->use_begin(),
- E = Ptr.Val->use_end(); I != E; ++I) {
- SDNode *Op = *I;
- if (Op == N ||
- (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
- continue;
-
- SDOperand BasePtr;
- SDOperand Offset;
- ISD::MemIndexedMode AM = ISD::UNINDEXED;
- if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
- if (Ptr == Offset)
- std::swap(BasePtr, Offset);
- if (Ptr != BasePtr)
- continue;
-
- // Try turning it into a post-indexed load / store except when
- // 1) All uses are load / store ops that use it as base ptr.
- // 2) Op must be independent of N, i.e. Op is neither a predecessor
- // nor a successor of N. Otherwise, if Op is folded that would
- // create a cycle.
-
- // Check for #1.
- bool TryNext = false;
- for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
- EE = BasePtr.Val->use_end(); II != EE; ++II) {
- SDNode *Use = *II;
- if (Use == Ptr.Val)
- continue;
-
- // If all the uses are load / store addresses, then don't do the
- // transformation.
- if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
- bool RealUse = false;
- for (SDNode::use_iterator III = Use->use_begin(),
- EEE = Use->use_end(); III != EEE; ++III) {
- SDNode *UseUse = *III;
- if (!((UseUse->getOpcode() == ISD::LOAD &&
- cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
- (UseUse->getOpcode() == ISD::STORE) &&
- cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
- RealUse = true;
- }
-
- if (!RealUse) {
- TryNext = true;
- break;
- }
- }
- }
- if (TryNext)
- continue;
-
- // Check for #2
- if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
- SDOperand Result = isLoad
- ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
- : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
- ++PostIndexedNodes;
- ++NodesCombined;
- DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
- std::cerr << "\nWith: "; Result.Val->dump(&DAG);
- std::cerr << '\n');
- std::vector<SDNode*> NowDead;
- if (isLoad) {
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
- NowDead);
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
- NowDead);
- } else {
- DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
- NowDead);
- }
-
- // Nodes can end up on the worklist more than once. Make sure we do
- // not process a node that has been replaced.
- for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
- removeFromWorkList(NowDead[i]);
- // Finally, since the node is now dead, remove it from the graph.
- DAG.DeleteNode(N);
-
- // Replace the uses of Use with uses of the updated base value.
- DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
- Result.getValue(isLoad ? 1 : 0),
- NowDead);
- removeFromWorkList(Op);
- for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
- removeFromWorkList(NowDead[i]);
- DAG.DeleteNode(Op);
-
- return true;
- }
- }
- }
- }
- return false;
- }
-
+ bool CombineToPreIndexedLoadStore(SDNode *N);
+ bool CombineToPostIndexedLoadStore(SDNode *N);
+
+
/// visit - call the node-specific routine that knows how to fold each
/// particular type of node.
SDOperand visit(SDNode *N);
@@ -2938,6 +2707,243 @@ SDOperand DAGCombiner::visitBR_CC(SDNode *N) {
return SDOperand();
}
+
+/// CombineToPreIndexedLoadStore - Try turning a load / store and a
+/// pre-indexed load / store when the base pointer is a add or subtract
+/// and it has other uses besides the load / store. After the
+/// transformation, the new indexed load / store has effectively folded
+/// the add / subtract in and all of its other uses are redirected to the
+/// new load / store.
+bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
+ if (!AfterLegalize)
+ return false;
+
+ bool isLoad = true;
+ SDOperand Ptr;
+ MVT::ValueType VT;
+ if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+ VT = LD->getLoadedVT();
+ if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
+ !TLI.isIndexedLoadLegal(ISD::PRE_DEC, VT))
+ return false;
+ Ptr = LD->getBasePtr();
+ } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+ VT = ST->getStoredVT();
+ if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
+ !TLI.isIndexedStoreLegal(ISD::PRE_DEC, VT))
+ return false;
+ Ptr = ST->getBasePtr();
+ isLoad = false;
+ } else
+ return false;
+
+ if ((Ptr.getOpcode() == ISD::ADD || Ptr.getOpcode() == ISD::SUB) &&
+ Ptr.Val->use_size() > 1) {
+ SDOperand BasePtr;
+ SDOperand Offset;
+ ISD::MemIndexedMode AM = ISD::UNINDEXED;
+ if (TLI.getPreIndexedAddressParts(N, BasePtr, Offset, AM, DAG)) {
+ // Try turning it into a pre-indexed load / store except when
+ // 1) If N is a store and the ptr is either the same as or is a
+ // predecessor of the value being stored.
+ // 2) Another use of base ptr is a predecessor of N. If ptr is folded
+ // that would create a cycle.
+ // 3) All uses are load / store ops that use it as base ptr.
+
+ // Checking #1.
+ if (!isLoad) {
+ SDOperand Val = cast<StoreSDNode>(N)->getValue();
+ if (Val == Ptr || Ptr.Val->isPredecessor(Val.Val))
+ return false;
+ }
+
+ // Now check for #2 and #3.
+ bool RealUse = false;
+ for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+ E = Ptr.Val->use_end(); I != E; ++I) {
+ SDNode *Use = *I;
+ if (Use == N)
+ continue;
+ if (Use->isPredecessor(N))
+ return false;
+
+ if (!((Use->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(Use)->getBasePtr() == Ptr) ||
+ (Use->getOpcode() == ISD::STORE) &&
+ cast<StoreSDNode>(Use)->getBasePtr() == Ptr))
+ RealUse = true;
+ }
+ if (!RealUse)
+ return false;
+
+ SDOperand Result = isLoad
+ ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
+ : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+ ++PreIndexedNodes;
+ ++NodesCombined;
+ DEBUG(std::cerr << "\nReplacing.4 "; N->dump();
+ std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+ std::cerr << '\n');
+ std::vector<SDNode*> NowDead;
+ if (isLoad) {
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
+ NowDead);
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+ NowDead);
+ } else {
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+ NowDead);
+ }
+
+ // Nodes can end up on the worklist more than once. Make sure we do
+ // not process a node that has been replaced.
+ for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+ removeFromWorkList(NowDead[i]);
+ // Finally, since the node is now dead, remove it from the graph.
+ DAG.DeleteNode(N);
+
+ // Replace the uses of Ptr with uses of the updated base value.
+ DAG.ReplaceAllUsesOfValueWith(Ptr, Result.getValue(isLoad ? 1 : 0),
+ NowDead);
+ removeFromWorkList(Ptr.Val);
+ for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+ removeFromWorkList(NowDead[i]);
+ DAG.DeleteNode(Ptr.Val);
+
+ return true;
+ }
+ }
+ return false;
+}
+
+/// CombineToPostIndexedLoadStore - Try combine a load / store with a
+/// add / sub of the base pointer node into a post-indexed load / store.
+/// The transformation folded the add / subtract into the new indexed
+/// load / store effectively and all of its uses are redirected to the
+/// new load / store.
+bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
+ if (!AfterLegalize)
+ return false;
+
+ bool isLoad = true;
+ SDOperand Ptr;
+ MVT::ValueType VT;
+ if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+ VT = LD->getLoadedVT();
+ if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
+ !TLI.isIndexedLoadLegal(ISD::POST_DEC, VT))
+ return false;
+ Ptr = LD->getBasePtr();
+ } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+ VT = ST->getStoredVT();
+ if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
+ !TLI.isIndexedStoreLegal(ISD::POST_DEC, VT))
+ return false;
+ Ptr = ST->getBasePtr();
+ isLoad = false;
+ } else
+ return false;
+
+ if (Ptr.Val->use_size() > 1) {
+ for (SDNode::use_iterator I = Ptr.Val->use_begin(),
+ E = Ptr.Val->use_end(); I != E; ++I) {
+ SDNode *Op = *I;
+ if (Op == N ||
+ (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
+ continue;
+
+ SDOperand BasePtr;
+ SDOperand Offset;
+ ISD::MemIndexedMode AM = ISD::UNINDEXED;
+ if (TLI.getPostIndexedAddressParts(N, Op, BasePtr, Offset, AM, DAG)) {
+ if (Ptr == Offset)
+ std::swap(BasePtr, Offset);
+ if (Ptr != BasePtr)
+ continue;
+
+ // Try turning it into a post-indexed load / store except when
+ // 1) All uses are load / store ops that use it as base ptr.
+ // 2) Op must be independent of N, i.e. Op is neither a predecessor
+ // nor a successor of N. Otherwise, if Op is folded that would
+ // create a cycle.
+
+ // Check for #1.
+ bool TryNext = false;
+ for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
+ EE = BasePtr.Val->use_end(); II != EE; ++II) {
+ SDNode *Use = *II;
+ if (Use == Ptr.Val)
+ continue;
+
+ // If all the uses are load / store addresses, then don't do the
+ // transformation.
+ if (Use->getOpcode() == ISD::ADD || Use->getOpcode() == ISD::SUB){
+ bool RealUse = false;
+ for (SDNode::use_iterator III = Use->use_begin(),
+ EEE = Use->use_end(); III != EEE; ++III) {
+ SDNode *UseUse = *III;
+ if (!((UseUse->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
+ (UseUse->getOpcode() == ISD::STORE) &&
+ cast<StoreSDNode>(UseUse)->getBasePtr().Val == Use))
+ RealUse = true;
+ }
+
+ if (!RealUse) {
+ TryNext = true;
+ break;
+ }
+ }
+ }
+ if (TryNext)
+ continue;
+
+ // Check for #2
+ if (!Op->isPredecessor(N) && !N->isPredecessor(Op)) {
+ SDOperand Result = isLoad
+ ? DAG.getIndexedLoad(SDOperand(N,0), BasePtr, Offset, AM)
+ : DAG.getIndexedStore(SDOperand(N,0), BasePtr, Offset, AM);
+ ++PostIndexedNodes;
+ ++NodesCombined;
+ DEBUG(std::cerr << "\nReplacing.5 "; N->dump();
+ std::cerr << "\nWith: "; Result.Val->dump(&DAG);
+ std::cerr << '\n');
+ std::vector<SDNode*> NowDead;
+ if (isLoad) {
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(0),
+ NowDead);
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 1), Result.getValue(2),
+ NowDead);
+ } else {
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(N, 0), Result.getValue(1),
+ NowDead);
+ }
+
+ // Nodes can end up on the worklist more than once. Make sure we do
+ // not process a node that has been replaced.
+ for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+ removeFromWorkList(NowDead[i]);
+ // Finally, since the node is now dead, remove it from the graph.
+ DAG.DeleteNode(N);
+
+ // Replace the uses of Use with uses of the updated base value.
+ DAG.ReplaceAllUsesOfValueWith(SDOperand(Op, 0),
+ Result.getValue(isLoad ? 1 : 0),
+ NowDead);
+ removeFromWorkList(Op);
+ for (unsigned i = 0, e = NowDead.size(); i != e; ++i)
+ removeFromWorkList(NowDead[i]);
+ DAG.DeleteNode(Op);
+
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
SDOperand DAGCombiner::visitLOAD(SDNode *N) {
LoadSDNode *LD = cast<LoadSDNode>(N);
SDOperand Chain = LD->getChain();