ReduceMemoryOperations.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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. #include "ReduceMemoryOperations.h"
  9. #include "Delta.h"
  10. #include "llvm/IR/InstIterator.h"
  11. #include "llvm/IR/Instructions.h"
  12. #include "llvm/IR/IntrinsicInst.h"
  13. using namespace llvm;
  14. static void removeVolatileInFunction(Oracle &O, Function &F) {
  15. LLVMContext &Ctx = F.getContext();
  16. for (Instruction &I : instructions(F)) {
  17. if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
  18. if (LI->isVolatile() && !O.shouldKeep())
  19. LI->setVolatile(false);
  20. } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
  21. if (SI->isVolatile() && !O.shouldKeep())
  22. SI->setVolatile(false);
  23. } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
  24. if (RMW->isVolatile() && !O.shouldKeep())
  25. RMW->setVolatile(false);
  26. } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
  27. if (CmpXChg->isVolatile() && !O.shouldKeep())
  28. CmpXChg->setVolatile(false);
  29. } else if (MemIntrinsic *MemIntrin = dyn_cast<MemIntrinsic>(&I)) {
  30. if (MemIntrin->isVolatile() && !O.shouldKeep())
  31. MemIntrin->setVolatile(ConstantInt::getFalse(Ctx));
  32. }
  33. }
  34. }
  35. static void removeVolatileInModule(Oracle &O, ReducerWorkItem &WorkItem) {
  36. for (Function &F : WorkItem.getModule())
  37. removeVolatileInFunction(O, F);
  38. }
  39. void llvm::reduceVolatileInstructionsDeltaPass(TestRunner &Test) {
  40. runDeltaPass(Test, removeVolatileInModule, "Reducing Volatile Instructions");
  41. }
  42. static void reduceAtomicSyncScopesInFunction(Oracle &O, Function &F) {
  43. for (Instruction &I : instructions(F)) {
  44. if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
  45. if (LI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
  46. LI->setSyncScopeID(SyncScope::System);
  47. } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) {
  48. if (SI->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
  49. SI->setSyncScopeID(SyncScope::System);
  50. } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(&I)) {
  51. if (RMW->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
  52. RMW->setSyncScopeID(SyncScope::System);
  53. } else if (AtomicCmpXchgInst *CmpXChg = dyn_cast<AtomicCmpXchgInst>(&I)) {
  54. if (CmpXChg->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
  55. CmpXChg->setSyncScopeID(SyncScope::System);
  56. } else if (FenceInst *Fence = dyn_cast<FenceInst>(&I)) {
  57. if (Fence->getSyncScopeID() != SyncScope::System && !O.shouldKeep())
  58. Fence->setSyncScopeID(SyncScope::System);
  59. }
  60. }
  61. }
  62. static void reduceAtomicSyncScopesInModule(Oracle &O,
  63. ReducerWorkItem &WorkItem) {
  64. for (Function &F : WorkItem.getModule())
  65. reduceAtomicSyncScopesInFunction(O, F);
  66. }
  67. void llvm::reduceAtomicSyncScopesDeltaPass(TestRunner &Test) {
  68. runDeltaPass(Test, reduceAtomicSyncScopesInModule,
  69. "Reducing Atomic Sync Scopes");
  70. }
  71. // TODO: Might be helpful to incrementally relax orders
  72. static 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. static void reduceAtomicOrderingInModule(Oracle &O, ReducerWorkItem &WorkItem) {
  94. for (Function &F : WorkItem.getModule())
  95. reduceAtomicOrderingInFunction(O, F);
  96. }
  97. void llvm::reduceAtomicOrderingDeltaPass(TestRunner &Test) {
  98. runDeltaPass(Test, reduceAtomicOrderingInModule, "Reducing Atomic Ordering");
  99. }