* Bugfix: InstrucIter no longer used for int_function iteration.
[dyninst.git] / dyninstAPI / src / liveness.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: liveness.C,v 1.2 2007/12/11 20:22:06 bill Exp $
43
44 #if defined(cap_liveness)
45
46 #include "debug.h"
47 #include "image-func.h"
48 #include "function.h"
49 #include "instPoint.h"
50 #include "registerSpace.h"
51 #include "debug.h"
52 #include "InstrucIter.h"
53 #include "symtab.h"
54
55 #if defined(arch_x86) || defined(arch_x86_64)
56 // Special-casing for IA-32...
57 #include "inst-x86.h"
58 #endif
59
60 // Code for register liveness detection
61
62 // Takes information from instPoint and resets
63 // regSpace liveness information accordingly
64 // Right now, all the registers are assumed to be live by default
65 void registerSpace::specializeSpace(const bitArray &liveRegs) {
66     // Liveness info is stored as a single bitarray for all registers.
67
68 #if defined(arch_x86) || defined(arch_x86_64) 
69     // We use "virtual" registers on the IA-32 platform (or AMD-64 in 
70     // 32-bit mode), and thus the registerSlot objects have _no_ relation
71     // to the liveRegs input set. We handle this as a special case, and
72     // look only for the flags representation (which is used to set
73     // the IA32_FLAG_VIRTUAL_REGISTER "register"
74     if (addr_width == 4) {
75         registers_[IA32_FLAG_VIRTUAL_REGISTER]->liveState = registerSlot::dead;
76         for (unsigned i = REGNUM_OF; i <= REGNUM_RF; i++) {
77             if (liveRegs[i]) {
78                 registers_[IA32_FLAG_VIRTUAL_REGISTER]->liveState = registerSlot::live;
79                 break;
80             }
81         }
82         // All we care about for now.
83         return;
84     }
85 #endif
86     assert(liveRegs.size() == getBitArray().size());
87     for (regDictIter i = registers_.begin(); i != registers_.end(); i++) {
88         if (liveRegs[i.currval()->number])
89             i.currval()->liveState = registerSlot::live;
90         else
91             i.currval()->liveState = registerSlot::dead;
92     }
93 }
94
95 const bitArray image_basicBlock::getLivenessOut() const {
96     bitArray out(in.size());
97
98     // OUT(X) = UNION(IN(Y)) for all successors Y of X
99     pdvector<image_edge *> target_edges;
100     getTargets(target_edges);
101     
102     for(unsigned i = 0; i < target_edges.size(); i++) {
103         if (target_edges[i]->getType() == ET_CALL) continue;
104         // Is this correct?
105         if (target_edges[i]->getType() == ET_CATCH) continue;
106         
107         // TODO: multiple entry functions and you?
108         
109         if (target_edges[i]->getTarget()) {
110             out |= target_edges[i]->getTarget()->getLivenessIn();
111         }
112     }
113     return out;
114 }
115
116 void image_basicBlock::summarizeBlockLivenessInfo() 
117 {
118     if(in.size())
119     {
120       return;
121     }
122
123     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
124
125     unsigned width = getFirstFunc()->img()->getObject()->getAddressWidth();
126
127     in = registerSpace::getBitArray();
128     def = in;
129     use = in;
130
131     liveness_printf("%s[%d]: Getting liveness summary for block starting at 0x%lx\n", 
132                     FILE__, __LINE__, firstInsnOffset());
133
134     bitArray read = in;
135     bitArray written = in;
136
137     InstrucIter ii(this);
138     while(ii.hasMore()) {
139         std::set<Register> tmpRead;
140         std::set<Register> tmpWritten;
141         ii.getAllRegistersUsedAndDefined(tmpRead, tmpWritten);
142
143         // We need to get numbers into our bit array representation
144         // However, we want a 0..n numbering rather than the native
145         // register numbers. For now, we map via the registerSpace. 
146
147         for (std::set<Register>::const_iterator i = tmpRead.begin(); i != tmpRead.end(); i++) {
148             read[*i] = true;
149         }
150         for (std::set<Register>::const_iterator i = tmpWritten.begin(); 
151              i != tmpWritten.end(); i++) {
152             written[*i] = true;
153         }
154
155         // TODO "If trusting the ABI..."
156         // Otherwise we should go interprocedural
157         if (ii.isACallInstruction()) {
158             read |= (registerSpace::getRegisterSpace(width)->getCallReadRegisters());
159             written |= (registerSpace::getRegisterSpace(width)->getCallWrittenRegisters());
160         }
161         if (ii.isAReturnInstruction()) {
162             read |= (registerSpace::getRegisterSpace(width)->getReturnReadRegisters());
163             // Nothing written implicitly by a return
164         }
165         if (ii.isSyscall()) {
166             read |= (registerSpace::getRegisterSpace(width)->getSyscallReadRegisters());
167             written |= (registerSpace::getRegisterSpace(width)->getSyscallWrittenRegisters());
168         }
169
170         // We have a special case for used registers. If a register
171         // was defined by an earlier instruction _in this block_,
172         // and used now, we _don't_ add the use to the summary. 
173         // This is because the summary represents conditions at
174         // the "top" of the block. 
175
176         // If something is read, then it has been used.
177         use |= (read & ~def);
178         // And if written, then was defined
179         def |= written;
180
181         liveness_printf("%s[%d] After instruction at address 0x%lx:\n", FILE__, __LINE__, *ii);
182         liveness_cerr << read << endl << written << endl << use << endl << def << endl;
183         
184         read.reset();
185         written.reset();
186         ++ii;
187     }
188
189     liveness_printf("%s[%d] Liveness summary for block:\n", FILE__, __LINE__);
190     liveness_cerr << in << endl << def << endl << use << endl;
191     liveness_printf("%s[%d] --------------------\n---------------------\n", FILE__, __LINE__);
192
193     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
194     return;
195 }
196
197 /* This is used to do fixed point iteration until 
198    the in and out don't change anymore */
199 bool image_basicBlock::updateBlockLivenessInfo() 
200 {
201   bool change = false;
202
203   stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
204
205   // old_IN = IN(X)
206   bitArray oldIn = in;
207   // tmp is an accumulator
208   bitArray out = getLivenessOut();
209   
210   // Liveness is a reverse dataflow algorithm
211  
212   // OUT(X) = UNION(IN(Y)) for all successors Y of X
213
214   // IN(X) = USE(X) + (OUT(X) - DEF(X))
215   in = use | (out - def);
216   
217   // if (old_IN != IN(X)) then change = true
218   if (in != oldIn)
219       change = true;
220       
221   liveness_printf("%s[%d] Step: block 0x%llx, hasChanged %d\n", FILE__, __LINE__, firstInsnOffset(), change);
222   liveness_cerr << in << endl;
223
224   stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
225
226   return change;
227 }
228
229 // Calculate basic block summaries of liveness information
230 // TODO: move this to an image_func level. 
231
232 void image_func::calcBlockLevelLiveness() {
233     if (livenessCalculated_) return;
234
235     // Make sure we have parsed...
236     blocks();
237
238     // Step 1: gather the block summaries
239     for (unsigned i = 0; i < blockList.size(); i++) {
240         blockList[i]->summarizeBlockLivenessInfo();
241     }
242     
243     // We now have block-level summaries of gen/kill info
244     // within the block. Propagate this via standard fixpoint
245     // calculation
246     bool changed = true;
247     while (changed) {
248         changed = false;
249         for (unsigned i = 0; i < blockList.size(); i++) {
250             if (blockList[i]->updateBlockLivenessInfo()) {
251                 changed = true;
252             }
253         }
254     }
255
256     livenessCalculated_ = true;
257 }
258
259 // This function does two things.
260 // First, it does a backwards iteration over instructions in its
261 // block to calculate its liveness.
262 // At the same time, we cache liveness (which was calculated) in
263 // any instPoints we cover. Since an iP only exists if the user
264 // asked for it, we take its existence to indicate that they'll
265 // also be instrumenting. 
266 void instPoint::calcLiveness() {
267     // Assume that the presence of information means we
268     // did this already.
269     if (postLiveRegisters_.size()) {
270         return;
271     }
272     // First, ensure that the block liveness is done.
273     func()->ifunc()->calcBlockLevelLiveness();
274
275     // We know: 
276     //    liveness in at the block level:
277     bitArray block_in = block()->llb()->getLivenessIn();
278     //    liveness _out_ at the block level:
279     bitArray block_out = block()->llb()->getLivenessOut();
280
281     postLiveRegisters_ = block_out;
282
283     // We now want to do liveness analysis for straight-line code. 
284         
285     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
286
287     // We iterate backwards over instructions in the block. 
288
289     InstrucIter ii(const_cast<image_basicBlock *>(block()->llb()));
290     // set to the last instruction in the block; setCurrentAddress handles the x86
291     // ii's inability to be a random-access iterator
292     ii.setCurrentAddress(block()->llb()->lastInsnOffset());
293
294     bitArray read(block_out.size());
295     bitArray written(block_out.size());
296     
297     liveness_printf("%s[%d] instPoint calcLiveness: %d, 0x%lx, 0x%lx\n", 
298                     FILE__, __LINE__, ii.hasPrev(), *ii, addr());
299
300     while(ii.hasPrev() && (*ii > addr())) {
301
302         // Cache it in the instPoint we just covered (if such exists)
303         instPoint *possiblePoint = func()->findInstPByAddr(*ii);
304         if (possiblePoint) {
305             if (possiblePoint->postLiveRegisters_.size() == 0) {
306                 possiblePoint->postLiveRegisters_ = postLiveRegisters_;
307             }
308         }
309
310         std::set<Register> tmpRead;
311         std::set<Register> tmpWritten;
312         ii.getAllRegistersUsedAndDefined(tmpRead, tmpWritten);
313
314         for (std::set<Register>::const_iterator i = tmpRead.begin(); 
315              i != tmpRead.end(); i++) {
316             read[*i] = true;
317         }
318         for (std::set<Register>::const_iterator i = tmpWritten.begin(); 
319              i != tmpWritten.end(); i++) {
320             written[*i] = true;
321         }
322
323         // TODO "If trusting the ABI..."
324         // Otherwise we should go interprocedural
325         if (ii.isACallInstruction()) {
326             read |= (registerSpace::getRegisterSpace(proc())->getCallReadRegisters());
327             written |= (registerSpace::getRegisterSpace(proc())->getCallWrittenRegisters());
328         }
329         if (ii.isAReturnInstruction()) {
330             read |= (registerSpace::getRegisterSpace(proc())->getReturnReadRegisters());
331             // Nothing written implicitly by a return
332         }
333
334         if (ii.isSyscall()) {
335             read |= (registerSpace::getRegisterSpace(proc())->getSyscallReadRegisters());
336             written |= (registerSpace::getRegisterSpace(proc())->getSyscallWrittenRegisters());
337         }
338
339         liveness_printf("%s[%d] Calculating liveness for iP 0x%lx, insn at 0x%lx\n",
340                         FILE__, __LINE__, addr(), *ii);
341         liveness_cerr << "Pre: " << postLiveRegisters_ << endl;
342
343         postLiveRegisters_ &= (~written);
344         postLiveRegisters_ |= read;
345         liveness_cerr << "Post: " << postLiveRegisters_ << endl;
346
347         written.reset();
348         read.reset();
349         --ii;
350     }
351
352     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
353
354     return;
355 }
356
357 const int *instPoint::liveRegisterArray() {
358     calcLiveness();
359
360     if (postLiveRegisters_.size() == 0) return NULL;
361
362     registerSpace *rs = registerSpace::getRegisterSpace(proc());
363
364     // Only do GPRs. 
365     unsigned size = rs->numGPRs();
366
367     int *liveRegs = new int[size];
368
369     for (unsigned i = 0; i < size; i++) {
370         int regNum = rs->GPRs()[i]->number;
371         assert(regNum < size);
372         if (postLiveRegisters_[i])
373             liveRegs[regNum] = 1;
374         else
375             liveRegs[regNum] = 0;
376     }
377     return liveRegs;
378 }
379
380
381 // It'd be nice to do the calcLiveness here, but it's defined as const...
382 bitArray instPoint::liveRegisters(callWhen when) {
383     // postLiveRegisters_ is our _output_ liveness. If the 
384     // instrumentation is pre-point, we need to update it with
385     // the effects of this instruction.
386
387     bool debug = false;
388
389     calcLiveness();
390
391     if ((when == callPostInsn) ||
392         (when == callBranchTargetInsn)) {
393         return postLiveRegisters_;
394     }
395     assert(when == callPreInsn);
396
397     // We need to do one more step.
398     // Get the current instruction iterator.
399     InstrucIter ii(block());
400     ii.setCurrentAddress(addr());
401
402     bitArray read(postLiveRegisters_.size());
403     bitArray written(postLiveRegisters_.size());
404     bitArray ret(postLiveRegisters_);
405
406     std::set<Register> tmpRead;
407     std::set<Register> tmpWritten;
408     ii.getAllRegistersUsedAndDefined(tmpRead, tmpWritten);
409
410     for (std::set<Register>::const_iterator i = tmpRead.begin(); 
411          i != tmpRead.end(); i++) {
412         read[*i] = true;
413     }
414     for (std::set<Register>::const_iterator i = tmpWritten.begin(); 
415          i != tmpWritten.end(); i++) {
416         written[*i] = true;
417     }
418
419
420     // TODO "If trusting the ABI..."
421     // Otherwise we should go interprocedural
422     if (ii.isACallInstruction()) {
423         read |= (registerSpace::getRegisterSpace(proc())->getCallReadRegisters());
424         written |= (registerSpace::getRegisterSpace(proc())->getCallWrittenRegisters());
425     }
426     if (ii.isAReturnInstruction()) {
427         read |= (registerSpace::getRegisterSpace(proc())->getReturnReadRegisters());
428         // Nothing written implicitly by a return
429     }
430
431     ret &= (~written);
432     ret |= read;
433
434     if (debug) {
435         fprintf(stderr, "Liveness out for instruction at 0x%lx\n",
436                 addr());
437         cerr << "        " << "?RNDITCPAZSOF11111100DSBSBDCA" << endl;
438         cerr << "        " << "?FTFFFFFFFFFP54321098IIPPXXXX" << endl;
439         cerr << "Read    " << read << endl;
440         cerr << "Written " << written << endl;
441         cerr << "Live    " << ret << endl;
442     }
443
444     return ret;
445 }
446
447 #endif
448
449 //// OLD VERSIONS FOR REFERENCE
450
451 #if 0
452 /* Iterates over instructions in the basic block to 
453    create the initial gen kill sets for that block */
454 bool int_basicBlock::initRegisterGenKill() 
455 {  
456   in = new bitArray;
457   in->bitarray_init(maxGPR,in);  
458
459   out = new bitArray;
460   out->bitarray_init(maxGPR,out);  
461
462   gen = new bitArray;
463   gen->bitarray_init(maxGPR,gen);  
464   
465   kill = new bitArray;
466   kill->bitarray_init(maxGPR,kill);  
467
468   inFP = new bitArray;
469   inFP->bitarray_init(maxFPR,inFP);  
470
471   outFP = new bitArray;
472   outFP->bitarray_init(maxFPR,outFP);  
473
474   genFP = new bitArray;
475   genFP->bitarray_init(maxFPR,genFP);  
476   
477   killFP = new bitArray;
478   killFP->bitarray_init(maxFPR,killFP);  
479
480   
481   InstrucIter ii(this);
482   
483   
484   while(ii.hasMore()) {
485     /* GPR Gens */
486     if (ii.isA_RT_ReadInstruction()){
487       if (!kill->bitarray_check(ii.getRTValue(),kill))
488         gen->bitarray_set(ii.getRTValue(),gen);
489     }
490     if (ii.isA_RA_ReadInstruction()){
491       if (!kill->bitarray_check(ii.getRAValue(),kill))
492         gen->bitarray_set(ii.getRAValue(),gen);
493     }
494     if (ii.isA_RB_ReadInstruction()){
495       if (!kill->bitarray_check(ii.getRBValue(),kill))
496         gen->bitarray_set(ii.getRBValue(),gen);
497     }
498     if (ii.isA_MRT_ReadInstruction()) {
499        /* Assume worst case scenario */
500        for (int i = ii.getRTValue(); i < 32; i++) {
501           if (!kill->bitarray_check(i,kill))
502              gen->bitarray_set(i,gen);
503        }
504     }
505     
506     /* FPR Gens */
507     if (ii.isA_FRT_ReadInstruction()){
508       if (!killFP->bitarray_check(ii.getFRTValue(),killFP))
509         genFP->bitarray_set(ii.getFRTValue(),genFP);
510     }
511     if (ii.isA_FRA_ReadInstruction()){
512       if (!killFP->bitarray_check(ii.getFRAValue(),killFP))
513         genFP->bitarray_set(ii.getFRAValue(),genFP);
514     }
515     if (ii.isA_FRB_ReadInstruction()){
516       if (!killFP->bitarray_check(ii.getFRBValue(),killFP))
517         genFP->bitarray_set(ii.getFRBValue(),genFP);
518     }
519     if (ii.isA_FRC_ReadInstruction()){
520       if (!killFP->bitarray_check(ii.getFRCValue(),killFP))
521         genFP->bitarray_set(ii.getFRCValue(),genFP);
522     }
523
524     /* GPR Kills */
525     if (ii.isA_RT_WriteInstruction()){
526       kill->bitarray_set(ii.getRTValue(),kill);
527     }    
528     if (ii.isA_RA_WriteInstruction()){
529       kill->bitarray_set(ii.getRAValue(),kill);
530     }
531     if (ii.isA_MRT_WriteInstruction()) {
532        /* Assume worst case scenario */
533        for (int i = ii.getRTValue(); i < 32; i++) {
534           kill->bitarray_set(i,kill);
535        }
536     }
537
538     /* FPR Kills */
539     if (ii.isA_FRT_WriteInstruction()){
540       killFP->bitarray_set(ii.getFRTValue(),killFP);
541     }    
542     if (ii.isA_FRA_WriteInstruction()){
543       killFP->bitarray_set(ii.getFRAValue(),killFP);
544     }
545
546     if (ii.isAReturnInstruction()){
547       /* Need to gen the possible regurn arguments */
548       gen->bitarray_set(3,gen);
549       gen->bitarray_set(4,gen);
550       genFP->bitarray_set(1,genFP);
551       genFP->bitarray_set(2,genFP);
552     }
553     if (ii.isAJumpInstruction()) {
554        Address branchAddress = ii.getBranchTargetAddress();
555        // Tail call optimization may mask a return
556
557        codeRange *range = func_->ifunc();
558
559        if (range) {
560           if (!(range->get_address_cr() <= branchAddress &&
561                 branchAddress < (range->get_address_cr() + range->get_size_cr()))) {
562              gen->bitarray_set(3,gen);
563              gen->bitarray_set(4,gen);
564              genFP->bitarray_set(1,genFP);
565              genFP->bitarray_set(2,genFP);
566              
567           }
568        } else {
569           gen->bitarray_set(3,gen);
570           gen->bitarray_set(4,gen);
571           genFP->bitarray_set(1,genFP);
572           genFP->bitarray_set(2,genFP);
573        }
574     }
575
576     if (ii.isADynamicCallInstruction())
577       {
578          for (int a = 3; a <= 10; a++)
579            gen->bitarray_set(a,gen);
580          for (int a = 1; a <= 13; a++)
581            genFP->bitarray_set(a,genFP);
582       }
583
584     /* If it is a call instruction we look at which registers are used
585        at the beginning of the called function, If we can't do that, we just
586        gen registers 3-10 (the parameter holding volative 
587        registers for power) & (1-13 for FPR)*/
588     if (ii.isACallInstruction())
589       {
590         Address callAddress = ii.getBranchTargetAddress();
591         //printf("Call Address is 0x%x \n",callAddress);
592         
593         //process *proc = flowGraph->getBProcess()->lowlevel_process();
594         
595         // process * procc = proc();
596         int_function * funcc;
597           
598         codeRange * range = proc()->findOrigByAddr(callAddress);
599         
600         if (range)
601           {
602             funcc = range->is_function();
603             if (funcc)
604               {
605                 InstrucIter ah(funcc);
606                 while (ah.hasMore())
607                   {
608                     // GPR
609                     if (ah.isA_RT_ReadInstruction()){
610                       gen->bitarray_set(ah.getRTValue(),gen);
611                     }
612                     if (ah.isA_RA_ReadInstruction()){
613                       gen->bitarray_set(ah.getRAValue(),gen);
614                     }
615                     if (ah.isA_RB_ReadInstruction()){
616                       gen->bitarray_set(ah.getRBValue(),gen);
617                     }
618                     
619                     // FPR
620                     if (ah.isA_FRT_ReadInstruction()){
621                       genFP->bitarray_set(ah.getFRTValue(),genFP);
622                     }
623                     if (ah.isA_FRA_ReadInstruction()){
624                       genFP->bitarray_set(ah.getFRAValue(),genFP);
625                     }
626                     if (ah.isA_FRB_ReadInstruction()){
627                       genFP->bitarray_set(ah.getFRBValue(),genFP);
628                     }
629                     if (ah.isA_FRC_ReadInstruction()){
630                       genFP->bitarray_set(ah.getFRCValue(),genFP);
631                     }
632                     if (ah.isACallInstruction() || ah.isAIndirectJumpInstruction()) {
633                       // Non-leaf.  Called function may
634                       // use registers never used by callee,
635                       // but used by this function.
636                       
637                       // Tail call optimization can also use the CTR
638                       // register that would normally be used by an
639                       // indirect jump.  Err on the safe side
640                       for (int a = 3; a <= 10; a++)
641                         gen->bitarray_set(a,gen);
642                       for (int a = 1; a <= 13; a++)
643                         genFP->bitarray_set(a,genFP);
644                       break;
645                     }
646                     if (ii.isAJumpInstruction()) {
647                       Address branchAddress = ii.getBranchTargetAddress();
648                       // This function might not use any input registers
649                       // but the tail-call optimization could
650                       
651                       codeRange *range = func_->ifunc();
652                       
653                       if (range) {
654                         if (!(range->get_address_cr() <= branchAddress &&
655                               branchAddress < (range->get_address_cr() + range->get_size_cr()))) {
656                           for (int a = 3; a <= 10; a++)
657                             gen->bitarray_set(a,gen);
658                           for (int a = 1; a <= 13; a++)
659                             genFP->bitarray_set(a,genFP);
660                           break;
661                         }
662                       } else {
663                         for (int a = 3; a <= 10; a++)
664                           gen->bitarray_set(a,gen);
665                         for (int a = 1; a <= 13; a++)
666                           genFP->bitarray_set(a,genFP);
667                         break;
668                       }
669                     }
670                     
671                     ah++;
672                   } /* ah.hasMore */
673               }
674             else
675               {
676                 for (int a = 3; a <= 10; a++)
677                   gen->bitarray_set(a,gen);
678                 for (int a = 1; a <= 13; a++)
679                   genFP->bitarray_set(a,genFP);
680               } /* funcc */
681           }
682         else /* if range */
683           {
684             for (int a = 3; a <= 10; a++)
685               gen->bitarray_set(a,gen);
686             for (int a = 1; a <= 13; a++)
687               genFP->bitarray_set(a,genFP);
688           }
689       } /* if call */
690     ++ii;
691   } /*while ii.hasMore */
692   return true;
693 }
694 #endif
695
696 #if 0
697 int int_basicBlock::liveSPRegistersIntoSet(instPoint *iP,
698                                            unsigned long address)
699 {
700    if (iP->hasSpecializedSPRegisters()) return 0;
701
702    stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
703
704     int *liveSPReg = new int[1]; // only care about MQ for Power for now
705     liveSPReg[0] = 0;
706     InstrucIter ii(this);
707     
708     while (ii.hasMore() &&
709            *ii <= address) {
710         if (ii.isA_MX_Instruction()) {
711             liveSPReg[0] = 1;
712             break;
713         }
714         ++ii;
715     }
716
717     iP->actualSPRLiveSet_ = liveSPReg;
718     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
719
720     return 1;
721 }
722
723 #endif