Otawa  0.10
DefaultFixPoint.h
Go to the documentation of this file.
1 /*
2  * $Id$
3  * Default FixPoint implementation (no loop unrolling)
4  *
5  * This file is part of OTAWA
6  * Copyright (c) 2007, IRIT UPS.
7  *
8  * OTAWA is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * OTAWA is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with OTAWA; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23 
24 #ifndef OTAWA_DFA_HAI_DEFAULTFIXPOINT_H_
25 #define OTAWA_DFA_HAI_DEFAULTFIXPOINT_H_
26 
27 
28 #include "HalfAbsInt.h"
29 #include <otawa/cfg/CFG.h>
30 #include <otawa/cfg/BasicBlock.h>
31 #include <otawa/cfg/Edge.h>
32 #include <otawa/prop/PropList.h>
33 #include <elm/genstruct/Vector.h>
34 
35 namespace otawa { namespace dfa { namespace hai {
36 
37 template <class Listener>
39 public:
40  typedef typename Listener::Problem Problem;
41  typedef typename Problem::Domain Domain;
42 
43 private:
46  Listener &list;
48 
49 public:
50  class FixPointState {
51  public:
53  inline FixPointState(const Domain &bottom): headerState(bottom) { }
54  };
55 
56  inline DefaultFixPoint(Listener & _list) :prob(_list.getProb()),list(_list),ai(0) { }
57  inline ~DefaultFixPoint() { }
58 
59  inline FixPointState *newState(void) { return(new FixPointState(bottom())); }
60  inline void init(HalfAbsInt<DefaultFixPoint> *_ai);
61  void fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const;
62 
63  // edge marking functions
64  inline void markEdge(PropList *e, const Domain &s);
65  inline void unmarkEdge(PropList *e);
66  inline void updateEdge(Edge *edge, Domain &dom);
67  inline Domain *getMark(PropList *e);
68 
69  // problem wrapper functions
70  inline const Domain& bottom(void) const;
71  inline const Domain& entry(void) const;
72  inline void lub(Domain &a, const Domain &b) const;
73  inline void assign(Domain &a, const Domain &b) const;
74  inline bool equals(const Domain &a, const Domain &b) const;
75  inline void update(Domain &out, const Domain &in, BasicBlock* bb);
76  inline void blockInterpreted(BasicBlock* bb, const Domain& in, const Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const;
77  inline void fixPointReached(BasicBlock* bb) const;
78  inline void enterContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
79  inline void leaveContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
80 
81 };
82 
84 
85 template < class Listener >
87  ai = _ai;
88 }
89 
90 
91 template < class Listener >
92 void DefaultFixPoint<Listener >::fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const {
93 
94  FixPointState *fpstate = ai->getFixPointState(bb);
95  Domain newHeaderState(bottom());
96  fixpoint = false;
97 
98 
99  if (firstTime)
100  assign(newHeaderState, ai->entryEdgeUnion(bb));
101  else {
102  assign(newHeaderState, ai->entryEdgeUnion(bb));
103  prob.lub(newHeaderState, ai->backEdgeUnion(bb));
104  if (prob.equals(newHeaderState, fpstate->headerState))
105  fixpoint = true;
106  }
107 
108  assign(fpstate->headerState, newHeaderState);
109  assign(in, newHeaderState);
110  }
111 
112 template < class Listener >
114  Domain tmp(bottom());
115  /*
116  * Because this FixPoint unrolls the first iteration of each loop,
117  * the loop-exit-edges will be marked at least 2 times
118  * (one time for 1st iteration, and one time for others iterations),
119  * so when we mark the edges for the 2nd time we need to merge (lub)
120  * with the existing value from the 1st iteration, instead of overwriting it.
121  */
122  if (STATE(e) == 0)
123  STATE(e) = new Domain(bottom());
124  prob.lub(**STATE(e), s);
125  prob.lub(tmp, s);
126  ASSERT(prob.equals(tmp,s));
127 }
128 
129 template < class Listener >
131  delete STATE(e);
132  STATE(e) = 0;
133 }
134 
135 template < class Listener >
137  return(STATE(e));
138 }
139 
140 template < class Listener >
142  return(prob.bottom());
143 }
144 
145 template < class Listener >
147  return(prob.entry());
148 }
149 
150 template < class Listener >
151 inline void DefaultFixPoint<Listener >::lub(typename Problem::Domain &a, const typename Problem::Domain &b) const {
152  prob.lub(a,b);
153 }
154 
155 template < class Listener >
156 inline void DefaultFixPoint<Listener >::assign(typename Problem::Domain &a, const typename Problem::Domain &b) const {
157  prob.assign(a,b);
158 }
159 
160 template < class Listener >
161 inline bool DefaultFixPoint<Listener >::equals(const typename Problem::Domain &a, const typename Problem::Domain &b) const {
162  return (prob.equals(a,b));
163 }
164 
165 template < class Listener >
167 }
168 
169 
170 template < class Listener >
171 inline void DefaultFixPoint<Listener>::update(Domain &out, const typename Problem::Domain &in, BasicBlock* bb) {
172  prob.update(out,in,bb);
173 }
174 
175 template < class Listener >
176 inline void DefaultFixPoint<Listener>::blockInterpreted(BasicBlock* bb, const typename Problem::Domain& in, const typename Problem::Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const {
177  list.blockInterpreted(this, bb, in, out, cur_cfg, callStack);
178 }
179 
180 template < class Listener >
182  list.fixPointReached(this, bb);
183 }
184 
185 template < class Listener >
187  prob.enterContext(dom, bb, ctx);
188 }
189 
190 template < class Listener >
192  prob.leaveContext(dom, bb, ctx);
193 }
194 
195 
196 } } } // otawa::dfa::hai
197 
198 #endif /* OTAWA_DFA_HAI_FIRSTUNROLLINGFIXPOINT_H_*/
static Identifier< Domain * > STATE
Definition: DefaultFixPoint.h:44
DefaultFixPoint(Listener &_list)
Definition: DefaultFixPoint.h:56
Definition: DefaultFixPoint.h:38
Definition: DefaultFixPoint.h:50
dtd::Element edge(dtd::make("edge", _EDGE).attr(source).attr(target).attr(called))
FixPointState(const Domain &bottom)
Definition: DefaultFixPoint.h:53
const Domain & bottom(void) const
This function gets the bottom of the problem's lattice This is usually delegated to the Problem...
Definition: DefaultFixPoint.h:141
void enterContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
This is called whenever we enter a loop.
Definition: DefaultFixPoint.h:186
Domain * getMark(PropList *e)
Get the mark of a proplist (typically an edge)
Definition: DefaultFixPoint.h:136
Listener & list
Definition: DefaultFixPoint.h:46
void init(HalfAbsInt< DefaultFixPoint > *_ai)
Is called by HalfAbsInt for fixpoint object initializeation.
Definition: DefaultFixPoint.h:86
bool equals(const Domain &a, const Domain &b) const
Tests a and b for equality.
Definition: DefaultFixPoint.h:161
HalfAbsInt< DefaultFixPoint > * ai
Definition: DefaultFixPoint.h:47
Problem::Domain Domain
Definition: DefaultFixPoint.h:41
Listener::Problem Problem
Definition: DefaultFixPoint.h:40
void fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const
Main fixPoint function: is called by HalfAbsInt whenever the analysis reaches a loop header...
Definition: DefaultFixPoint.h:92
void assign(Domain &a, const Domain &b) const
Performs operation a = b This is delegated to the Problem.
Definition: DefaultFixPoint.h:156
void lub(Domain &a, const Domain &b) const
Performs operation: a = a lub b This is delegated to the Problem.
Definition: DefaultFixPoint.h:151
void fixPointReached(BasicBlock *bb) const
This listener is called whenever a fixpoint is reached for a loop.
Definition: DefaultFixPoint.h:181
void blockInterpreted(BasicBlock *bb, const Domain &in, const Domain &out, CFG *cur_cfg, elm::genstruct::Vector< Edge * > *callStack) const
This listener is called whenever HalfAbsInt has processed a basic block.
Definition: DefaultFixPoint.h:176
sys::SystemInStream & in
dtd::Element bb(dtd::make("bb", _BB).attr(id).attr(address).attr(size))
Control Flow Graph representation.
Definition: CFG.h:42
const Domain & entry(void) const
This function returns the entry state of the whole program to be analyzed.
Definition: DefaultFixPoint.h:146
void unmarkEdge(PropList *e)
Unmark a proplist (typically an edge)
Definition: DefaultFixPoint.h:130
FixPointState * newState(void)
Definition: DefaultFixPoint.h:59
Implements abstract interpretation.
Definition: HalfAbsInt.h:64
Problem & prob
Definition: DefaultFixPoint.h:45
Identifier< State * > STATE("otawa::stack::STATE", 0)
Stack analysis state at entry of BBs.
sys::SystemOutStream & out
~DefaultFixPoint()
Definition: DefaultFixPoint.h:57
hai_context_t
Definition: HalfAbsInt.h:50
Domain headerState
Definition: DefaultFixPoint.h:52
void markEdge(PropList *e, const Domain &s)
Marks a proplist (typically an edge) e with state s.
Definition: DefaultFixPoint.h:113
This class represents edges in the CFG representation.
Definition: Edge.h:33
This is the minimal definition of a basic block.
Definition: BasicBlock.h:43
void leaveContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
This is called whenever we leave a loop.
Definition: DefaultFixPoint.h:191
This a list of properties.
Definition: PropList.h:63
void update(Domain &out, const Domain &in, BasicBlock *bb)
Is called whenever the analysis needs to get the Output state for a basic block, given its input stat...
Definition: DefaultFixPoint.h:171
void updateEdge(Edge *edge, Domain &dom)
Definition: DefaultFixPoint.h:166