00001 /* Copyright 1996, LongView Technologies L.L.C. $Revision: 1.6 $ */ 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 #ifdef DELTA_COMPILER 00025 00026 // Implementation of loop optimizations: moving type tests out of loops, finding candidates for register 00027 // allocation within a loop, plus integer-specific optimizations (removing tag checks and bound checks). 00028 00029 // a candidate for register allocation within a loop 00030 class LoopRegCandidate : public PrintableResourceObj { 00031 PReg* _preg; 00032 int _nuses, _ndefs; 00033 public: 00034 LoopRegCandidate(PReg* r) { _preg = r; _nuses = _ndefs = 0; } 00035 PReg* preg() const { return _preg; } 00036 int nuses() const { return _nuses; } 00037 int ndefs() const { return _ndefs; } 00038 int weight() const { return _ndefs + _nuses; } 00039 void incDUs(int u, int d) { _nuses += u; _ndefs += d; } 00040 void print(); 00041 }; 00042 00043 00044 // A CompiledLoop contains annotations for the compiler for integer loop optimizations. 00045 00046 class CompiledLoop : public PrintableResourceObj { 00047 InlinedScope* _scope; 00048 Node* _beforeLoop; // last node before loop (init. of loop var) 00049 LoopHeaderNode* _loopHeader; 00050 Node* _startOfLoop; 00051 Node* _endOfLoop; 00052 Node* _startOfBody; 00053 Node* _endOfBody; 00054 Node* _startOfCond; 00055 Node* _endOfCond; 00056 BranchNode* _loopBranch; // branch ending loop condition 00057 int _firstNodeID, _lastNodeID; // all node IDs in loop are between these two 00058 00059 // the instance variables below are set as a result of recognize() 00060 // and are valid only if isIntegerLoop() 00061 bool _isIntegerLoop; // is this loop a recognized integer loop? 00062 PReg* _loopVar; // suspected loop variable 00063 PReg* _lowerBound; // lower bound of for-like loop (see comment in findLowerBound) 00064 PReg* _upperBound; // upper bound 00065 PReg* _increment; // increment of loopVar 00066 bool _isCountingUp; // true if loop is counting up, false if counting down 00067 NonTrivialNode* _incNode; // node incrementing loop var 00068 PReg* _loopArray; // array whose size is upper bound (or NULL) 00069 LoadOffsetNode* _loopSizeLoad; // node loading loopArray's size 00070 00071 // instance variables for general loop optimizations 00072 GrowableArray<HoistedTypeTest*>* _hoistableTests; // tests that can be hoisted out of the loop 00073 static GrowableArray<BB*>* _bbs; // BBs in code generation order 00074 public: 00075 CompiledLoop(); 00076 00077 // the routines below should be called with the appropriate nodes 00078 void set_startOfLoop(LoopHeaderNode* current); 00079 void set_startOfBody(Node* current); 00080 void set_endOfBody(Node* current); 00081 void set_startOfCond(Node* current); 00082 void set_endOfCond(Node* current); 00083 void set_endOfLoop(Node* end); 00084 00085 bool isInLoop(Node* n) const; 00086 bool isInLoopCond(Node* n) const; 00087 bool isInLoopBody(Node* n) const; 00088 LoopHeaderNode* loopHeader() const { return _loopHeader; } 00089 00090 00091 char* recognize(); // does integer loop recognition; called after defs/uses built 00092 // returns NULL if successful, reason otherwise 00093 bool isIntegerLoop() const { return _isIntegerLoop; } 00094 void optimize(); // perform general loop optimization 00095 void optimizeIntegerLoop(); // perform integer loop optimization 00096 00097 void print(); 00098 00099 protected: 00100 void discoverLoopNesting(); 00101 int findStartOfSend(int bci); 00102 char* findLowerBound(); 00103 char* findUpperBound(); 00104 char* checkLoopVar(); 00105 char* checkUpperBound(); 00106 NonTrivialNode* findDefInLoop(PReg* r); // find single definition of r in loop 00107 bool isIncrement(PReg* r, ArithOpCode op); // is r a suitable loop variable increment? 00108 void removeTagChecks(); 00109 void removeLoopVarOverflow(); 00110 void checkForArraysDefinedInLoop(); 00111 void hoistTypeTests(); 00112 void removeBoundsChecks(PReg* array, PReg* var); 00113 void findRegCandidates(); 00114 bool isEquivalentType(GrowableArray<klassOop>* klasses1, GrowableArray<klassOop>* klasses2); 00115 public: // for iterators 00116 int defsInLoop(PReg* r, NonTrivialNode** defNode = NULL); // return number of definitions of r in loop and sets defNode if non-NULL 00117 }; 00118 00119 // holds the info associated with a single type test hoisted out of a loop 00120 class HoistedTypeTest: public PrintableResourceObj { 00121 public: 00122 NonTrivialNode* node; // node (within loop) doing the test 00123 PReg* testedPR; // PReg whose type is tested 00124 GrowableArray<klassOop>* klasses; // klasses for which the PReg is tested 00125 bool invalid; 00126 00127 HoistedTypeTest(NonTrivialNode* node, PReg* testedPR, GrowableArray<klassOop>* klasses); 00128 void print(); 00129 void print_test_on(outputStream* s); 00130 }; 00131 00132 #endif 00133