xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceMemoryOperations.cpp (revision 333ffafb4500cad19aec81e841686ade1f31f67f)
1 //===- ReduceOpcodes.cpp - Specialized Delta Pass -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ReduceMemoryOperations.h"
10 #include "Delta.h"
11 #include "llvm/IR/InstIterator.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/IntrinsicInst.h"
14 
15 using namespace llvm;
16 
removeVolatileInFunction(Oracle & O,Function & F)17 static void removeVolatileInFunction(Oracle &O, Function &F) {
18   LLVMContext &Ctx = F.getContext();
19   for (Instruction &I : instructions(F)) {
20     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
21       if (LI->isVolatile() && !O.shouldKeep())
22         LI->setVolatile(false);
23     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
24       if (SI->isVolatile() && !O.shouldKeep())
25         SI->setVolatile(false);
26     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
27       if (RMW->isVolatile() && !O.shouldKeep())
28         RMW->setVolatile(false);
29     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
30       if (CmpXChg->isVolatile() && !O.shouldKeep())
31         CmpXChg->setVolatile(false);
32     } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) {
33       if (MemIntrin->isVolatile() && !O.shouldKeep())
34         MemIntrin->setVolatile(ConstantInt::getFalse(Ctx));
35     }
36   }
37 }
38 
removeVolatileInModule(Oracle & O,ReducerWorkItem & WorkItem)39 static void removeVolatileInModule(Oracle &O, ReducerWorkItem &WorkItem) {
40   for (Function &F : WorkItem.getModule())
41     removeVolatileInFunction(O, F);
42 }
43 
reduceVolatileInstructionsDeltaPass(TestRunner & Test)44 void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) {
45   runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions");
46 }
47 
reduceAtomicSyncScopesInFunction(Oracle & O,Function & F)48 static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) {
49   for (Instruction &I : instructions(F)) {
50     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
51       if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
52         LI->setSyncScopeID(SyncScope::System);
53     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
54       if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
55         SI->setSyncScopeID(SyncScope::System);
56     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
57       if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
58         RMW->setSyncScopeID(SyncScope::System);
59     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
60       if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
61         CmpXChg->setSyncScopeID(SyncScope::System);
62     } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) {
63       if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
64         Fence->setSyncScopeID(SyncScope::System);
65     }
66   }
67 }
68 
reduceAtomicSyncScopesInModule(Oracle & O,ReducerWorkItem & WorkItem)69 static void reduceAtomicSyncScopesInModule(Oracle &O,
70                                            ReducerWorkItem &WorkItem) {
71   for (Function &F : WorkItem.getModule())
72     reduceAtomicSyncScopesInFunction(O, F);
73 }
74 
reduceAtomicSyncScopesDeltaPass(TestRunner & Test)75 void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) {
76   runDeltaPass(Test, reduceAtomicSyncScopesInModule,
77                "Reducing Atomic Sync Scopes");
78 }
79 
80 // TODO: Might be helpful to incrementally relax orders
reduceAtomicOrderingInFunction(Oracle & O,Function & F)81 static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) {
82   for (Instruction &I : instructions(F)) {
83     if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
84       if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
85         LI->setAtomic(AtomicOrdering::NotAtomic);
86     } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
87       if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
88         SI->setAtomic(AtomicOrdering::NotAtomic);
89     } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
90       if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep())
91         RMW->setOrdering(AtomicOrdering::Monotonic);
92     } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
93       if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic &&
94           !O.shouldKeep())
95         CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic);
96       if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic &&
97           !O.shouldKeep())
98         CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic);
99     }
100   }
101 }
102 
reduceAtomicOrderingInModule(Oracle & O,ReducerWorkItem & WorkItem)103 static void reduceAtomicOrderingInModule(Oracle &O, ReducerWorkItem &WorkItem) {
104   for (Function &F : WorkItem.getModule())
105     reduceAtomicOrderingInFunction(O, F);
106 }
107 
reduceAtomicOrderingDeltaPass(TestRunner & Test)108 void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) {
109   runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Ordering");
110 }
111