Skip to content

Commit

Permalink
Tweak some atomics functions in preparation for larger changes; NFC.
Browse files Browse the repository at this point in the history
- Rename getATOMIC to getSYNC, as llvm will soon be able to emit both
  '__sync' libcalls and '__atomic' libcalls, and this function is for
  the '__sync' ones.

- getInsertFencesForAtomic() has been replaced with
  shouldInsertFencesForAtomic(Instruction), so that the decision can be
  made per-instruction. This functionality will be used soon.

- emitLeadingFence/emitTrailingFence are no longer called if
  shouldInsertFencesForAtomic returns false, and thus don't need to
  check the condition themselves.

llvm-svn: 263665
  • Loading branch information
jyknight committed Mar 16, 2016
1 parent b321050 commit f44fc52
Show file tree
Hide file tree
Showing 17 changed files with 58 additions and 56 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ namespace RTLIB {

/// Return the SYNC_FETCH_AND_* value for the given opcode and type, or
/// UNKNOWN_LIBCALL if there is none.
Libcall getATOMIC(unsigned Opc, MVT VT);
Libcall getSYNC(unsigned Opc, MVT VT);
}
}

Expand Down
33 changes: 9 additions & 24 deletions llvm/include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -1003,12 +1003,6 @@ class TargetLoweringBase {
return PrefLoopAlignment;
}

/// Return whether the DAG builder should automatically insert fences and
/// reduce ordering for atomics.
bool getInsertFencesForAtomic() const {
return InsertFencesForAtomic;
}

/// Return true if the target stores stack protector cookies at a fixed offset
/// in some non-standard address space, and populates the address space and
/// offset as appropriate.
Expand Down Expand Up @@ -1052,6 +1046,13 @@ class TargetLoweringBase {
/// \name Helpers for atomic expansion.
/// @{

/// Whether AtomicExpandPass should automatically insert fences and reduce
/// ordering for this atomic. This should be true for most architectures with
/// weak memory ordering. Defaults to false.
virtual bool shouldInsertFencesForAtomic(const Instruction *I) const {
return false;
}

/// Perform a load-linked operation on Addr, returning a "Value *" with the
/// corresponding pointee type. This may entail some non-trivial operations to
/// truncate or reconstruct types that will be illegal in the backend. See
Expand All @@ -1070,12 +1071,12 @@ class TargetLoweringBase {

/// Inserts in the IR a target-specific intrinsic specifying a fence.
/// It is called by AtomicExpandPass before expanding an
/// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad.
/// AtomicRMW/AtomicCmpXchg/AtomicStore/AtomicLoad
/// if shouldInsertFencesForAtomic returns true.
/// RMW and CmpXchg set both IsStore and IsLoad to true.
/// This function should either return a nullptr, or a pointer to an IR-level
/// Instruction*. Even complex fence sequences can be represented by a
/// single Instruction* through an intrinsic to be lowered later.
/// Backends with !getInsertFencesForAtomic() should keep a no-op here.
/// Backends should override this method to produce target-specific intrinsic
/// for their fences.
/// FIXME: Please note that the default implementation here in terms of
Expand All @@ -1101,9 +1102,6 @@ class TargetLoweringBase {
virtual Instruction *emitLeadingFence(IRBuilder<> &Builder,
AtomicOrdering Ord, bool IsStore,
bool IsLoad) const {
if (!getInsertFencesForAtomic())
return nullptr;

if (isAtLeastRelease(Ord) && IsStore)
return Builder.CreateFence(Ord);
else
Expand All @@ -1113,9 +1111,6 @@ class TargetLoweringBase {
virtual Instruction *emitTrailingFence(IRBuilder<> &Builder,
AtomicOrdering Ord, bool IsStore,
bool IsLoad) const {
if (!getInsertFencesForAtomic())
return nullptr;

if (isAtLeastAcquire(Ord))
return Builder.CreateFence(Ord);
else
Expand Down Expand Up @@ -1441,12 +1436,6 @@ class TargetLoweringBase {
MinStackArgumentAlignment = Align;
}

/// Set if the DAG builder should automatically insert fences and reduce the
/// order of atomic memory operations to Monotonic.
void setInsertFencesForAtomic(bool fence) {
InsertFencesForAtomic = fence;
}

public:
//===--------------------------------------------------------------------===//
// Addressing mode description hooks (used by LSR etc).
Expand Down Expand Up @@ -1856,10 +1845,6 @@ class TargetLoweringBase {
/// The preferred loop alignment.
unsigned PrefLoopAlignment;

/// Whether the DAG builder should automatically insert fences and reduce
/// ordering for atomics. (This will be set for for most architectures with
/// weak memory ordering.)
bool InsertFencesForAtomic;

/// If set to a physical register, this specifies the register that
/// llvm.savestack/llvm.restorestack should save and restore.
Expand Down
27 changes: 15 additions & 12 deletions llvm/lib/CodeGen/AtomicExpandPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ bool AtomicExpand::runOnFunction(Function &F) {
assert((LI || SI || RMWI || CASI || isa<FenceInst>(I)) &&
"Unknown atomic instruction");

if (TLI->getInsertFencesForAtomic()) {
if (TLI->shouldInsertFencesForAtomic(I)) {
auto FenceOrdering = Monotonic;
bool IsStore, IsLoad;
if (LI && isAtLeastAcquire(LI->getOrdering())) {
Expand Down Expand Up @@ -514,12 +514,13 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
BasicBlock *BB = CI->getParent();
Function *F = BB->getParent();
LLVMContext &Ctx = F->getContext();
// If getInsertFencesForAtomic() returns true, then the target does not want
// to deal with memory orders, and emitLeading/TrailingFence should take care
// of everything. Otherwise, emitLeading/TrailingFence are no-op and we
// If shouldInsertFencesForAtomic() returns true, then the target does not
// want to deal with memory orders, and emitLeading/TrailingFence should take
// care of everything. Otherwise, emitLeading/TrailingFence are no-op and we
// should preserve the ordering.
bool ShouldInsertFencesForAtomic = TLI->shouldInsertFencesForAtomic(CI);
AtomicOrdering MemOpOrder =
TLI->getInsertFencesForAtomic() ? Monotonic : SuccessOrder;
ShouldInsertFencesForAtomic ? Monotonic : SuccessOrder;

// In implementations which use a barrier to achieve release semantics, we can
// delay emitting this barrier until we know a store is actually going to be
Expand All @@ -530,7 +531,7 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
// since in other cases the extra blocks naturally collapse down to the
// minimal loop. Unfortunately, this puts too much stress on later
// optimisations so we avoid emitting the extra logic in those cases too.
bool HasReleasedLoadBB = !CI->isWeak() && TLI->getInsertFencesForAtomic() &&
bool HasReleasedLoadBB = !CI->isWeak() && ShouldInsertFencesForAtomic &&
SuccessOrder != Monotonic &&
SuccessOrder != Acquire && !F->optForMinSize();

Expand Down Expand Up @@ -601,7 +602,7 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
// the branch entirely.
std::prev(BB->end())->eraseFromParent();
Builder.SetInsertPoint(BB);
if (UseUnconditionalReleaseBarrier)
if (ShouldInsertFencesForAtomic && UseUnconditionalReleaseBarrier)
TLI->emitLeadingFence(Builder, SuccessOrder, /*IsStore=*/true,
/*IsLoad=*/true);
Builder.CreateBr(StartBB);
Expand All @@ -617,7 +618,7 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
Builder.CreateCondBr(ShouldStore, ReleasingStoreBB, NoStoreBB);

Builder.SetInsertPoint(ReleasingStoreBB);
if (!UseUnconditionalReleaseBarrier)
if (ShouldInsertFencesForAtomic && !UseUnconditionalReleaseBarrier)
TLI->emitLeadingFence(Builder, SuccessOrder, /*IsStore=*/true,
/*IsLoad=*/true);
Builder.CreateBr(TryStoreBB);
Expand Down Expand Up @@ -647,8 +648,9 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
// Make sure later instructions don't get reordered with a fence if
// necessary.
Builder.SetInsertPoint(SuccessBB);
TLI->emitTrailingFence(Builder, SuccessOrder, /*IsStore=*/true,
/*IsLoad=*/true);
if (ShouldInsertFencesForAtomic)
TLI->emitTrailingFence(Builder, SuccessOrder, /*IsStore=*/true,
/*IsLoad=*/true);
Builder.CreateBr(ExitBB);

Builder.SetInsertPoint(NoStoreBB);
Expand All @@ -659,8 +661,9 @@ bool AtomicExpand::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
Builder.CreateBr(FailureBB);

Builder.SetInsertPoint(FailureBB);
TLI->emitTrailingFence(Builder, FailureOrder, /*IsStore=*/true,
/*IsLoad=*/true);
if (ShouldInsertFencesForAtomic)
TLI->emitTrailingFence(Builder, FailureOrder, /*IsStore=*/true,
/*IsLoad=*/true);
Builder.CreateBr(ExitBB);

// Finally, we have control-flow based knowledge of whether the cmpxchg
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4035,7 +4035,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
case ISD::ATOMIC_LOAD_UMAX:
case ISD::ATOMIC_CMP_SWAP: {
MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
RTLIB::Libcall LC = RTLIB::getATOMIC(Opc, VT);
RTLIB::Libcall LC = RTLIB::getSYNC(Opc, VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected atomic op or value type!");

std::pair<SDValue, SDValue> Tmp = ExpandChainLibCall(LC, Node, false);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1404,7 +1404,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
unsigned Opc = Node->getOpcode();
MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT();
RTLIB::Libcall LC = RTLIB::getATOMIC(Opc, VT);
RTLIB::Libcall LC = RTLIB::getSYNC(Opc, VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected atomic op or value type!");

return ExpandChainLibCall(LC, Node, false);
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
return UNKNOWN_LIBCALL;
}

RTLIB::Libcall RTLIB::getATOMIC(unsigned Opc, MVT VT) {
RTLIB::Libcall RTLIB::getSYNC(unsigned Opc, MVT VT) {
#define OP_TO_LIBCALL(Name, Enum) \
case Name: \
switch (VT.SimpleTy) { \
Expand Down Expand Up @@ -774,7 +774,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
PrefLoopAlignment = 0;
GatherAllAliasesMaxDepth = 6;
MinStackArgumentAlignment = 1;
InsertFencesForAtomic = false;
MinimumJumpTableEntries = 4;

InitLibcallNames(LibcallRoutineNames, TM.getTargetTriple());
Expand Down
14 changes: 7 additions & 7 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
// the default expansion. If we are targeting a single threaded system,
// then set them all for expand so we can lower them later into their
// non-atomic form.
InsertFencesForAtomic = false;
if (TM.Options.ThreadModel == ThreadModel::Single)
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
else if (Subtarget->hasAnyDataBarrier() && (!Subtarget->isThumb() ||
Expand All @@ -852,7 +853,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
// if they can be combined with nearby atomic loads and stores.
if (!Subtarget->hasV8Ops()) {
// Automatically insert fences (dmb ish) around ATOMIC_SWAP etc.
setInsertFencesForAtomic(true);
InsertFencesForAtomic = true;
}
} else {
// If there's anything we can use as a barrier, go through custom lowering
Expand Down Expand Up @@ -11997,9 +11998,6 @@ Instruction* ARMTargetLowering::makeDMB(IRBuilder<> &Builder,
Instruction* ARMTargetLowering::emitLeadingFence(IRBuilder<> &Builder,
AtomicOrdering Ord, bool IsStore,
bool IsLoad) const {
if (!getInsertFencesForAtomic())
return nullptr;

switch (Ord) {
case NotAtomic:
case Unordered:
Expand All @@ -12025,9 +12023,6 @@ Instruction* ARMTargetLowering::emitLeadingFence(IRBuilder<> &Builder,
Instruction* ARMTargetLowering::emitTrailingFence(IRBuilder<> &Builder,
AtomicOrdering Ord, bool IsStore,
bool IsLoad) const {
if (!getInsertFencesForAtomic())
return nullptr;

switch (Ord) {
case NotAtomic:
case Unordered:
Expand Down Expand Up @@ -12081,6 +12076,11 @@ bool ARMTargetLowering::shouldExpandAtomicCmpXchgInIR(
return true;
}

bool ARMTargetLowering::shouldInsertFencesForAtomic(
const Instruction *I) const {
return InsertFencesForAtomic;
}

// This has so far only been implemented for MachO.
bool ARMTargetLowering::useLoadStackGuardNode() const {
return Subtarget->isTargetMachO();
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ namespace llvm {
bool lowerInterleavedStore(StoreInst *SI, ShuffleVectorInst *SVI,
unsigned Factor) const override;

bool shouldInsertFencesForAtomic(const Instruction *I) const override;
TargetLoweringBase::AtomicExpansionKind
shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
Expand Down Expand Up @@ -486,6 +487,10 @@ namespace llvm {
///
unsigned ARMPCLabelIndex;

// TODO: remove this, and have shouldInsertFencesForAtomic do the proper
// check.
bool InsertFencesForAtomic;

void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
void addDRTypeForNEON(MVT VT);
void addQRTypeForNEON(MVT VT);
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setPrefLoopAlignment(4);
setPrefFunctionAlignment(4);
setMinFunctionAlignment(2);
setInsertFencesForAtomic(false);
setStackPointerRegisterToSaveRestore(HRI.getStackRegister());

if (EnableHexSDNodeSched)
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand);
}

setInsertFencesForAtomic(true);

if (!Subtarget.hasMips32r2()) {
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,10 @@ namespace llvm {
unsigned getJumpTableEncoding() const override;
bool useSoftFloat() const override;

bool shouldInsertFencesForAtomic(const Instruction *I) const override {
return true;
}

/// Emit a sign-extension using sll/sra, seb, or seh appropriately.
MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr *MI,
MachineBasicBlock *BB,
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
break;
}

setInsertFencesForAtomic(true);

if (Subtarget.enableMachineScheduler())
setSchedulingPreference(Sched::Source);
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/PowerPC/PPCISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ namespace llvm {

unsigned getPrefLoopAlignment(MachineLoop *ML) const override;

bool shouldInsertFencesForAtomic(const Instruction *I) const override {
return true;
}

Instruction* emitLeadingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
bool IsStore, bool IsLoad) const override;
Instruction* emitTrailingFence(IRBuilder<> &Builder, AtomicOrdering Ord,
Expand Down
4 changes: 0 additions & 4 deletions llvm/lib/Target/Sparc/SparcISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1603,10 +1603,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM,
}

// ATOMICs.
// FIXME: We insert fences for each atomics and generate sub-optimal code
// for PSO/TSO. Also, implement other atomicrmw operations.

setInsertFencesForAtomic(true);

setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Legal);
setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32,
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/Sparc/SparcISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ namespace llvm {
return VT != MVT::f128;
}

bool shouldInsertFencesForAtomic(const Instruction *I) const override {
// FIXME: We insert fences for each atomics and generate
// sub-optimal code for PSO/TSO. (Approximately nobody uses any
// mode but TSO, which makes this even more silly)
return true;
}

void ReplaceNodeResults(SDNode *N,
SmallVectorImpl<SDValue>& Results,
SelectionDAG &DAG) const override;
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/XCore/XCoreISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ XCoreTargetLowering::XCoreTargetLowering(const TargetMachine &TM,
// Atomic operations
// We request a fence for ATOMIC_* instructions, to reduce them to Monotonic.
// As we are always Sequential Consistent, an ATOMIC_FENCE becomes a no OP.
setInsertFencesForAtomic(true);
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom);
setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/XCore/XCoreISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ namespace llvm {
bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
LLVMContext &Context) const override;
bool shouldInsertFencesForAtomic(const Instruction *I) const override {
return true;
}
};
}

Expand Down

0 comments on commit f44fc52

Please sign in to comment.