Otawa  0.10
WideningFixPoint.h
Go to the documentation of this file.
1 /*
2  * $Id$
3  * Widening 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_WIDENINGFIXPOINT_H_
25 #define OTAWA_DFA_HAI_WIDENINGFIXPOINT_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 #ifdef HAI_DEBUG
36 # define HAIW_TRACE(t) cerr << t;
37 #else
38 # define HAIW_TRACE(t)
39 #endif
40 
41 namespace otawa { namespace dfa { namespace hai {
42 
43 template <class Listener>
45 
46  // Types
47  public:
48  typedef typename Listener::Problem Problem;
49  typedef typename Problem::Domain Domain;
50 
51  private:
52 
53 
54 
55  // Fields
58  Listener &list;
60 
61  public:
62  // FixPointState class
63  class FixPointState {
64  public:
66  inline FixPointState(const Domain &bottom): headerState(bottom){
67  }
68  };
69 
70  inline FixPointState *newState(void) {
71  return(new FixPointState(bottom()));
72  }
73 
74 
75  inline WideningFixPoint(Listener & _list)
76  :prob(_list.getProb()),list(_list),ai(0)
77  {
78  }
79  // Destructor
80  inline ~WideningFixPoint() {
81  }
82 
83  // Accessors
84 
85  // Mutators
86  inline void init(HalfAbsInt<WideningFixPoint> *_ai);
87 
88  // FixPoint function
89  void fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const;
90 
91  // Edge marking functions
92  inline void markEdge(PropList *e, const Domain &s);
93  inline void unmarkEdge(PropList *e);
94  inline Domain *getMark(PropList *e);
95  inline void updateEdge(Edge *edge, Domain &dom);
96 
97  // Problem wrapper functions
98  inline const Domain& bottom(void) const;
99  inline const Domain& entry(void) const;
100  inline void lub(Domain &a, const Domain &b) const;
101  inline void assign(Domain &a, const Domain &b) const;
102  inline bool equals(const Domain &a, const Domain &b) const;
103  inline void update(Domain &out, const Domain &in, BasicBlock* bb);
104  inline void blockInterpreted(BasicBlock* bb, const Domain& in, const Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const;
105  inline void fixPointReached(BasicBlock* bb) const;
106  inline void enterContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
107  inline void leaveContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
108 
109 };
110 
112 
113 template < class Listener >
115  ai = _ai;
116 }
117 
118 
119 template < class Listener >
120 void WideningFixPoint<Listener >::fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const {
121 
122  FixPointState *fpstate = ai->getFixPointState(bb);
123  Domain newHeaderState(bottom());
124  fixpoint = false;
125 
126 
127  if (firstTime)
128  assign(newHeaderState, ai->entryEdgeUnion(bb));
129  else {
130  assign(newHeaderState, fpstate->headerState);
131  HAIW_TRACE("before widening, state + 1: " << newHeaderState << io::endl);
132  // TODO Uncomment and fix!
133  prob.widening(bb, newHeaderState, ai->backEdgeUnion(bb));
134 
135 
136  if (prob.equals(newHeaderState, fpstate->headerState))
137  fixpoint = true;
138  }
139 
140  assign(fpstate->headerState, newHeaderState);
141  assign(in, newHeaderState);
142  HAIW_TRACE("after widening " << in << io::endl);
143  }
144 
145 template < class Listener >
147 
148  Domain tmp(bottom());
149  /*
150  * Because this FixPoint unrolls the first iteration of each loop,
151  * the loop-exit-edges will be marked at least 2 times
152  * (one time for 1st iteration, and one time for others iterations),
153  * so when we mark the edges for the 2nd time we need to merge (lub)
154  * with the existing value from the 1st iteration, instead of overwriting it.
155  */
156  if (STATE(e) == 0)
157  STATE(e) = new Domain(bottom());
158 
159 /* prob.lub(tmp, *STATE(e));
160  prob.lub(*STATE(e), s);
161  prob.lub(tmp, s);
162  ASSERT(prob.equals(tmp,s)); */
163  prob.assign(**STATE(e), s);
164 
165  }
166 
167 template < class Listener >
169  delete STATE(e);
170  STATE(e) = 0;
171 }
172 
173 template < class Listener >
175  return(STATE(e));
176 }
177 
178 
179  /*
180  * Wrappers for the Problem methods and types
181  */
182 
183 template < class Listener >
185  return(prob.bottom());
186 }
187 
188 template < class Listener >
190  return(prob.entry());
191 }
192 
193 template < class Listener >
194 inline void WideningFixPoint<Listener >::lub(typename Problem::Domain &a, const typename Problem::Domain &b) const {
195  prob.lub(a,b);
196 }
197 
198 template < class Listener >
199 inline void WideningFixPoint<Listener >::assign(typename Problem::Domain &a, const typename Problem::Domain &b) const {
200  prob.assign(a,b);
201 }
202 
203 template < class Listener >
204 inline bool WideningFixPoint<Listener >::equals(const typename Problem::Domain &a, const typename Problem::Domain &b) const {
205  return (prob.equals(a,b));
206 }
207 
208 template < class Listener >
209 inline void WideningFixPoint<Listener>::update(Domain &out, const typename Problem::Domain &in, BasicBlock* bb) {
210  prob.update(out,in,bb);
211 }
212 
213 template < class Listener >
214 inline void WideningFixPoint<Listener>::blockInterpreted(BasicBlock* bb, const typename Problem::Domain& in, const typename Problem::Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const {
215  list.blockInterpreted(this, bb, in, out, cur_cfg, callStack);
216 }
217 
218 template < class Listener >
220  list.fixPointReached(this, bb);
221 }
222 
223 template < class Listener >
225  prob.enterContext(dom, bb, ctx);
226 }
227 
228 template < class Listener >
230  prob.leaveContext(dom, bb, ctx);
231 }
232 
233 template < class Listener >
235  prob.updateEdge(edge, dom);
236 }
237 
238 
239 } } } // otawa::dfa::hai
240 
241 #endif /*OTAWA_DFA_HAI_WIDENINGFIXPOINT_H_*/
dtd::Element edge(dtd::make("edge", _EDGE).attr(source).attr(target).attr(called))
Listener & list
Definition: WideningFixPoint.h:58
void fixPointReached(BasicBlock *bb) const
This listener is called whenever a fixpoint is reached for a loop.
Definition: WideningFixPoint.h:219
FixPointState * newState(void)
Definition: WideningFixPoint.h:70
void leaveContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
This is called whenever we leave a loop.
Definition: WideningFixPoint.h:229
void init(HalfAbsInt< WideningFixPoint > *_ai)
Is called by HalfAbsInt for fixpoint object initializeation.
Definition: WideningFixPoint.h:114
const Domain & bottom(void) const
This function gets the bottom of the problem's lattice This is usually delegated to the Problem...
Definition: WideningFixPoint.h:184
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: WideningFixPoint.h:120
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: WideningFixPoint.h:209
Domain headerState
Definition: WideningFixPoint.h:65
Definition: WideningFixPoint.h:44
bool equals(const Domain &a, const Domain &b) const
Tests a and b for equality.
Definition: WideningFixPoint.h:204
#define HAIW_TRACE(t)
Definition: WideningFixPoint.h:38
sys::SystemInStream & in
void updateEdge(Edge *edge, Domain &dom)
Definition: WideningFixPoint.h:234
FixPointState(const Domain &bottom)
Definition: WideningFixPoint.h:66
dtd::Element bb(dtd::make("bb", _BB).attr(id).attr(address).attr(size))
void unmarkEdge(PropList *e)
Unmark a proplist (typically an edge)
Definition: WideningFixPoint.h:168
Control Flow Graph representation.
Definition: CFG.h:42
void markEdge(PropList *e, const Domain &s)
Marks a proplist (typically an edge) e with state s.
Definition: WideningFixPoint.h:146
void enterContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
This is called whenever we enter a loop.
Definition: WideningFixPoint.h:224
void lub(Domain &a, const Domain &b) const
Performs operation: a = a lub b This is delegated to the Problem.
Definition: WideningFixPoint.h:194
Implements abstract interpretation.
Definition: HalfAbsInt.h:64
Problem & prob
Definition: WideningFixPoint.h:57
Identifier< State * > STATE("otawa::stack::STATE", 0)
Stack analysis state at entry of BBs.
HalfAbsInt< WideningFixPoint > * ai
Definition: WideningFixPoint.h:59
Problem::Domain Domain
Definition: WideningFixPoint.h:49
sys::SystemOutStream & out
Domain * getMark(PropList *e)
Get the mark of a proplist (typically an edge)
Definition: WideningFixPoint.h:174
WideningFixPoint(Listener &_list)
Definition: WideningFixPoint.h:75
hai_context_t
Definition: HalfAbsInt.h:50
This class represents edges in the CFG representation.
Definition: Edge.h:33
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: WideningFixPoint.h:214
This is the minimal definition of a basic block.
Definition: BasicBlock.h:43
static Identifier< Domain * > STATE
Definition: WideningFixPoint.h:56
This a list of properties.
Definition: PropList.h:63
const Domain & entry(void) const
This function returns the entry state of the whole program to be analyzed.
Definition: WideningFixPoint.h:189
~WideningFixPoint()
Definition: WideningFixPoint.h:80
Definition: WideningFixPoint.h:63
void assign(Domain &a, const Domain &b) const
Performs operation a = b This is delegated to the Problem.
Definition: WideningFixPoint.h:199
Listener::Problem Problem
Definition: WideningFixPoint.h:48