basicBlock.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.66 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 
00026 # ifdef DELTA_COMPILER
00027 # include "incls/_basicBlock.cpp.incl"
00028 
00029 int BB::genCounter = 0;
00030 
00031 void BB::init(Node* f, Node* l, int n) {
00032   first = f; last = l; nnodes = n;
00033   _id = 0; _genCount = 0; BB::genCounter = 0;
00034   _loopDepth = 0;
00035 }
00036 
00037 BB*  BB::next()         const { Node* n = last ->next();      return n ? n->bb() : NULL; }
00038 BB*  BB::firstPrev()    const { Node* n = first->firstPrev(); return n ? n->bb() : NULL; }
00039 BB*  BB::next(int i)    const { Node* n = last ->next(i);     return n ? n->bb() : NULL; }
00040 BB*  BB::prev(int i)    const { Node* n = first->prev(i);     return n ? n->bb() : NULL; }
00041 int  BB::nSuccessors()  const { return last ->nSuccessors(); }
00042 int  BB::nPredecessors()const { return first->nPredecessors(); }
00043 bool BB::isSuccessor  (const BB* bb) const { return last->isSuccessor(bb->first); }
00044 bool BB::isPredecessor(const BB* bb) const { return first->isPredecessor(bb->last); }
00045 
00046 // note: the functions below are defined here rather than in PReg to localize
00047 // this temporary hack
00048 const int MaxSearch = 50;       // max. # of nodes to search backwards
00049 NonTrivialNode* findDefinitionOf(Node* endNode, const PReg* r, int max = MaxSearch) {
00050   // search backwards for a definition of r
00051   Node* current = endNode;
00052   for (int i = 0; i < max && current != NULL; i++) {
00053     if (current->deleted) continue;
00054     if (current->hasSinglePredecessor()) {
00055       if ((current->isAssignNode() || current->isInlinedReturnNode()) && 
00056           ((NonTrivialNode*)current)->dest() == r) {
00057         return (NonTrivialNode*)current;
00058       }
00059     } else {
00060       // merge node with several predecessors: search each one and make sure all find the same def
00061       assert(current->isMergeNode(), "must be a merge");
00062       MergeNode* merge = (MergeNode*)current;
00063       NonTrivialNode* candidate = NULL; // possible def of r
00064       for (int j = merge->nPredecessors() - 1; j >= 0; j--) {
00065         Node* prev = merge->prev(j);
00066         NonTrivialNode* cand = findDefinitionOf(prev, r, max - i);
00067         if (cand == NULL || candidate && cand != candidate) return NULL;
00068         candidate = cand;
00069       }
00070       return candidate; // all paths lead to the same candidate
00071     }
00072     current = current->firstPrev();
00073   }
00074   return NULL;  // search limit exceeded
00075 }
00076 
00077 
00078 void propagateTo(BB* useBB, Use* use, NonTrivialNode* fromNode, PReg* src,
00079                  NonTrivialNode* toNode) {
00080   // r1 := r2; ...; r3 := op(r1)  -->  r1 := r2; ...; r3 := op(r2)
00081   if (toNode->canCopyPropagate(fromNode)) {
00082     if (!src->extendLiveRange(toNode)) {
00083       if (CompilerDebug) {
00084         cout(PrintCopyPropagation)->print("*brute-force cp: cannot propagate %s from N%ld to N%ld because of extendLiveRange\n",
00085                 src->name(), fromNode->id(), toNode->id());
00086       }
00087       return;
00088     }
00089     PReg* replaced = fromNode->dest();
00090     bool ok = toNode->copyPropagate(useBB, use, src, true);
00091 
00092     if (!ok) {
00093       // This if statement has been added by Lars Bak 29-4-96 to work around the type check node
00094       // elimination problem. (Ask Urs for details).
00095       return;
00096     }
00097     assert(ok, "should have worked");
00098     if (CompilerDebug) {
00099       cout(PrintCopyPropagation)->print("*brute-force cp: propagate %s from N%ld to N%ld\n",
00100               src->name(), fromNode->id(), toNode->id());
00101     }
00102     // if this was the last use, make sure its value can be recovered for debugging
00103     if (replaced->debug && replaced->hasNoUses()) {
00104       assert(!replaced->cpInfo, "already has cpInfo");
00105       replaced->cpInfo = new_CPInfo(fromNode);
00106       assert(replaced->cpInfo, "should have cpInfo now");
00107     }
00108   } else {
00109     if (CompilerDebug) cout(PrintCopyPropagation)->print("*Node N%d cannot copy-propagate\n", toNode->id());
00110   }
00111 }
00112 
00113 
00114 bool regAssignedBetween(const PReg* r, const Node* startNode, Node* endNode) {
00115   // check if r is assigned somewhere between start and end node
00116   // quite inefficient
00117   // search backwards from end to start
00118   BB* bbWithoutDefs = NULL;     // BB w/o defs of r
00119   for (Node* n = endNode; n != startNode; n = n->firstPrev()) {
00120     // see if n's bb has a def or r
00121     BB* bb = n->bb();
00122     if (bb == bbWithoutDefs) continue; // no defs here
00123     bool hasDefs = false;
00124     for (int i = 0; i < bb->duInfo.info->length(); i++) {// forall def/use info lists
00125       DUInfo* dui = bb->duInfo.info->at(i);
00126       if (dui->reg == r && !dui->defs.isEmpty()) {
00127         // yes, it has a def
00128         hasDefs = true;
00129         for (SListElem<Def*>* d = dui->defs.head(); d; d = d->next()) {
00130           if (d->data()->node == n) return true; 
00131         }
00132         break;  // no need to search the other duInfo entries
00133       }
00134     }
00135     if (!hasDefs) {
00136       // r has no def in this BB, avoid search next time
00137       bbWithoutDefs = bb;
00138     }
00139   }
00140   return false;         // no def found
00141 }
00142 
00143 
00144 void BB::bruteForceCopyPropagate() {
00145   const int len = duInfo.info->length();
00146   
00147   for (int i = 0; i < len; i++) {               // forall def/use info lists
00148     DUInfo* dui = duInfo.info->at(i);
00149     const PReg* r = dui->reg;
00150     if (!r->isSAPReg() || !r->loc.equals(unAllocated)) {
00151       // optimize only SAPRegs for now
00152       // preallocated PReg may have aliases - don't do CP
00153       continue;
00154     }
00155 
00156     // try to find a def them with other PRegs
00157     if (dui->uses.isEmpty()) continue;  // has only defs        
00158     const Use* use = dui->uses.head()->data();
00159     Node* firstUseNode = use->node;
00160     NonTrivialNode* defNode = findDefinitionOf(firstUseNode, r);
00161     if (defNode == NULL) continue;      // no def found
00162 
00163     PReg* candidate = ((NonTrivialNode*)defNode)->src();
00164     if (!candidate->loc.equals(unAllocated)) continue;
00165     assert(candidate->isUsed(), "should not be unused");
00166     if (!regAssignedBetween(candidate, defNode, firstUseNode)) {
00167       // ok: the candidate reaches the use at firstUseNode
00168       // try to propagate it to all uses of r in this BB
00169       SListElem<Use*>* nextu;
00170       for (SListElem<Use*>* u = dui->uses.head(); u; u = nextu) {
00171         nextu = u->next();      // because we're mutating the list
00172         Use* thisUse = u->data();
00173         NonTrivialNode* thisNode = thisUse->node;
00174         if (!regAssignedBetween(candidate, firstUseNode, thisNode)) {
00175           propagateTo(this, thisUse, defNode, candidate, thisNode);
00176         } else {
00177           // candidate can't reach anything downstream of this use
00178           break;
00179         }
00180       }
00181     }
00182   }     
00183 }
00184 
00185 
00186 void BB::localCopyPropagate() {
00187   // perform local copy propagation using the local def/use information
00188   // should be rewritten to make just one pass over the nodes, keeping track of
00189   // aliases created by assignments -- fix this 
00190   const int len = duInfo.info->length();
00191   SimpleBitVector used = 0;             // hardwired registers used
00192   SimpleBitVector usedTwice = 0;
00193   for (int i = 0; i < len; i++) {
00194     PReg* r = duInfo.info->at(i)->reg;
00195     if (!r->loc.equals(unAllocated) && r->loc.isRegisterLocation()) {
00196       if (used.isAllocated(r->loc.number())) {
00197         // two PRegs have same preallocated reg - algorithm below can't handle this
00198         usedTwice = usedTwice.allocate(r->loc.number());
00199       } else {
00200         used = used.allocate(r->loc.number());
00201       }
00202     }
00203   }
00204   
00205   for (i = 0; i < len; i++) {
00206     const int BIG = 9999999;
00207     DUInfo* dui = duInfo.info->at(i);
00208     PReg* r = dui->reg;
00209     if (!r->loc.equals(unAllocated) && r->loc.isRegisterLocation() && usedTwice.isAllocated(r->loc.number())) {
00210       // this preallocated PReg has aliases - don't do CP
00211       continue;
00212     }
00213     SListElem<Use*>* u = dui->uses.head();
00214     SListElem<Def*>* nextd;
00215     for (SListElem<Def*>* d = dui->defs.head(); d && u; d = nextd) {
00216       // try to find a use of the def at d
00217       nextd = d->next();
00218       const Def* def = d->data();
00219       SList<Def*>* srcDefs = NULL;      // redefinition of src that defines this def (if any) 
00220       if (def->node->hasSrc()) {
00221         PReg* src = def->node->src();
00222         if (src->loc.isRegisterLocation() && usedTwice.isAllocated(src->loc.number())) {
00223           // r := f(r2), and r2 is aliased preallocated - can't handle
00224           continue;
00225         }
00226         if (!src->isSinglyAssigned()) {
00227           // careful: r is only equivalent to src as long as src isn't reassigned
00228           // within this basic block
00229           for (int j = 0; j < len; j++) {
00230             PReg* r = duInfo.info->at(j)->reg;
00231             if (r == src) break;
00232           }
00233           assert(j < len, "should have found duInfo for src");
00234           srcDefs = &duInfo.info->at(j)->defs;
00235           if (srcDefs->length() == 0) {
00236             srcDefs = NULL;   // ok, src is constant during this BB
00237           }
00238         }
00239       }
00240       const int d_id = def->node->num();
00241       int u_id;
00242       // find a use in a node following the current def
00243       for ( ; u && (u_id = u->data()->node->num()) <= d_id; u = u->next()) ;
00244       if (!u) break;      // no such use in this BB
00245 
00246       // visit all uses with a node ID between here and the next def of either the
00247       // current PReg or the source PReg that defines it
00248       int stop_id = nextd ? nextd->data()->node->num() : BIG;
00249       if (srcDefs) {
00250         for (SListElem<Def*>* d = srcDefs->head(); 
00251              d && d->data()->node->num() < u_id; 
00252              d = d->next()) ;
00253         if (d) stop_id = min(stop_id, d->data()->node->num());
00254       }
00255 
00256       while (u_id <= stop_id) {
00257         // the def at d_id reaches the use at u_id
00258         assert(d_id < u_id, "just checking");
00259         dui->propagateTo(this, r, def, u->data(), false);
00260         u = u->next();
00261         u_id = u ? u->data()->node->num() : BIG + 1;
00262       }
00263     }
00264   }     
00265 }
00266 
00267 
00268 void BB::makeUses() {
00269   // collect defs and uses for all pregs (and fill pregTable in the process)
00270   assert(duInfo.info == NULL, "shouldn't be set");
00271   duInfo.info = new GrowableArray<DUInfo*>(nnodes + 10);
00272   for (Node* n = first; n != last->next(); n = n->next()) {
00273     if (n->deleted) continue;
00274     n->makeUses(this);
00275   }
00276 }
00277 
00278 
00279 void BB::renumber() {
00280   int count = 0;
00281   for (Node* n = first; n != last->next(); n = n->next()) n->setNum(count++);
00282   nnodes = count;
00283 }
00284 
00285 
00286 void BB::remove(Node* n) {
00287   // remove this node and its defs & uses
00288   // NB: nodes aren't actually removed from the graph but just marked as
00289   // deleted.  This is much simpler because the topology of the flow graph
00290   // doesn't change this way
00291   assert(contains(n), "node isn't in this BB");
00292   n->removeUses(this);
00293   n->deleted = true;
00294 }
00295 
00296 
00297 void BB::addAfter(Node* prev, Node* newNode) {
00298   // prev == NULL means add as first node
00299   assert(nnodes, "shouldn't add anything to this BB");
00300   assert(prev == NULL || contains(prev), "node isn't in this BB");
00301   if (prev) {
00302     prev->insertNext(newNode);
00303     if (prev == last) last = newNode;
00304   } else {
00305     first->insertPrev(newNode);
00306     first = newNode;
00307   }
00308   if (bbIterator->usesBuilt) {
00309     newNode->makeUses(this);
00310   } else {
00311     newNode->setBB(this);
00312   }
00313   renumber();
00314   assert(newNode->bb() == this, "should point to me now");
00315 }
00316 
00317 
00318 static BB* thisBB;
00319 static void duChecker(PRegBBIndex* p) {
00320   if (p->bb == thisBB) fatal("should not be in middle of list");
00321 }
00322 
00323 
00324 static bool findMyBB(void* bb, PRegBBIndex* p) {
00325   return p->bb == (BB*)bb;
00326 }
00327 
00328 
00329 int BB::addUDHelper(PReg* r) {
00330   // we're computing the uses block by block, and the current BB's
00331   // PRegBBIndex is always the last entry in the preg's list.
00332   assert(nnodes, "shouldn't add anything to this BB");
00333   bbIterator->pregTable->at_put_grow(r->id(), r);
00334   PRegBBIndex* p;
00335   if (bbIterator->usesBuilt) {
00336     // find entry for the PReg
00337     int i = r->dus.find(this, findMyBB);
00338     if (i >= 0) {
00339       p = r->dus.at(i);
00340     } else {
00341       // create new entry
00342       duInfo.info->append(new DUInfo(r));
00343       r->dus.append(p = new PRegBBIndex(this, duInfo.info->length() - 1, r));
00344     }
00345   } else {
00346     // while building the defs & uses, the PReg's entry must be the last
00347     // one in the list (if there is an entry for this BB)
00348     if (r->dus.isEmpty() || r->dus.last()->bb != this) {
00349       // PReg doesn't yet have an entry for this block
00350 #       ifdef ASSERT
00351         thisBB = this;
00352         r->dus.apply(duChecker);
00353 #       endif
00354       duInfo.info->append(new DUInfo(r));
00355       r->dus.append(new PRegBBIndex(this, duInfo.info->length() - 1, r));
00356     }
00357     p = r->dus.last();
00358   }
00359   assert(p->bb == this, "wrong BB");
00360   assert(duInfo.info->at(p->index)->reg == r, "wrong PReg");
00361   return p->index;
00362 }
00363 
00364 
00365 Use* BB::addUse(NonTrivialNode* n, PReg* r, bool soft) {
00366   assert(contains(n), "node isn't in this BB");
00367   if (r->isNoPReg()) return NULL;
00368   Use* u = soft ? new PSoftUse(n) : new Use(n);
00369   r->incUses(u);
00370   int index = addUDHelper(r);
00371   duInfo.info->at(index)->uses.append(u);
00372   return u;
00373 }
00374 
00375 
00376 Def* BB::addDef(NonTrivialNode* n, PReg* r) {
00377   assert(contains(n), "node isn't in this BB");
00378   if (r->isNoPReg()) return NULL;
00379   Def* d = new Def(n);
00380   r->incDefs(d);
00381   int index = addUDHelper(r);
00382   duInfo.info->at(index)->defs.append(d);
00383   return d;
00384 }
00385 
00386 
00387 // allocate PRegs that are used & defined solely within this BB
00388 void BB::localAlloc(GrowableArray<BitVector*>* hardwired, 
00389                     GrowableArray<PReg*>* localRegs,
00390                     GrowableArray<BitVector*>* lives) {
00391   // try fast allocation first -- use only local regs that aren't touched
00392   // by any pre-allocated (hardwired) registers
00393 
00394   // hardwired, localRegs, lives: just passed on to slowLocalAlloc
00395 
00396   // Note: Fix problem with registers that are used after a call in PrimNodes
00397   // such as ContextCreateNode, etc. Problem is that values like self might
00398   // be allocated in registers but the registers are trashed after a call.
00399   // Right now: PrologueNode terminates BB to fix the problem.
00400 
00401   if (!nnodes) return;              // empty BB
00402 
00403   GrowableArray<RegCandidate*> cands(nnodes);
00404   GrowableArray<RegisterEqClass*> regClasses(nnodes + 1);
00405   regClasses.append(NULL);          // first reg class has index 1
00406 
00407   int  use_count[nofRegisters], def_count[nofRegisters];
00408   for (int i = 0; i < nofRegisters; i++) use_count[i] = def_count[i] = 0;
00409 
00410   for (Node* nn = first; nn != last->next(); nn = nn->next()) {
00411     if (nn->deleted) continue;
00412     nn->markAllocated(use_count, def_count);
00413     if (nn->isAssignNode()) {
00414       NonTrivialNode* n = (NonTrivialNode*)nn;
00415       PReg* src = n->src();
00416       PReg* dest = n->dest();
00417       bool localSrc  = src ->isLocalTo(this);
00418       bool localDest = dest->isLocalTo(this);
00419       if (src->loc.isRegisterLocation()) {
00420         if (dest->loc.equals(unAllocated) && localDest) {
00421           // PR = PR2(reg)
00422           // allocate dest->loc to src->loc, but only if src->loc
00423           // isn't defined again
00424           cands.append(new RegCandidate(dest, src->loc, def_count[src->loc.number()]));
00425         }
00426       } else if (dest->loc.isRegisterLocation()) {
00427         if (src->loc.equals(unAllocated) && localSrc) {
00428           // PR2(reg) = PR
00429           // should allocate src->loc to dest->loc, but only if dest->loc
00430           // has single definition (this one) and isn't used before
00431           // this point   [simplification]
00432           if (def_count[dest->loc.number()] != 1 || use_count[dest->loc.number()]) {
00433             // not eligible for special treatment
00434           } else {
00435             cands.append(new RegCandidate(src, dest->loc, 1));
00436           }
00437         }
00438       } else if (localSrc && localDest) {
00439         // both regs are local and unallocated - put them in same
00440         // equivalence class
00441         // fix this - must check for overlapping live ranges first
00442       } else {
00443         // non-local registers - skip
00444       }
00445     }
00446   }
00447 
00448   // now examine all candidates and allocate them to preferred register
00449   // if possible
00450   while (cands.nonEmpty()) {
00451     RegCandidate* c = cands.pop();
00452     if (def_count[c->loc.number()] == c->ndefs) {
00453       doAlloc(c->r, c->loc);
00454     }
00455   }
00456 
00457   // allocate other local regs (using the untouched temp regs of this BB)
00458   int temp = 0;
00459   for (i = 0; i < duInfo.info->length(); i++) {
00460     // collect local regs 
00461     PReg* r = duInfo.info->at(i)->reg;
00462     if (r->loc.equals(unAllocated) && !r->isUnused() && r->isLocalTo(this)) {
00463       assert(r->dus.first()->index == i, "should be the same");
00464       for ( ; temp < nofLocalRegisters &&
00465            use_count[Mapping::localRegister(temp).number()] + def_count[Mapping::localRegister(temp).number()] > 0;
00466            temp++) ;
00467       if (temp == nofLocalRegisters) break;         // ran out of regs
00468       // ok, allocate Mapping::localRegisters[temp] to the preg and equivalent pregs
00469       Location t = Mapping::localRegister(temp++);
00470       PReg* frst = r->regClass ? regClasses.at(r->regClass)->first : r;
00471       for (PReg* pr = frst; pr;
00472            pr = pr->regClassLink) {
00473         doAlloc(pr, t);
00474         pr->regClass = 0;
00475       }
00476     }
00477     r->regClass = 0;
00478   }
00479 
00480   if (temp == nofLocalRegisters) {
00481     // ran out of local regs with the simple strategy - try using slow
00482     // allocation algorithm
00483     slowLocalAlloc(hardwired, localRegs, lives);
00484   }
00485 }
00486 
00487         
00488 // slower but more capable version of local allocation; keeps track of live
00489 // ranges via a bit map
00490 // note: temporary data structs are passed in so they can be reused for all
00491 // BBs (otherwise would allocate too much junk in resource area)
00492 void BB::slowLocalAlloc(GrowableArray<BitVector*>* hardwired, 
00493                         GrowableArray<PReg*>* localRegs,
00494                         GrowableArray<BitVector*>* lives) {
00495   // clear temporary data structures
00496   localRegs->clear();
00497   lives->clear();
00498   for (int i = 0; i < nofLocalRegisters; i++) {
00499     hardwired->at(i)->setLength(nnodes);
00500     hardwired->at(i)->clear();
00501   }
00502   // hardwired->at(i): indexed by reg no, gives nodes in which register is busy
00503   // localRegs: collects all PRegs that could be allocated locally
00504   // lives: for each reg in localRegs, holds live range (bit vector with one bit per node)
00505 
00506   for (i = 0; i < duInfo.info->length(); i++) {
00507     // collect local regs
00508     PReg* r = duInfo.info->at(i)->reg;
00509     if (r->isLocalTo(this)) {
00510       assert(r->dus.first()->index == i, "should be the same");
00511       if (r->isUnused()) {
00512         // unused register - ignore
00513       } else {
00514         DUInfo* info = duInfo.info->at(r->dus.first()->index);
00515         localRegs->append(r);
00516         BitVector* bv = new BitVector(nnodes);
00517         lives->append(bv);
00518         int firstUse = 0, lastUse = nnodes - 1;
00519         duInfo.info->at(i)->getLiveRange(firstUse, lastUse);
00520         bv->addFromTo(firstUse, lastUse);
00521       }
00522     } else if (r->loc.isLocalRegister()) {
00523       // already allocated (i.e., hardwired register)
00524       assert(!r->loc.equals(unAllocated), "unAllocated should not count as isRegister()");
00525       int firstUse = 0, lastUse = nnodes - 1;
00526       if (!r->incorrectDU()) {
00527         duInfo.info->at(i)->getLiveRange(firstUse, lastUse);
00528       } else {
00529         // can't really compute live range since the temp might be non-local
00530         // so assume it's live from first node til the end
00531       }
00532       hardwired->at(Mapping::localRegisterIndex(r->loc))->addFromTo(firstUse, lastUse);
00533     }
00534   }
00535 
00536   // now, localRegs holds all local regs, and lives contains each register's
00537   // live range (one bit per node, 1 = reg is live); hardwired contains
00538   // the ranges where temp regs are already taken (e.g. for NLR, calls, etc)
00539 
00540   // just add trashed registers now
00541   for (Node* n = first; n != last->next(); n = n->next()) {
00542     if (n->deleted) continue;
00543     SimpleBitVector v = n->trashedMask();
00544     if (v.isEmpty()) continue;  // nothing trashed (normal case)
00545     for (int i = 0; i < nofLocalRegisters; i++) {
00546       if (v.isAllocated(i)) hardwired->at(i)->add(n->num());
00547     }
00548   }
00549 
00550 
00551   // cycle through the temp registers to (hopefully) allow more optimizations
00552   // later (e.g. scheduling)
00553   int lastTemp = 0;
00554 #   define nextTemp(n) (n == nofLocalRegisters - 1) ? 0 : n + 1
00555 
00556   for (i = 0; i < localRegs->length(); i++) {
00557     // try to allocate localRegs[i] to a local (temp) register
00558     PReg* r = localRegs->at(i);
00559     if (!r->loc.equals(unAllocated)) {
00560       assert(r->regClass == 0, "should have been cleared");
00561       continue;
00562     }
00563     BitVector* liveRange = lives->at(i);
00564     for (int tempNo = lastTemp, ntries = 0; ntries < nofLocalRegisters;
00565          tempNo = nextTemp(tempNo), ntries++) {
00566       if (liveRange->isDisjointFrom(hardwired->at(tempNo))) {
00567         Location temp = Mapping::localRegister(tempNo);
00568         doAlloc(r, temp);
00569         hardwired->at(tempNo)->unionWith(liveRange);
00570         lastTemp = nextTemp(tempNo);
00571         break;
00572       }
00573     }
00574     if (CompilerDebug) {
00575       if (r->loc.equals(unAllocated)) {
00576         cout(PrintLocalAllocation)->print("*could NOT find local assignment for local %s in BB%ld\n", r->name(), id());
00577       }
00578     }
00579     r->regClass = 0;
00580   }
00581 }
00582 
00583 
00584 void BB::doAlloc(PReg* r, Location l) {
00585   if (CompilerDebug) cout(PrintLocalAllocation)->print("*assigning %s to local %s in BB%ld\n", l.name(), r->name(), id());
00586   assert(!r->debug, "should not allocate to temp reg");
00587   r->loc = l;
00588 }
00589 
00590 
00591 void BB::computeEscapingBlocks(GrowableArray<BlockPReg*>* l) {
00592   // add all escaping blocks to l
00593   for (Node* n = first; n != last->next(); n = n->next()) {
00594     if (n->deleted) continue;
00595     n->computeEscapingBlocks(l);
00596   }
00597 }
00598 
00599 
00600 void BB::apply(NodeVisitor* v) {
00601   if (nnodes > 0) {
00602     Node* end = last->next();
00603     for (Node* n = first; n != end; n = n->next()) {
00604       if (!n->deleted) {
00605         v->beginOfNode(n);
00606         n->apply(v);
00607         v->endOfNode(n);
00608       }
00609     }
00610   } else {
00611   #ifdef ASSERT
00612     // just checking...
00613     assert(nnodes == 0, "nnodes should be 0");
00614     Node* end = last->next();
00615     for (Node* n = first; n != end; n = n->next) {
00616       assert(n->deleted, "basic block is not empty even though nnodes == 0!");
00617     }
00618   #endif
00619   }
00620 }
00621 
00622 
00623 bool BB::verifyLabels() {
00624   bool ok = true;
00625   if (nnodes > 0) {
00626     for (Node* n = first; n != last->next(); n = n->next()) {
00627       if (n->deleted) continue;
00628       if (n->label.is_unbound()) {
00629         ok = false;
00630         lprintf("unbound label at N%d\n", n->id());
00631       }
00632     }
00633   }
00634   return ok;
00635 }
00636 
00637 
00638 static void printPrevBBs(BB* b, const char* str) {
00639   lprintf("BB%ld%s", b->id(), str);
00640 }
00641 
00642 
00643 void BB::print_short() {
00644   lprintf("BB%-3ld[%d] %#lx (%ld, %ld); prevs ", id(), _loopDepth, this, first->id(), last->id());
00645   for (int i = 0; i < nPredecessors(); i++) printPrevBBs(prev(i),  (i == nPredecessors() - 1) ? " : " : ", ");
00646   lprintf("; ");
00647   if (next ()) lprintf("next BB%ld", next ()->id());
00648   for (i = 1; i < nSuccessors(); i++) printPrevBBs(next(i), (i == nSuccessors() - 1) ? " : " : ", ");
00649 }
00650 
00651 
00652 void BB::print() {
00653   print_short(); lprintf("(%ld nodes):\n", nnodes);
00654   print_code(false);
00655   lprintf("duInfo: "); duInfo.print();
00656 }
00657 
00658 
00659 void BB::print_code(bool suppressTrivial) {
00660   for (Node* n = first; n != last->next(); n = n->next()) {
00661     if (n->deleted && !(n == first || n == last)) continue;
00662     if (suppressTrivial && n->isTrivial()) {
00663       // don't print
00664     } else {
00665       n->printID(); n->print_short(); lprintf("\n");
00666     }
00667   }
00668 }
00669 
00670 
00671 bool BB::contains(const Node* which) const {
00672   for (Node* n = first; n != last->next(); n = n->next()) {
00673     if (n == which) return true;
00674   }
00675   return false;
00676 }
00677 
00678 
00679 void BB::verify() {
00680   int count = 0;
00681   for (Node* n = first; n != last->next(); n = n->next()) {
00682     count++;
00683     if (n->deleted) continue;
00684     n->verify();
00685     if (n->bb() != this)
00686       error("BB %#lx: Node %#lx doesn't point back to me", this, n);
00687     if (n == last && !n->endsBB() &&
00688         !(n->next() && n->next()->isMergeNode() &&
00689           ((MergeNode*)(n->next()))->didStartBB)) {
00690       error("BB %#lx: last Node %#lx isn't endsBB()", this, n);
00691     }
00692     if (n->endsBB() && n != last)
00693       error("BB %#lx: Node %#lx ends BB but isn't last node", this, n);
00694   }
00695   if (count != nnodes) error("incorrect nnodes in BB %#lx", this);
00696   if (_loopDepth < 0) error  ("BB %#lx: negative loopDepth %d", this, _loopDepth);
00697   
00698   // Fix this Urs, 3/11/96
00699   if (_loopDepth > 9) warning("BB %#lx: suspiciously high loopDepth %d", this, _loopDepth);
00700 }
00701 
00702 
00703 BBIterator* bbIterator;
00704 
00705 void BBIterator::build(Node* first) {
00706   assert(bbTable == NULL, "already built");
00707   _first = first;
00708   bbCount = 0;
00709   pregTable = globals = NULL;
00710   buildBBs();
00711   blocksBuilt = true;
00712 }
00713 
00714 
00715 void BBIterator::buildBBs() {
00716   // build basic blocks
00717   // first, sort them topologically (ignoring backward arcs)
00718   // some things (e.g. SplitPReg::isLiveAt) depend on correct ordering
00719   GrowableArray<BB*>* list = new GrowableArray<BB*>(max(BasicNode::currentID >> 3, 10));
00720   _first->newBB()->dfs(list, 0);
00721   // now, the list contains the BBs in reverse order
00722   bbCount = list->length();
00723   bbTable = new GrowableArray<BB*>(bbCount);
00724   for (int i = bbCount-1; i >= 0; i--) {
00725     BB* bb = list->at(i);
00726     bb->_id = bbCount - i - 1;
00727     bbTable->append(bb);
00728   }
00729 }
00730 
00731 
00732 void BB::dfs(GrowableArray<BB*>* list, int loopDepth) {
00733   // build BB graph with depth-first traversal
00734   if (_id == 1) return;
00735   _id = 1;              // mark as visited
00736 #ifdef fix_this
00737   setting of isLoopStart/End is broken -- fix this (currently not used)
00738   if (first->isMergeNode()) {
00739     MergeNode* m = (MergeNode*)first;
00740     if (m->isLoopStart) {
00741       loopDepth++;
00742     } else if (m->isLoopEnd) {
00743       assert(loopDepth > 0, "bad loop end marker");
00744       loopDepth--;
00745     }
00746   }
00747 #endif
00748 _loopDepth = loopDepth;
00749   // Note: originally this code simply skipped missing (NULL) successors;
00750   //       however it doesn't work correctly because if a node (or a BB)
00751   //       has n successors they're all assumed to be non-NULL. Code with
00752   //       missing successors (e.g. TypeTestNode with no next(0) = NULL)
00753   //       cause the BB graph to screw up after this node. (gri 7/22/96)
00754   int n = last->nSuccessors();
00755   for (int i = 0; i < n; i++) {
00756     Node* next = last->next(i);
00757     BB* nextBB = next->newBB();
00758   }     
00759   for (i = nSuccessors() - 1; i >= 0; i--) {
00760     BB* nextBB = next(i);
00761     // only follow the link if next->bb hasn't been visited yet
00762     if (nextBB->id() == 0) nextBB->dfs(list, loopDepth);
00763   }
00764   list->append(this);
00765 }
00766 
00767 
00768 static void clearNodes(BB* bb) {
00769   for (Node* n = bb->first; n != bb->last->next(); n = n->next()) {
00770     n->setBB(NULL);
00771   }
00772 }
00773 
00774 
00775 void BBIterator::clear() {
00776   apply(clearNodes);
00777   bbTable = NULL; pregTable = globals = NULL;
00778 }
00779 
00780 
00781 void BBIterator::makeUses() {
00782   // a few PRegs may be created during makeUses (e.g. for deadBlockObj,
00783   // true/false etc), so leave a bit of room
00784   const int ExtraPRegs = 10;
00785   int n = PReg::currentNo + ExtraPRegs;
00786   pregTable = new GrowableArray<PReg*>(n);
00787   for (int i = 0; i < n; i++) pregTable->append(NULL);
00788   for (i = 0; i < bbCount; i++) { bbTable->at(i)->makeUses(); }
00789   usesBuilt = true;
00790 }
00791 
00792 
00793 void BBIterator::localAlloc() {
00794   // speed/space optimization: allocate hardwired et al only once, not for
00795   // every BB
00796   { ResourceMark rm;
00797     GrowableArray<BitVector*> hardwired(nofLocalRegisters, nofLocalRegisters, NULL); 
00798     GrowableArray<PReg*> localRegs(BasicNode::currentID);
00799     GrowableArray<BitVector*> lives(BasicNode::currentID);    
00800     for (int i = 0; i < nofLocalRegisters; i++) {
00801       hardwired.at_put(i, new BitVector(roundTo(BasicNode::currentID, BitsPerWord)));
00802     }
00803   
00804     for (i = 0; i < bbCount; i++) {
00805       bbTable->at(i)->localAlloc(&hardwired, &localRegs, &lives);
00806     }
00807   }
00808 
00809   int done = 0;
00810   globals = new GrowableArray<PReg*>(pregTable->length());
00811   for (int i = 0; i < pregTable->length(); i++) {
00812     PReg* r = pregTable->at(i);
00813     if (r) {
00814       if (r->isUnused()) {
00815         pregTable->at_put(i, NULL);             // no longer needed
00816       } else if (r->loc.equals(unAllocated)) {
00817         globals->append(r);
00818       } else {
00819         done++;                         // locally allocated
00820       }
00821     }
00822   }
00823   if (PrintLocalAllocation) {
00824     int total = globals->length() + done;
00825     lprintf("*local reg. allocations done; %ld out of %ld = (%3.1f%%).\n",
00826            done, total, 100.0 * done / total);
00827   }
00828 }
00829 
00830 
00831 void BBIterator::print() {
00832   for (int i = 0; i < bbCount; i++) {
00833     lprintf("  "); bbTable->at(i)->print_short(); lprintf("\n");
00834   }
00835 }
00836 
00837 
00838 void BBIterator::localCopyPropagate() {
00839   for (int i = 0; i < bbCount; i++) { bbTable->at(i)->localCopyPropagate(); }
00840 }
00841 
00842 
00843 void BBIterator::bruteForceCopyPropagate() {
00844   for (int i = 0; i < bbCount; i++) { bbTable->at(i)->bruteForceCopyPropagate(); }
00845 }
00846 
00847 
00848 void BBIterator::computeEscapingBlocks() {
00849   // Escape analysis for blocks: compute initial approximation (lower bound)
00850   // by collecting all blocks that are stored into the heap or returned from
00851   // nmethods.
00852   // Terminology: an "escaping" block is a block closure that
00853   // could potentially be created at runtime and passed to some code which
00854   // could store it in the heap (thus "escape").  An escaping block could
00855   // thus be invoked during any non-inlined send (since the callee could 
00856   // read the block from the heap and send value to it) or after the method
00857   // has returned.  Consequently, the variables uplevel-accessed by an escaping
00858   // block cannot be stack-allocated, and any uplevel-written variables cannot
00859   // be cached across calls.
00860   exposedBlks = new GrowableArray<BlockPReg*>(BlockPReg::numBlocks());
00861   for (int i = 0; i < bbCount; i++) {
00862     bbTable->at(i)->computeEscapingBlocks(exposedBlks);
00863   }
00864 }
00865 
00866 
00867 void BBIterator::computeUplevelAccesses() {
00868   // Compute the set of uplevel-accessed variables for each exposed block.
00869   // Terminology: variables are considered "uplevel-accessed" only if they
00870   // are accessed by an exposed block.  I.e., if a block is completely inlined,
00871   // it's uplevel accesses aren't really "uplevel" anymore and thus are ignored.
00872   int len = exposedBlks->length();
00873   for (int i = 0; i < len; i++) {
00874     BlockPReg* r = exposedBlks->at(i);
00875     assert (r->parent() == r->scope(), "block preg was copied/changed scope");
00876     assert(r->scope()->isInlinedScope(), "must be code scope");
00877     r->computeUplevelAccesses();
00878   }
00879 }
00880 
00881 
00882 bool BBIterator::isSequentialCode(BB* curr, BB* next) const {
00883   return curr == next || 
00884          (curr->genCount() + 1 == next->genCount() &&
00885           curr->next() == next);
00886 }
00887 
00888 
00889 bool BBIterator::isSequential(int curr, int next) const {
00890   // is control flow between current and next BB sequential?
00891   if (curr == next) return true;
00892   if (next < bbCount && bbTable->at(curr)->next() != NULL &&
00893       bbTable->at(curr)->next() != bbTable->at(next)) {
00894     return false; // non-sequential control flow
00895   }
00896 
00897   if (next == bbCount && bbTable->at(curr)->next() != NULL) {
00898     // we're "running off the end", so must be non-seq
00899     return false;
00900   }
00901 
00902   return true;      // none of the above, so must be sequential
00903 }
00904 
00905 
00906 BB* BBIterator::bb_for(Node* n) {
00907   return n != NULL ? n->bb() : NULL;
00908 }
00909 
00910 
00911 void BBIterator::add_BBs_to_list(GrowableArray<BB*>& list, GrowableArray<BB*>& work) {
00912   if (!work.isEmpty()) {
00913     GrowableArray<BB*> uncommon;        // uncommon BBs are handled at the very end
00914     do {
00915       BB* bb = work.pop();
00916       assert(bb->visited(), "must have been visited");
00917       list.append(bb);                  // do this even if empty (label may be referenced)
00918       bb->setGenCount();                // can probably be removed at some point
00919       // determine likely & uncommon successors
00920       BB* likely_next   = bb_for(bb->last->likelySuccessor());
00921       BB* uncommon_next = bb_for(bb->last->uncommonSuccessor());
00922       assert(likely_next != uncommon_next || likely_next == NULL, "likely BB cannot be uncommon BB at the same time");
00923       // first, push all other successors
00924       for (int i = bb->nSuccessors(); i-- > 0; ) {
00925         BB* next = (BB*)bb->next(i);
00926         if (next != NULL && !next->visited() && next != likely_next && next != uncommon_next) {
00927           work.push(next->after_visit());
00928         }
00929       }
00930       // then, push likely successor (will be handled next)
00931       if (likely_next != NULL && !likely_next->visited()) {
00932         work.push(likely_next->after_visit());
00933       }
00934       // remember uncommon successor for the very end
00935       if (uncommon_next != NULL && !uncommon_next->visited()) uncommon.push(uncommon_next->after_visit());
00936     } while(!work.isEmpty());
00937     // add all the uncommon cases
00938     add_BBs_to_list(list, uncommon);
00939   }
00940 }
00941 
00942 
00943 GrowableArray<BB*>* BBIterator::code_generation_order() {
00944   if (!ReorderBBs) return bbTable;
00945   // initialize visited field for all nodes
00946   for (int i = 0; i < bbCount; i++) bbTable->at(i)->before_visit();
00947   // working sets
00948   GrowableArray<BB*>* list = new GrowableArray<BB*>(bbCount);   // eventually holds all reachable BBs again
00949   GrowableArray<BB*>  work(bbCount);                            // may hold only a part of all BBs at any given time
00950   // setup starting point
00951   BB* bb = _first->bb();
00952   work.push(bb->after_visit());
00953   // compute order
00954   add_BBs_to_list(*list, work);
00955   // NB: "loosing" BBs is ok since some may become unreachable during optimization  -Robert 7/96
00956   assert(list->length() <= bbCount, "gained BBs?");
00957   return list;
00958 }
00959 
00960 
00961 void BBIterator::print_code(bool suppressTrivial) {
00962   GrowableArray<BB*>* list = code_generation_order();
00963   for (int i = 0; i < list->length(); i++) {
00964     BB* bb = list->at(i);
00965     if (bb->nnodes > 0) bb->print_code(suppressTrivial);
00966     if (bb->next() != NULL) std->print_cr("\tgoto N%d", bb->next()->first->id());
00967     if (!suppressTrivial) lprintf("\n");
00968   }
00969 }
00970 
00971 
00972 void BBIterator::apply(NodeVisitor* v) {
00973   GrowableArray<BB*>* list = code_generation_order();
00974   int length = list->length();
00975   for (int i = 0; i < length; i++) {
00976     BB*   bb    = list->at(i);
00977     Node* first = bb->first;
00978     Node* last  = bb->last;
00979     v->beginOfBasicBlock(first);
00980     bb->apply(v);
00981     v->endOfBasicBlock(last);
00982   }
00983 }
00984 
00985 
00986 bool BBIterator::verifyLabels() {
00987   bool ok = true;
00988   for (int i = 0; i < bbCount; i++) ok &= bbTable->at(i)->verifyLabels();
00989   return ok;
00990 }
00991 
00992 
00993 void BBIterator::globalCopyPropagate() {
00994   // do global copy propagation of singly-assigned PRegs
00995 
00996   for (int i = 0; i < pregTable->length(); i++) {
00997     PReg* r = pregTable->at(i);
00998     if (!r || r->isConstPReg() || !r->canCopyPropagate()) continue;
00999     Def* def = NULL;
01000     // get definition
01001     int dulength = r->dus.length();
01002     for (int e = 0; e < dulength; e++) {
01003       PRegBBIndex* index = r->dus.at(e);
01004       DUInfo* info = index->bb->duInfo.info->at(index->index);
01005       if (info->defs.length()) {
01006         assert(info->defs.length() == 1, "should be one definition only");
01007         assert(def == NULL, "already have def!?!");
01008         def = info->defs.first();
01009 #       ifndef ASSERT
01010           break;
01011 #       endif
01012       }
01013     }
01014     assert(def, "should have found the definition");
01015     NonTrivialNode* defNode = def->node;
01016       
01017     // don't propagate if the defNode isn't assignment
01018     if (!defNode->isAssignmentLike()) continue;
01019     assert(defNode->dest() == r, "not assignment-like");
01020 
01021     PReg* defSrc = defNode->src();
01022 
01023     // don't propagate if source does not survive calls (i.e. is local to BB), 
01024     // or if it isn't singly-assigned as well (if it's multiply assigned,
01025     // we'd have to make sure it's not assigned between defNode and the use nodes
01026     if (!defSrc->isSinglyAssigned() || defSrc->loc.isTrashedRegister())
01027         continue;
01028 
01029     // ok, everything is fine - propagate the def to the uses
01030     for (e = 0; e < dulength; e++) {
01031       PRegBBIndex* index = r->dus.at(e);
01032       BB* bb = index->bb;
01033       DUInfo* info = bb->duInfo.info->at(index->index);
01034       // caution: propagateTo may eliminate nodes and thus shorten
01035       // info->uses
01036       int j = 0;
01037       while (j < info->uses.length()) {
01038         int oldLen = info->uses.length();
01039         info->propagateTo(bb, info->reg, def, info->uses.at(j), true);
01040         if (info->uses.length() == oldLen) {
01041           // propagate didn't eliminate this use; try next one
01042           j++;
01043         }
01044       }
01045     }
01046   }
01047 }
01048 
01049 
01050 void BBIterator::eliminateUnneededResults() {
01051   // eliminate nodes producing results that are never used
01052   for (int i = 0; i < pregTable->length(); i++) {
01053     PReg* r = pregTable->at(i);
01054     if (r && r->isOnlySoftUsed()) {
01055       r->eliminate(false);
01056     }
01057   }
01058 }
01059 
01060 
01061 void BBIterator::apply(BBDoFn f) {
01062   for (int i = 0; i < bbCount; i++) { f(bbTable->at(i)); }
01063 }
01064 
01065 
01066 void BBIterator::verify() {
01067   if (bbTable) {
01068     for (int i = 0; i < bbCount; i++) { bbTable->at(i)->verify(); }
01069     if (pregTable) {
01070       for (i = 0; i < pregTable->length(); i++) {
01071         if (pregTable->at(i)) pregTable->at(i)->verify();
01072       }
01073     }
01074   }
01075 }
01076 
01077 
01078 # endif

Generated on Mon Oct 9 13:37:02 2006 for Strongtalk VM by  doxygen 1.4.7