OTAWA  2.0
Framework to perform machine analysis and compute WCET.
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/data/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;
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(Block *bb) const { return(ai->getFixPointState(bb)->numIter); }
65  inline void init(HalfAbsInt<FirstUnrollingFixPoint> *_ai) { ai = _ai; }
66  void fixPoint(Block *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& top(void) const { return prob.top(); }
76  inline const Domain& bottom(void) const;
77  inline const Domain& entry(void) const;
78  inline void lub(Domain &a, const Domain &b) const;
79  inline void assign(Domain &a, const Domain &b) const;
80  inline bool equals(const Domain &a, const Domain &b) const;
81  inline void update(Domain &out, const Domain &in, Block* bb);
82  inline void blockInterpreted(Block* bb, const Domain& in, const Domain& out, CFG *cur_cfg, Vector<Edge*> *callStack) const;
83  inline void fixPointReached(Block* bb) const;
84  inline void enterContext(Domain &dom, Block* bb, hai_context_t ctx) const;
85  inline void leaveContext(Domain &dom, Block* bb, hai_context_t ctx) const;
86 };
87 
88 template <class Listener>
90 
91 template < class Listener >
92 void FirstUnrollingFixPoint<Listener >::fixPoint(Block *bb, bool &fixpoint, Domain &in, bool firstTime) const {
93  FixPointState *fpstate = ai->getFixPointState(bb);
94  Domain newHeaderState(bottom());
95  fixpoint = false;
96 
97  switch(fpstate->numIter) {
98 
99  // We never did any iteration, we begin the first:
100  // Use for IN the union of entry edges. Fixpoint is always false.
101  case 0:
102  assign(newHeaderState, ai->entryEdgeUnion(bb));
103  break;
104 
105  // We finished the first iteration, we begin the 2nd:
106  // Use for IN the union of back edges. Fixpoint may be reached at this point
107  // but even if it is, we still want to do another iteration anyway.
108  case 1:
109  assign(newHeaderState, ai->backEdgeUnion(bb));
110  assign(fpstate->firstIterState, newHeaderState);
111  break;
112 
113  // We finished the 2..n^th iteration:
114  // Use for IN the union of back edges + the union of entry edges
115  // of the first iteration.
116  // Test for fixpoint.
117  default:
118  assign(newHeaderState, ai->backEdgeUnion(bb));
119  prob.lub(newHeaderState, fpstate->firstIterState);
120  if (prob.equals(newHeaderState, fpstate->headerState))
121  fixpoint = true;
122  break;
123  }
124  fpstate->numIter ++;
125 
126  // Store the new loop header state in the FixPointState
127  assign(fpstate->headerState, newHeaderState);
128 
129  // Pass the new loop header state to the caller (HalfAbsInt)
130  assign(in, newHeaderState);
131 }
132 
133 template < class Listener >
135 
136  /*
137  * Because this FixPoint unrolls the first iteration of each loop,
138  * the loop-exit-edges will be marked at least 2 times
139  * (one time for 1st iteration, and one time for others iterations),
140  * so when we mark the edges for the 2nd time we need to merge (lub)
141  * with the existing value from the 1st iteration, instead of overwriting it.
142  */
143  if (STATE(e) == 0)
144  STATE(e) = new Domain(bottom());
145 
146  prob.lub(**STATE(e), s);
147  }
148 
149 template < class Listener >
151  delete STATE(e);
152  STATE(e) = 0;
153 }
154 
155 template < class Listener >
157  return(STATE(e));
158 }
159 
160 
161  /*
162  * Wrappers for the Problem methods and types
163  */
164 
165 template < class Listener >
167  return(prob.bottom());
168 }
169 
170 template < class Listener >
172  return(prob.entry());
173 }
174 
175 template < class Listener >
176 inline void FirstUnrollingFixPoint<Listener >::lub(typename Problem::Domain &a, const typename Problem::Domain &b) const {
177  prob.lub(a,b);
178 }
179 
180 template < class Listener >
181 inline void FirstUnrollingFixPoint<Listener >::assign(typename Problem::Domain &a, const typename Problem::Domain &b) const {
182  prob.assign(a,b);
183 }
184 
185 template < class Listener >
186 inline bool FirstUnrollingFixPoint<Listener >::equals(const typename Problem::Domain &a, const typename Problem::Domain &b) const {
187  return (prob.equals(a,b));
188 }
189 
190 template < class Listener >
192  prob.update(out,in,bb);
193 }
194 
195 template < class Listener >
196 inline void FirstUnrollingFixPoint<Listener>::blockInterpreted(Block* bb, const typename Problem::Domain& in, const typename Problem::Domain& out, CFG *cur_cfg, Vector<Edge*> *callStack) const {
197  list.blockInterpreted(this, bb, in, out, cur_cfg, callStack);
198 }
199 
200 template < class Listener >
202  list.fixPointReached(this, bb);
203 }
204 
205 template < class Listener >
207  prob.enterContext(dom, bb, ctx);
208 }
209 
210 template < class Listener >
212  prob.leaveContext(dom, bb, ctx);
213 }
214 
215 template < class Listener >
217 }
218 
219 
220 } } } // otawa::dfa::hai
221 
222 #endif /*OTAWA_DFA_HAI_FIRSTUNROLLINGFIXPOINT_H_*/
otawa::dfa::hai::FirstUnrollingFixPoint::newState
FixPointState * newState(void)
Definition: FirstUnrollingFixPoint.h:60
out
typename type_info< T >::out_t out
otawa::dfa::hai::FirstUnrollingFixPoint
Definition: FirstUnrollingFixPoint.h:38
otawa::dfa::hai::FirstUnrollingFixPoint::FixPointState::firstIterState
Domain firstIterState
Definition: FirstUnrollingFixPoint.h:55
otawa::dfa::hai::FirstUnrollingFixPoint::bottom
const Domain & bottom(void) const
Definition: FirstUnrollingFixPoint.h:166
otawa::dfa::hai::FirstUnrollingFixPoint::fixPoint
void fixPoint(Block *bb, bool &fixpoint, Domain &in, bool firstTime) const
Definition: FirstUnrollingFixPoint.h:92
otawa::dfa::hai::FirstUnrollingFixPoint::lub
void lub(Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:176
otawa::dfa::hai::FirstUnrollingFixPoint::fixPointReached
void fixPointReached(Block *bb) const
Definition: FirstUnrollingFixPoint.h:201
otawa::dfa::hai::FirstUnrollingFixPoint::leaveContext
void leaveContext(Domain &dom, Block *bb, hai_context_t ctx) const
Definition: FirstUnrollingFixPoint.h:211
otawa::dfa::hai::FirstUnrollingFixPoint::blockInterpreted
void blockInterpreted(Block *bb, const Domain &in, const Domain &out, CFG *cur_cfg, Vector< Edge * > *callStack) const
Definition: FirstUnrollingFixPoint.h:196
otawa::dfa::hai::FirstUnrollingFixPoint::update
void update(Domain &out, const Domain &in, Block *bb)
Definition: FirstUnrollingFixPoint.h:191
otawa::dfa::hai::FirstUnrollingFixPoint::~FirstUnrollingFixPoint
~FirstUnrollingFixPoint(void)
Definition: FirstUnrollingFixPoint.h:62
otawa::dfa::hai::FirstUnrollingFixPoint::top
const Domain & top(void) const
Definition: FirstUnrollingFixPoint.h:75
otawa::dfa::hai::FirstUnrollingFixPoint::list
Listener & list
Definition: FirstUnrollingFixPoint.h:47
otawa::dfa::hai::FirstUnrollingFixPoint::equals
bool equals(const Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:186
otawa::dfa::hai::FirstUnrollingFixPoint::updateEdge
void updateEdge(Edge *edge, Domain &dom)
Definition: FirstUnrollingFixPoint.h:216
otawa::dynbranch::Domain
FastStateWrapper Domain
Definition: GlobalAnalysis.h:38
otawa::dfa::hai::FirstUnrollingFixPoint::entry
const Domain & entry(void) const
Definition: FirstUnrollingFixPoint.h:171
in
typename type_info< T >::in_t in
otawa::dfa::hai::FirstUnrollingFixPoint::init
void init(HalfAbsInt< FirstUnrollingFixPoint > *_ai)
Definition: FirstUnrollingFixPoint.h:65
otawa::dfa::hai::HalfAbsInt
Definition: HalfAbsInt.h:81
BasicBlock.h
otawa::dfa::hai::FirstUnrollingFixPoint::FirstUnrollingFixPoint
FirstUnrollingFixPoint(Listener &_list)
Definition: FirstUnrollingFixPoint.h:61
otawa::stack::STATE
Identifier< State * > STATE("otawa::stack::STATE", 0)
Stack analysis state at entry of BBs.
otawa::dfa::hai::FirstUnrollingFixPoint::FixPointState::FixPointState
FixPointState(const Domain &bottom)
Definition: FirstUnrollingFixPoint.h:57
elm::io::list
ListPrinter< T > list(const T &l, cstring s="", typename ListPrinter< T >::fun_t f=ListPrinter< T >::asis)
otawa::Identifier< Domain * >
otawa::dfa::hai::FirstUnrollingFixPoint::enterContext
void enterContext(Domain &dom, Block *bb, hai_context_t ctx) const
Definition: FirstUnrollingFixPoint.h:206
otawa::Edge
Definition: CFG.h:42
otawa::Block
Definition: CFG.h:68
otawa::dfa::hai::FirstUnrollingFixPoint::markEdge
void markEdge(PropList *e, const Domain &s)
Definition: FirstUnrollingFixPoint.h:134
otawa::dfa::hai::FirstUnrollingFixPoint::FixPointState
Definition: FirstUnrollingFixPoint.h:52
elm::Vector
otawa::CFG
Definition: CFG.h:196
otawa::dfa::hai::FirstUnrollingFixPoint::Problem
Listener::Problem Problem
Definition: FirstUnrollingFixPoint.h:40
Edge.h
otawa::dfa::hai::FirstUnrollingFixPoint::assign
void assign(Domain &a, const Domain &b) const
Definition: FirstUnrollingFixPoint.h:181
otawa::dfa::hai::FirstUnrollingFixPoint::getIter
int getIter(Block *bb) const
Definition: FirstUnrollingFixPoint.h:64
otawa::dfa::hai::hai_context_t
hai_context_t
Definition: HalfAbsInt.h:66
otawa::dfa::hai::FirstUnrollingFixPoint::getMark
Domain * getMark(PropList *e)
Definition: FirstUnrollingFixPoint.h:156
otawa::dfa::hai::FirstUnrollingFixPoint::STATE
static Identifier< Domain * > STATE
Definition: FirstUnrollingFixPoint.h:45
otawa::dfa::hai::FirstUnrollingFixPoint::unmarkEdge
void unmarkEdge(PropList *e)
Definition: FirstUnrollingFixPoint.h:150
CFG.h
otawa::dfa::hai::FirstUnrollingFixPoint::Domain
Problem::Domain Domain
Definition: FirstUnrollingFixPoint.h:41
HalfAbsInt.h
otawa::dfa::hai::FirstUnrollingFixPoint::FixPointState::numIter
int numIter
Definition: FirstUnrollingFixPoint.h:56
otawa::dfa::hai::FirstUnrollingFixPoint::FixPointState::headerState
Domain headerState
Definition: FirstUnrollingFixPoint.h:54
otawa::PropList
Definition: PropList.h:67
otawa::dfa::hai::FirstUnrollingFixPoint::prob
Problem & prob
Definition: FirstUnrollingFixPoint.h:46
PropList.h
otawa::dfa::hai::FirstUnrollingFixPoint::ai
HalfAbsInt< FirstUnrollingFixPoint > * ai
Definition: FirstUnrollingFixPoint.h:48
otawa
Development Note Letting the ToDo / ToDoList class visible in the header is clumsy.
Definition: ArrayStore.h:25