1596fdf75SMatt Arsenault //===- ReduceOpcodes.cpp - Specialized Delta Pass -------------------------===//
2596fdf75SMatt Arsenault //
3596fdf75SMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4596fdf75SMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
5596fdf75SMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6596fdf75SMatt Arsenault //
7596fdf75SMatt Arsenault //===----------------------------------------------------------------------===//
8596fdf75SMatt Arsenault
9596fdf75SMatt Arsenault #include "ReduceMemoryOperations.h"
10596fdf75SMatt Arsenault #include "Delta.h"
11596fdf75SMatt Arsenault #include "llvm/IR/InstIterator.h"
12596fdf75SMatt Arsenault #include "llvm/IR/Instructions.h"
13596fdf75SMatt Arsenault #include "llvm/IR/IntrinsicInst.h"
14596fdf75SMatt Arsenault
15*333ffafbSMatt Arsenault using namespace llvm;
16*333ffafbSMatt Arsenault
removeVolatileInFunction(Oracle & O,Function & F)17596fdf75SMatt Arsenault static void removeVolatileInFunction(Oracle &O, Function &F) {
18596fdf75SMatt Arsenault LLVMContext &Ctx = F.getContext();
19596fdf75SMatt Arsenault for (Instruction &I : instructions(F)) {
20596fdf75SMatt Arsenault if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
21596fdf75SMatt Arsenault if (LI->isVolatile() && !O.shouldKeep())
22596fdf75SMatt Arsenault LI->setVolatile(false);
23596fdf75SMatt Arsenault } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
24596fdf75SMatt Arsenault if (SI->isVolatile() && !O.shouldKeep())
25596fdf75SMatt Arsenault SI->setVolatile(false);
26596fdf75SMatt Arsenault } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
27596fdf75SMatt Arsenault if (RMW->isVolatile() && !O.shouldKeep())
28596fdf75SMatt Arsenault RMW->setVolatile(false);
29596fdf75SMatt Arsenault } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
30596fdf75SMatt Arsenault if (CmpXChg->isVolatile() && !O.shouldKeep())
31596fdf75SMatt Arsenault CmpXChg->setVolatile(false);
32596fdf75SMatt Arsenault } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) {
33596fdf75SMatt Arsenault if (MemIntrin->isVolatile() && !O.shouldKeep())
34596fdf75SMatt Arsenault MemIntrin->setVolatile(ConstantInt::getFalse(Ctx));
35596fdf75SMatt Arsenault }
36596fdf75SMatt Arsenault }
37596fdf75SMatt Arsenault }
38596fdf75SMatt Arsenault
removeVolatileInModule(Oracle & O,ReducerWorkItem & WorkItem)3923cc36e4SMatt Arsenault static void removeVolatileInModule(Oracle &O, ReducerWorkItem &WorkItem) {
4023cc36e4SMatt Arsenault for (Function &F : WorkItem.getModule())
41596fdf75SMatt Arsenault removeVolatileInFunction(O, F);
42596fdf75SMatt Arsenault }
43596fdf75SMatt Arsenault
reduceVolatileInstructionsDeltaPass(TestRunner & Test)44596fdf75SMatt Arsenault void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) {
45596fdf75SMatt Arsenault runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions");
46596fdf75SMatt Arsenault }
47b1e17199SMatt Arsenault
reduceAtomicSyncScopesInFunction(Oracle & O,Function & F)48b1e17199SMatt Arsenault static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) {
49b1e17199SMatt Arsenault for (Instruction &I : instructions(F)) {
50b1e17199SMatt Arsenault if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
51b1e17199SMatt Arsenault if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
52b1e17199SMatt Arsenault LI->setSyncScopeID(SyncScope::System);
53b1e17199SMatt Arsenault } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
54b1e17199SMatt Arsenault if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
55b1e17199SMatt Arsenault SI->setSyncScopeID(SyncScope::System);
56b1e17199SMatt Arsenault } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
57b1e17199SMatt Arsenault if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
58b1e17199SMatt Arsenault RMW->setSyncScopeID(SyncScope::System);
59b1e17199SMatt Arsenault } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
60b1e17199SMatt Arsenault if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
61b1e17199SMatt Arsenault CmpXChg->setSyncScopeID(SyncScope::System);
62b1e17199SMatt Arsenault } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) {
63b1e17199SMatt Arsenault if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
64b1e17199SMatt Arsenault Fence->setSyncScopeID(SyncScope::System);
65b1e17199SMatt Arsenault }
66b1e17199SMatt Arsenault }
67b1e17199SMatt Arsenault }
68b1e17199SMatt Arsenault
reduceAtomicSyncScopesInModule(Oracle & O,ReducerWorkItem & WorkItem)6923cc36e4SMatt Arsenault static void reduceAtomicSyncScopesInModule(Oracle &O,
7023cc36e4SMatt Arsenault ReducerWorkItem &WorkItem) {
7123cc36e4SMatt Arsenault for (Function &F : WorkItem.getModule())
72b1e17199SMatt Arsenault reduceAtomicSyncScopesInFunction(O, F);
73b1e17199SMatt Arsenault }
74b1e17199SMatt Arsenault
reduceAtomicSyncScopesDeltaPass(TestRunner & Test)75b1e17199SMatt Arsenault void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) {
76b1e17199SMatt Arsenault runDeltaPass(Test, reduceAtomicSyncScopesInModule,
77b1e17199SMatt Arsenault "Reducing Atomic Sync Scopes");
78b1e17199SMatt Arsenault }
7983da1a6aSMatt Arsenault
8083da1a6aSMatt Arsenault // TODO: Might be helpful to incrementally relax orders
reduceAtomicOrderingInFunction(Oracle & O,Function & F)8183da1a6aSMatt Arsenault static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) {
8283da1a6aSMatt Arsenault for (Instruction &I : instructions(F)) {
8383da1a6aSMatt Arsenault if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
8483da1a6aSMatt Arsenault if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
8583da1a6aSMatt Arsenault LI->setAtomic(AtomicOrdering::NotAtomic);
8683da1a6aSMatt Arsenault } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
8783da1a6aSMatt Arsenault if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())
8883da1a6aSMatt Arsenault SI->setAtomic(AtomicOrdering::NotAtomic);
8983da1a6aSMatt Arsenault } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
9083da1a6aSMatt Arsenault if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep())
9183da1a6aSMatt Arsenault RMW->setOrdering(AtomicOrdering::Monotonic);
9283da1a6aSMatt Arsenault } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
9383da1a6aSMatt Arsenault if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic &&
9483da1a6aSMatt Arsenault !O.shouldKeep())
9583da1a6aSMatt Arsenault CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic);
9683da1a6aSMatt Arsenault if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic &&
9783da1a6aSMatt Arsenault !O.shouldKeep())
9883da1a6aSMatt Arsenault CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic);
9983da1a6aSMatt Arsenault }
10083da1a6aSMatt Arsenault }
10183da1a6aSMatt Arsenault }
10283da1a6aSMatt Arsenault
reduceAtomicOrderingInModule(Oracle & O,ReducerWorkItem & WorkItem)10323cc36e4SMatt Arsenault static void reduceAtomicOrderingInModule(Oracle &O, ReducerWorkItem &WorkItem) {
10423cc36e4SMatt Arsenault for (Function &F : WorkItem.getModule())
10583da1a6aSMatt Arsenault reduceAtomicOrderingInFunction(O, F);
10683da1a6aSMatt Arsenault }
10783da1a6aSMatt Arsenault
reduceAtomicOrderingDeltaPass(TestRunner & Test)10883da1a6aSMatt Arsenault void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) {
109756ee72aSMatt Arsenault runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Ordering");
11083da1a6aSMatt Arsenault }
111