X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FAtomicExpandPass.cpp;h=077c52b19a7a3d1907cdd3dcda9eb967ccaf0f51;hp=d0615aeca143a1c2ea9425d7862ab8bb4b2a5371;hb=53395c948459c88257c8ae57b65831fab51e4646;hpb=56318195bfc629213f2b45e8769c472b0e0ea425 diff --git a/lib/CodeGen/AtomicExpandPass.cpp b/lib/CodeGen/AtomicExpandPass.cpp index d0615aeca14..077c52b19a7 100644 --- a/lib/CodeGen/AtomicExpandPass.cpp +++ b/lib/CodeGen/AtomicExpandPass.cpp @@ -15,6 +15,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/SetOperations.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/CodeGen/AtomicExpandUtils.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" @@ -23,10 +28,13 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -63,6 +71,33 @@ namespace { bool isIdempotentRMW(AtomicRMWInst *AI); bool simplifyIdempotentRMW(AtomicRMWInst *AI); }; + + + // If 'LI' is a relaxed load, and it is immediately followed by a +// atomic read-modify-write that has acq_rel parameter, we don't have to do +// anything since the rmw serves as a natural barrier. +void MarkRelaxedLoadBeforeAcqrelRMW(LoadInst* LI) { + auto* BB = LI->getParent(); + auto BBI = LI->getIterator(); + for (BBI++; BBI != BB->end(); BBI++) { + Instruction* CurInst = &*BBI; + if (!CurInst) { + return; + } + if (!CurInst->isAtomic()) { + continue; + } + auto* RMW = dyn_cast(CurInst); + if (!RMW) { + return; + } + if (RMW->getOrdering() == AcquireRelease || + RMW->getOrdering() == SequentiallyConsistent) { + LI->setHasSubsequentAcqlRMW(true); + } + } +} + } char AtomicExpand::ID = 0; @@ -81,12 +116,61 @@ bool AtomicExpand::runOnFunction(Function &F) { TLI = TM->getSubtargetImpl(F)->getTargetLowering(); SmallVector AtomicInsts; + SmallVector MonotonicLoadInsts; // Changing control-flow while iterating through it is a bad idea, so gather a // list of all atomic instructions before we start. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { - if (I->isAtomic()) + // XXX-update: For relaxed loads, change them to acquire. This includes + // relaxed loads, relaxed atomic RMW & relaxed atomic compare exchange. + if (I->isAtomic()) { + switch (I->getOpcode()) { + case Instruction::AtomicCmpXchg: { + // XXX-comment: AtomicCmpXchg in AArch64 will be translated to a + // conditional branch that contains the value of the load anyway, so + // we don't need to do anything. + /* + auto* CmpXchg = dyn_cast(&*I); + auto SuccOrdering = CmpXchg->getSuccessOrdering(); + if (SuccOrdering == Monotonic) { + CmpXchg->setSuccessOrdering(Acquire); + } else if (SuccOrdering == Release) { + CmpXchg->setSuccessOrdering(AcquireRelease); + } + */ + break; + } + case Instruction::AtomicRMW: { + // XXX-comment: Similar to AtomicCmpXchg. These instructions in + // AArch64 will be translated to a loop whose condition depends on the + // store status, which further depends on the load value. + /* + auto* RMW = dyn_cast(&*I); + if (RMW->getOrdering() == Monotonic) { + RMW->setOrdering(Acquire); + } + */ + break; + } + case Instruction::Load: { + auto* LI = dyn_cast(&*I); + if (LI->getOrdering() == Monotonic) { + /* + DEBUG(dbgs() << "Transforming relaxed loads to acquire loads: " + << *LI << '\n'); + LI->setOrdering(Acquire); + */ +// MonotonicLoadInsts.push_back(LI); + MarkRelaxedLoadBeforeAcqrelRMW(LI); + } + break; + } + default: { + break; + } + } AtomicInsts.push_back(&*I); + } } bool MadeChange = false; @@ -103,7 +187,7 @@ bool AtomicExpand::runOnFunction(Function &F) { if (TLI->getInsertFencesForAtomic()) { if (LI && isAtLeastAcquire(LI->getOrdering())) { FenceOrdering = LI->getOrdering(); - LI->setOrdering(Monotonic); +// AddFakeConditionalBranch( IsStore = false; IsLoad = true; } else if (SI && isAtLeastRelease(SI->getOrdering())) { @@ -171,6 +255,7 @@ bool AtomicExpand::runOnFunction(Function &F) { MadeChange |= expandAtomicCmpXchg(CASI); } } + return MadeChange; }