98 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ReduceMemoryOperations.h"10#include "llvm/IR/InstIterator.h"11#include "llvm/IR/Instructions.h"12#include "llvm/IR/IntrinsicInst.h"13 14using namespace llvm;15 16static void removeVolatileInFunction(Oracle &O, Function &F) {17 LLVMContext &Ctx = F.getContext();18 for (Instruction &I : instructions(F)) {19 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {20 if (LI->isVolatile() && !O.shouldKeep())21 LI->setVolatile(false);22 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {23 if (SI->isVolatile() && !O.shouldKeep())24 SI->setVolatile(false);25 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {26 if (RMW->isVolatile() && !O.shouldKeep())27 RMW->setVolatile(false);28 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {29 if (CmpXChg->isVolatile() && !O.shouldKeep())30 CmpXChg->setVolatile(false);31 } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) {32 if (MemIntrin->isVolatile() && !O.shouldKeep())33 MemIntrin->setVolatile(ConstantInt::getFalse(Ctx));34 }35 }36}37 38void llvm::reduceVolatileInstructionsDeltaPass(Oracle &O,39 ReducerWorkItem &WorkItem) {40 for (Function &F : WorkItem.getModule())41 removeVolatileInFunction(O, F);42}43 44static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) {45 for (Instruction &I : instructions(F)) {46 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {47 if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())48 LI->setSyncScopeID(SyncScope::System);49 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {50 if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())51 SI->setSyncScopeID(SyncScope::System);52 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {53 if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep())54 RMW->setSyncScopeID(SyncScope::System);55 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {56 if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep())57 CmpXChg->setSyncScopeID(SyncScope::System);58 } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) {59 if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep())60 Fence->setSyncScopeID(SyncScope::System);61 }62 }63}64 65void llvm::reduceAtomicSyncScopesDeltaPass(Oracle &O,66 ReducerWorkItem &WorkItem) {67 for (Function &F : WorkItem.getModule())68 reduceAtomicSyncScopesInFunction(O, F);69}70 71// TODO: Might be helpful to incrementally relax orders72static void reduceAtomicOrderingInFunction(Oracle &O, Function &F) {73 for (Instruction &I : instructions(F)) {74 if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {75 if (LI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())76 LI->setAtomic(AtomicOrdering::NotAtomic);77 } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {78 if (SI->getOrdering() != AtomicOrdering::NotAtomic && !O.shouldKeep())79 SI->setAtomic(AtomicOrdering::NotAtomic);80 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {81 if (RMW->getOrdering() != AtomicOrdering::Monotonic && !O.shouldKeep())82 RMW->setOrdering(AtomicOrdering::Monotonic);83 } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {84 if (CmpXChg->getSuccessOrdering() != AtomicOrdering::Monotonic &&85 !O.shouldKeep())86 CmpXChg->setSuccessOrdering(AtomicOrdering::Monotonic);87 if (CmpXChg->getFailureOrdering() != AtomicOrdering::Monotonic &&88 !O.shouldKeep())89 CmpXChg->setFailureOrdering(AtomicOrdering::Monotonic);90 }91 }92}93 94void llvm::reduceAtomicOrderingDeltaPass(Oracle &O, ReducerWorkItem &WorkItem) {95 for (Function &F : WorkItem.getModule())96 reduceAtomicOrderingInFunction(O, F);97}98