2 extern bool gVectorSwitch
;
3 extern bool gOpenMPSwitch
;
4 extern bool gOpenMPLoop
;
9 * Print n tabs (for indentation purpose)
10 * @param n number of tabs to print
11 * @param fout output stream
13 static void tab (int n
, ostream
& fout
)
16 while (n
--) fout
<< '\t';
21 * Print a list of lines
22 * @param n number of tabs of indentation
23 * @param lines list of lines to be printed
24 * @param fout output stream
26 static void printlines (int n
, list
<string
>& lines
, ostream
& fout
)
28 list
<string
>::iterator s
;
29 for (s
= lines
.begin(); s
!= lines
.end(); s
++) {
30 tab(n
, fout
); fout
<< *s
;
36 * Create a recursive loop
37 * @param recsymbol the recursive symbol defined in this loop
38 * @param encl the enclosing loop
39 * @param size the number of iterations of the loop
41 Loop::Loop(Tree recsymbol
, Loop
* encl
, const string
& size
)
42 : fIsRecursive(true), fRecSymbolSet(singleton(recsymbol
)), fEnclosingLoop(encl
), fSize(size
), fOrder(-1), fIndex(-1), fUseCount(0), fPrinted(0)
47 * Create a non recursive loop
48 * @param encl the enclosing loop
49 * @param size the number of iterations of the loop
51 Loop::Loop(Loop
* encl
, const string
& size
)
52 : fIsRecursive(false), fRecSymbolSet(nil
), fEnclosingLoop(encl
), fSize(size
), fOrder(-1), fIndex(-1), fUseCount(0), fPrinted(0)
57 * A loop with recursive dependencies can't be run alone.
58 * It must be included into another loop.
59 * returns true is this loop has recursive dependencies
60 * and must be included in an enclosing loop
63 bool Loop::hasRecDependencyIn(Tree S
)
66 while ( l
&& isNil(setIntersection(l
->fRecSymbolSet
,S
)) ) l
=l
->fEnclosingLoop
;
71 * Test if a loop is empty that is if it contains no lines of code).
72 * @return true if the loop is empty
76 return fPreCode
.empty() && fExecCode
.empty() && fPostCode
.empty() && (fExtraLoops
.begin()==fExtraLoops
.end());
80 * Add a line of pre code (begin of the loop)
82 void Loop::addPreCode (const string
& str
)
84 // cerr << this << "->addExecCode " << str << endl;
85 fPreCode
.push_back(str
);
89 * Add a line of exec code
91 void Loop::addExecCode (const string
& str
)
93 // cerr << this << "->addExecCode " << str << endl;
94 fExecCode
.push_back(str
);
99 * Add a line of post exec code (end of the loop)
101 void Loop::addPostCode (const string
& str
)
103 // cerr << this << "->addPostCode " << str << endl;
104 fPostCode
.push_front(str
);
109 * Absorb a loop by copying its recursive dependencies, its loop dependencies
110 * and its lines of exec and post exec code.
111 * @param l the Loop to be absorbed
113 void Loop::absorb (Loop
* l
)
115 // the loops must have the same number of iterations
116 assert(fSize
== l
->fSize
);
117 fRecSymbolSet
= setUnion(fRecSymbolSet
, l
->fRecSymbolSet
);
119 // update loop dependencies by adding those from the absorbed loop
120 fBackwardLoopDependencies
.insert(l
->fBackwardLoopDependencies
.begin(), l
->fBackwardLoopDependencies
.end());
122 // add the line of code of the absorbed loop
123 fPreCode
.insert(fPreCode
.end(), l
->fPreCode
.begin(), l
->fPreCode
.end());
124 fExecCode
.insert(fExecCode
.end(), l
->fExecCode
.begin(), l
->fExecCode
.end());
125 fPostCode
.insert(fPostCode
.begin(), l
->fPostCode
.begin(), l
->fPostCode
.end());
130 * Print a loop (unless it is empty)
131 * @param n number of tabs of indentation
132 * @param fout output stream
134 void Loop::println(int n
, ostream
& fout
)
136 for (list
<Loop
*>::const_iterator s
= fExtraLoops
.begin(); s
!= fExtraLoops
.end(); s
++) {
137 (*s
)->println(n
, fout
);
140 if (fPreCode
.size()+fExecCode
.size()+fPostCode
.size() > 0) {
141 /* if (gVectorSwitch) {
143 fout << ((fIsRecursive) ? "// recursive loop" : "// vectorizable loop");
146 tab(n
,fout
); fout
<< "// LOOP " << this ;
147 if (fPreCode
.size()>0) {
148 tab(n
,fout
); fout
<< "// pre processing";
149 printlines(n
, fPreCode
, fout
);
152 tab(n
,fout
); fout
<< "// exec code";
153 tab(n
,fout
); fout
<< "for (int i=0; i<" << fSize
<< "; i++) {";
154 printlines(n
+1, fExecCode
, fout
);
155 tab(n
,fout
); fout
<< "}";
157 if (fPostCode
.size()>0) {
158 tab(n
,fout
); fout
<< "// post processing";
159 printlines(n
, fPostCode
, fout
);
167 * Print a parallel loop (unless it is empty). Should be called only for loop
168 * without pre and post processing
169 * @param n number of tabs of indentation
170 * @param fout output stream
172 void Loop::printParLoopln(int n
, ostream
& fout
)
174 for (list
<Loop
*>::const_iterator s
= fExtraLoops
.begin(); s
!= fExtraLoops
.end(); s
++) {
175 tab(n
,fout
); fout
<< "#pragma omp single";
176 tab(n
,fout
); fout
<< "{";
177 (*s
)->println(n
+1, fout
);
178 tab(n
,fout
); fout
<< "}";
181 if (fPreCode
.size()+fExecCode
.size()+fPostCode
.size() > 0) {
183 tab(n
,fout
); fout
<< "// LOOP " << this ;
184 if (fPreCode
.size()>0) {
185 tab(n
,fout
); fout
<< "#pragma omp single";
186 tab(n
,fout
); fout
<< "{";
187 tab(n
+1,fout
); fout
<< "// pre processing";
188 printlines(n
+1, fPreCode
, fout
);
189 tab(n
,fout
); fout
<< "}";
192 tab(n
,fout
); fout
<< "// exec code";
193 tab(n
,fout
); fout
<< "#pragma omp for";
194 tab(n
,fout
); fout
<< "for (int i=0; i<" << fSize
<< "; i++) {";
195 printlines(n
+1, fExecCode
, fout
);
196 tab(n
,fout
); fout
<< "}";
198 if (fPostCode
.size()>0) {
199 tab(n
,fout
); fout
<< "#pragma omp single";
200 tab(n
,fout
); fout
<< "{";
201 tab(n
+1,fout
); fout
<< "// post processing";
202 printlines(n
+1, fPostCode
, fout
);
203 tab(n
,fout
); fout
<< "}";
210 * Print a single loop (unless it is empty)
211 * @param n number of tabs of indentation
212 * @param fout output stream
214 void Loop::printoneln(int n
, ostream
& fout
)
216 if (fPreCode
.size()+fExecCode
.size()+fPostCode
.size() > 0) {
217 /* if (gVectorSwitch) {
219 fout << ((fIsRecursive) ? "// recursive loop" : "// vectorizable loop");
222 tab(n
,fout
); fout
<< "for (int i=0; i<" << fSize
<< "; i++) {";
223 if (fPreCode
.size()>0) {
224 tab(n
+1,fout
); fout
<< "// pre processing";
225 printlines(n
+1, fPreCode
, fout
);
227 printlines(n
+1, fExecCode
, fout
);
228 if (fPostCode
.size()>0) {
229 tab(n
+1,fout
); fout
<< "// post processing";
230 printlines(n
+1, fPostCode
, fout
);
232 tab(n
,fout
); fout
<< "}";
236 //-------------------------------------------------------
237 void Loop::concat(Loop
* l
)
239 assert(l
->fUseCount
== 1);
240 assert(fBackwardLoopDependencies
.size() == 1);
241 assert((*fBackwardLoopDependencies
.begin()) == l
);
243 fExtraLoops
.push_front(l
);
244 fBackwardLoopDependencies
= l
->fBackwardLoopDependencies
;