Refactor AtomicExpandPass and add a generic isAtomic() method to Instruction

Summary:
Split shouldExpandAtomicInIR() into different versions for Stores/Loads/RMWs/CmpXchgs.
Makes runOnFunction cleaner (no more redundant checking/casting), and will help moving
the X86 backend to this pass.

This requires a way of easily detecting which instructions are atomic.
I followed the pattern of mayReadFromMemory, mayWriteOrReadMemory, etc.. in making
isAtomic() a method of Instruction implemented by a switch on the opcodes.

Test Plan: make check

Reviewers: jfb

Subscribers: mcrosier, llvm-commits

Differential Revision: http://reviews.llvm.org/D5035

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217080 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Robin Morisset
2014-09-03 21:29:59 +00:00
parent f0644b42a7
commit 1ad925ccf8
9 changed files with 121 additions and 74 deletions

View File

@@ -31,6 +31,7 @@
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Target/TargetCallingConv.h"
@@ -955,7 +956,7 @@ public:
/// It is called by AtomicExpandPass before expanding an
/// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad.
/// RMW and CmpXchg set both IsStore and IsLoad to true.
/// Backends with !getInsertFencesForAtomic() should keep a no-op here
/// Backends with !getInsertFencesForAtomic() should keep a no-op here.
virtual void emitLeadingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
bool IsStore, bool IsLoad) const {
assert(!getInsertFencesForAtomic());
@@ -965,20 +966,28 @@ public:
/// It is called by AtomicExpandPass after expanding an
/// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad.
/// RMW and CmpXchg set both IsStore and IsLoad to true.
/// Backends with !getInsertFencesForAtomic() should keep a no-op here
/// Backends with !getInsertFencesForAtomic() should keep a no-op here.
virtual void emitTrailingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
bool IsStore, bool IsLoad) const {
assert(!getInsertFencesForAtomic());
}
/// Return true if the given (atomic) instruction should be expanded by the
/// IR-level AtomicExpand pass into a loop involving
/// load-linked/store-conditional pairs. Atomic stores will be expanded in the
/// same way as "atomic xchg" operations which ignore their output if needed.
virtual bool shouldExpandAtomicInIR(Instruction *Inst) const {
/// Returns true if the given (atomic) store should be expanded by the
/// IR-level AtomicExpand pass into an "atomic xchg" which ignores its input.
virtual bool shouldExpandAtomicStoreInIR(StoreInst *SI) const {
return false;
}
/// Returns true if the given (atomic) load should be expanded by the
/// IR-level AtomicExpand pass into a load-linked instruction
/// (through emitLoadLinked()).
virtual bool shouldExpandAtomicLoadInIR(LoadInst *LI) const { return false; }
/// Returns true if the given AtomicRMW should be expanded by the
/// IR-level AtomicExpand pass into a loop using LoadLinked/StoreConditional.
virtual bool shouldExpandAtomicRMWInIR(AtomicRMWInst *RMWI) const {
return false;
}
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by