1 //===- ReduceOpcodes.cpp - Specialized Delta Pass -------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ReduceMemoryOperations.h"
11 #include "llvm/IR/InstIterator.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/IntrinsicInst.h"
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
));
39 static void removeVolatileInModule(Oracle
&O
, ReducerWorkItem
&WorkItem
) {
40 for (Function
&F
: WorkItem
.getModule())
41 removeVolatileInFunction(O
, F
);
44 void llvm::reduceVolatileInstructionsDeltaPass(TestRunner
&Test
) {
45 runDeltaPass(Test
, removeVolatileInModule
, "Reducing Volatile Instructions");
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
);
69 static void reduceAtomicSyncScopesInModule(Oracle
&O
,
70 ReducerWorkItem
&WorkItem
) {
71 for (Function
&F
: WorkItem
.getModule())
72 reduceAtomicSyncScopesInFunction(O
, F
);
75 void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner
&Test
) {
76 runDeltaPass(Test
, reduceAtomicSyncScopesInModule
,
77 "Reducing Atomic Sync Scopes");
80 // TODO: Might be helpful to incrementally relax orders
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
&&
95 CmpXChg
->setSuccessOrdering(AtomicOrdering::Monotonic
);
96 if (CmpXChg
->getFailureOrdering() != AtomicOrdering::Monotonic
&&
98 CmpXChg
->setFailureOrdering(AtomicOrdering::Monotonic
);
103 static void reduceAtomicOrderingInModule(Oracle
&O
, ReducerWorkItem
&WorkItem
) {
104 for (Function
&F
: WorkItem
.getModule())
105 reduceAtomicOrderingInFunction(O
, F
);
108 void llvm::reduceAtomicOrderingDeltaPass(TestRunner
&Test
) {
109 runDeltaPass(Test
, reduceAtomicOrderingInModule
, "Reducing Atomic Ordering");