[clang] Propagate -ftime-report to offload lto (#122143)
[llvm-project.git] / llvm / tools / llvm-reduce / deltas / ReduceOperands.cpp
blob6bf84f2985dc28349395bbf42148860f4679631d
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 //===----------------------------------------------------------------------===//
9 #include "ReduceOperands.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/InstIterator.h"
12 #include "llvm/IR/InstrTypes.h"
13 #include "llvm/IR/Operator.h"
14 #include "llvm/IR/PatternMatch.h"
15 #include "llvm/IR/Type.h"
17 using namespace llvm;
18 using namespace PatternMatch;
20 static void
21 extractOperandsFromModule(Oracle &O, ReducerWorkItem &WorkItem,
22 function_ref<Value *(Use &)> ReduceValue) {
23 Module &Program = WorkItem.getModule();
25 for (auto &F : Program.functions()) {
26 for (auto &I : instructions(&F)) {
27 if (PHINode *Phi = dyn_cast<PHINode>(&I)) {
28 for (auto &Op : Phi->incoming_values()) {
29 if (!O.shouldKeep()) {
30 if (Value *Reduced = ReduceValue(Op))
31 Phi->setIncomingValueForBlock(Phi->getIncomingBlock(Op), Reduced);
35 continue;
38 for (auto &Op : I.operands()) {
39 if (Value *Reduced = ReduceValue(Op)) {
40 if (!O.shouldKeep())
41 Op.set(Reduced);
48 static bool isOne(Use &Op) {
49 auto *C = dyn_cast<Constant>(Op);
50 return C && C->isOneValue();
53 static bool isZero(Use &Op) {
54 auto *C = dyn_cast<Constant>(Op);
55 return C && C->isNullValue();
58 static bool isZeroOrOneFP(Value *Op) {
59 const APFloat *C;
60 return match(Op, m_APFloat(C)) &&
61 ((C->isZero() && !C->isNegative()) || C->isExactlyValue(1.0));
64 static bool shouldReduceOperand(Use &Op) {
65 Type *Ty = Op->getType();
66 if (Ty->isLabelTy() || Ty->isMetadataTy())
67 return false;
68 // TODO: be more precise about which GEP operands we can reduce (e.g. array
69 // indexes)
70 if (isa<GEPOperator>(Op.getUser()))
71 return false;
72 if (auto *CB = dyn_cast<CallBase>(Op.getUser())) {
73 if (&CB->getCalledOperandUse() == &Op)
74 return false;
76 return true;
79 static bool switchCaseExists(Use &Op, ConstantInt *CI) {
80 SwitchInst *SI = dyn_cast<SwitchInst>(Op.getUser());
81 if (!SI)
82 return false;
83 return SI->findCaseValue(CI) != SI->case_default();
86 void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) {
87 auto ReduceValue = [](Use &Op) -> Value * {
88 if (!shouldReduceOperand(Op))
89 return nullptr;
91 Type *Ty = Op->getType();
92 if (auto *IntTy = dyn_cast<IntegerType>(Ty)) {
93 // Don't duplicate an existing switch case.
94 if (switchCaseExists(Op, ConstantInt::get(IntTy, 1)))
95 return nullptr;
96 // Don't replace existing ones and zeroes.
97 return (isOne(Op) || isZero(Op)) ? nullptr : ConstantInt::get(IntTy, 1);
100 if (Ty->isFloatingPointTy())
101 return isZeroOrOneFP(Op) ? nullptr : ConstantFP::get(Ty, 1.0);
103 if (VectorType *VT = dyn_cast<VectorType>(Ty)) {
104 if (isOne(Op) || isZero(Op) || isZeroOrOneFP(Op))
105 return nullptr;
107 Type *ElementType = VT->getElementType();
108 Constant *C;
109 if (ElementType->isFloatingPointTy()) {
110 C = ConstantFP::get(ElementType, 1.0);
111 } else if (IntegerType *IntTy = dyn_cast<IntegerType>(ElementType)) {
112 C = ConstantInt::get(IntTy, 1);
113 } else {
114 return nullptr;
116 return ConstantVector::getSplat(VT->getElementCount(), C);
119 return nullptr;
121 runDeltaPass(
122 Test,
123 [ReduceValue](Oracle &O, ReducerWorkItem &WorkItem) {
124 extractOperandsFromModule(O, WorkItem, ReduceValue);
126 "Reducing Operands to one");
129 void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) {
130 auto ReduceValue = [](Use &Op) -> Value * {
131 if (!shouldReduceOperand(Op))
132 return nullptr;
133 // Don't duplicate an existing switch case.
134 if (auto *IntTy = dyn_cast<IntegerType>(Op->getType()))
135 if (switchCaseExists(Op, ConstantInt::get(IntTy, 0)))
136 return nullptr;
137 // Don't replace existing zeroes.
138 return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType());
140 runDeltaPass(
141 Test,
142 [ReduceValue](Oracle &O, ReducerWorkItem &Program) {
143 extractOperandsFromModule(O, Program, ReduceValue);
145 "Reducing Operands to zero");
148 void llvm::reduceOperandsNaNDeltaPass(TestRunner &Test) {
149 auto ReduceValue = [](Use &Op) -> Value * {
150 Type *Ty = Op->getType();
151 if (!Ty->isFPOrFPVectorTy())
152 return nullptr;
154 // Prefer 0.0 or 1.0 over NaN.
156 // TODO: Preferring NaN may make more sense because FP operations are more
157 // universally foldable.
158 if (match(Op.get(), m_NaN()) || isZeroOrOneFP(Op.get()))
159 return nullptr;
161 if (VectorType *VT = dyn_cast<VectorType>(Ty)) {
162 return ConstantVector::getSplat(VT->getElementCount(),
163 ConstantFP::getQNaN(VT->getElementType()));
166 return ConstantFP::getQNaN(Ty);
168 runDeltaPass(
169 Test,
170 [ReduceValue](Oracle &O, ReducerWorkItem &Program) {
171 extractOperandsFromModule(O, Program, ReduceValue);
173 "Reducing Operands to NaN");