@@ -153,20 +153,25 @@ bool prepareEmbedding(int64_t id, Program &sub, Operation::Type embeddingType) {
153153 return true ;
154154}
155155
156- bool Subprogram::unfold (Program &main) {
156+ bool Subprogram::canUnfold (Operation::Type type) {
157+ return type == Operation::Type::SEQ || type == Operation::Type::PRG;
158+ }
159+
160+ bool Subprogram::unfold (Program &main, int64_t pos) {
157161 if (ProgramUtil::hasIndirectOperand (main)) {
158162 return false ;
159163 }
160- // find first seq or prg operation
161- int64_t pos = - 1 ;
162- for (size_t i = 0 ; i < main.ops .size (); i++) {
163- if (main.ops [i].type == Operation::Type::SEQ ||
164- main. ops [i]. type == Operation::Type::PRG) {
165- pos = i ;
166- break ;
164+ if (pos < 0 ) {
165+ // find first operation that can be unfolded
166+ for (size_t i = 0 ; i < main.ops .size (); i++) {
167+ if (canUnfold ( main.ops [i].type )) {
168+ pos = i;
169+ break ;
170+ }
167171 }
168172 }
169- if (pos < 0 ) {
173+ if (pos < 0 || static_cast <size_t >(pos) >= main.ops .size () ||
174+ !canUnfold (main.ops [pos].type )) {
170175 return false ;
171176 }
172177 const auto &emb_op = main.ops [pos];
@@ -187,7 +192,7 @@ bool Subprogram::unfold(Program &main) {
187192 updateOperand (op.target , start, shared_region_length, largest_used);
188193 updateOperand (op.source , start, shared_region_length, largest_used);
189194 }
190- // delete seq operation
195+ // delete old operation
191196 main.ops .erase (main.ops .begin () + pos);
192197 // embed program
193198 main.ops .insert (main.ops .begin () + pos, sub.ops .begin (), sub.ops .end ());
@@ -197,18 +202,28 @@ bool Subprogram::unfold(Program &main) {
197202bool Subprogram::autoUnfold (Program &main) {
198203 bool changed = false ;
199204 while (true ) {
200- // try to unfold
201205 auto copy = main;
202- if (!unfold (copy)) {
203- break ;
206+ bool unfolded = false ;
207+ for (size_t i = 0 ; i < copy.ops .size (); i++) {
208+ // try to unfold
209+ if (!unfold (copy, i)) {
210+ continue ;
211+ }
212+ // revert if unfolded program is too complex
213+ if (shouldFold (copy)) {
214+ copy = main;
215+ } else {
216+ unfolded = true ;
217+ break ;
218+ }
204219 }
205- // abort if unfolded program is too complex
206- if (shouldFold (copy)) {
220+ // update main program if unfolding was successful
221+ if (unfolded) {
222+ main = copy;
223+ changed = true ;
224+ } else {
207225 break ;
208226 }
209- // ok, update program!
210- main = copy;
211- changed = true ;
212227 }
213228 return changed;
214229}
0 commit comments