ReduceOperands.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //===----------------------------------------------------------------------===//
  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 "ReduceOperands.h"
  9. #include "llvm/IR/Constants.h"
  10. #include "llvm/IR/InstIterator.h"
  11. #include "llvm/IR/InstrTypes.h"
  12. #include "llvm/IR/Operator.h"
  13. #include "llvm/IR/Type.h"
  14. using namespace llvm;
  15. static void
  16. extractOperandsFromModule(Oracle &O, Module &Program,
  17. function_ref<Value *(Use &)> ReduceValue) {
  18. for (auto &F : Program.functions()) {
  19. for (auto &I : instructions(&F)) {
  20. for (auto &Op : I.operands()) {
  21. Value *Reduced = ReduceValue(Op);
  22. if (Reduced && !O.shouldKeep())
  23. Op.set(Reduced);
  24. }
  25. }
  26. }
  27. }
  28. static bool isOne(Use &Op) {
  29. auto *C = dyn_cast<Constant>(Op);
  30. return C && C->isOneValue();
  31. }
  32. static bool isZero(Use &Op) {
  33. auto *C = dyn_cast<Constant>(Op);
  34. return C && C->isNullValue();
  35. }
  36. static bool shouldReduceOperand(Use &Op) {
  37. Type *Ty = Op->getType();
  38. if (Ty->isLabelTy() || Ty->isMetadataTy())
  39. return false;
  40. // TODO: be more precise about which GEP operands we can reduce (e.g. array
  41. // indexes)
  42. if (isa<GEPOperator>(Op.getUser()))
  43. return false;
  44. if (auto *CB = dyn_cast<CallBase>(Op.getUser())) {
  45. if (&CB->getCalledOperandUse() == &Op)
  46. return false;
  47. }
  48. return true;
  49. }
  50. void llvm::reduceOperandsUndefDeltaPass(TestRunner &Test) {
  51. errs() << "*** Reducing Operands to undef...\n";
  52. auto ReduceValue = [](Use &Op) -> Value * {
  53. if (!shouldReduceOperand(Op))
  54. return nullptr;
  55. // Don't replace existing ConstantData Uses.
  56. return isa<ConstantData>(*Op) ? nullptr : UndefValue::get(Op->getType());
  57. };
  58. runDeltaPass(Test, [ReduceValue](Oracle &O, Module &Program) {
  59. extractOperandsFromModule(O, Program, ReduceValue);
  60. });
  61. }
  62. void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) {
  63. errs() << "*** Reducing Operands to one...\n";
  64. auto ReduceValue = [](Use &Op) -> Value * {
  65. // TODO: support floats
  66. if (!shouldReduceOperand(Op))
  67. return nullptr;
  68. auto *Ty = dyn_cast<IntegerType>(Op->getType());
  69. if (!Ty)
  70. return nullptr;
  71. // Don't replace existing ones and zeroes.
  72. return (isOne(Op) || isZero(Op)) ? nullptr : ConstantInt::get(Ty, 1);
  73. };
  74. runDeltaPass(Test, [ReduceValue](Oracle &O, Module &Program) {
  75. extractOperandsFromModule(O, Program, ReduceValue);
  76. });
  77. }
  78. void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) {
  79. errs() << "*** Reducing Operands to zero...\n";
  80. auto ReduceValue = [](Use &Op) -> Value * {
  81. if (!shouldReduceOperand(Op))
  82. return nullptr;
  83. // Don't replace existing zeroes.
  84. return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType());
  85. };
  86. runDeltaPass(Test, [ReduceValue](Oracle &O, Module &Program) {
  87. extractOperandsFromModule(O, Program, ReduceValue);
  88. });
  89. }