diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-01-17 22:19:26 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-01-17 22:19:26 +0000 |
| commit | 4d9651c76056989afffc8d6b6501211e1bfbb556 (patch) | |
| tree | 20b78d983a554241915e6bae8f133c69a0919d59 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
| parent | e86c933df76aa938dd8e9078ea669c89a25fe66d (diff) | |
| download | bcm5719-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.cpp | 42 |
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)); } |

