inline.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.11 $ */
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 # include "incls/_precompiled.incl"
00024 
00025 # ifdef COMPILER
00026 
00027 # include "incls/_inline.cpp.incl"
00028 
00029   static int msgCost = 0;       // estimated cost of last inlining candidate
00030   
00031 
00032   void CodeScope::memoizeBlocks(symbolOop sel) {
00033     // memoize block args so they aren't created for inlined cases
00034     int top = exprStack->length();
00035     int argc = sel->arg_count();
00036     for (int i = 1; i <= argc; i++) {
00037       PReg* r = exprStack->nth(top - i)->preg();
00038       if (r->isBlockPReg()) ((BlockPReg*)r)->memoize();
00039     }
00040   }
00041 
00042   int InlinedScope::calleeSize(RScope* rs) {
00043     // try to get the callee's size (in bytes)
00044     if (!rs->isPICScope()) return 0;    // no info
00045     RPICScope* ps = (RPICScope*)rs;
00046     nmethod* inlinee = ps->nm;
00047     if (inlinee->compiler() == NIC) {
00048       return 0;         // can't say much about the real code size
00049     }
00050     int size = inlinee->instsLen() - oopSize * PrologueSize;
00051     if (inlinee->isUncommonRecompiled()) {
00052       // uncommon nmethods are bigger because the contain many more non-
00053       // inlined sends for all the uncomon cases
00054       size /= 2;
00055     }
00056     return size;
00057   }
00058   
00059   bool CodeScope::calleeTooBig(SendInfo* info, RScope* rs,
00060                                 InlineLimitType limitType) {
00061     // try to see if the potential inlinee is too big
00062     int size = calleeSize(rs);
00063     // NB: continue even if size == 0 to bring current estimated size into play
00064     assert(limitType >= NormalFnLimit && limitType <= BlockFnLimit,
00065            "bad limit");
00066     limitType = InlineLimitType(limitType + NormalFnInstrLimit-NormalFnLimit);
00067     int cutoff = theCompiler->inlineLimit[limitType];
00068     int estimated = theCompiler->estimatedSize();
00069     int limit = theCompiler->inlineLimit[NmInstrLimit];
00070     // reject if inlinee too large, but correct for well-known cheap messages
00071     bool bad = size > cutoff &&
00072       !(info->rcvr->hasKlass() &&
00073         isCheapMessage(info->sel, info->rcvr->klass()));
00074     if (bad && estimated + size < limit / 2) {
00075       // allow inlining if recompilee itself is small (i.e., a forwarder)
00076       if (recompilee &&
00077           recompilee->instsLen() - oopSize * PrologueSize < cutoff) {
00078         bad = false;
00079       }
00080     }
00081     // also reject if est. total size too large (except for ifTrue et al)
00082     // but don't trust the isCheap thing if we're way over the limit
00083     bad = bad || estimated + size >= limit;
00084     if (bad &&
00085         estimated + size < 2 * limit &&
00086         (size == 0 || size < cutoff / 8) &&
00087         info->rcvr->hasKlass() &&
00088         isReallyCheapMessage(info->sel, info->rcvr->klass())) {
00089       bad = false;
00090     }
00091     if (bad && PrintInlining) {
00092       lprintf("%*s*not inlining %s: callee too big (%d/%d/%d/%d)\n", depth, "",
00093               selector_string(info->sel), size, cutoff, estimated, limit);
00094     }
00095     if (CompilerDebug && bad && estimated > limit)
00096       warning("Compiler: (while compiling %s/%s) estimated nmethod size > limit (%ld > %ld)",
00097                selector_string(theCompiler->key->L.selector),
00098                selector_string(info->sel), estimated, limit);
00099     return bad;
00100   }
00101   
00102   bool CodeScope::calleeIsSmall(SendInfo* info, RScope* rs,
00103                                  InlineLimitType limitType) {
00104     // try to see if the potential inlinee is small
00105     int size = calleeSize(rs);
00106     if (!size) return false;    // no size info
00107     assert(limitType >= NormalFnLimit && limitType <= BlockFnLimit,
00108            "bad limit");
00109     limitType = InlineLimitType(limitType + NormalFnInstrLimit-NormalFnLimit);
00110     int cutoff = theCompiler->inlineLimit[limitType];
00111     int estimated = theCompiler->estimatedSize();
00112     int limit = theCompiler->inlineLimit[NmInstrLimit];
00113     bool ok = size <= cutoff && estimated + size < limit;
00114     if (ok && PrintInlining) {
00115       lprintf("%*s*inlining %s anyway: callee is small (%d/%d/%d/%d)\n",
00116               depth, "", selector_string(info->sel),
00117               size, cutoff, estimated, limit);
00118     }
00119     return ok;
00120   }
00121   
00122   bool CodeScope::shouldInlineSend(SendInfo* info, RScope* rs, Expr* rcvr,
00123                                     oop m, InlineLimitType limitType) {
00124     LookupKey* L = info->L;
00125     if (!L->selector->is_string()) return false;
00126 
00127     if (isRecursiveCall(m, L->receiverKlass, MaxRecursionUnroll)) {
00128       info->uninlinable = true;
00129       return false;
00130     }
00131     
00132     if (limitType == NormalFnLimit) {
00133       // check args to see if any of them is a block; if so, increase limit
00134       int top = exprStack->length();
00135       int argc = symbolOop(L->selector)->arg_count();
00136       for (int i = argc; i > 0; i--) {
00137         if (exprStack->nth(top - i)->preg()->isBlockPReg()) {
00138           limitType = BlockArgFnLimit;
00139           goto done;
00140         }
00141       }
00142       // check receiver
00143       if (lookupReceiverIsDelta(L->lookupType)) {
00144         if (self->preg()->isBlockPReg()) limitType = BlockArgFnLimit;
00145       } else if (exprStack->nth(top - argc - 1)->preg()->isBlockPReg()) {
00146         limitType = BlockArgFnLimit;
00147       }
00148     }
00149     
00150    done:
00151     if (calleeTooBig(info, rs, limitType)) {
00152       // register this send as uninlinable
00153       theCompiler->registerUninlinable(info, limitType, 9999);
00154       return false;
00155     }
00156 
00157     // NB: this test comes after calleeTooBig to prevent forced inlining of
00158     // e.g. a really complicated user-defined '+' for matrices
00159     if (isCheapMessage(symbolOop(L->selector))) {
00160       msgCost = costP->cheapSendCost;
00161       return true;
00162     }
00163 
00164     int cutoff = theCompiler->inlineLimit[limitType];
00165     msgCost = sicCost((methodKlass*)m->klass(), this, costP);
00166     if (info->primFailure &&
00167         info->nsends < MinPrimFailureInvocations) {
00168       if (rs->isPICScope() && ((RPICScope*)rs)->sd->isOptimized()) {
00169         // the fail block send is optimized, it's probably executed frequently
00170       } else if (rs->isInlinedScope()) {
00171         // was inlined in previous version, so do it again
00172       } else {
00173         // don't inline error block unless trivial or taken often
00174         if (msgCost > MaxTrivialPrimFailureCost) return false;
00175         // should also look at block method, not default value:With:
00176         Klass* map = rcvr->klass()->addr();
00177         if (map->is_block()) {
00178           memOop method = ((blockKlass*)map)->value();
00179           msgCost = sicCost((methodKlass*)method->klass(), this, failCostP);
00180           // bug: should estimate real length of prim failure; e.g. could
00181           // have single send (cost 1) but that method sends more and more
00182           // msgs...i.e. need concept of "being in fail branch" so that
00183           // no further inlining takes place -- fix this
00184           if (msgCost > MaxTrivialPrimFailureCost) return false;
00185         }
00186       }
00187     }
00188     if (msgCost > cutoff) {
00189       if (calleeIsSmall(info, rs, limitType)) return true;
00190       theCompiler->registerUninlinable(info, limitType, msgCost);
00191       return false;
00192     }
00193     return true;
00194   }
00195 
00196   bool CodeScope::shouldInlineBlock(SendInfo* info, RScope* rs,
00197                                      Expr* rcvr, oop method) {
00198     return shouldInlineSend(info, rs, rcvr, method, BlockFnLimit);
00199   }
00200 
00201   bool CodeScope::shouldInlineMethod(SendInfo* info, RScope* rs,
00202                                       Expr* rcvr, oop meth) {
00203     return shouldInlineSend(info, rs, rcvr, meth, NormalFnLimit);
00204   }
00205   
00206   Expr* CodeScope::picPredictUnlikely(SendInfo* info,
00207                                         RUntakenScope* uscope) {
00208     if (theCompiler->useUncommonTraps &&
00209         info->primFailure && uscope->isUnlikely()) {
00210       // this send was never executed in the recompilee
00211       // only make the send unlikely if it had a chance to execute
00212       // (If the send isn't a prim failure, don't trust the info --
00213       // it's unlikely that the method just stops executing in the middle.
00214       // What probably happened is that recompilation happens before the
00215       // rest of the method got a chance to execute (e.g. recursion), or it
00216       // always quit via NLR.  In any case, the compiler can't handle this
00217       // yet - need to treat it specially similar to endsDead.)
00218       info->nsends = 0;
00219       const int MinSends = MinPrimFailureInvocations;
00220       int count = uscope->caller->invocationCount();
00221       if (count <= 0) {
00222         // hack: optimized method has no count, so assume it's > MinSends
00223         count = MinSends + 1;
00224       }
00225       bool makeUncommon = count >= MinSends && uscope->sd->wasNeverExecuted();
00226       if (PrintInlining) {
00227         lprintf("%*s*%sPIC-type-predicting %s as never executed\n",
00228                 depth, "", makeUncommon ? "" : "NOT ",
00229                 info->sel->copy_null_terminated());
00230       }
00231       if (makeUncommon) {
00232         return new UnknownExpr(info->rcvr->preg(), NULL, true);
00233       }
00234     }
00235     return info->rcvr;
00236   }
00237 
00238   Expr* CodeScope::picPredict(SendInfo* info) {
00239     // check PICs for information
00240     if (!UsePICRecompilation) return info->rcvr;
00241     bool canBeUnlikely = theCompiler->useUncommonTraps;
00242     if (rscope->hasSubScopes(_bci)) {
00243       RScopeBList* l = rscope->subScopes(_bci);
00244       if (l->first()->isUntakenScope() && l->length() == 1) {
00245         return picPredictUnlikely(info, (RUntakenScope*)l->first());
00246       } else if (info->rcvr->containsUnknown()) {
00247         if (PrintInlining) {
00248           lprintf("%*s*PIC-type-predicting %s (%ld maps)\n", depth, "",
00249                   info->sel->copy_null_terminated(), l->length());
00250         }
00251         for (int i = 0; i < l->length(); i++) {
00252           RScope* r = l->nth(i);
00253           Expr* expr = r->receiverExpr();
00254           if (expr->isUnknownExpr()) {
00255             // untaken real send (from PIC)
00256           } else if (expr->klass()->addr()->is_block()) {
00257             // for now, doesn't make sense to predict block maps because of
00258             // map cloning
00259             if (PrintInlining) {
00260               lprintf("%*s*not predicting block map\n", depth, ""); 
00261             }
00262             canBeUnlikely = false;
00263           } else {
00264             Expr* alreadyThere = info->rcvr->findKlass(expr->klass());
00265             if (alreadyThere) {
00266               // generalize to map if only have constant
00267               if (alreadyThere->isConstantExpr())
00268                 info->rcvr = info->rcvr->mergeWith(expr, NULL);
00269             } else {
00270               // add map only if type isn't already present (for splitting)
00271               info->predicted = true;
00272               info->rcvr = info->rcvr->mergeWith(expr, NULL);
00273               if (expr->hasConstant() && l->length() == 1) {
00274                 // check to see if single predicted receiver is true or false;
00275                 // if so, add other boolean to prediction.  Reduces the number
00276                 // of uncommon branches; not doing so appears to be overly
00277                 // aggressive (as observed experimentally)
00278                 oop c = expr->constant();
00279                 if (c == Memory->trueObj &&
00280                     !info->rcvr->findKlass(as_klassOop(Memory->falseObj->klass()))) {
00281                   Expr* f = new ConstantExpr(Memory->falseObj, NULL, NULL);
00282                   info->rcvr = info->rcvr->mergeWith(f, NULL);
00283                 } else if (c == Memory->falseObj &&
00284                            !info->rcvr->findKlass(as_klassOop(Memory->trueObj->klass()))) {
00285                   Expr* t = new ConstantExpr(Memory->trueObj, NULL, NULL);
00286                   info->rcvr = info->rcvr->mergeWith(t, NULL);
00287                 }
00288               }
00289             }
00290           }
00291         }
00292       } else {
00293         // know receiver type precisely
00294         return info->rcvr;
00295       }
00296       // mark unknown branch as unlikely
00297       UnknownExpr* u = info->rcvr->findUnknown();
00298       if (u && canBeUnlikely && theCompiler->useUncommonTraps && 
00299           rscope->isUncommonAt(_bci, false)) {
00300         info->rcvr = info->rcvr->makeUnknownUnlikely(this);
00301       }
00302     } else if (theCompiler->useUncommonTraps &&
00303                info->primFailure &&
00304                rscope->isUncommonAt(_bci, true)) {
00305       // this is the failure send of a primitive, and the failure was made
00306       // uncommon in the recompilee, and it was never taken, so keep it
00307       // uncommon
00308       if (PrintInlining) {
00309         lprintf("%*s*PIC-type-predicting %s as never executed (2)\n",
00310                 depth, "", info->sel->copy_null_terminated());
00311       }
00312       info->rcvr = new UnknownExpr(info->rcvr->preg(), NULL, true);
00313     }
00314      
00315     assert(info->rcvr->preg(), "should have a preg");
00316     return info->rcvr;
00317   }
00318 
00319   Expr* CodeScope::typePredict(SendInfo* info) {
00320     // try static type prediction
00321     PReg* r = info->rcvr->preg();
00322     symbolOop sel = info->sel;
00323     if (sel == VMString[IF_TRUE_] ||
00324         sel == VMString[IF_FALSE_] ||
00325         sel == VMString[IF_TRUE_FALSE_] ||
00326         sel == VMString[IF_FALSE_TRUE_] ||
00327         sel == VMString[OR]  || sel == VMString[AND] || sel == VMString[NOT]) {
00328       // boolean message
00329       if (PrintInlining) {
00330         lprintf("%*s*type-predicting %s\n", depth, "",
00331                sel->copy_null_terminated());
00332       }
00333       info->predicted = true;
00334       bool allowUnlikely = theCompiler->useUncommonTraps;
00335       if (CompilerDeferUncommonBranches &&
00336           (sel == VMString[IF_TRUE_] ||
00337            sel == VMString[IF_FALSE_] ||
00338            sel == VMString[IF_TRUE_FALSE_] ||
00339            sel == VMString[IF_FALSE_TRUE_])) {
00340         // these bets are really safe - make uncommon even when recompiling
00341         // due to uncommon trap (if the ifTrue itself caused the trap,
00342         // rscope->isUncommonAt will be false, so this is safe)
00343         allowUnlikely = true;
00344       }
00345       if (allowUnlikely) {
00346         if (rscope->isUncommonAt(_bci, false)) {
00347           // ok, no uncommon trap here
00348         } else if (rscope->hasSubScopes(_bci)) {
00349           // has real send for ifTrue et al. -- must be NIC-compiled
00350           // make uncommon unlikely if no non-true/false receiver present
00351           RScopeBList* subs = rscope->subScopes(_bci);
00352           for (int i = subs->length() - 1; i >= 0; i--) {
00353             RScope* s = subs->nth(i);
00354             Expr* rcvr = s->receiverExpr();
00355             if (rcvr->hasKlass()) {
00356               Klass* m = rcvr->klass()->addr();
00357               if (m != Memory->trueObj->klass() &&
00358                   m != Memory->falseObj->klass()) {
00359                 allowUnlikely = false;
00360                 break;
00361               }
00362             }
00363           }
00364           if (WizardMode && !allowUnlikely)
00365             warning("Compiler: non-bool receiver for ifTrue: et al. detected");
00366         }
00367         if (allowUnlikely) {
00368           // make unknown case unlikely despite 
00369           info->rcvr = info->rcvr->makeUnknownUnlikely(this);
00370         }
00371       }
00372       Expr* rcvr = info->rcvr;
00373       Expr* t = new ConstantExpr(Memory->trueObj , r, NULL);
00374       Expr* f = new ConstantExpr(Memory->falseObj, r, NULL);
00375       // make sure we don't destroy splitting info; only add types if not
00376       // already present
00377       if (rcvr->findKlass(as_klassOop(Memory->trueObj->klass())) == NULL)
00378 d135 1
00379 a135 1
00380       if (rcvr->findKlass(as_klassOop(Memory->falseObj->klass())) == NULL)
00381 d141 7
00382 # endif

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