mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-11 23:16:20 +00:00
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:
parent
5c65981a57
commit
d3948116b8
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user