LLVM  13.0.0git
InstructionCost.h
Go to the documentation of this file.
1 //===- InstructionCost.h ----------------------------------------*- C++ -*-===//
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 /// \file
9 /// This file defines an InstructionCost class that is used when calculating
10 /// the cost of an instruction, or a group of instructions. In addition to a
11 /// numeric value representing the cost the class also contains a state that
12 /// can be used to encode particular properties, i.e. a cost being invalid or
13 /// unknown.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_SUPPORT_INSTRUCTIONCOST_H
18 #define LLVM_SUPPORT_INSTRUCTIONCOST_H
19 
20 #include "llvm/ADT/Optional.h"
21 
22 namespace llvm {
23 
24 class raw_ostream;
25 
27 public:
28  using CostType = int;
29 
30  /// These states can currently be used to indicate whether a cost is valid or
31  /// invalid. Examples of an invalid cost might be where the cost is
32  /// prohibitively expensive and the user wants to prevent certain
33  /// optimizations being performed. Or perhaps the cost is simply unknown
34  /// because the operation makes no sense in certain circumstances. These
35  /// states can be expanded in future to support other cases if necessary.
36  enum CostState { Valid, Invalid };
37 
38 private:
39  CostType Value = 0;
40  CostState State = Valid;
41 
42  void propagateState(const InstructionCost &RHS) {
43  if (RHS.State == Invalid)
44  State = Invalid;
45  }
46 
47 public:
48  // A default constructed InstructionCost is a valid zero cost
49  InstructionCost() = default;
50 
51  InstructionCost(CostState) = delete;
52  InstructionCost(CostType Val) : Value(Val), State(Valid) {}
53 
55  InstructionCost Tmp(Val);
56  Tmp.setInvalid();
57  return Tmp;
58  }
59 
60  bool isValid() const { return State == Valid; }
61  void setValid() { State = Valid; }
62  void setInvalid() { State = Invalid; }
63  CostState getState() const { return State; }
64 
65  /// This function is intended to be used as sparingly as possible, since the
66  /// class provides the full range of operator support required for arithmetic
67  /// and comparisons.
69  if (isValid())
70  return Value;
71  return None;
72  }
73 
74  /// For all of the arithmetic operators provided here any invalid state is
75  /// perpetuated and cannot be removed. Once a cost becomes invalid it stays
76  /// invalid, and it also inherits any invalid state from the RHS. Regardless
77  /// of the state, arithmetic and comparisons work on the actual values in the
78  /// same way as they would on a basic type, such as integer.
79 
81  propagateState(RHS);
82  Value += RHS.Value;
83  return *this;
84  }
85 
87  InstructionCost RHS2(RHS);
88  *this += RHS2;
89  return *this;
90  }
91 
93  propagateState(RHS);
94  Value -= RHS.Value;
95  return *this;
96  }
97 
99  InstructionCost RHS2(RHS);
100  *this -= RHS2;
101  return *this;
102  }
103 
105  propagateState(RHS);
106  Value *= RHS.Value;
107  return *this;
108  }
109 
111  InstructionCost RHS2(RHS);
112  *this *= RHS2;
113  return *this;
114  }
115 
117  propagateState(RHS);
118  Value /= RHS.Value;
119  return *this;
120  }
121 
123  InstructionCost RHS2(RHS);
124  *this /= RHS2;
125  return *this;
126  }
127 
129  *this += 1;
130  return *this;
131  }
132 
134  InstructionCost Copy = *this;
135  ++*this;
136  return Copy;
137  }
138 
140  *this -= 1;
141  return *this;
142  }
143 
145  InstructionCost Copy = *this;
146  --*this;
147  return Copy;
148  }
149 
150  /// For the comparison operators we have chosen to use lexicographical
151  /// ordering where valid costs are always considered to be less than invalid
152  /// costs. This avoids having to add asserts to the comparison operators that
153  /// the states are valid and users can test for validity of the cost
154  /// explicitly.
155  bool operator<(const InstructionCost &RHS) const {
156  if (State != RHS.State)
157  return State < RHS.State;
158  return Value < RHS.Value;
159  }
160 
161  // Implement in terms of operator< to ensure that the two comparisons stay in
162  // sync
163  bool operator==(const InstructionCost &RHS) const {
164  return !(*this < RHS) && !(RHS < *this);
165  }
166 
167  bool operator!=(const InstructionCost &RHS) const { return !(*this == RHS); }
168 
169  bool operator==(const CostType RHS) const {
170  InstructionCost RHS2(RHS);
171  return *this == RHS2;
172  }
173 
174  bool operator!=(const CostType RHS) const { return !(*this == RHS); }
175 
176  bool operator>(const InstructionCost &RHS) const { return RHS < *this; }
177 
178  bool operator<=(const InstructionCost &RHS) const { return !(RHS < *this); }
179 
180  bool operator>=(const InstructionCost &RHS) const { return !(*this < RHS); }
181 
182  bool operator<(const CostType RHS) const {
183  InstructionCost RHS2(RHS);
184  return *this < RHS2;
185  }
186 
187  bool operator>(const CostType RHS) const {
188  InstructionCost RHS2(RHS);
189  return *this > RHS2;
190  }
191 
192  bool operator<=(const CostType RHS) const {
193  InstructionCost RHS2(RHS);
194  return *this <= RHS2;
195  }
196 
197  bool operator>=(const CostType RHS) const {
198  InstructionCost RHS2(RHS);
199  return *this >= RHS2;
200  }
201 
202  void print(raw_ostream &OS) const;
203 
204  template <class Function>
205  auto map(const Function &F) const -> InstructionCost {
206  if (isValid())
207  return F(*getValue());
208  return getInvalid();
209  }
210 };
211 
213  const InstructionCost &RHS) {
214  InstructionCost LHS2(LHS);
215  LHS2 += RHS;
216  return LHS2;
217 }
218 
220  const InstructionCost &RHS) {
221  InstructionCost LHS2(LHS);
222  LHS2 -= RHS;
223  return LHS2;
224 }
225 
227  const InstructionCost &RHS) {
228  InstructionCost LHS2(LHS);
229  LHS2 *= RHS;
230  return LHS2;
231 }
232 
234  const InstructionCost &RHS) {
235  InstructionCost LHS2(LHS);
236  LHS2 /= RHS;
237  return LHS2;
238 }
239 
241  V.print(OS);
242  return OS;
243 }
244 
245 } // namespace llvm
246 
247 #endif
llvm::InstructionCost::operator>
bool operator>(const InstructionCost &RHS) const
Definition: InstructionCost.h:176
llvm::InstructionCost
Definition: InstructionCost.h:26
llvm::InstructionCost::operator+=
InstructionCost & operator+=(const CostType RHS)
Definition: InstructionCost.h:86
llvm
Definition: AllocatorList.h:23
Optional.h
llvm::InstructionCost::getValue
Optional< CostType > getValue() const
This function is intended to be used as sparingly as possible, since the class provides the full rang...
Definition: InstructionCost.h:68
llvm::InstructionCost::operator>=
bool operator>=(const CostType RHS) const
Definition: InstructionCost.h:197
llvm::InstructionCost::map
auto map(const Function &F) const -> InstructionCost
Definition: InstructionCost.h:205
llvm::InstructionCost::CostState
CostState
These states can currently be used to indicate whether a cost is valid or invalid.
Definition: InstructionCost.h:36
llvm::InstructionCost::operator++
InstructionCost & operator++()
Definition: InstructionCost.h:128
llvm::Function
Definition: Function.h:61
llvm::InstructionCost::InstructionCost
InstructionCost()=default
llvm::InstructionCost::operator<=
bool operator<=(const InstructionCost &RHS) const
Definition: InstructionCost.h:178
llvm::InstructionCost::operator>
bool operator>(const CostType RHS) const
Definition: InstructionCost.h:187
llvm::Optional
Definition: APInt.h:33
llvm::InstructionCost::operator<=
bool operator<=(const CostType RHS) const
Definition: InstructionCost.h:192
llvm::InstructionCost::print
void print(raw_ostream &OS) const
Definition: InstructionCost.cpp:19
llvm::operator/
Align operator/(Align Lhs, uint64_t Divisor)
Definition: Alignment.h:337
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::InstructionCost::operator--
InstructionCost & operator--()
Definition: InstructionCost.h:139
llvm::InstructionCost::operator/=
InstructionCost & operator/=(const InstructionCost &RHS)
Definition: InstructionCost.h:116
llvm::InstructionCost::operator<
bool operator<(const CostType RHS) const
Definition: InstructionCost.h:182
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::operator-
APInt operator-(APInt)
Definition: APInt.h:2112
llvm::InstructionCost::operator+=
InstructionCost & operator+=(const InstructionCost &RHS)
For all of the arithmetic operators provided here any invalid state is perpetuated and cannot be remo...
Definition: InstructionCost.h:80
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
llvm::InstructionCost::operator==
bool operator==(const CostType RHS) const
Definition: InstructionCost.h:169
llvm::InstructionCost::operator!=
bool operator!=(const InstructionCost &RHS) const
Definition: InstructionCost.h:167
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::None
const NoneType None
Definition: None.h:23
llvm::InstructionCost::setInvalid
void setInvalid()
Definition: InstructionCost.h:62
llvm::InstructionCost::CostType
int CostType
Definition: InstructionCost.h:28
llvm::InstructionCost::operator<
bool operator<(const InstructionCost &RHS) const
For the comparison operators we have chosen to use lexicographical ordering where valid costs are alw...
Definition: InstructionCost.h:155
llvm::operator+
APInt operator+(APInt a, const APInt &b)
Definition: APInt.h:2117
llvm::InstructionCost::operator!=
bool operator!=(const CostType RHS) const
Definition: InstructionCost.h:174
llvm::operator*
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2159
llvm::InstructionCost::operator--
InstructionCost operator--(int)
Definition: InstructionCost.h:144
llvm::InstructionCost::operator*=
InstructionCost & operator*=(const InstructionCost &RHS)
Definition: InstructionCost.h:104
llvm::InstructionCost::operator-=
InstructionCost & operator-=(const CostType RHS)
Definition: InstructionCost.h:98
llvm::InstructionCost::operator-=
InstructionCost & operator-=(const InstructionCost &RHS)
Definition: InstructionCost.h:92
llvm::InstructionCost::isValid
bool isValid() const
Definition: InstructionCost.h:60
llvm::InstructionCost::setValid
void setValid()
Definition: InstructionCost.h:61
llvm::InstructionCost::operator==
bool operator==(const InstructionCost &RHS) const
Definition: InstructionCost.h:163
llvm::InstructionCost::getInvalid
static InstructionCost getInvalid(CostType Val=0)
Definition: InstructionCost.h:54
llvm::InstructionCost::operator++
InstructionCost operator++(int)
Definition: InstructionCost.h:133
llvm::InstructionCost::Invalid
@ Invalid
Definition: InstructionCost.h:36
llvm::InstructionCost::getState
CostState getState() const
Definition: InstructionCost.h:63
llvm::InstructionCost::operator>=
bool operator>=(const InstructionCost &RHS) const
Definition: InstructionCost.h:180
llvm::InstructionCost::operator/=
InstructionCost & operator/=(const CostType RHS)
Definition: InstructionCost.h:122
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::InstructionCost::InstructionCost
InstructionCost(CostType Val)
Definition: InstructionCost.h:52
llvm::InstructionCost::Valid
@ Valid
Definition: InstructionCost.h:36
llvm::InstructionCost::operator*=
InstructionCost & operator*=(const CostType RHS)
Definition: InstructionCost.h:110