retdec
arithm_expr_evaluator.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_LLVMIR2HLL_EVALUATOR_ARITHM_EXPR_EVALUATOR_H
8 #define RETDEC_LLVMIR2HLL_EVALUATOR_ARITHM_EXPR_EVALUATOR_H
9 
10 #include <optional>
11 #include <stack>
12 #include <string>
13 
22 
23 namespace retdec {
24 namespace llvmir2hll {
25 
38 public:
40  using APSIntPair = std::pair<llvm::APSInt, llvm::APSInt>;
41 
43  using APFloatPair = std::pair<llvm::APFloat, llvm::APFloat>;
44 
46  using ConstIntPair = std::pair<ShPtr<ConstInt>, ShPtr<ConstInt>>;
47 
49  using ConstFloatPair = std::pair<ShPtr<ConstFloat>, ShPtr<ConstFloat>>;
50 
52  using ConstBoolPair = std::pair<ShPtr<ConstBool>, ShPtr<ConstBool>>;
53 
55  using ConstPair = std::pair<ShPtr<Constant>, ShPtr<Constant>>;
56 
58  using ConstStack = std::stack<ShPtr<Constant>>;
59 
61  using VarConstMap = std::map<ShPtr<Variable>, ShPtr<Constant>>;
62 
63 public:
67  virtual std::string getId() const = 0;
68  virtual std::optional<bool> toBool(ShPtr<Expression> expr, VarConstMap
70 
73  &varValues);
74 
75  template<typename ConstType>
76  static std::optional<std::pair<ShPtr<ConstType>, ShPtr<ConstType>>> castConstPair(
77  const ConstPair &constPair);
78 
79 protected:
80  ArithmExprEvaluator() = default;
81 
82  static APSIntPair getAPSIntsFromConstants(const std::optional<ConstIntPair>
83  &constIntPair);
84  static APFloatPair getAPFloatsFromConstants(const std::optional<ConstFloatPair>
86  static bool isConstantZero(ShPtr<Constant> constant);
87 
88 protected:
90  bool canBeEvaluated = true;
91 
92 private:
93  using LLVMAPIntAPIntBoolOp = llvm::APInt (llvm::APInt::*)(
94  const llvm::APInt &, bool &) const;
95  using LLVMBoolAPIntOp = bool (llvm::APInt::*)(
96  const llvm::APInt &) const;
97  using LLVMAPIntAPIntOp = llvm::APInt (llvm::APInt::*)(
98  const llvm::APInt &) const;
99  using LLVMAPFloatOp = llvm::APFloat::opStatus (llvm::APFloat::*)(
100  const llvm::APFloat &, llvm::APFloat::roundingMode);
101  // Since LLVM 3.9, APFloat::mode() and APFloat::remainder() do not accept
102  // roundingMode, so we have to create another alias for operations without
103  // the rounding mode.
104  using LLVMAPFloatOpNoRounding = llvm::APFloat::opStatus (llvm::APFloat::*)(
105  const llvm::APFloat &);
106 
107 private:
111  // Expressions
112  virtual void visit(ShPtr<AddOpExpr> expr) override;
113  virtual void visit(ShPtr<AddressOpExpr> expr) override;
114  virtual void visit(ShPtr<AndOpExpr> expr) override;
115  virtual void visit(ShPtr<ArrayIndexOpExpr> expr) override;
116  virtual void visit(ShPtr<BitAndOpExpr> expr) override;
117  virtual void visit(ShPtr<BitOrOpExpr> expr) override;
118  virtual void visit(ShPtr<BitShlOpExpr> expr) override;
119  virtual void visit(ShPtr<BitShrOpExpr> expr) override;
120  virtual void visit(ShPtr<BitXorOpExpr> expr) override;
121  virtual void visit(ShPtr<CallExpr> expr) override;
122  virtual void visit(ShPtr<DerefOpExpr> expr) override;
123  virtual void visit(ShPtr<DivOpExpr> expr) override;
124  virtual void visit(ShPtr<EqOpExpr> expr) override;
125  virtual void visit(ShPtr<GtEqOpExpr> expr) override;
126  virtual void visit(ShPtr<GtOpExpr> expr) override;
127  virtual void visit(ShPtr<LtEqOpExpr> expr) override;
128  virtual void visit(ShPtr<LtOpExpr> expr) override;
129  virtual void visit(ShPtr<ModOpExpr> expr) override;
130  virtual void visit(ShPtr<MulOpExpr> expr) override;
131  virtual void visit(ShPtr<NegOpExpr> expr) override;
132  virtual void visit(ShPtr<NeqOpExpr> expr) override;
133  virtual void visit(ShPtr<NotOpExpr> expr) override;
134  virtual void visit(ShPtr<OrOpExpr> expr) override;
135  virtual void visit(ShPtr<StructIndexOpExpr> expr) override;
136  virtual void visit(ShPtr<SubOpExpr> expr) override;
137  virtual void visit(ShPtr<TernaryOpExpr> expr) override;
138  virtual void visit(ShPtr<Variable> var) override;
139  // Casts
140  virtual void visit(ShPtr<BitCastExpr> expr) override;
141  virtual void visit(ShPtr<ExtCastExpr> expr) override;
142  virtual void visit(ShPtr<FPToIntCastExpr> expr) override;
143  virtual void visit(ShPtr<IntToFPCastExpr> expr) override;
144  virtual void visit(ShPtr<IntToPtrCastExpr> expr) override;
145  virtual void visit(ShPtr<PtrToIntCastExpr> expr) override;
146  virtual void visit(ShPtr<TruncCastExpr> expr) override;
147  // Constants
148  virtual void visit(ShPtr<ConstArray> constant) override;
149  virtual void visit(ShPtr<ConstBool> constant) override;
150  virtual void visit(ShPtr<ConstFloat> constant) override;
151  virtual void visit(ShPtr<ConstInt> constant) override;
152  virtual void visit(ShPtr<ConstNullPointer> constant) override;
153  virtual void visit(ShPtr<ConstString> constant) override;
154  virtual void visit(ShPtr<ConstStruct> constant) override;
155  virtual void visit(ShPtr<ConstSymbol> constant) override;
157 
158  // Resolve types.
159  virtual void resolveTypesUnaryOp(ShPtr<Constant> &operand);
160  virtual void resolveTypesBinaryOp(ConstPair &constPair);
161 
162  // Resolve operators specifications.
163  virtual void resolveOpSpecifications(ShPtr<AddOpExpr> expr,
164  ConstPair &constPair);
165  virtual void resolveOpSpecifications(ShPtr<AndOpExpr> expr,
166  ConstPair &constPair);
168  ConstPair &constPair);
170  ConstPair &constPair);
172  ConstPair &constPair);
174  ConstPair &constPair);
176  ConstPair &constPair);
177  virtual void resolveOpSpecifications(ShPtr<DivOpExpr> expr,
178  ConstPair &constPair);
179  virtual void resolveOpSpecifications(ShPtr<EqOpExpr> expr,
180  ConstPair &constPair);
181  virtual void resolveOpSpecifications(ShPtr<GtEqOpExpr> expr,
182  ConstPair &constPair);
183  virtual void resolveOpSpecifications(ShPtr<GtOpExpr> expr,
184  ConstPair &constPair);
185  virtual void resolveOpSpecifications(ShPtr<LtEqOpExpr> expr,
186  ConstPair &constPair);
187  virtual void resolveOpSpecifications(ShPtr<LtOpExpr> expr,
188  ConstPair &constPair);
189  virtual void resolveOpSpecifications(ShPtr<ModOpExpr> expr,
190  ConstPair &constPair);
191  virtual void resolveOpSpecifications(ShPtr<MulOpExpr> expr,
192  ConstPair &constPair);
193  virtual void resolveOpSpecifications(ShPtr<NegOpExpr> expr,
194  ShPtr<Constant> &constant);
195  virtual void resolveOpSpecifications(ShPtr<NeqOpExpr> expr,
196  ConstPair &constPair);
197  virtual void resolveOpSpecifications(ShPtr<NotOpExpr> expr,
198  ShPtr<Constant> &constant);
199  virtual void resolveOpSpecifications(ShPtr<OrOpExpr> expr,
200  ConstPair &constPair);
201  virtual void resolveOpSpecifications(ShPtr<SubOpExpr> expr,
202  ConstPair &constPair);
203 
204  // Resolve casts.
205  virtual void resolveCast(ShPtr<BitCastExpr> expr, ShPtr<Constant> &constant);
206  virtual void resolveCast(ShPtr<ExtCastExpr> expr, ShPtr<Constant> &constant);
207  virtual void resolveCast(ShPtr<FPToIntCastExpr> expr,
208  ShPtr<Constant> &constant);
209  virtual void resolveCast(ShPtr<IntToFPCastExpr> expr,
210  ShPtr<Constant> &constant);
211  virtual void resolveCast(ShPtr<TruncCastExpr> expr,
212  ShPtr<Constant> &constant);
213 
214  // Resolve overflow.
215  virtual void resolveOverflowForAPInt(bool overflow);
216  virtual void resolveOverflowForAPFloat(llvm::APFloat::opStatus opStatus);
217 
218  // Perform functions.
219  ShPtr<ConstFloat> performOperationOverApFloat(const std::optional<ConstFloatPair>
220  &constFloatPair, LLVMAPFloatOp op, llvm::APFloat::opStatus &status);
221  ShPtr<ConstFloat> performOperationOverApFloat(const std::optional<ConstFloatPair>
222  &constFloatPair, LLVMAPFloatOpNoRounding op, llvm::APFloat::opStatus &status);
223  llvm::APFloat::cmpResult performOperationOverApFloat(const std::optional<
224  ConstFloatPair> &constFloatPair);
225  ShPtr<ConstInt> performOperationOverApInt(const std::optional<ConstIntPair>
226  &constIntPair, LLVMAPIntAPIntBoolOp op, bool &overflow);
227  ShPtr<ConstInt> performOperationOverApInt(const std::optional<ConstIntPair>
228  &constIntPair, LLVMAPIntAPIntOp op);
229  ShPtr<ConstBool> performOperationOverApInt(const std::optional<ConstIntPair>
230  &constIntPair, LLVMBoolAPIntOp op);
231 
232  // Other functions.
235  void resolveOverflows(bool overflow, llvm::APFloat::opStatus opStatus);
236 
237 private:
240 
243 };
244 
245 } // namespace llvmir2hll
246 } // namespace retdec
247 
248 #endif
Base class for cast instructions.
A base class for all evaluators.
Definition: arithm_expr_evaluator.h:37
std::stack< ShPtr< Constant > > ConstStack
Stack of constats.
Definition: arithm_expr_evaluator.h:58
ConstPair getOperandsForBinaryOpAndResolveTypes()
Get operands from stackOfResults and call resolve types method that is implemented in sub-evaluators.
Definition: arithm_expr_evaluator.cpp:969
std::pair< ShPtr< ConstFloat >, ShPtr< ConstFloat > > ConstFloatPair
Pair of float constants.
Definition: arithm_expr_evaluator.h:49
virtual void resolveOverflowForAPInt(bool overflow)
Definition: arithm_expr_evaluator.cpp:945
virtual void resolveOverflowForAPFloat(llvm::APFloat::opStatus opStatus)
Definition: arithm_expr_evaluator.cpp:947
llvm::APFloat::opStatus(llvm::APFloat::*)(const llvm::APFloat &) LLVMAPFloatOpNoRounding
Definition: arithm_expr_evaluator.h:105
virtual void resolveCast(ShPtr< BitCastExpr > expr, ShPtr< Constant > &constant)
Definition: arithm_expr_evaluator.cpp:930
ConstStack stackOfResults
Stack of results during the evaluation.
Definition: arithm_expr_evaluator.h:242
virtual void resolveTypesUnaryOp(ShPtr< Constant > &operand)
Definition: arithm_expr_evaluator.cpp:866
std::pair< ShPtr< ConstBool >, ShPtr< ConstBool > > ConstBoolPair
Pair of bool constants.
Definition: arithm_expr_evaluator.h:52
static std::optional< std::pair< ShPtr< ConstType >, ShPtr< ConstType > > > castConstPair(const ConstPair &constPair)
Casts the constants in constPair to the given type.
Definition: arithm_expr_evaluator.cpp:985
ShPtr< Constant > evaluate(ShPtr< Expression > expr)
Evaluate an expr.
Definition: arithm_expr_evaluator.cpp:105
virtual void resolveOpSpecifications(ShPtr< AddOpExpr > expr, ConstPair &constPair)
Definition: arithm_expr_evaluator.cpp:870
virtual void visit(ShPtr< GlobalVarDef > varDef) override
Definition: ordered_all_visitor.cpp:95
void resolveOverflows(bool overflow, llvm::APFloat::opStatus opStatus)
Call resolve methods for overflow.
Definition: arithm_expr_evaluator.cpp:1142
std::map< ShPtr< Variable >, ShPtr< Constant > > VarConstMap
Mapping of variables to constants.
Definition: arithm_expr_evaluator.h:61
virtual void resolveTypesBinaryOp(ConstPair &constPair)
Definition: arithm_expr_evaluator.cpp:868
static APSIntPair getAPSIntsFromConstants(const std::optional< ConstIntPair > &constIntPair)
Create APSIntPair from constIntPair and return it.
Definition: arithm_expr_evaluator.cpp:1117
virtual std::optional< bool > toBool(ShPtr< Expression > expr, VarConstMap varValues=VarConstMap())
Evaluate expr and return if result is bool.
Definition: arithm_expr_evaluator.cpp:139
static APFloatPair getAPFloatsFromConstants(const std::optional< ConstFloatPair > &ConstFloatPair)
Create APFloatPair from constFloatPair and return it.
Definition: arithm_expr_evaluator.cpp:1130
virtual std::string getId() const =0
Returns the ID of the optimizer.
ShPtr< Constant > getOperandForUnaryOpAndResolveTypes()
Get operand from stackOfResults and call resolve types method that is implemented in sub-evaluators.
Definition: arithm_expr_evaluator.cpp:956
bool canBeEvaluated
Signalizes if evaluation can go on.
Definition: arithm_expr_evaluator.h:90
bool(llvm::APInt::*)(const llvm::APInt &) const LLVMBoolAPIntOp
Definition: arithm_expr_evaluator.h:96
llvm::APInt(llvm::APInt::*)(const llvm::APInt &, bool &) const LLVMAPIntAPIntBoolOp
Definition: arithm_expr_evaluator.h:94
llvm::APFloat::opStatus(llvm::APFloat::*)(const llvm::APFloat &, llvm::APFloat::roundingMode) LLVMAPFloatOp
Definition: arithm_expr_evaluator.h:100
std::pair< ShPtr< Constant >, ShPtr< Constant > > ConstPair
Pair of constants.
Definition: arithm_expr_evaluator.h:55
const VarConstMap * varValues
Map of constants that substitute variables in evaluation.
Definition: arithm_expr_evaluator.h:239
ShPtr< ConstFloat > performOperationOverApFloat(const std::optional< ConstFloatPair > &constFloatPair, LLVMAPFloatOp op, llvm::APFloat::opStatus &status)
Perform the operation specified by op on the first and the second operand in constFloatPair.
Definition: arithm_expr_evaluator.cpp:1089
static bool isConstantZero(ShPtr< Constant > constant)
Return if constant is a ConstInt or a ConstFloat zero.
Definition: arithm_expr_evaluator.cpp:1155
llvm::APInt(llvm::APInt::*)(const llvm::APInt &) const LLVMAPIntAPIntOp
Definition: arithm_expr_evaluator.h:98
std::pair< llvm::APFloat, llvm::APFloat > APFloatPair
Pair of llvm::APFloat.
Definition: arithm_expr_evaluator.h:43
std::pair< llvm::APSInt, llvm::APSInt > APSIntPair
Pair of llvm::APSInt.
Definition: arithm_expr_evaluator.h:40
std::pair< ShPtr< ConstInt >, ShPtr< ConstInt > > ConstIntPair
Pair of integer constants.
Definition: arithm_expr_evaluator.h:46
ShPtr< ConstInt > performOperationOverApInt(const std::optional< ConstIntPair > &constIntPair, LLVMAPIntAPIntBoolOp op, bool &overflow)
Perform the operation specified by op on the first and the second operand in constIntPair.
Definition: arithm_expr_evaluator.cpp:1011
A visitor that visits everything in an ordered way.
Definition: ordered_all_visitor.h:44
virtual void visit(ShPtr< GlobalVarDef > varDef) override
Definition: ordered_all_visitor.cpp:95
A mixin to make classes non-copyable.
Definition: non_copyable.h:27
A bool constant.
A float constant.
An integer constant.
A base class for all constants.
A library providing API for working with back-end IR.
std::shared_ptr< T > ShPtr
An alias for a shared pointer.
Definition: smart_ptr.h:18
Definition: archive_wrapper.h:19
A mixin to make classes non-copyable.
A visitor that visits everything in an ordered way.
Aliases for several useful types.