/// is only computed once and is cached.
mutable MCSymbol *CachedMCSymbol = nullptr;
- // XXX-update: A flag that checks whether we can eliminate this machine basic
- // block.
- bool canEliminateMachineBB;
-
// Intrusive list support
MachineBasicBlock() {}
friend class MachineFunction;
public:
- // XXX-update:
- void disableCanEliminateMachineBB() {
- canEliminateMachineBB = false;
- }
-
- bool getCanEliminateMachineBB() {
- return canEliminateMachineBB;
- }
-
/// Return the LLVM basic block that this instance corresponded to originally.
/// Note that this may be NULL if this instance does not correspond directly
/// to an LLVM basic block.
InstListType InstList;
Function *Parent;
- // XXX-update: A flag that checks whether we can eliminate this block.
- bool canEliminateBlock;
-
void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock>;
Function *Parent = nullptr,
BasicBlock *InsertBefore = nullptr);
public:
- // XXX-update:
- void disableCanEliminateBlock() {
- canEliminateBlock = false;
- }
-
- bool getCanEliminateBlock() {
- return canEliminateBlock;
- }
-
-
/// \brief Get the context in which this basic block lives.
LLVMContext &getContext() const;
LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
BasicBlock *InsertAtEnd);
- bool getHasSubsequentAcqlRMW() {
- return hasSubsequentAcqlRMW_;
- }
-
- void setHasSubsequentAcqlRMW(bool val) {
- hasSubsequentAcqlRMW_ = val;
- }
-
/// isVolatile - Return true if this is a load from a volatile memory
/// location.
///
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
-
- bool hasSubsequentAcqlRMW_;
};
//===----------------------------------------------------------------------===//
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<AtomicRMWInst>(CurInst);
- if (!RMW) {
- return;
- }
- if (RMW->getOrdering() == AcquireRelease ||
- RMW->getOrdering() == SequentiallyConsistent) {
- LI->setHasSubsequentAcqlRMW(true);
- }
- }
-}
-
}
char AtomicExpand::ID = 0;
TLI = TM->getSubtargetImpl(F)->getTargetLowering();
SmallVector<Instruction *, 1> AtomicInsts;
- SmallVector<LoadInst*, 1> MonotonicLoadInsts;
bool MadeChange = false;
// XXX-comment: Converts relaxed stores to release stores.
// 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) {
- // 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<AtomicCmpXchgInst>(&*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<AtomicRMWInst>(&*I);
- if (RMW->getOrdering() == Monotonic) {
- RMW->setOrdering(Acquire);
- }
- */
- break;
- }
- case Instruction::Load: {
- auto* LI = dyn_cast<LoadInst>(&*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;
- }
- }
+ if (I->isAtomic())
AtomicInsts.push_back(&*I);
- }
}
for (auto I : AtomicInsts) {
if (TLI->getInsertFencesForAtomic()) {
if (LI && isAtLeastAcquire(LI->getOrdering())) {
FenceOrdering = LI->getOrdering();
-// AddFakeConditionalBranch(
+ LI->setOrdering(Monotonic);
IsStore = false;
IsLoad = true;
} else if (SI && isAtLeastRelease(SI->getOrdering())) {
MadeChange |= expandAtomicCmpXchg(CASI);
}
}
-
return MadeChange;
}