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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19644 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-01-17 22:19:26 +00:00
parent 5c65981a57
commit d3948116b8

View File

@ -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));
}