From e0e32a9ef06188c1aa4bfd10097d2b7b589ec982 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 3 Jan 2011 03:46:34 +0000 Subject: [PATCH] now that loads are in their own table, we can implement store->load forwarding. This allows EarlyCSE to zap 600 more loads from 176.gcc. llvm-svn: 122732 --- llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 13 ++++++++++++- llvm/test/Transforms/EarlyCSE/basic.ll | 9 +++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index a899640d0adc..06c1b9111187 100644 --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -380,8 +380,19 @@ bool EarlyCSE::processNode(DomTreeNode *Node) { // Okay, this isn't something we can CSE at all. Check to see if it is // something that could modify memory. If so, our available memory values // cannot be used so bump the generation count. - if (Inst->mayWriteToMemory()) + if (Inst->mayWriteToMemory()) { ++CurrentGeneration; + + // Okay, we just invalidated anything we knew about loaded values. Try to + // salvage *something* by remembering that the stored value is a live + // version of the pointer. It is safe to forward from volatile stores to + // non-volatile loads, so we don't have to check for volatility of the + // store. + if (StoreInst *SI = dyn_cast(Inst)) { + AvailableLoads->insert(SI->getPointerOperand(), + std::pair(SI->getValueOperand(), CurrentGeneration)); + } + } } unsigned LiveOutGeneration = CurrentGeneration; diff --git a/llvm/test/Transforms/EarlyCSE/basic.ll b/llvm/test/Transforms/EarlyCSE/basic.ll index 6d772599b361..5599a1c0b7b1 100644 --- a/llvm/test/Transforms/EarlyCSE/basic.ll +++ b/llvm/test/Transforms/EarlyCSE/basic.ll @@ -87,3 +87,12 @@ define i32 @test5(i32 *%P) { ret i32 %Diff ; CHECK: ret i32 0 } + +;; Trivial Store->load forwarding +; CHECK: @test6 +define i32 @test6(i32 *%P) { + store i32 42, i32* %P + %V1 = load i32* %P + ret i32 %V1 + ; CHECK: ret i32 42 +}