diff options
author | Alex Bradbury <asb@lowrisc.org> | 2018-09-19 14:51:42 +0000 |
---|---|---|
committer | Alex Bradbury <asb@lowrisc.org> | 2018-09-19 14:51:42 +0000 |
commit | 79518b02cd3ef91a9fb5ddae381e826e80cae582 (patch) | |
tree | 57897012b6770236cb7b5981f3991538b2b4eb7f /llvm/lib/CodeGen/AtomicExpandPass.cpp | |
parent | 023dfa5716326449662059516ddff2ed459526a1 (diff) | |
download | bcm5719-llvm-79518b02cd3ef91a9fb5ddae381e826e80cae582.tar.gz bcm5719-llvm-79518b02cd3ef91a9fb5ddae381e826e80cae582.zip |
[AtomicExpandPass]: Add a hook for custom cmpxchg expansion in IR
This involves changing the shouldExpandAtomicCmpXchgInIR interface, but I have
updated the in-tree backends using this hook (ARM, AArch64, Hexagon) so they
will see no functional change. Previously this hook returned bool, but it now
returns AtomicExpansionKind.
This hook allows targets to select how a given cmpxchg is to be expanded.
D48131 uses this to expand part-word cmpxchg to a target-specific intrinsic.
See my associated RFC for more info on the motivation for this change
<http://lists.llvm.org/pipermail/llvm-dev/2018-June/123993.html>.
Differential Revision: https://reviews.llvm.org/D48130
llvm-svn: 342550
Diffstat (limited to 'llvm/lib/CodeGen/AtomicExpandPass.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AtomicExpandPass.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp index 3a283ca7048..c1b98794015 100644 --- a/llvm/lib/CodeGen/AtomicExpandPass.cpp +++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp @@ -98,6 +98,7 @@ namespace { AtomicOrdering MemOpOrder, function_ref<Value *(IRBuilder<> &, Value *)> PerformOp, CreateCmpXchgInstFun CreateCmpXchg); + bool tryExpandAtomicCmpXchg(AtomicCmpXchgInst *CI); bool expandAtomicCmpXchg(AtomicCmpXchgInst *CI); bool isIdempotentRMW(AtomicRMWInst *RMWI); @@ -260,7 +261,9 @@ bool AtomicExpand::runOnFunction(Function &F) { isAcquireOrStronger(RMWI->getOrdering()))) { FenceOrdering = RMWI->getOrdering(); RMWI->setOrdering(AtomicOrdering::Monotonic); - } else if (CASI && !TLI->shouldExpandAtomicCmpXchgInIR(CASI) && + } else if (CASI && + TLI->shouldExpandAtomicCmpXchgInIR(CASI) == + TargetLoweringBase::AtomicExpansionKind::None && (isReleaseOrStronger(CASI->getSuccessOrdering()) || isAcquireOrStronger(CASI->getSuccessOrdering()))) { // If a compare and swap is lowered to LL/SC, we can do smarter fence @@ -334,16 +337,7 @@ bool AtomicExpand::runOnFunction(Function &F) { MadeChange = true; } - unsigned MinCASSize = TLI->getMinCmpXchgSizeInBits() / 8; - unsigned ValueSize = getAtomicOpSize(CASI); - if (ValueSize < MinCASSize) { - assert(!TLI->shouldExpandAtomicCmpXchgInIR(CASI) && - "MinCmpXchgSizeInBits not yet supported for LL/SC expansions."); - expandPartwordCmpXchg(CASI); - } else { - if (TLI->shouldExpandAtomicCmpXchgInIR(CASI)) - MadeChange |= expandAtomicCmpXchg(CASI); - } + MadeChange |= tryExpandAtomicCmpXchg(CASI); } } return MadeChange; @@ -1355,6 +1349,28 @@ Value *AtomicExpand::insertRMWCmpXchgLoop( return NewLoaded; } +bool AtomicExpand::tryExpandAtomicCmpXchg(AtomicCmpXchgInst *CI) { + unsigned MinCASSize = TLI->getMinCmpXchgSizeInBits() / 8; + unsigned ValueSize = getAtomicOpSize(CI); + + switch (TLI->shouldExpandAtomicCmpXchgInIR(CI)) { + default: + llvm_unreachable("Unhandled case in tryExpandAtomicCmpXchg"); + case TargetLoweringBase::AtomicExpansionKind::None: + if (ValueSize < MinCASSize) + expandPartwordCmpXchg(CI); + return false; + case TargetLoweringBase::AtomicExpansionKind::LLSC: { + assert(ValueSize >= MinCASSize && + "MinCmpXchgSizeInBits not yet supported for LL/SC expansions."); + return expandAtomicCmpXchg(CI); + } + case TargetLoweringBase::AtomicExpansionKind::MaskedIntrinsic: + llvm_unreachable( + "MaskedIntrinsic expansion of cmpxhg not yet implemented"); + } +} + // Note: This function is exposed externally by AtomicExpandUtils.h bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun CreateCmpXchg) { |