defUse.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.23 $ */
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 
00028 # include "incls/_defUse.cpp.incl"
00029 
00030 
00031   void DUInfo::propagateTo(BB* useBB, Use* use, const NonTrivialNode* fromNode, 
00032                            PReg* src, NonTrivialNode* toNode, const bool global) {
00033     // r1 := r2; ...; r3 := op(r1)  -->  r1 := r2; ...; r3 := op(r2)
00034     bool ok = toNode->copyPropagate(useBB, use, src);
00035     if (CompilerDebug) {
00036       cout(PrintCopyPropagation)->print("*%s cp:%s propagate %s from N%ld (%#lx) to N%ld (%#lx)\n",
00037         global ? "global" : "local", ok ? "" : " couldn't",
00038         src->name(), fromNode ? fromNode->id() : 0, PrintHexAddresses ? fromNode : 0,
00039         toNode->id(), PrintHexAddresses ? toNode : 0);
00040     }
00041   }
00042 
00043   void DUInfo::propagateTo(BB* useBB, const PReg* r, const Def* def, Use* use,
00044                            const bool global) {
00045     // def reaches use; try to eliminate r's use by using copy propagation
00046     NonTrivialNode* fromNode = def->node;
00047     const bool isAssignment = fromNode->isAssignmentLike();
00048     NonTrivialNode* toNode = use->node;
00049     const bool hasSrc = fromNode->hasSrc();
00050     PReg* fromPR = hasSrc ? fromNode->src() : NULL;
00051     const bool isConst = hasSrc && fromPR->isConstPReg();
00052 
00053     if (isAssignment && isConst && toNode->canCopyPropagateOop()) {
00054       // loadOop r1, oop; ...; r2 := op(r1)    --->
00055       // loadOop r1, oop; ...; r2 := op(oop)
00056       bool ok = toNode->copyPropagate(useBB, use, fromPR);
00057       if (CompilerDebug) {
00058         // the original code broke the MSC++ 3.0 optimizer, so now it looks a bit weird.  -Urs 7/96
00059         char* glob = global ? "global" : "local";
00060         char* prop = ok ? "" : " couldn't propagate";
00061         char* name = def->node->src()->name();      // using fromNode or fromPR here will break
00062         void* from = PrintHexAddresses ? fromNode : 0;
00063         void* to   = PrintHexAddresses ? toNode : 0;
00064         cout(PrintCopyPropagation)->print("*%s cp:%s %s from N%ld (%#lx) to N%ld (%#lx)\n",
00065                                           glob, prop, name, def->node->id(), from, toNode->id(), to);
00066       }
00067       return;
00068     }
00069 
00070     if (fromNode->loopDepth() != toNode->loopDepth()) {
00071       // currently can't propagate into a loop: PReg would have to be extended to
00072       // end of loop, but is only extended to use -- fix this later
00073       // NB: this is not completely safe since fromNode might be in different loop than
00074       // toNode (but at same loop nesting), so loopDepths match
00075       assert(global, "can't be local cp");
00076       if (CompilerDebug) {
00077         cout(PrintCopyPropagation)->print("*global cp: can't propagate %s from N%ld (%#lx) to N%ld (%#lx) -- loopDepth mismatch\n",
00078           fromPR->name(), fromNode->id(), PrintHexAddresses ? fromNode : 0, toNode->id(), PrintHexAddresses ? toNode : 0);
00079       }
00080       return;
00081     }
00082 
00083     if (isAssignment && !isConst && hasSrc && toNode->canCopyPropagate(fromNode)) {
00084       // r1 := r2; ...; r3 := op(r1)  -->  r1 := r2; ...; r3 := op(r2)
00085       propagateTo(useBB, use, fromNode, fromPR, toNode, global);
00086       return;
00087     } 
00088     
00089     if (!global && r->isSinglyUsed() && (toNode->isAssignNode() || toNode->isInlinedReturnNode()) &&  // fix this -- should it be isAssignmentLike?
00090         toNode->canBeEliminated() && fromNode->hasDest() && fromNode->canChangeDest() &&
00091         r->canBeEliminated(true) && !toNode->dest()->loc.isTopOfStack()) {
00092       // fromNode: r := ...;  ... ; toNode: x := r    --->
00093       // fromNode: x := ...;
00094       // NB: should extend live range of toNode->dest() backwards to include fromNode
00095       // currently not done (extendLiveRange handles only forward extensions), but as
00096       // long as this optimization isn't performed globally this shouldn't hurt
00097       if (CompilerDebug) {
00098         cout(PrintCopyPropagation)->print("*%s cp: changing dest of N%ld (%#lx) to %s to match use at N%ld (%#lx)\n",
00099                global ? "global" : "local", 
00100                fromNode->id(), PrintHexAddresses ? fromNode : 0, toNode->dest()->name(), toNode->id(), PrintHexAddresses ? toNode : 0);
00101       }
00102       assert(!r->incorrectDU(), "shouldn't try CP on this");
00103       assert(!global || r->isSinglyAssigned(), "not safe with >1 defs");
00104       assert(fromNode->dest() == r, "unexpected dest");
00105       fromNode->setDest(fromNode->bb(), toNode->dest());
00106       toNode->eliminate(toNode->bb(), NULL, false, true);
00107       return;
00108     } 
00109 
00110     // nothing worked
00111     if (CompilerDebug) {
00112       cout(PrintCopyPropagation)->print("*%s cp: can't propagate N%ld (%#lx) to N%ld (%#lx)\n",
00113               global ? "global" : "local", fromNode->id(), PrintHexAddresses ? fromNode : 0,
00114               toNode->id(), PrintHexAddresses ? toNode : 0);
00115     }
00116   }
00117   
00118   void Use::print()                     { lprintf("Use %#lx (N%ld)", PrintHexAddresses ? this : 0, node->id()); }
00119   void PSoftUse::print()                { lprintf("PSoftUse %#lx (N%ld)", PrintHexAddresses ? this : 0, node->id());}
00120   void Def::print()                     { lprintf("Def %#lx (N%ld)", PrintHexAddresses ? this : 0, node->id()); }
00121 
00122   void BBDUTable::print() {
00123     if (!info) return;      // not built yet
00124     print_short();
00125     for (int i = 0; i < info->length(); i++) {
00126       lprintf("%3ld: ", i); info->at(i)->print();
00127     }
00128   }
00129   
00130   void DUInfo::getLiveRange(int& firstNodeNum, int& lastNodeNum) {
00131     // compute live range of a local register
00132     // IN:  first & last node ID of BB
00133     // OUT: first & last node ID where this PReg is live
00134     // algorithm: first = first def if def precedes first use
00135     //                    0 if first use precedes def (live from start)
00136     //            last  = last use if it is later than last def
00137     //                    lastNodeNum if last def is later (live until end)
00138     SListElem<Def*>* d = defs.head();
00139     SListElem<Use*>* u = uses.head();
00140 
00141     // set firstNodeNum
00142     if (u && d) {
00143       int unode = u->data()->node->num();
00144       int dnode = d->data()->node->num();
00145       if (unode > dnode) {
00146         firstNodeNum = dnode;   // live range starts at definition
00147       } else {
00148         // use before def -- leave first at zero
00149         assert(firstNodeNum == 0, "should be zero");
00150       }
00151     } else if (u) {
00152       // only a use -- live range = [0..unode]
00153       assert(firstNodeNum == 0, "should be zero");
00154       while (u && u->next()) u = u->next();
00155       lastNodeNum = u->data()->node->num();
00156       return;
00157     } else if (d) {
00158       firstNodeNum = d->data()->node->num();    // live range starts at definition and ends at end of BB
00159       return;
00160     } else {
00161       // no defs or uses in this BB; must be a result register whose use has been
00162       // eliminated (the def is in the last node of the previous BB)
00163       assert(reg->loc == resultLoc, "must be result loc");
00164       firstNodeNum = lastNodeNum = 0;
00165       return;
00166     }
00167 
00168     // set lastNodeNum; first find last def and last use
00169     while (u && u->next()) u = u->next();
00170     while (d && d->next()) d = d->next();
00171     int unode = u->data()->node->num();
00172     int dnode = d->data()->node->num();
00173     if (unode > dnode) {
00174       lastNodeNum = unode;      // live range ends at last use
00175     } else {
00176       // defined last -- live until end of BB
00177     }
00178   }
00179 
00180   void DUInfo::print_short() { lprintf("DUInfo %#lx", this); }
00181   void DUInfo::print() {
00182     print_short(); lprintf(" for "); reg->print_short(); lprintf(": ");
00183     uses.print(); lprintf("; "); defs.print(); lprintf("\n");
00184   }
00185 
00186   void PRegBBIndex::print_short() {
00187     lprintf("PRegBBIndex [%ld] for", index); bb->print_short(); 
00188   }
00189 
00190   void PRegBBIndex::print() {
00191     print_short(); lprintf(": "); bb->duInfo.info->at(index)->print();
00192   }
00193 
00194   static bool cpCreateFailed = false;
00195 
00196   CPInfo* new_CPInfo(NonTrivialNode* n) {
00197     CPInfo* cpi = new CPInfo(n);
00198     if (cpCreateFailed) {
00199       cpCreateFailed = false;
00200       return NULL;
00201     }
00202     return cpi;
00203   }
00204   
00205   CPInfo::CPInfo(NonTrivialNode* n) {
00206     def = n;
00207     if (!n->hasSrc()) {
00208       cpCreateFailed = true;        // can't eliminate register
00209       return;
00210     }
00211     r = n->src();
00212     if (r->isConstPReg()) return;   // can always eliminate if defined by constant  (was bug; fixed 7/26/96 -Urs)
00213                                     // (as long as constants aren't register-allocated)  
00214     PReg* eliminatee = n->dest();
00215     if (eliminatee->debug) {
00216       if (r->extendLiveRange(eliminatee->scope(), eliminatee->endBCI())) {
00217         // ok, the replacement PReg covers the eliminated PReg's debug-visible live range
00218         // (begBCI must be covered if endBCI is covered)
00219       } else {
00220         cpCreateFailed = true;    // need register for debug info (was bug; fixed 5/14/96 -Urs)
00221       }
00222     }
00223   }
00224 
00225   bool CPInfo::isConstant() const       { return r->isConstPReg(); }
00226   oop  CPInfo::constant() const         {
00227     assert(isConstant(), "not constant");
00228     return ((ConstPReg*)r)->constant;
00229   }
00230 
00231   void CPInfo::print() {
00232     lprintf("*(CPInfo*)%#x : def %#x, %s\n", this, def, r->name());
00233   }
00234   
00235   static void printNodeFn(DefUse* du) { lprintf("N%d ", du->node->id()); }
00236   
00237   struct PrintNodeClosureD : public Closure<Def*> {
00238     void do_it(Def* d) { printNodeFn(d); }
00239   };
00240 
00241   struct PrintNodeClosureU : public Closure<Use*> {
00242     void do_it(Use* u) { printNodeFn(u); }
00243   };
00244 
00245   void printDefsAndUses(const GrowableArray<PRegBBIndex*>* l) {
00246     lprintf("defs: ");
00247     PrintNodeClosureD printNodeD;
00248     forAllDefsDo(l, &printNodeD);
00249     lprintf("; uses: ");
00250     PrintNodeClosureU printNodeU;
00251     forAllUsesDo(l, &printNodeU);
00252   }
00253 
00254 
00255 
00256   static Closure<Def*>* theDefIterator;
00257   static void doDefsFn(PRegBBIndex* p) {
00258     DUInfo* info = p->bb->duInfo.info->at(p->index);
00259     info->defs.apply(theDefIterator);
00260   }
00261   
00262   void forAllDefsDo(const GrowableArray<PRegBBIndex*>* l, Closure<Def*>* f) {
00263     theDefIterator = f;
00264     l->apply(doDefsFn);
00265   }
00266 
00267   static Closure<Use*>* theUseIterator;
00268   static void doUsesFn(PRegBBIndex* p) {
00269     DUInfo* info = p->bb->duInfo.info->at(p->index);
00270     info->uses.apply(theUseIterator);
00271   }
00272   
00273   void forAllUsesDo(const GrowableArray<PRegBBIndex*>* l, Closure<Use*>* f) {
00274     theUseIterator = f;
00275     l->apply(doUsesFn);
00276   }
00277   
00278 # endif

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