summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorQuentin Colombet <quentin.colombet@gmail.com>2019-02-07 21:27:23 +0000
committerQuentin Colombet <quentin.colombet@gmail.com>2019-02-07 21:27:23 +0000
commit96f54de8ff5d357fadcf474823f70288561923bf (patch)
tree5f458880c0e8823862215080eafd91f82ce0447e /llvm/lib
parent82bf8e82c96b79fcafea5d0026feab24a270e9af (diff)
downloadbcm5719-llvm-96f54de8ff5d357fadcf474823f70288561923bf.tar.gz
bcm5719-llvm-96f54de8ff5d357fadcf474823f70288561923bf.zip
[InstCombine] Optimize `atomicrmw <op>, 0` into `load atomic` when possible
This commit teaches InstCombine how to replace an atomicrmw operation into a simple load atomic. For a given `atomicrmw <op>`, this is possible when: 1. The ordering of that operation is compatible with a load (i.e., anything that doesn't have a release semantic). 2. <op> does not modify the value being stored Differential Revision: https://reviews.llvm.org/D57854 llvm-svn: 353471
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/CMakeLists.txt1
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp48
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineInternal.h1
3 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/CMakeLists.txt b/llvm/lib/Transforms/InstCombine/CMakeLists.txt
index 8a3a58e9ecc..bba399bba35 100644
--- a/llvm/lib/Transforms/InstCombine/CMakeLists.txt
+++ b/llvm/lib/Transforms/InstCombine/CMakeLists.txt
@@ -5,6 +5,7 @@ add_public_tablegen_target(InstCombineTableGen)
add_llvm_library(LLVMInstCombine
InstructionCombining.cpp
InstCombineAddSub.cpp
+ InstCombineAtomicRMW.cpp
InstCombineAndOrXor.cpp
InstCombineCalls.cpp
InstCombineCasts.cpp
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
new file mode 100644
index 00000000000..86bbfb15986
--- /dev/null
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAtomicRMW.cpp
@@ -0,0 +1,48 @@
+//===- InstCombineAtomicRMW.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the visit functions for atomic rmw instructions.
+//
+//===----------------------------------------------------------------------===//
+#include "InstCombineInternal.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace llvm;
+
+Instruction *InstCombiner::visitAtomicRMWInst(AtomicRMWInst &RMWI) {
+ switch (RMWI.getOperation()) {
+ default:
+ break;
+ case AtomicRMWInst::Add:
+ case AtomicRMWInst::Sub:
+ case AtomicRMWInst::Or:
+ // Replace atomicrmw <op> addr, 0 => load atomic addr.
+
+ // Volatile RMWs perform a load and a store, we cannot replace
+ // this by just a load.
+ if (RMWI.isVolatile())
+ break;
+
+ auto *CI = dyn_cast<ConstantInt>(RMWI.getValOperand());
+ if (!CI || !CI->isZero())
+ break;
+ // Check if the required ordering is compatible with an
+ // atomic load.
+ AtomicOrdering Ordering = RMWI.getOrdering();
+ assert(Ordering != AtomicOrdering::NotAtomic &&
+ Ordering != AtomicOrdering::Unordered &&
+ "AtomicRMWs don't make sense with Unordered or NotAtomic");
+ if (Ordering != AtomicOrdering::Acquire &&
+ Ordering != AtomicOrdering::Monotonic)
+ break;
+ LoadInst *Load = new LoadInst(RMWI.getType(), RMWI.getPointerOperand());
+ Load->setAtomic(Ordering, RMWI.getSyncScopeID());
+ return Load;
+ }
+ return nullptr;
+}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 11993a46323..951e0e72e9e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -401,6 +401,7 @@ public:
Instruction *visitFree(CallInst &FI);
Instruction *visitLoadInst(LoadInst &LI);
Instruction *visitStoreInst(StoreInst &SI);
+ Instruction *visitAtomicRMWInst(AtomicRMWInst &SI);
Instruction *visitBranchInst(BranchInst &BI);
Instruction *visitFenceInst(FenceInst &FI);
Instruction *visitSwitchInst(SwitchInst &SI);
OpenPOWER on IntegriCloud