Otawa  0.10
FirstUnrollingFixPoint.h
Go to the documentation of this file.
1 /*
2  * $Id$
3  * FixPoint which unrolls the first iteration of each loop.
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_FIRSTUNROLLINGFIXPOINT_H_
25 #define OTAWA_DFA_HAI_FIRSTUNROLLINGFIXPOINT_H_
26 
27 #include "HalfAbsInt.h"
28 #include <otawa/cfg/CFG.h>
29 #include <otawa/cfg/BasicBlock.h>
30 #include <otawa/cfg/Edge.h>
31 #include <otawa/prop/PropList.h>
32 #include <elm/genstruct/Vector.h>
33 
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 
44 protected:
47  Listener &list;
49 
50 public:
51 
52  class FixPointState {
53  public:
56  int numIter;
57  inline FixPointState(const Domain &bottom): headerState(bottom), firstIterState(bottom) { numIter = 0; }
58  };
59 
60  inline FixPointState *newState(void) { return(new FixPointState(bottom())); }
61  inline FirstUnrollingFixPoint(Listener & _list):prob(_list.getProb()), list(_list) ,ai(0) { }
62  inline ~FirstUnrollingFixPoint(void) { }
63 
64  inline int getIter(BasicBlock *bb) const { return(ai->getFixPointState(bb)->numIter); }
65  inline void init(HalfAbsInt<FirstUnrollingFixPoint> *_ai) { ai = _ai; }
66  void fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const;
67 
68  // edge marking functions
69  inline void markEdge(PropList *e, const Domain &s);
70  inline void unmarkEdge(PropList *e);
71  inline Domain *getMark(PropList *e);
72  inline void updateEdge(Edge *edge, Domain &dom);
73 
74  // problem wrapper functions
75  inline const Domain& bottom(void) const;
76  inline const Domain& entry(void) const;
77  inline void lub(Domain &a, const Domain &b) const;
78  inline void assign(Domain &a, const Domain &b) const;
79  inline bool equals(const Domain &a, const Domain &b) const;
80  inline void update(Domain &out, const Domain &in, BasicBlock* bb);
81  inline void blockInterpreted(BasicBlock* bb, const Domain& in, const Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const;
82  inline void fixPointReached(BasicBlock* bb) const;
83  inline void enterContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
84  inline void leaveContext(Domain &dom, BasicBlock* bb, hai_context_t ctx) const;
85 };
86 
87 template <class Listener>
89 
90 template < class Listener >
91 void FirstUnrollingFixPoint<Listener >::fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const {
92  FixPointState *fpstate = ai->getFixPointState(bb);
93  Domain newHeaderState(bottom());
94  fixpoint = false;
95 
96  switch(fpstate->numIter) {
97 
98  // We never did any iteration, we begin the first:
99  // Use for IN the union of entry edges. Fixpoint is always false.
100  case 0:
101  assign(newHeaderState, ai->entryEdgeUnion(bb));
102  break;
103 
104  // We finished the first iteration, we begin the 2nd:
105  // Use for IN the union of back edges. Fixpoint may be reached at this point
106  // but even if it is, we still want to do another iteration anyway.
107  case 1:
108  assign(newHeaderState, ai->backEdgeUnion(bb));
109  assign(fpstate->firstIterState, newHeaderState);
110  break;
111 
112  // We finished the 2..n^th iteration:
113  // Use for IN the union of back edges + the union of entry edges
114  // of the first iteration.
115  // Test for fixpoint.
116  default:
117  assign(newHeaderState, ai->backEdgeUnion(bb));
118  prob.lub(newHeaderState, fpstate->firstIterState);
119  if (prob.equals(newHeaderState, fpstate->headerState))
120  fixpoint = true;
121  break;
122  }
123  fpstate->numIter ++;
124 
125  // Store the new loop header state in the FixPointState
126  assign(fpstate->headerState, newHeaderState);
127 
128  // Pass the new loop header state to the caller (HalfAbsInt)
129  assign(in, newHeaderState);
130 }
131 
132 template < class Listener >
134 
135  /*
136  * Because this FixPoint unrolls the first iteration of each loop,
137  * the loop-exit-edges will be marked at least 2 times
138  * (one time for 1st iteration, and one time for others iterations),
139  * so when we mark the edges for the 2nd time we need to merge (lub)
140  * with the existing value from the 1st iteration, instead of overwriting it.
141  */
142  if (STATE(e) == 0)
143  STATE(e) = new Domain(bottom());
144 
145  prob.lub(**STATE(e), s);
146  }
147 
148 template < class Listener >
150  delete STATE(e);
151  STATE(e) = 0;
152 }
153 
154 template < class Listener >
156  return(STATE(e));
157 }
158 
159 
160  /*
161  * Wrappers for the Problem methods and types
162  */
163 
164 template < class Listener >
166  return(prob.bottom());
167 }
168 
169 template < class Listener >
171  return(prob.entry());
172 }
173 
174 template < class Listener >
175 inline void FirstUnrollingFixPoint<Listener >::lub(typename Problem::Domain &a, const typename Problem::Domain &b) const {
176  prob.lub(a,b);
177 }
178 
179 template < class Listener >
180 inline void FirstUnrollingFixPoint<Listener >::assign(typename Problem::Domain &a, const typename Problem::Domain &b) const {
181  prob.assign(a,b);
182 }
183 
184 template < class Listener >
185 inline bool FirstUnrollingFixPoint<Listener >::equals(const typename Problem::Domain &a, const typename Problem::Domain &b) const {
186  return (prob.equals(a,b));
187 }
188 
189 template < class Listener >
190 inline void FirstUnrollingFixPoint<Listener>::update(Domain &out, const typename Problem::Domain &in, BasicBlock* bb) {
191  prob.update(out,in,bb);
192 }
193 
194 template < class Listener >
195 inline void FirstUnrollingFixPoint<Listener>::blockInterpreted(BasicBlock* bb, const typename Problem::Domain& in, const typename Problem::Domain& out, CFG *cur_cfg, elm::genstruct::Vector<Edge*> *callStack) const {
196  list.blockInterpreted(this, bb, in, out, cur_cfg, callStack);
197 }
198 
199 template < class Listener >
201  list.fixPointReached(this, bb);
202 }
203 
204 template < class Listener >
206  prob.enterContext(dom, bb, ctx);
207 }
208 
209 template < class Listener >
211  prob.leaveContext(dom, bb, ctx);
212 }
213 
214 template < class Listener >
216 }
217 
218 
219 } } } // otawa::dfa::hai
220 
221 #endif /*OTAWA_DFA_HAI_FIRSTUNROLLINGFIXPOINT_H_*/
void markEdge(PropList *e, const Domain &s)
Definition: FirstUnrollingFixPoint.h:133
void enterContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
Definition: FirstUnrollingFixPoint.h:205
dtd::Element edge(dtd::make("edge", _EDGE).attr(source).attr(target).attr(called))
State info class for FirstUnrollingFixPoint This FixPoint needs to remember:
Definition: FirstUnrollingFixPoint.h:52
void lub(Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:175
bool equals(const Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:185
static Identifier< Domain * > STATE
Definition: FirstUnrollingFixPoint.h:45
Domain headerState
Definition: FirstUnrollingFixPoint.h:54
FirstUnrollingFixPoint(Listener &_list)
Definition: FirstUnrollingFixPoint.h:61
Domain * getMark(PropList *e)
Definition: FirstUnrollingFixPoint.h:155
void update(Domain &out, const Domain &in, BasicBlock *bb)
Definition: FirstUnrollingFixPoint.h:190
FixPointState(const Domain &bottom)
Definition: FirstUnrollingFixPoint.h:57
void leaveContext(Domain &dom, BasicBlock *bb, hai_context_t ctx) const
Definition: FirstUnrollingFixPoint.h:210
const Domain & entry(void) const
Definition: FirstUnrollingFixPoint.h:170
sys::SystemInStream & in
dtd::Element bb(dtd::make("bb", _BB).attr(id).attr(address).attr(size))
Control Flow Graph representation.
Definition: CFG.h:42
void blockInterpreted(BasicBlock *bb, const Domain &in, const Domain &out, CFG *cur_cfg, elm::genstruct::Vector< Edge * > *callStack) const
Definition: FirstUnrollingFixPoint.h:195
void init(HalfAbsInt< FirstUnrollingFixPoint > *_ai)
Definition: FirstUnrollingFixPoint.h:65
Implements abstract interpretation.
Definition: HalfAbsInt.h:64
FixPointState * newState(void)
Definition: FirstUnrollingFixPoint.h:60
FixPoint class for HalfAbsInt The DefaultFixPoint manages loops in a simple way.
Definition: FirstUnrollingFixPoint.h:38
Identifier< State * > STATE("otawa::stack::STATE", 0)
Stack analysis state at entry of BBs.
void unmarkEdge(PropList *e)
Definition: FirstUnrollingFixPoint.h:149
sys::SystemOutStream & out
int numIter
Definition: FirstUnrollingFixPoint.h:56
hai_context_t
Definition: HalfAbsInt.h:50
This class represents edges in the CFG representation.
Definition: Edge.h:33
Problem::Domain Domain
Definition: FirstUnrollingFixPoint.h:41
Listener & list
Definition: FirstUnrollingFixPoint.h:47
void assign(Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:180
This is the minimal definition of a basic block.
Definition: BasicBlock.h:43
void fixPoint(BasicBlock *bb, bool &fixpoint, Domain &in, bool firstTime) const
Definition: FirstUnrollingFixPoint.h:91
void updateEdge(Edge *edge, Domain &dom)
Definition: FirstUnrollingFixPoint.h:215
~FirstUnrollingFixPoint(void)
Definition: FirstUnrollingFixPoint.h:62
This a list of properties.
Definition: PropList.h:63
Listener::Problem Problem
Definition: FirstUnrollingFixPoint.h:40
Problem & prob
Definition: FirstUnrollingFixPoint.h:46
const Domain & bottom(void) const
Definition: FirstUnrollingFixPoint.h:165
HalfAbsInt< FirstUnrollingFixPoint > * ai
Definition: FirstUnrollingFixPoint.h:48
int getIter(BasicBlock *bb) const
Definition: FirstUnrollingFixPoint.h:64
void fixPointReached(BasicBlock *bb) const
Definition: FirstUnrollingFixPoint.h:200
Domain firstIterState
Definition: FirstUnrollingFixPoint.h:55