forked from OSchip/llvm-project
Add a new subtarget hook for whether or not we'd like to enable
the atomic load linked expander pass to run for a particular subtarget. This requires a check of the subtarget and so save the TargetMachine rather than only TargetLoweringInfo and update all callers. llvm-svn: 211314
This commit is contained in:
parent
61d5d38e80
commit
c40e5edbbc
|
@ -73,6 +73,9 @@ public:
|
|||
/// MISchedPostRA, is set.
|
||||
virtual bool enablePostMachineScheduler() const;
|
||||
|
||||
/// \brief True if the subtarget should run the atomic expansion pass.
|
||||
virtual bool enableAtomicExpandLoadLinked() const;
|
||||
|
||||
/// \brief Override generic scheduling policy within a region.
|
||||
///
|
||||
/// This is a convenient way for targets that don't provide any custom
|
||||
|
|
|
@ -21,17 +21,19 @@
|
|||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "arm-atomic-expand"
|
||||
|
||||
namespace {
|
||||
class AtomicExpandLoadLinked : public FunctionPass {
|
||||
const TargetLowering *TLI;
|
||||
const TargetMachine *TM;
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit AtomicExpandLoadLinked(const TargetMachine *TM = nullptr)
|
||||
: FunctionPass(ID), TLI(TM ? TM->getTargetLowering() : nullptr) {
|
||||
: FunctionPass(ID), TM(TM) {
|
||||
initializeAtomicExpandLoadLinkedPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ FunctionPass *llvm::createAtomicExpandLoadLinkedPass(const TargetMachine *TM) {
|
|||
}
|
||||
|
||||
bool AtomicExpandLoadLinked::runOnFunction(Function &F) {
|
||||
if (!TLI)
|
||||
if (!TM || !TM->getSubtargetImpl()->enableAtomicExpandLoadLinked())
|
||||
return false;
|
||||
|
||||
SmallVector<Instruction *, 1> AtomicInsts;
|
||||
|
@ -76,7 +78,7 @@ bool AtomicExpandLoadLinked::runOnFunction(Function &F) {
|
|||
|
||||
bool MadeChange = false;
|
||||
for (Instruction *Inst : AtomicInsts) {
|
||||
if (!TLI->shouldExpandAtomicInIR(Inst))
|
||||
if (!TM->getTargetLowering()->shouldExpandAtomicInIR(Inst))
|
||||
continue;
|
||||
|
||||
if (AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(Inst))
|
||||
|
@ -98,13 +100,14 @@ bool AtomicExpandLoadLinked::expandAtomicLoad(LoadInst *LI) {
|
|||
// Load instructions don't actually need a leading fence, even in the
|
||||
// SequentiallyConsistent case.
|
||||
AtomicOrdering MemOpOrder =
|
||||
TLI->getInsertFencesForAtomic() ? Monotonic : LI->getOrdering();
|
||||
TM->getTargetLowering()->getInsertFencesForAtomic() ? Monotonic
|
||||
: LI->getOrdering();
|
||||
|
||||
// The only 64-bit load guaranteed to be single-copy atomic by the ARM ARM is
|
||||
// an ldrexd (A3.5.3).
|
||||
IRBuilder<> Builder(LI);
|
||||
Value *Val =
|
||||
TLI->emitLoadLinked(Builder, LI->getPointerOperand(), MemOpOrder);
|
||||
Value *Val = TM->getTargetLowering()->emitLoadLinked(
|
||||
Builder, LI->getPointerOperand(), MemOpOrder);
|
||||
|
||||
insertTrailingFence(Builder, LI->getOrdering());
|
||||
|
||||
|
@ -165,7 +168,8 @@ bool AtomicExpandLoadLinked::expandAtomicRMW(AtomicRMWInst *AI) {
|
|||
|
||||
// Start the main loop block now that we've taken care of the preliminaries.
|
||||
Builder.SetInsertPoint(LoopBB);
|
||||
Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder);
|
||||
Value *Loaded =
|
||||
TM->getTargetLowering()->emitLoadLinked(Builder, Addr, MemOpOrder);
|
||||
|
||||
Value *NewVal;
|
||||
switch (AI->getOperation()) {
|
||||
|
@ -211,8 +215,8 @@ bool AtomicExpandLoadLinked::expandAtomicRMW(AtomicRMWInst *AI) {
|
|||
llvm_unreachable("Unknown atomic op");
|
||||
}
|
||||
|
||||
Value *StoreSuccess =
|
||||
TLI->emitStoreConditional(Builder, NewVal, Addr, MemOpOrder);
|
||||
Value *StoreSuccess = TM->getTargetLowering()->emitStoreConditional(
|
||||
Builder, NewVal, Addr, MemOpOrder);
|
||||
Value *TryAgain = Builder.CreateICmpNE(
|
||||
StoreSuccess, ConstantInt::get(IntegerType::get(Ctx, 32), 0), "tryagain");
|
||||
Builder.CreateCondBr(TryAgain, LoopBB, ExitBB);
|
||||
|
@ -278,7 +282,8 @@ bool AtomicExpandLoadLinked::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
|
|||
|
||||
// Start the main loop block now that we've taken care of the preliminaries.
|
||||
Builder.SetInsertPoint(LoopBB);
|
||||
Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder);
|
||||
Value *Loaded =
|
||||
TM->getTargetLowering()->emitLoadLinked(Builder, Addr, MemOpOrder);
|
||||
Value *ShouldStore =
|
||||
Builder.CreateICmpEQ(Loaded, CI->getCompareOperand(), "should_store");
|
||||
|
||||
|
@ -287,7 +292,7 @@ bool AtomicExpandLoadLinked::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
|
|||
Builder.CreateCondBr(ShouldStore, TryStoreBB, FailureBB);
|
||||
|
||||
Builder.SetInsertPoint(TryStoreBB);
|
||||
Value *StoreSuccess = TLI->emitStoreConditional(
|
||||
Value *StoreSuccess = TM->getTargetLowering()->emitStoreConditional(
|
||||
Builder, CI->getNewValOperand(), Addr, MemOpOrder);
|
||||
StoreSuccess = Builder.CreateICmpEQ(
|
||||
StoreSuccess, ConstantInt::get(Type::getInt32Ty(Ctx), 0), "success");
|
||||
|
@ -352,7 +357,7 @@ bool AtomicExpandLoadLinked::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
|
|||
|
||||
AtomicOrdering AtomicExpandLoadLinked::insertLeadingFence(IRBuilder<> &Builder,
|
||||
AtomicOrdering Ord) {
|
||||
if (!TLI->getInsertFencesForAtomic())
|
||||
if (!TM->getTargetLowering()->getInsertFencesForAtomic())
|
||||
return Ord;
|
||||
|
||||
if (Ord == Release || Ord == AcquireRelease || Ord == SequentiallyConsistent)
|
||||
|
@ -365,7 +370,7 @@ AtomicOrdering AtomicExpandLoadLinked::insertLeadingFence(IRBuilder<> &Builder,
|
|||
|
||||
void AtomicExpandLoadLinked::insertTrailingFence(IRBuilder<> &Builder,
|
||||
AtomicOrdering Ord) {
|
||||
if (!TLI->getInsertFencesForAtomic())
|
||||
if (!TM->getTargetLowering()->getInsertFencesForAtomic())
|
||||
return;
|
||||
|
||||
if (Ord == Acquire || Ord == AcquireRelease)
|
||||
|
|
|
@ -417,6 +417,10 @@ bool ARMSubtarget::enablePostMachineScheduler() const {
|
|||
return PostRAScheduler;
|
||||
}
|
||||
|
||||
bool ARMSubtarget::enableAtomicExpandLoadLinked() const {
|
||||
return hasAnyDataBarrier() && !isThumb1Only();
|
||||
}
|
||||
|
||||
bool ARMSubtarget::enablePostRAScheduler(
|
||||
CodeGenOpt::Level OptLevel,
|
||||
TargetSubtargetInfo::AntiDepBreakMode& Mode,
|
||||
|
|
|
@ -425,6 +425,9 @@ public:
|
|||
TargetSubtargetInfo::AntiDepBreakMode& Mode,
|
||||
RegClassVector& CriticalPathRCs) const override;
|
||||
|
||||
// enableAtomicExpandLoadLinked - True if we need to expand our atomics.
|
||||
bool enableAtomicExpandLoadLinked() const override;
|
||||
|
||||
/// getInstrItins - Return the instruction itineraies based on subtarget
|
||||
/// selection.
|
||||
const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
|
||||
|
|
|
@ -171,16 +171,15 @@ TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
|
|||
}
|
||||
|
||||
void ARMPassConfig::addIRPasses() {
|
||||
const ARMSubtarget *Subtarget = &getARMSubtarget();
|
||||
if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only()) {
|
||||
addPass(createAtomicExpandLoadLinkedPass(TM));
|
||||
addPass(createAtomicExpandLoadLinkedPass(TM));
|
||||
|
||||
// Cmpxchg instructions are often used with a subsequent comparison to
|
||||
// determine whether it succeeded. We can exploit existing control-flow in
|
||||
// ldrex/strex loops to simplify this, but it needs tidying up.
|
||||
// Cmpxchg instructions are often used with a subsequent comparison to
|
||||
// determine whether it succeeded. We can exploit existing control-flow in
|
||||
// ldrex/strex loops to simplify this, but it needs tidying up.
|
||||
const ARMSubtarget *Subtarget = &getARMSubtarget();
|
||||
if (Subtarget->hasAnyDataBarrier() && !Subtarget->isThumb1Only())
|
||||
if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy)
|
||||
addPass(createCFGSimplificationPass());
|
||||
}
|
||||
|
||||
TargetPassConfig::addIRPasses();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ bool TargetSubtargetInfo::useMachineScheduler() const {
|
|||
return enableMachineScheduler();
|
||||
}
|
||||
|
||||
bool TargetSubtargetInfo::enableAtomicExpandLoadLinked() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TargetSubtargetInfo::enableMachineScheduler() const {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue