llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
symbolic_visitor.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include "passes/pre_eval/symbolic_value.h"
8 #include "passes/pre_eval/symbolic_context.h"
9 
10 
14 template<typename T>
16 public:
19  : eval_(eval)
20  , ctx_(eval_.GetContext())
21  , inst_(i)
22  , lhs_(eval_.Find(i.GetLHS()))
23  , rhs_(eval_.Find(i.GetRHS()))
24  {
25  }
26 
28  bool Evaluate();
29 
30 protected:
32  struct Undefined {};
34  struct Scalar {};
36  struct LowerBoundedInteger { const APInt &Bound; };
38  struct Mask { const APInt &Known; const APInt &Value; };
40  struct Value { const SymbolicPointer::Ref &Ptr; };
42  struct Pointer { const SymbolicPointer::Ref &Ptr; };
44  struct Nullable { const SymbolicPointer::Ref &Ptr; };
45 
46  #define VISITOR(lhs, rhs) \
47  virtual bool Visit(lhs, rhs) \
48  { llvm_unreachable(("not implemented: " #lhs " and " #rhs)); }
49 
50  #define VISITOR_GROUP(lhs) \
51  VISITOR(lhs, Scalar) \
52  VISITOR(lhs, LowerBoundedInteger) \
53  VISITOR(lhs, Mask) \
54  VISITOR(lhs, const APInt &) \
55  VISITOR(lhs, const APFloat &) \
56  VISITOR(lhs, Pointer) \
57  VISITOR(lhs, Undefined) \
58  VISITOR(lhs, Value) \
59  VISITOR(lhs, Nullable)
60 
61  VISITOR_GROUP(Scalar);
62  VISITOR_GROUP(LowerBoundedInteger);
63  VISITOR_GROUP(Mask);
64  VISITOR_GROUP(const APInt &);
65  VISITOR_GROUP(const APFloat &);
66  VISITOR_GROUP(Pointer);
67  VISITOR_GROUP(Undefined);
68  VISITOR_GROUP(Value);
69  VISITOR_GROUP(Nullable);
70 
71  #undef VISITOR_GROUP
72  #undef VISITOR
73 
74 protected:
76  bool SetInteger(const APInt &i) { return eval_.SetInteger(i); }
78  bool SetLowerBounded(const APInt &i) { return eval_.SetLowerBounded(i); }
80  bool SetUndefined() { return eval_.SetUndefined(); }
82  bool SetScalar() { return eval_.SetScalar(); }
84  bool SetPointer(const SymbolicPointer::Ref &p) { return eval_.SetPointer(p); }
86  bool SetNullable(const SymbolicPointer::Ref &p) { return eval_.SetNullable(p); }
88  bool SetValue(const SymbolicPointer::Ref &p) { return eval_.SetValue(p); }
90  bool SetMask(const APInt &k, const APInt &v) { return eval_.SetMask(k, v); }
91 
92 protected:
98  T &inst_;
103 };
104 
105 // -----------------------------------------------------------------------------
106 template <typename T>
108 {
109  #define DISPATCH(value) \
110  switch (rhs_.GetKind()) { \
111  case SymbolicValue::Kind::SCALAR: \
112  return Visit(value, Scalar{}); \
113  case SymbolicValue::Kind::LOWER_BOUNDED_INTEGER: \
114  return Visit(value, LowerBoundedInteger{rhs_.GetInteger()}); \
115  case SymbolicValue::Kind::MASKED_INTEGER: \
116  return Visit(value, Mask{rhs_.GetMaskKnown(), rhs_.GetMaskValue()}); \
117  case SymbolicValue::Kind::UNDEFINED: \
118  return Visit(value, Undefined{}); \
119  case SymbolicValue::Kind::INTEGER: \
120  return Visit(value, rhs_.GetInteger()); \
121  case SymbolicValue::Kind::FLOAT: \
122  return Visit(value, rhs_.GetFloat()); \
123  case SymbolicValue::Kind::POINTER: \
124  return Visit(value, Pointer{rhs_.GetPointer()}); \
125  case SymbolicValue::Kind::NULLABLE: \
126  return Visit(value, Nullable{rhs_.GetPointer()}); \
127  case SymbolicValue::Kind::VALUE: \
128  return Visit(value, Value{rhs_.GetPointer()}); \
129  } \
130  llvm_unreachable("invalid rhs kind");
131 
132  switch (lhs_.GetKind()) {
134  DISPATCH((Scalar{}));
136  DISPATCH((LowerBoundedInteger{lhs_.GetInteger()}));
138  DISPATCH((Mask{lhs_.GetMaskKnown(), lhs_.GetMaskValue()}));
140  DISPATCH((lhs_.GetInteger()));
142  DISPATCH((lhs_.GetFloat()));
144  DISPATCH((Pointer{lhs_.GetPointer()}));
146  DISPATCH((Value{lhs_.GetPointer()}));
148  DISPATCH((Nullable{lhs_.GetPointer()}));
150  DISPATCH((Undefined{}));
151  }
152  llvm_unreachable("invalid lhs kind");
153 #undef DISPATCH
154 }
SymbolicContext
Definition: symbolic_context.h:28
SymbolicValue
Definition: symbolic_value.h:24
SymbolicEval::SetUndefined
bool SetUndefined()
Helper to return a scalar.
Definition: symbolic_eval.h:45
BinaryVisitor::SetNullable
bool SetNullable(const SymbolicPointer::Ref &p)
Forward to evaluator, return a nullable.
Definition: symbolic_visitor.h:86
SymbolicEval::SetScalar
bool SetScalar()
Helper to return a scalar.
Definition: symbolic_eval.h:51
BinaryVisitor::SetScalar
bool SetScalar()
Forward to evaluator, return a scalar.
Definition: symbolic_visitor.h:82
SymbolicEval
Definition: symbolic_eval.h:19
BinaryVisitor::inst_
T & inst_
Instruction to be evaluated.
Definition: symbolic_visitor.h:98
SymbolicEval::SetInteger
bool SetInteger(const APInt &i)
Helper to return an integer.
Definition: symbolic_eval.h:57
BinaryVisitor::SetValue
bool SetValue(const SymbolicPointer::Ref &p)
Forward to evaluator, return a pointer.
Definition: symbolic_visitor.h:88
SymbolicValue::Kind::UNDEFINED
@ UNDEFINED
A undefined value.
BinaryVisitor::ctx_
SymbolicContext & ctx_
Reference to the context.
Definition: symbolic_visitor.h:96
BinaryVisitor::Pointer
Token for pointers.
Definition: symbolic_visitor.h:42
BinaryVisitor::SetLowerBounded
bool SetLowerBounded(const APInt &i)
Forward to evaluator, return a lower bounded integer.
Definition: symbolic_visitor.h:78
BinaryVisitor::LowerBoundedInteger
Token for lower bounded integers.
Definition: symbolic_visitor.h:36
SymbolicValue::Kind::POINTER
@ POINTER
A pointer or a range of pointers.
BinaryVisitor::SetPointer
bool SetPointer(const SymbolicPointer::Ref &p)
Forward to evaluator, return a valu.
Definition: symbolic_visitor.h:84
SymbolicValue::Kind::FLOAT
@ FLOAT
Floating-point value.
SymbolicEval::SetNullable
bool SetNullable(const SymbolicPointer::Ref &ptr)
Helper to forward a pointer (nullptr).
Definition: symbolic_eval.h:93
SymbolicEval::SetPointer
bool SetPointer(const SymbolicPointer::Ref &ptr)
Helper to forward a pointer (pointer).
Definition: symbolic_eval.h:87
SymbolicValue::Kind::LOWER_BOUNDED_INTEGER
@ LOWER_BOUNDED_INTEGER
An unknown integer with a lower bound.
SymbolicValue::Kind::NULLABLE
@ NULLABLE
A pointer or null.
BinaryVisitor::Mask
Token for masked integers.
Definition: symbolic_visitor.h:38
BinaryVisitor::SetMask
bool SetMask(const APInt &k, const APInt &v)
Forward to evaluator, return a pointer.
Definition: symbolic_visitor.h:90
BinaryVisitor::SetInteger
bool SetInteger(const APInt &i)
Forward to evaluator, return an integer.
Definition: symbolic_visitor.h:76
BinaryVisitor
Definition: symbolic_visitor.h:15
SymbolicEval::SetMask
bool SetMask(const APInt &k, const APInt &v)
Forward to frameuator, return a pointer.
Definition: symbolic_eval.h:75
BinaryVisitor::SetUndefined
bool SetUndefined()
Forward to evaluator, return a undefined value.
Definition: symbolic_visitor.h:80
BinaryVisitor::Nullable
Token for pointer or null values.
Definition: symbolic_visitor.h:44
BinaryVisitor::Value
Token for values.
Definition: symbolic_visitor.h:40
SymbolicEval::SetLowerBounded
bool SetLowerBounded(const APInt &i)
Helper to return a lower bounded integer.
Definition: symbolic_eval.h:69
SymbolicValue::Kind::INTEGER
@ INTEGER
A specific integer.
BinaryVisitor::rhs_
const SymbolicValue & rhs_
Right-hand operand.
Definition: symbolic_visitor.h:102
BinaryVisitor::Undefined
Token for an undefined value.
Definition: symbolic_visitor.h:32
BinaryVisitor::Evaluate
bool Evaluate()
Dispatch to the correct case.
Definition: symbolic_visitor.h:107
BinaryVisitor::eval_
SymbolicEval & eval_
Reference to the evaluator.
Definition: symbolic_visitor.h:94
BinaryVisitor::lhs_
const SymbolicValue & lhs_
Left-hand operand.
Definition: symbolic_visitor.h:100
SymbolicValue::Kind::SCALAR
@ SCALAR
A integer of an unknown value.
SymbolicValue::Kind::MASKED_INTEGER
@ MASKED_INTEGER
An integer with some known bits.
BinaryVisitor::Scalar
Token for unknown integer values.
Definition: symbolic_visitor.h:34
BinaryVisitor::BinaryVisitor
BinaryVisitor(SymbolicEval &eval, T &i)
Looks up the values and dispatches them to the correct case.
Definition: symbolic_visitor.h:18
SymbolicEval::SetValue
bool SetValue(const SymbolicPointer::Ref &ptr)
Helper to forward a pointer (value).
Definition: symbolic_eval.h:81
SymbolicValue::Kind::VALUE
@ VALUE
Value - unknown integer or pointer.