SmallVector<Instruction *, 1> AtomicInsts;
SmallVector<LoadInst*, 1> MonotonicLoadInsts;
+ bool MadeChange = false;
+ // XXX-comment: Converts relaxed stores to release stores.
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (I->isAtomic()) {
+ switch (I->getOpcode()) {
+ case Instruction::Store: {
+ auto* SI = dyn_cast<StoreInst>(&*I);
+ if (SI->getOrdering() == Monotonic) {
+ SI->setOrdering(Release);
+ MadeChange = true;
+ }
+ break;
+ }
+ case Instruction::AtomicCmpXchg: {
+ auto* CmpXInst = dyn_cast<AtomicCmpXchgInst>(&*I);
+ if (CmpXInst->getSuccessOrdering() == Monotonic) {
+ CmpXInst->setSuccessOrdering(Release);
+ MadeChange = true;
+ }
+ break;
+ }
+ case Instruction::AtomicRMW: {
+ auto* RMWInst = dyn_cast<AtomicRMWInst>(&*I);
+ if (RMWInst->getOrdering() == Monotonic) {
+ RMWInst->setOrdering(Release);
+ MadeChange = true;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+
// 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) {
}
}
- bool MadeChange = false;
for (auto I : AtomicInsts) {
auto LI = dyn_cast<LoadInst>(I);
auto SI = dyn_cast<StoreInst>(I);
for (auto &I : Statepoints)
EverMadeChange |= simplifyOffsetableRelocate(*I);
}
-
- // XXX-comment: Delay dealing with relaxed loads in this function to avoid
- // further changes done by other passes (e.g., SimplifyCFG).
- // Collect all the relaxed loads.
- SmallSet<LoadInst*, 1> MonotonicLoadInsts;
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (I->isAtomic()) {
- switch (I->getOpcode()) {
- case Instruction::Load: {
- auto* LI = dyn_cast<LoadInst>(&*I);
- if (LI->getOrdering() == Monotonic &&
- !LI->getHasSubsequentAcqlRMW()) {
- MonotonicLoadInsts.insert(LI);
- }
- break;
- }
- default: {
- break;
- }
- }
- }
- }
- EverMadeChange |= ConvertMonotonicLoadsToAcquire(MonotonicLoadInsts);
-
return EverMadeChange;
}