1 //===- ReduceOperands.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 //
9 // This file implements a function to reduce operands to undef.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ReduceOperands.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/InstIterator.h"
16 
17 using namespace llvm;
18 
19 /// Returns if the given operand is undef.
20 static bool operandIsUndefValue(Use &Op) {
21   if (auto *C = dyn_cast<Constant>(Op)) {
22     return isa<UndefValue>(C);
23   }
24   return false;
25 }
26 
27 /// Returns if an operand can be reduced to undef.
28 /// TODO: make this logic check what types are reducible rather than
29 /// check what types that are not reducible.
30 static bool canReduceOperand(Use &Op) {
31   auto *Ty = Op->getType();
32   // Can't reduce labels to undef
33   return !Ty->isLabelTy() && !operandIsUndefValue(Op);
34 }
35 
36 /// Sets Operands to undef.
37 static void extractOperandsFromModule(Oracle &O, Module &Program) {
38   // Extract Operands from the module.
39   for (auto &F : Program.functions()) {
40     for (auto &I : instructions(&F)) {
41       for (auto &Op : I.operands()) {
42         // Filter Operands then set to undef.
43         if (canReduceOperand(Op) && !O.shouldKeep()) {
44           auto *Ty = Op->getType();
45           Op.set(UndefValue::get(Ty));
46         }
47       }
48     }
49   }
50 }
51 
52 /// Counts the amount of operands in the module that can be reduced.
53 static int countOperands(Module &Program) {
54   int Count = 0;
55   for (auto &F : Program.functions()) {
56     for (auto &I : instructions(&F)) {
57       for (auto &Op : I.operands()) {
58         if (canReduceOperand(Op)) {
59           Count++;
60         }
61       }
62     }
63   }
64   return Count;
65 }
66 
67 void llvm::reduceOperandsDeltaPass(TestRunner &Test) {
68   errs() << "*** Reducing Operands...\n";
69   int Count = countOperands(Test.getProgram());
70   runDeltaPass(Test, Count, extractOperandsFromModule);
71 }
72