summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-01-17 22:19:26 +0000
committerChris Lattner <sabre@nondot.org>2005-01-17 22:19:26 +0000
commit4d9651c76056989afffc8d6b6501211e1bfbb556 (patch)
tree20b78d983a554241915e6bae8f133c69a0919d59 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parente86c933df76aa938dd8e9078ea669c89a25fe66d (diff)
downloadbcm5719-llvm-4d9651c76056989afffc8d6b6501211e1bfbb556.tar.gz
bcm5719-llvm-4d9651c76056989afffc8d6b6501211e1bfbb556.zip
Non-volatile loads can be freely reordered against each other. This fixes
X86/reg-pressure.ll again, and allows us to do nice things in other cases. For example, we now codegen this sort of thing: int %loadload(int *%X, int* %Y) { %Z = load int* %Y %Y = load int* %X ;; load between %Z and store %Q = add int %Z, 1 store int %Q, int* %Y ret int %Y } Into this: loadload: mov %EAX, DWORD PTR [%ESP + 4] mov %EAX, DWORD PTR [%EAX] mov %ECX, DWORD PTR [%ESP + 8] inc DWORD PTR [%ECX] ret where we weren't able to form the 'inc [mem]' before. This also lets the instruction selector emit loads in any order it wants to, which can be good for register pressure as well. llvm-svn: 19644
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp42
1 files changed, 38 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1ccbdd7d0b0..87997ce7b52 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -187,6 +187,12 @@ class SelectionDAGLowering {
std::map<const Value*, SDOperand> NodeMap;
+ /// 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
+ /// get simple disambiguation between loads without worrying about alias
+ /// analysis.
+ std::vector<SDOperand> PendingLoads;
+
public:
// TLI - This is information that describes the available target features we
// need for lowering. This indicates when operations are unavailable,
@@ -208,7 +214,21 @@ public:
/// getRoot - Return the current virtual root of the Selection DAG.
///
SDOperand getRoot() {
- return DAG.getRoot();
+ if (PendingLoads.empty())
+ return DAG.getRoot();
+
+ if (PendingLoads.size() == 1) {
+ SDOperand Root = PendingLoads[0];
+ DAG.setRoot(Root);
+ PendingLoads.clear();
+ return Root;
+ }
+
+ // Otherwise, we have to make a token factor node.
+ SDOperand Root = DAG.getNode(ISD::TokenFactor, MVT::Other, PendingLoads);
+ PendingLoads.clear();
+ DAG.setRoot(Root);
+ return Root;
}
void visit(Instruction &I) { visit(I.getOpcode(), I); }
@@ -590,8 +610,22 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
void SelectionDAGLowering::visitLoad(LoadInst &I) {
SDOperand Ptr = getValue(I.getOperand(0));
- SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), getRoot(), Ptr);
- DAG.setRoot(setValue(&I, L).getValue(1));
+
+ SDOperand Root;
+ if (I.isVolatile())
+ Root = getRoot();
+ else {
+ // Do not serialize non-volatile loads against each other.
+ Root = DAG.getRoot();
+ }
+
+ SDOperand L = DAG.getLoad(TLI.getValueType(I.getType()), Root, Ptr);
+ setValue(&I, L);
+
+ if (I.isVolatile())
+ DAG.setRoot(L.getValue(1));
+ else
+ PendingLoads.push_back(L.getValue(1));
}
@@ -982,7 +1016,7 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
// Turn all of the unordered chains into one factored node.
if (!UnorderedChains.empty()) {
- UnorderedChains.push_back(DAG.getRoot());
+ UnorderedChains.push_back(SDL.getRoot());
DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, UnorderedChains));
}
OpenPOWER on IntegriCloud