Source Code Cross Referenced for LoadStoreOptimizer.java in  » Code-Analyzer » soot » soot » baf » toolkits » base » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » soot » soot.baf.toolkits.base 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Soot - a J*va Optimization Framework
0002:         * Copyright (C) 1999 Patrice Pominville
0003:         *
0004:         * This library is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License as published by the Free Software Foundation; either
0007:         * version 2.1 of the License, or (at your option) any later version.
0008:         *
0009:         * This library is distributed in the hope that it will be useful,
0010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012:         * Lesser General Public License for more details.
0013:         *
0014:         * You should have received a copy of the GNU Lesser General Public
0015:         * License along with this library; if not, write to the
0016:         * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0017:         * Boston, MA 02111-1307, USA.
0018:         */
0019:
0020:        /*
0021:         * Modified by the Sable Research Group and others 1997-1999.  
0022:         * See the 'credits' file distributed with Soot for the complete list of
0023:         * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
0024:         */
0025:
0026:        package soot.baf.toolkits.base;
0027:
0028:        import soot.options.*;
0029:
0030:        import soot.util.*;
0031:        import java.util.*;
0032:        import soot.*;
0033:        import soot.baf.*;
0034:        import soot.toolkits.scalar.*;
0035:        import soot.toolkits.graph.*;
0036:
0037:        public class LoadStoreOptimizer extends BodyTransformer {
0038:            public LoadStoreOptimizer(Singletons.Global g) {
0039:            }
0040:
0041:            public static LoadStoreOptimizer v() {
0042:                return G.v().soot_baf_toolkits_base_LoadStoreOptimizer();
0043:            }
0044:
0045:            // Constants
0046:            boolean debug = false;
0047:
0048:            // constants returned by the stackIndependent function.
0049:            final static private int FAILURE = 0;
0050:            final static private int SUCCESS = 1;
0051:            final static private int MAKE_DUP = 2;
0052:            final static private int MAKE_DUP1_X1 = 3;
0053:            final static private int SPECIAL_SUCCESS = 4;
0054:            final static private int HAS_CHANGED = 5;
0055:            final static private int SPECIAL_SUCCESS2 = 6;
0056:
0057:            final static private int STORE_LOAD_ELIMINATION = 0;
0058:            final static private int STORE_LOAD_LOAD_ELIMINATION = -1;
0059:
0060:            private Map gOptions;
0061:
0062:            /** The method that drives the optimizations. */
0063:            /* This is the public interface to LoadStoreOptimizer */
0064:
0065:            protected void internalTransform(Body body, String phaseName,
0066:                    Map options) {
0067:
0068:                gOptions = options;
0069:
0070:                Instance instance = new Instance();
0071:                instance.mBody = body;
0072:                instance.mUnits = body.getUnits();
0073:
0074:                debug = PhaseOptions.getBoolean(gOptions, "debug");
0075:
0076:                if (Options.v().verbose())
0077:                    G.v().out.println("[" + body.getMethod().getName()
0078:                            + "] Performing LoadStore optimizations...");
0079:
0080:                if (debug) {
0081:                    G.v().out.println("\n\nOptimizing Method: "
0082:                            + body.getMethod().getName());
0083:                }
0084:
0085:                instance.go();
0086:            }
0087:
0088:            class Instance {
0089:                // Instance vars.
0090:                private Chain mUnits;
0091:                private Body mBody;
0092:                private ExceptionalUnitGraph mExceptionalUnitGraph;
0093:                private LocalDefs mLocalDefs;
0094:                private LocalUses mLocalUses;
0095:                private Map<Unit, Block> mUnitToBlockMap; // maps a unit it's containing block
0096:                private boolean mPass2 = false;
0097:
0098:                void go() {
0099:                    if (!mUnits.isEmpty()) {
0100:                        buildUnitToBlockMap();
0101:                        computeLocalDefsAndLocalUsesInfo();
0102:
0103:                        if (debug) {
0104:                            G.v().out.println("Calling optimizeLoadStore(1)\n");
0105:                        }
0106:                        optimizeLoadStores();
0107:
0108:                        if (PhaseOptions.getBoolean(gOptions, "inter")) {
0109:                            if (debug) {
0110:                                G.v().out
0111:                                        .println("Calling doInterBlockOptimizations");
0112:                            }
0113:                            doInterBlockOptimizations();
0114:
0115:                            //computeLocalDefsAndLocalUsesInfo();          
0116:                            //propagateLoadsBackwards();         if(debug)     G.v().out.println("pass 3");         
0117:                            //optimizeLoadStores();      if(debug)   G.v().out.println("pass 4"); 
0118:                            //propagateLoadsForward();   if(debug)   G.v().out.println("pass 5"); 
0119:                            //propagateBackwardsIndependentHunk(); if(debug)  G.v().out.println("pass 6");                        
0120:                        }
0121:
0122:                        if (PhaseOptions.getBoolean(gOptions, "sl2")
0123:                                || PhaseOptions.getBoolean(gOptions, "sll2")) {
0124:                            mPass2 = true;
0125:                            if (debug) {
0126:                                G.v().out
0127:                                        .println("Calling optimizeLoadStore(2)");
0128:                            }
0129:                            optimizeLoadStores();
0130:                        }
0131:                    }
0132:                }
0133:
0134:                /*
0135:                 *  Computes a map binding each unit in a method to the unique basic block    
0136:                 *  that contains it.
0137:                 */
0138:                private void buildUnitToBlockMap() {
0139:                    BlockGraph blockGraph = new ZonedBlockGraph(mBody);
0140:                    if (debug) {
0141:                        G.v().out.println("Method "
0142:                                + mBody.getMethod().getName()
0143:                                + " Block Graph: ");
0144:                        G.v().out.println(blockGraph);
0145:                    }
0146:
0147:                    List blocks = blockGraph.getBlocks();
0148:                    mUnitToBlockMap = new HashMap<Unit, Block>();
0149:
0150:                    Iterator blockIt = blocks.iterator();
0151:                    while (blockIt.hasNext()) {
0152:                        Block block = (Block) blockIt.next();
0153:
0154:                        Iterator unitIt = block.iterator();
0155:                        while (unitIt.hasNext()) {
0156:                            Unit unit = (Unit) unitIt.next();
0157:                            mUnitToBlockMap.put(unit, block);
0158:                        }
0159:                    }
0160:                }
0161:
0162:                // computes a list of all the stores in mUnits in order of their occurence therein.
0163:
0164:                private List<Unit> buildStoreList() {
0165:                    Iterator it = mUnits.iterator();
0166:                    List<Unit> storeList = new ArrayList<Unit>();
0167:
0168:                    while (it.hasNext()) {
0169:                        Unit unit = (Unit) it.next();
0170:                        if (unit instanceof  StoreInst)
0171:                            storeList.add(unit);
0172:                    }
0173:                    return storeList;
0174:                }
0175:
0176:                private void computeLocalDefsAndLocalUsesInfo() {
0177:                    mExceptionalUnitGraph = new ExceptionalUnitGraph(mBody);
0178:                    mLocalDefs = new SmartLocalDefs(mExceptionalUnitGraph,
0179:                            new SimpleLiveLocals(mExceptionalUnitGraph));
0180:                    mLocalUses = new SimpleLocalUses(mExceptionalUnitGraph,
0181:                            mLocalDefs);
0182:                }
0183:
0184:                // main optimizing method
0185:                private void optimizeLoadStores() {
0186:                    List<Unit> storeList;
0187:
0188:                    // build a list of all store units in mUnits
0189:                    storeList = buildStoreList();
0190:
0191:                    // Eliminate store/load  
0192:                    {
0193:
0194:                        boolean hasChanged = true;
0195:
0196:                        boolean hasChangedFlag = false;
0197:                        while (hasChanged) {
0198:
0199:                            hasChanged = false;
0200:
0201:                            // Iterate over the storeList 
0202:                            Iterator<Unit> unitIt = storeList.iterator();
0203:
0204:                            nextUnit: while (unitIt.hasNext()) {
0205:                                Unit unit = unitIt.next();
0206:                                List uses = mLocalUses.getUsesOf(unit);
0207:
0208:                                // if uses of a store < 3, attempt some form of store/load elimination
0209:                                if (uses.size() < 3) {
0210:
0211:                                    // check that all uses have only the current store as their definition
0212:                                    {
0213:                                        Iterator useIt = uses.iterator();
0214:                                        while (useIt.hasNext()) {
0215:                                            UnitValueBoxPair pair = (UnitValueBoxPair) useIt
0216:                                                    .next();
0217:                                            Unit loadUnit = pair.getUnit();
0218:                                            if (!(loadUnit instanceof  LoadInst))
0219:                                                continue nextUnit;
0220:
0221:                                            List<Unit> defs = mLocalDefs
0222:                                                    .getDefsOfAt((Local) pair
0223:                                                            .getValueBox()
0224:                                                            .getValue(),
0225:                                                            loadUnit);
0226:                                            if (defs.size() > 1) {
0227:                                                continue nextUnit;
0228:                                            } else if (defs.get(0) != unit) {
0229:                                                continue nextUnit; // xxx how can you get here?
0230:                                            }
0231:                                        }
0232:                                    }
0233:
0234:                                    // Check that all loads are in the same bb as the store
0235:                                    {
0236:                                        Block storeBlock = mUnitToBlockMap
0237:                                                .get(unit);
0238:
0239:                                        Iterator useIt = uses.iterator();
0240:                                        while (useIt.hasNext()) {
0241:                                            UnitValueBoxPair pair = (UnitValueBoxPair) useIt
0242:                                                    .next();
0243:                                            Block useBlock = mUnitToBlockMap
0244:                                                    .get(pair.getUnit());
0245:                                            if (useBlock != storeBlock)
0246:                                                continue nextUnit;
0247:                                        }
0248:                                    }
0249:
0250:                                    // Check for stack independance (automatic reordering may be performed by stackIndependent() fcnt)
0251:                                    {
0252:                                        Block block;
0253:                                        switch (uses.size()) {
0254:                                        case 0: /*
0255:                                                                if(Options.getBoolean(gOptions, "s-elimination")) {
0256:                                                                // replace store by a pop and remove store from store list
0257:                                                                replaceUnit(unit, Baf.v().newPopInst(((StoreInst)unit).getOpType()));
0258:                                                                unitIt.remove();
0259:                                                                    
0260:                                                                hasChanged = true;        hasChangedFlag = false;
0261:                                                                }*/
0262:                                            break;
0263:
0264:                                        case 1:
0265:                                            if (PhaseOptions.getBoolean(
0266:                                                    gOptions, "sl")) {
0267:                                                if (!mPass2
0268:                                                        || PhaseOptions
0269:                                                                .getBoolean(
0270:                                                                        gOptions,
0271:                                                                        "sl2")) {
0272:                                                    // try to eliminate store/load pair
0273:                                                    Unit loadUnit = ((UnitValueBoxPair) uses
0274:                                                            .get(0)).getUnit();
0275:                                                    block = mUnitToBlockMap
0276:                                                            .get(unit);
0277:                                                    int test = stackIndependent(
0278:                                                            unit, loadUnit,
0279:                                                            block,
0280:                                                            STORE_LOAD_ELIMINATION);
0281:
0282:                                                    //xxx 
0283:                                                    //if(block.getIndexInMethod() < 1 ) { // <13
0284:                                                    if (test == SUCCESS
0285:                                                            || test == SPECIAL_SUCCESS) {
0286:
0287:                                                        block.remove(unit);
0288:                                                        block.remove(loadUnit);
0289:                                                        unitIt.remove();
0290:                                                        hasChanged = true;
0291:                                                        hasChangedFlag = false;
0292:
0293:                                                        //delme[
0294:                                                        if (debug) {
0295:                                                            G.v().out
0296:                                                                    .println("Store/Load elimination occurred case1.");
0297:                                                        }
0298:                                                        //delme]
0299:                                                    } /*else if (test == SPECIAL_SUCCESS2) {
0300:                                                                                               if(!hasChangedFlag) {
0301:                                                                                               hasChangedFlag = true;
0302:                                                                                               hasChanged = true;
0303:                                                                                               } 
0304:                                                                                               }*/
0305:                                                }
0306:                                            }
0307:                                            break;
0308:
0309:                                        case 2:
0310:                                            if (PhaseOptions.getBoolean(
0311:                                                    gOptions, "sll")) {
0312:                                                if (!mPass2
0313:                                                        || PhaseOptions
0314:                                                                .getBoolean(
0315:                                                                        gOptions,
0316:                                                                        "sll2")) {
0317:                                                    // try to replace store/load/load trio by a flavor of the dup unit
0318:                                                    Unit firstLoad = ((UnitValueBoxPair) uses
0319:                                                            .get(0)).getUnit();
0320:                                                    Unit secondLoad = ((UnitValueBoxPair) uses
0321:                                                            .get(1)).getUnit();
0322:                                                    block = mUnitToBlockMap
0323:                                                            .get(unit);
0324:
0325:                                                    Unit temp; // xxx try to optimize this
0326:                                                    if (mUnits.follows(
0327:                                                            firstLoad,
0328:                                                            secondLoad)) {
0329:                                                        temp = secondLoad;
0330:                                                        secondLoad = firstLoad;
0331:                                                        firstLoad = temp;
0332:                                                    }
0333:
0334:                                                    int result = stackIndependent(
0335:                                                            unit, firstLoad,
0336:                                                            block,
0337:                                                            STORE_LOAD_ELIMINATION);
0338:                                                    if (result == SUCCESS) {
0339:
0340:                                                        // move the first load just after its defining store.
0341:                                                        block.remove(firstLoad);
0342:                                                        block
0343:                                                                .insertAfter(
0344:                                                                        firstLoad,
0345:                                                                        unit);
0346:
0347:                                                        int res = stackIndependent(
0348:                                                                unit,
0349:                                                                secondLoad,
0350:                                                                block,
0351:                                                                STORE_LOAD_LOAD_ELIMINATION);
0352:                                                        if (res == MAKE_DUP) {
0353:                                                            // replace store by dup, drop both loads
0354:                                                            Dup1Inst dup = Baf
0355:                                                                    .v()
0356:                                                                    .newDup1Inst(
0357:                                                                            ((LoadInst) secondLoad)
0358:                                                                                    .getOpType());
0359:                                                            dup
0360:                                                                    .addAllTagsOf(unit);
0361:                                                            replaceUnit(unit,
0362:                                                                    dup);
0363:                                                            unitIt.remove(); // remove store from store list
0364:
0365:                                                            block
0366:                                                                    .remove(firstLoad);
0367:                                                            block
0368:                                                                    .remove(secondLoad);
0369:
0370:                                                            hasChanged = true;
0371:                                                            hasChangedFlag = false;
0372:
0373:                                                        } /* else if(res == MAKE_DUP1_X1) {
0374:                                                                                                
0375:                                                                                                        // replace store/load/load by a dup1_x1
0376:                                                                                                        Unit stackUnit = getStackItemAt2(unit, block, -2); 
0377:                                                                                              
0378:                                                                                                        if(stackUnit instanceof PushInst)
0379:                                                                                                        break;
0380:                                                                                              
0381:                                                                                                        Type underType = type(stackUnit);
0382:                                                                                                        if(underType == null) {                                         
0383:                                                                                                        throw new RuntimeException("this has to be corrected (loadstoroptimiser.java)" + stackUnit);
0384:                                                                                                        }
0385:                                                                                              
0386:                                                                                                        if(debug) { G.v().out.println("stack unit is: " + stackUnit + " stack type is " + underType);}
0387:                                                                                                        replaceUnit(unit, Baf.v().newDup1_x1Inst(((LoadInst) secondLoad).getOpType(),underType));
0388:                                                                                                        unitIt.remove();                
0389:                                                                                              
0390:                                                                                                        block.remove(firstLoad); 
0391:                                                                                                        block.remove(secondLoad);
0392:                                                                                              
0393:                                                                                                        hasChanged = true;          hasChangedFlag = false;                                      
0394:                                                                                                        break;                                        
0395:                                                                                              
0396:                                                                                                        } */
0397:
0398:                                                    } else if (result == SPECIAL_SUCCESS
0399:                                                            || result == HAS_CHANGED
0400:                                                            || result == SPECIAL_SUCCESS2) {
0401:                                                        if (!hasChangedFlag) {
0402:                                                            hasChangedFlag = true;
0403:                                                            hasChanged = true;
0404:                                                        }
0405:                                                    }
0406:                                                }
0407:
0408:                                            }
0409:                                        }
0410:                                    }
0411:                                }
0412:                            }
0413:                        }
0414:                    }
0415:                }
0416:
0417:                /** 
0418:                 *  Checks if the units occuring between [from, to] consume 
0419:                 *. stack items not produced by these interval units. (ie if the
0420:                 *  stack height ever goes negative between from and to, assuming the 
0421:                 *  stack height is set to 0 upon executing the instruction following 'from'.
0422:                 *  
0423:                 */
0424:                private boolean isRequiredByFollowingUnits(Unit from, Unit to) {
0425:                    Iterator it = mUnits.iterator(from, to);
0426:                    int stackHeight = 0;
0427:                    boolean res = false;
0428:
0429:                    if (from != to) {
0430:                        // advance past the 'from' unit
0431:                        it.next();
0432:                        while (it.hasNext()) {
0433:                            Unit currentInst = (Unit) it.next();
0434:                            if (currentInst == to)
0435:                                break;
0436:
0437:                            stackHeight -= ((Inst) currentInst).getInCount();
0438:                            if (stackHeight < 0) {
0439:                                res = true;
0440:                                break;
0441:                            }
0442:                            stackHeight += ((Inst) currentInst).getOutCount();
0443:                        }
0444:                    }
0445:                    return res;
0446:                }
0447:
0448:                private int pushStoreToLoad(Unit from, Unit to, Block block) {
0449:                    Unit storePred = block.getPredOf(from);
0450:                    if (storePred != null) {
0451:                        if (((Inst) storePred).getOutCount() == 1) {
0452:                            Set<Unit> unitsToMove = new HashSet<Unit>();
0453:                            unitsToMove.add(storePred);
0454:                            unitsToMove.add(from);
0455:                            int h = ((Inst) storePred).getInCount();
0456:                            Unit currentUnit = storePred;
0457:                            if (h != 0) {
0458:                                currentUnit = block.getPredOf(storePred);
0459:                                while (currentUnit != null) {
0460:
0461:                                    h -= ((Inst) currentUnit).getOutCount();
0462:                                    if (h < 0) { // xxx could be more flexible here?
0463:                                        if (debug) {
0464:                                            G.v().out.println("xxx: negative");
0465:                                        }
0466:                                        return FAILURE;
0467:                                    }
0468:                                    h += ((Inst) currentUnit).getInCount();
0469:                                    unitsToMove.add(currentUnit);
0470:                                    if (h == 0)
0471:                                        break;
0472:                                    currentUnit = block.getPredOf(currentUnit);
0473:                                }
0474:                            }
0475:                            if (currentUnit == null) {
0476:                                if (debug) {
0477:                                    G.v().out.println("xxx: null");
0478:                                }
0479:                                return FAILURE;
0480:                            }
0481:
0482:                            Unit uu = from;
0483:                            for (;;) {
0484:                                uu = block.getSuccOf(uu);
0485:                                if (uu == to)
0486:                                    break;
0487:                                Iterator<Unit> it2 = unitsToMove.iterator();
0488:                                while (it2.hasNext()) {
0489:                                    Unit nu = it2.next();
0490:                                    if (debug) {
0491:                                        G.v().out
0492:                                                .println("xxxspecial;success pushing forward stuff.");
0493:                                    }
0494:
0495:                                    if (!canMoveUnitOver(nu, uu)) {
0496:                                        if (debug) {
0497:                                            G.v().out
0498:                                                    .println("xxx: cant move over faillure"
0499:                                                            + nu);
0500:                                        }
0501:                                        return FAILURE;
0502:                                    }
0503:                                    if (debug) {
0504:                                        G.v().out.println("can move" + nu
0505:                                                + " over " + uu);
0506:                                    }
0507:                                }
0508:                            }
0509:
0510:                            // if we get here it means we can move all the units in the set pass the units in between [to, from]
0511:                            Unit unitToMove = currentUnit;
0512:                            while (unitToMove != from) {
0513:                                Unit succ = block.getSuccOf(unitToMove);
0514:                                if (debug) {
0515:                                    G.v().out.println("moving " + unitToMove);
0516:                                }
0517:                                block.remove(unitToMove);
0518:                                block.insertBefore(unitToMove, to);
0519:                                unitToMove = succ;
0520:                            }
0521:                            block.remove(from);
0522:                            block.insertBefore(from, to);
0523:
0524:                            if (debug) {
0525:                                G.v().out
0526:                                        .println("xxx1success pushing forward stuff.");
0527:                            }
0528:                            return SPECIAL_SUCCESS;
0529:                        }
0530:                    }
0531:
0532:                    return FAILURE;
0533:                }
0534:
0535:                /**
0536:                 *
0537:                 *
0538:                 * @return FAILURE when store load elimination is not possible in any form.
0539:                 * @return SUCCESS when a load in a store load pair can be moved IMMEDIATELY after it's defining store
0540:                 * @return MAKE_DUP when a store/load/load trio can be replaced by a dup unit.
0541:                 * @return MAKE_DUP_X1 when store/load/load trio can be replaced by a dup1_x1 unit
0542:                 * @return SPECIAL_SUCCESS when a store/load pair can AND must be immediately annihilated. 
0543:                 * @return HAS_CHANGED when store load elimination is not possible in any form, but some unit reordering has occured
0544:                 */
0545:
0546:                private int stackIndependent(Unit from, Unit to, Block block,
0547:                        int aContext) {
0548:                    if (debug) {
0549:                        G.v().out.println("Trying: " + from + "/" + to
0550:                                + " in block  " + block.getIndexInMethod()
0551:                                + ":");
0552:                        G.v().out
0553:                                .println("context:"
0554:                                        + (aContext == STORE_LOAD_ELIMINATION ? "STORE_LOAD_ELIMINATION"
0555:                                                : "STORE_LOAD_LOAD_ELIMINATION"));
0556:                    }
0557:
0558:                    int minStackHeightAttained = 0; // records the min stack height attained between [from, to]
0559:                    int stackHeight = 0; // records the stack height when similating the effects on the stack
0560:                    Iterator it = mUnits.iterator(mUnits.getSuccOf(from));
0561:                    int res = FAILURE;
0562:
0563:                    Unit currentInst = (Unit) it.next(); // get unit following the store
0564:
0565:                    if (aContext == STORE_LOAD_LOAD_ELIMINATION) {
0566:                        currentInst = (Unit) it.next(); // jump after first load 
0567:                    }
0568:
0569:                    // find minStackHeightAttained
0570:                    while (currentInst != to) {
0571:                        stackHeight -= ((Inst) currentInst).getInCount();
0572:                        if (stackHeight < minStackHeightAttained)
0573:                            minStackHeightAttained = stackHeight;
0574:
0575:                        stackHeight += ((Inst) currentInst).getOutCount();
0576:
0577:                        currentInst = (Unit) it.next();
0578:                    }
0579:
0580:                    // note: now stackHeight contains the delta height of the stack after executing the units contained in
0581:                    // [from, to] non-inclusive.
0582:
0583:                    if (debug) {
0584:                        G.v().out.println("nshv = " + stackHeight);
0585:                        G.v().out.println("mshv = " + minStackHeightAttained);
0586:                    }
0587:
0588:                    boolean hasChanged = true;
0589:
0590:                    // Iterate until an elimination clause is taken or no reordering of the code occurs         
0591:                    while (hasChanged) {
0592:                        hasChanged = false;
0593:
0594:                        // check for possible sll elimination
0595:                        if (aContext == STORE_LOAD_LOAD_ELIMINATION) {
0596:
0597:                            if (stackHeight == 0 && minStackHeightAttained == 0) {
0598:                                if (debug) {
0599:                                    G.v().out
0600:                                            .println("xxx: succ: -1, makedup ");
0601:                                }
0602:                                return MAKE_DUP;
0603:                            } else if (stackHeight == -1
0604:                                    && minStackHeightAttained == -1) {
0605:                                if (debug) {
0606:                                    G.v().out
0607:                                            .println("xxx: succ: -1, makedup , -1");
0608:                                }
0609:                                return MAKE_DUP;
0610:                            } else if (stackHeight == -2
0611:                                    && minStackHeightAttained == -2) {
0612:                                if (debug) {
0613:                                    G.v().out
0614:                                            .println("xxx: succ -1 , make dupx1 ");
0615:                                }
0616:                                return MAKE_DUP1_X1;
0617:                            }
0618:
0619:                            else if (minStackHeightAttained < -2) {
0620:                                if (debug) {
0621:                                    G.v().out
0622:                                            .println("xxx: failled due: minStackHeightAttained < -2 ");
0623:                                }
0624:                                return FAILURE;
0625:                            }
0626:                        }
0627:
0628:                        // check for possible sl elimination
0629:                        if (aContext == STORE_LOAD_ELIMINATION) {
0630:                            if (stackHeight == 0 && minStackHeightAttained == 0) {
0631:                                if (debug) {
0632:                                    G.v().out
0633:                                            .println("xxx: success due: 0, SUCCESS ");
0634:                                }
0635:                                return SUCCESS;
0636:                            }
0637:                            /* xxx broken data depensie problem.
0638:                            else if (minStackHeightAttained == -1 && stackHeight == -1) { // try to make it more generic
0639:                                Unit u = (Unit) block.getPredOf(from);
0640:                                if(u instanceof FieldGetInst)
0641:                                    if(block.getPredOf(u) instanceof Dup1Inst) {
0642:                                        block.remove(u);
0643:                                        block.insertBefore(u, to);
0644:                                        block.remove(from);
0645:                                        block.insertBefore(from, to);
0646:                                        if(debug) { G.v().out.println("xxx: success due to 1, SPECIAL_SUCCESS2");}
0647:                                        return SPECIAL_SUCCESS2;
0648:                                    }                    
0649:                            }*/
0650:                            else if (minStackHeightAttained < 0) {
0651:                                return pushStoreToLoad(from, to, block);
0652:                            }
0653:                        }
0654:
0655:                        it = mUnits.iterator(mUnits.getSuccOf(from), to);
0656:
0657:                        Unit unitToMove = null;
0658:                        Unit u = (Unit) it.next();
0659:
0660:                        if (aContext == STORE_LOAD_LOAD_ELIMINATION) {
0661:                            u = (Unit) it.next();
0662:                        }
0663:                        int currentH = 0;
0664:
0665:                        // find a candidate to move before the store/load/(load)  group 
0666:                        while (u != to) {
0667:
0668:                            if (((Inst) u).getNetCount() == 1) {
0669:                                // xxx remove this check
0670:                                if (u instanceof  LoadInst
0671:                                        || u instanceof  PushInst
0672:                                        || u instanceof  NewInst
0673:                                        || u instanceof  StaticGetInst
0674:                                        || u instanceof  Dup1Inst) {
0675:
0676:                                    // verify that unitToMove is not required by following units (until the 'to' unit)
0677:                                    if (!isRequiredByFollowingUnits(u, to)) {
0678:                                        unitToMove = u;
0679:                                    }
0680:
0681:                                } else {
0682:                                    if (debug) {
0683:                                        G.v().out
0684:                                                .println("1003:(LoadStoreOptimizer@stackIndependent): found unknown unit w/ getNetCount == 1"
0685:                                                        + u);
0686:                                    }
0687:                                }
0688:                            }
0689:
0690:                            if (unitToMove != null) {
0691:                                int flag = 0;
0692:                                //if(aContext == 0 || !(stackHeight > -2 && minStackHeightAttained == -2 ) ) {
0693:
0694:                                if (tryToMoveUnit(unitToMove, block, from, to,
0695:                                        flag)) {
0696:                                    if (stackHeight > -2
0697:                                            && minStackHeightAttained == -2) {
0698:                                        return HAS_CHANGED;
0699:                                    }
0700:
0701:                                    stackHeight--;
0702:                                    if (stackHeight < minStackHeightAttained)
0703:                                        minStackHeightAttained = stackHeight;
0704:                                    hasChanged = true;
0705:                                    break;
0706:                                }
0707:                            }
0708:
0709:                            currentH += ((Inst) u).getNetCount();
0710:                            unitToMove = null;
0711:                            u = (Unit) it.next();
0712:                        }
0713:                    }
0714:
0715:                    if (isCommutativeBinOp(block.getSuccOf(to))) {
0716:                        if (aContext == STORE_LOAD_ELIMINATION
0717:                                && stackHeight == 1
0718:                                && minStackHeightAttained == 0) {
0719:                            if (debug) {
0720:                                G.v().out.println("xxx: commutative ");
0721:                            }
0722:                            return SPECIAL_SUCCESS;
0723:                        } else if (((Inst) to).getOutCount() == 1
0724:                                && ((Inst) to).getInCount() == 0
0725:                                && ((Inst) mUnits.getPredOf(to)).getOutCount() == 1
0726:                                && ((Inst) mUnits.getPredOf(to)).getInCount() == 0) {
0727:
0728:                            Object toPred = mUnits.getPredOf(to);
0729:                            block.remove((Unit) toPred);
0730:                            block.insertAfter((Unit) toPred, to);
0731:                            return HAS_CHANGED; // return has changed
0732:                        } else
0733:                            return FAILURE;
0734:                    }
0735:                    if (aContext == STORE_LOAD_ELIMINATION)
0736:                        return pushStoreToLoad(from, to, block);
0737:
0738:                    return res;
0739:                }
0740:
0741:                /**
0742:                 * @return true if aUnit perform a non-local read or write. false otherwise.
0743:                 */
0744:                private boolean isNonLocalReadOrWrite(Unit aUnit) {
0745:                    if ((aUnit instanceof  FieldArgInst)
0746:                            || (aUnit instanceof  ArrayReadInst)
0747:                            || (aUnit instanceof  ArrayWriteInst))
0748:                        return true;
0749:                    else
0750:                        return false;
0751:                }
0752:
0753:                /**
0754:                 *  When reordering bytecode, check if it is safe to move aUnitToMove past aUnitToGoOver.
0755:                 *  @return true if aUnitToMove can be moved past aUnitToGoOver.
0756:                 */
0757:                private boolean canMoveUnitOver(Unit aUnitToMove,
0758:                        Unit aUnitToGoOver) // xxx missing cases
0759:                {
0760:
0761:                    // can't change method call order or change fieldargInst and method call order
0762:                    if ((aUnitToGoOver instanceof  MethodArgInst && aUnitToMove instanceof  MethodArgInst)
0763:                            || (aUnitToGoOver instanceof  MethodArgInst && isNonLocalReadOrWrite(aUnitToMove))
0764:                            || (isNonLocalReadOrWrite(aUnitToGoOver) && aUnitToMove instanceof  MethodArgInst)
0765:                            ||
0766:
0767:                            (aUnitToGoOver instanceof  ArrayReadInst && aUnitToMove instanceof  ArrayWriteInst)
0768:                            || (aUnitToGoOver instanceof  ArrayWriteInst && aUnitToMove instanceof  ArrayReadInst)
0769:                            || (aUnitToGoOver instanceof  ArrayWriteInst && aUnitToMove instanceof  ArrayWriteInst)
0770:                            ||
0771:
0772:                            (aUnitToGoOver instanceof  FieldPutInst
0773:                                    && aUnitToMove instanceof  FieldGetInst && ((FieldArgInst) aUnitToGoOver)
0774:                                    .getField() == ((FieldArgInst) aUnitToMove)
0775:                                    .getField())
0776:                            || (aUnitToGoOver instanceof  FieldGetInst
0777:                                    && aUnitToMove instanceof  FieldPutInst && ((FieldArgInst) aUnitToGoOver)
0778:                                    .getField() == ((FieldArgInst) aUnitToMove)
0779:                                    .getField())
0780:                            || (aUnitToGoOver instanceof  FieldPutInst
0781:                                    && aUnitToMove instanceof  FieldPutInst && ((FieldArgInst) aUnitToGoOver)
0782:                                    .getField() == ((FieldArgInst) aUnitToMove)
0783:                                    .getField())
0784:                            ||
0785:
0786:                            (aUnitToGoOver instanceof  StaticPutInst
0787:                                    && aUnitToMove instanceof  StaticGetInst && ((FieldArgInst) aUnitToGoOver)
0788:                                    .getField() == ((FieldArgInst) aUnitToMove)
0789:                                    .getField())
0790:                            || (aUnitToGoOver instanceof  StaticGetInst
0791:                                    && aUnitToMove instanceof  StaticPutInst && ((FieldArgInst) aUnitToGoOver)
0792:                                    .getField() == ((FieldArgInst) aUnitToMove)
0793:                                    .getField())
0794:                            || (aUnitToGoOver instanceof  StaticPutInst
0795:                                    && aUnitToMove instanceof  StaticPutInst && ((FieldArgInst) aUnitToGoOver)
0796:                                    .getField() == ((FieldArgInst) aUnitToMove)
0797:                                    .getField()))
0798:                        return false;
0799:
0800:                    // xxx to be safe don't mess w/ monitors. These rules could be relaxed. ? Maybe.
0801:                    if (aUnitToGoOver instanceof  EnterMonitorInst
0802:                            || aUnitToGoOver instanceof  ExitMonitorInst)
0803:                        return false;
0804:
0805:                    if (aUnitToMove instanceof  EnterMonitorInst
0806:                            || aUnitToGoOver instanceof  ExitMonitorInst)
0807:                        return false;
0808:
0809:                    if (aUnitToGoOver instanceof  IdentityInst
0810:                            || aUnitToMove instanceof  IdentityInst)
0811:                        return false;
0812:
0813:                    if (aUnitToMove instanceof  LoadInst) {
0814:                        if (aUnitToGoOver instanceof  StoreInst) {
0815:                            if (((StoreInst) aUnitToGoOver).getLocal() == ((LoadInst) aUnitToMove)
0816:                                    .getLocal()) {
0817:                                return false;
0818:                            }
0819:                        } else if (aUnitToGoOver instanceof  IncInst) {
0820:                            if (((IncInst) aUnitToGoOver).getLocal() == ((LoadInst) aUnitToMove)
0821:                                    .getLocal()) {
0822:                                return false;
0823:                            }
0824:                        }
0825:                    }
0826:
0827:                    // don't move def of load  pass it.
0828:                    if (aUnitToMove instanceof  StoreInst) {
0829:                        if (aUnitToGoOver instanceof  LoadInst) {
0830:                            if (((LoadInst) aUnitToGoOver).getLocal() == ((StoreInst) aUnitToMove)
0831:                                    .getLocal()) {
0832:                                return false;
0833:                            }
0834:                        } else if (aUnitToGoOver instanceof  IncInst) {
0835:                            if (((IncInst) aUnitToGoOver).getLocal() == ((StoreInst) aUnitToMove)
0836:                                    .getLocal()) {
0837:                                return false;
0838:                            }
0839:                        }
0840:                    }
0841:
0842:                    if (aUnitToMove instanceof  IncInst) {
0843:                        if (aUnitToGoOver instanceof  StoreInst) {
0844:                            if (((StoreInst) aUnitToGoOver).getLocal() == ((IncInst) aUnitToMove)
0845:                                    .getLocal()) {
0846:                                return false;
0847:                            }
0848:                        } else if (aUnitToGoOver instanceof  LoadInst) {
0849:                            if (((LoadInst) aUnitToGoOver).getLocal() == ((IncInst) aUnitToMove)
0850:                                    .getLocal()) {
0851:                                return false;
0852:                            }
0853:                        }
0854:                    }
0855:                    return true;
0856:                }
0857:
0858:                private boolean tryToMoveUnit(Unit unitToMove, Block block,
0859:                        Unit from, Unit to, int flag) {
0860:
0861:                    int h = 0;
0862:                    Unit current = unitToMove;
0863:                    boolean reachedStore = false;
0864:                    boolean reorderingOccurred = false;
0865:
0866:                    if (debug) {
0867:                        G.v().out.println("[tryToMoveUnit]: trying to move:"
0868:                                + unitToMove);
0869:                    }
0870:                    if (unitToMove == null)
0871:                        return false;
0872:
0873:                    while (current != block.getHead()) { // do not go past basic block limit
0874:                        current = (Unit) mUnits.getPredOf(current);
0875:
0876:                        if (!canMoveUnitOver(current, unitToMove))
0877:                            return false;
0878:
0879:                        if (current == from)
0880:                            reachedStore = true;
0881:
0882:                        h -= ((Inst) current).getOutCount();
0883:                        if (h < 0) {
0884:                            if (debug) {
0885:                                G.v().out
0886:                                        .println("1006:(LoadStoreOptimizer@stackIndependent): Stack went negative while trying to reorder code.");
0887:                            }
0888:
0889:                            if (flag == 1) {
0890:                                if (current instanceof  DupInst) {
0891:                                    block.remove(unitToMove);
0892:                                    block.insertAfter(unitToMove, current);
0893:                                    //                        block.insertAfter(  new BSwapInst(  )     ,unitToMove);
0894:                                }
0895:
0896:                            }
0897:                            return false;
0898:                        }
0899:                        h += ((Inst) current).getInCount();
0900:
0901:                        if (h == 0 && reachedStore == true) {
0902:                            if (!isRequiredByFollowingUnits(unitToMove, to)) {
0903:                                if (debug) {
0904:                                    G.v().out
0905:                                            .println("10077:(LoadStoreOptimizer@stackIndependent): reordering bytecode move: "
0906:                                                    + unitToMove
0907:                                                    + "before: "
0908:                                                    + current);
0909:                                }
0910:                                block.remove(unitToMove);
0911:                                block.insertBefore(unitToMove, current);
0912:
0913:                                reorderingOccurred = true;
0914:                                break;
0915:                            }
0916:                        }
0917:                    }
0918:
0919:                    if (reorderingOccurred) {
0920:                        if (debug) {
0921:                            G.v().out.println("reordering occured");
0922:                        }
0923:                        return true;
0924:                    } else {
0925:                        if (debug) {
0926:                            G.v().out
0927:                                    .println("1008:(LoadStoreOptimizer@stackIndependent):failled to find a new slot for unit to move");
0928:                        }
0929:                        return false;
0930:                    }
0931:                }
0932:
0933:                /** 
0934:                 *  Replace 1 or 2 units by a third unit in a block. Both units to 
0935:                 *  replace should be in the same block. The map 'mUnitToBlockMap'   
0936:                 *  is updated. The replacement unit is inserted in the position,
0937:                 *  of the aToReplace2 if not null, otherwise in aToReplace1's slot.
0938:                 *
0939:                 *  @param aToReplace1 Unit to replace. (shouldn't be null)
0940:                 *  @param aToReplace2 Second Unit to replace (can be  null)
0941:                 *  @param aReplacement Unit that replaces the 2 previous units (shouldn't be null)
0942:                 */
0943:                private void replaceUnit(Unit aToReplace1, Unit aToReplace2,
0944:                        Unit aReplacement) {
0945:                    Block block = mUnitToBlockMap.get(aToReplace1);
0946:
0947:                    if (aToReplace2 != null) {
0948:                        block.insertAfter(aReplacement, aToReplace2);
0949:                        block.remove(aToReplace2);
0950:                    } else {
0951:                        block.insertAfter(aReplacement, aToReplace1);
0952:                    }
0953:
0954:                    block.remove(aToReplace1);
0955:
0956:                    // add the new unit the block map
0957:                    mUnitToBlockMap.put(aReplacement, block);
0958:                }
0959:
0960:                private void replaceUnit(Unit aToReplace, Unit aReplacement) {
0961:                    replaceUnit(aToReplace, null, aReplacement);
0962:                }
0963:
0964:                /* 
0965:                 * @param some block
0966:                 * @return true if the block is an exception handler.
0967:                 */
0968:                private boolean isExceptionHandlerBlock(Block aBlock) {
0969:                    Unit blockHead = aBlock.getHead();
0970:                    Iterator it = mBody.getTraps().iterator();
0971:                    while (it.hasNext()) {
0972:                        Trap trap = (Trap) it.next();
0973:                        if (trap.getHandlerUnit() == blockHead)
0974:                            return true;
0975:                    }
0976:                    return false;
0977:                }
0978:
0979:                // not a save function :: goes over block boundries
0980:                private int getDeltaStackHeightFromTo(Unit aFrom, Unit aTo) {
0981:                    Iterator it = mUnits.iterator(aFrom, aTo);
0982:                    int h = 0;
0983:
0984:                    while (it.hasNext()) {
0985:                        h += ((Inst) it.next()).getNetCount();
0986:                    }
0987:
0988:                    return h;
0989:                }
0990:
0991:                /** 
0992:                 *   Performs 2 simple inter-block optimizations in order to keep 
0993:                 *   some variables  on the stack between blocks. Both are intented to catch
0994:                 *   'if' like constructs where the control flow branches temporarely into two paths 
0995:                 *    that join up at a latter point. 
0996:                 *
0997:                 */
0998:                private void doInterBlockOptimizations() {
0999:                    boolean hasChanged = true;
1000:                    while (hasChanged) {
1001:                        hasChanged = false;
1002:
1003:                        List<Unit> tempList = new ArrayList<Unit>();
1004:                        tempList.addAll(mUnits);
1005:                        Iterator<Unit> it = tempList.iterator();
1006:                        while (it.hasNext()) {
1007:                            Unit u = it.next();
1008:
1009:                            if (u instanceof  LoadInst) {
1010:                                if (debug) {
1011:                                    G.v().out.println("inter trying: " + u);
1012:                                }
1013:                                Block loadBlock = mUnitToBlockMap.get(u);
1014:                                List<Unit> defs = mLocalDefs.getDefsOfAt(
1015:                                        ((LoadInst) u).getLocal(), u);
1016:
1017:                                // first optimization 
1018:                                if (defs.size() == 1) {
1019:                                    Block defBlock = mUnitToBlockMap.get(defs
1020:                                            .get(0));
1021:                                    if (defBlock != loadBlock
1022:                                            && !(isExceptionHandlerBlock(loadBlock))) {
1023:                                        Unit storeUnit = defs.get(0);
1024:                                        if (storeUnit instanceof  StoreInst) {
1025:                                            List uses = mLocalUses
1026:                                                    .getUsesOf(storeUnit);
1027:                                            if (uses.size() == 1) {
1028:                                                if (allSuccesorsOfAreThePredecessorsOf(
1029:                                                        defBlock, loadBlock)) {
1030:                                                    if (getDeltaStackHeightFromTo(
1031:                                                            defBlock
1032:                                                                    .getSuccOf(storeUnit),
1033:                                                            defBlock.getTail()) == 0) {
1034:                                                        Iterator it2 = defBlock
1035:                                                                .getSuccs()
1036:                                                                .iterator();
1037:                                                        boolean res = true;
1038:                                                        while (it2.hasNext()) {
1039:                                                            Block b = (Block) it2
1040:                                                                    .next();
1041:                                                            if (getDeltaStackHeightFromTo(
1042:                                                                    b.getHead(),
1043:                                                                    b.getTail()) != 0) {
1044:                                                                res = false;
1045:                                                                break;
1046:                                                            }
1047:                                                            if (b.getPreds()
1048:                                                                    .size() != 1
1049:                                                                    || b
1050:                                                                            .getSuccs()
1051:                                                                            .size() != 1) {
1052:                                                                res = false;
1053:                                                                break;
1054:                                                            }
1055:                                                        }
1056:                                                        if (debug) {
1057:                                                            G.v().out
1058:                                                                    .println(defBlock
1059:                                                                            .toString()
1060:                                                                            + loadBlock
1061:                                                                                    .toString());
1062:                                                        }
1063:
1064:                                                        if (res) {
1065:                                                            defBlock
1066:                                                                    .remove(storeUnit);
1067:                                                            mUnitToBlockMap
1068:                                                                    .put(
1069:                                                                            storeUnit,
1070:                                                                            loadBlock);
1071:                                                            loadBlock
1072:                                                                    .insertBefore(
1073:                                                                            storeUnit,
1074:                                                                            loadBlock
1075:                                                                                    .getHead());
1076:                                                            hasChanged = true;
1077:                                                            if (debug) {
1078:                                                                G.v().out
1079:                                                                        .println("inter-block opti occurred "
1080:                                                                                + storeUnit
1081:                                                                                + " "
1082:                                                                                + u);
1083:                                                            }
1084:                                                            if (debug) {
1085:                                                                G.v().out
1086:                                                                        .println(defBlock
1087:                                                                                .toString()
1088:                                                                                + loadBlock
1089:                                                                                        .toString());
1090:                                                            }
1091:                                                        }
1092:                                                    }
1093:                                                }
1094:                                            }
1095:                                        }
1096:                                    }
1097:                                }
1098:                                // second optimization
1099:                                else if (defs.size() == 2) {
1100:
1101:                                    Unit def0 = defs.get(0);
1102:                                    Unit def1 = defs.get(1);
1103:
1104:                                    Block defBlock0 = mUnitToBlockMap.get(def0);
1105:                                    Block defBlock1 = mUnitToBlockMap.get(def1);
1106:                                    if (defBlock0 != loadBlock
1107:                                            && defBlock1 != loadBlock
1108:                                            && defBlock0 != defBlock1
1109:                                            && !(isExceptionHandlerBlock(loadBlock))) {
1110:                                        if (mLocalUses.getUsesOf(def0).size() == 1
1111:                                                && mLocalUses.getUsesOf(def1)
1112:                                                        .size() == 1) {
1113:                                            List def0Succs = defBlock0
1114:                                                    .getSuccs();
1115:                                            List def1Succs = defBlock1
1116:                                                    .getSuccs();
1117:                                            if (def0Succs.size() == 1
1118:                                                    && def1Succs.size() == 1) {
1119:                                                if (def0Succs.get(0) == loadBlock
1120:                                                        && def1Succs.get(0) == loadBlock) {
1121:                                                    if (loadBlock.getPreds()
1122:                                                            .size() == 2) {
1123:                                                        if ((def0 == defBlock0
1124:                                                                .getTail() || getDeltaStackHeightFromTo(
1125:                                                                defBlock0
1126:                                                                        .getSuccOf(def0),
1127:                                                                defBlock0
1128:                                                                        .getTail()) == 0)
1129:                                                                && (def1 == defBlock1
1130:                                                                        .getTail() || getDeltaStackHeightFromTo(
1131:                                                                        defBlock1
1132:                                                                                .getSuccOf(def1),
1133:                                                                        defBlock1
1134:                                                                                .getTail()) == 0)) {
1135:                                                            defBlock0
1136:                                                                    .remove(def0);
1137:                                                            defBlock1
1138:                                                                    .remove(def1);
1139:                                                            loadBlock
1140:                                                                    .insertBefore(
1141:                                                                            def0,
1142:                                                                            loadBlock
1143:                                                                                    .getHead());
1144:                                                            mUnitToBlockMap
1145:                                                                    .put(def0,
1146:                                                                            loadBlock);
1147:                                                            hasChanged = true;
1148:                                                            if (debug) {
1149:                                                                G.v().out
1150:                                                                        .println("inter-block opti2 occurred "
1151:                                                                                + def0);
1152:                                                            }
1153:                                                        } else {
1154:                                                            if (debug) {
1155:                                                                G.v().out
1156:                                                                        .println("failed: inter1");
1157:                                                            }
1158:                                                        }
1159:                                                    } else {
1160:                                                        if (debug) {
1161:                                                            G.v().out
1162:                                                                    .println("failed: inter2");
1163:                                                        }
1164:                                                    }
1165:                                                } else {
1166:                                                    if (debug) {
1167:                                                        G.v().out
1168:                                                                .println("failed: inter3");
1169:                                                    }
1170:                                                }
1171:                                            } else {
1172:                                                if (debug) {
1173:                                                    G.v().out
1174:                                                            .println("failed: inter4");
1175:                                                }
1176:                                            }
1177:                                        } else {
1178:                                            if (debug) {
1179:                                                G.v().out
1180:                                                        .println("failed: inter5");
1181:                                            }
1182:                                        }
1183:                                    } else {
1184:                                        if (debug) {
1185:                                            G.v().out.println("failed: inter6");
1186:                                        }
1187:                                    }
1188:                                }
1189:                            }
1190:                        }
1191:                    }
1192:                }
1193:
1194:                /**
1195:                 *  Given 2 blocks, assertains whether all the succesors of the first block are the predecessors 
1196:                 *  of the second block.
1197:                 */
1198:                private boolean allSuccesorsOfAreThePredecessorsOf(
1199:                        Block aFirstBlock, Block aSecondBlock) {
1200:                    int size = aFirstBlock.getSuccs().size();
1201:                    Iterator it = aFirstBlock.getSuccs().iterator();
1202:
1203:                    List preds = aSecondBlock.getPreds();
1204:                    while (it.hasNext()) {
1205:                        if (!preds.contains(it.next()))
1206:                            return false;
1207:                    }
1208:
1209:                    if (size == preds.size())
1210:                        return true;
1211:                    else
1212:                        return false;
1213:                }
1214:
1215:                /**
1216:                 *  @return true if aUnit is a commutative binary operator
1217:                 */
1218:                private boolean isCommutativeBinOp(Unit aUnit) {
1219:                    if (aUnit == null)
1220:                        return false;
1221:
1222:                    if (aUnit instanceof  AddInst || aUnit instanceof  MulInst
1223:                            || aUnit instanceof  AndInst
1224:                            || aUnit instanceof  OrInst
1225:                            || aUnit instanceof  XorInst)
1226:                        return true;
1227:                    else
1228:                        return false;
1229:                }
1230:
1231:                void propagateBackwardsIndependentHunk() {
1232:
1233:                    List<Unit> tempList = new ArrayList<Unit>();
1234:                    tempList.addAll(mUnits);
1235:                    Iterator<Unit> it = tempList.iterator();
1236:
1237:                    while (it.hasNext()) {
1238:                        Unit u = it.next();
1239:
1240:                        if (u instanceof  NewInst) {
1241:                            Block block = mUnitToBlockMap.get(u);
1242:                            Unit succ = block.getSuccOf(u);
1243:                            if (succ instanceof  StoreInst) {
1244:                                Unit currentUnit = u;
1245:                                Unit candidate = null;
1246:
1247:                                while (currentUnit != block.getHead()) {
1248:                                    currentUnit = block.getPredOf(currentUnit);
1249:                                    if (canMoveUnitOver(currentUnit, succ)) {
1250:                                        candidate = currentUnit;
1251:                                    } else
1252:                                        break;
1253:                                }
1254:                                if (candidate != null) {
1255:                                    block.remove(u);
1256:                                    block.remove(succ);
1257:                                    block.insertBefore(u, candidate);
1258:                                    block.insertBefore(succ, candidate);
1259:                                }
1260:                            }
1261:                        }
1262:                    }
1263:                }
1264:
1265:                // recycled code:
1266:                /*
1267:                  // convertsa series of loads into dups when applicable
1268:                  void superDuper1() { 
1269:                  List tempList = new ArrayList();
1270:                  tempList.addAll(mUnits);
1271:                  Iterator it = tempList.iterator();
1272:                  boolean fetchUnit = true;
1273:                    
1274:                  while(it.hasNext()) {
1275:                  Unit currentInst = null;
1276:                        
1277:                  if(fetchUnit) {
1278:                  currentInst = (Unit) it.next();               
1279:                  }
1280:                  fetchUnit = true;
1281:                        
1282:                  if(currentInst instanceof LoadInst) {
1283:                  Block block = (Block) mUnitToBlockMap.get(currentInst);
1284:                            
1285:                  Local local = ((LoadInst)currentInst).getLocal();
1286:                                
1287:                  // count the number of identical loads
1288:                            
1289:                  Unit u;
1290:                  for(;;){
1291:                  if(it.hasNext()) {
1292:                  u = (Unit) it.next();
1293:                  if(mUnitToBlockMap.get(u) != block)
1294:                  break;
1295:                                    
1296:                  if(u instanceof LoadInst) {
1297:                  if(((LoadInst)u).getLocal() == local) {
1298:                  replaceUnit(u, Baf.v().newDup1Inst(((LoadInst) u).getOpType()));
1299:
1300:                  } else {
1301:                  fetchUnit =false;
1302:                  break;
1303:                  }
1304:                  } else {                        
1305:                  break;
1306:                  }
1307:                  } else 
1308:                  break;
1309:                  }                
1310:                  }
1311:                  }
1312:                  }
1313:
1314:                
1315:                  //broken use superDuper1
1316:                  void superDuper() {
1317:                  // compress a serie of loads using dup2's and dup's
1318:                  {
1319:                  List tempList = new ArrayList();
1320:                  tempList.addAll(mUnits);
1321:                  Iterator it = tempList.iterator();
1322:                  while(it.hasNext()) {
1323:                  Unit currentInst = (Unit) it.next();
1324:                               
1325:                  if(currentInst instanceof LoadInst) {
1326:                  Block block = (Block) mUnitToBlockMap.get(currentInst);
1327:                                
1328:                  int loadCount = 1;
1329:                  Local local = ((LoadInst)currentInst).getLocal();
1330:                                
1331:                  // count the number of identical loads
1332:                                
1333:                  Unit u;
1334:                  for(;;){
1335:                  u = (Unit) it.next();
1336:                  if(mUnitToBlockMap.get(u) != block)
1337:                  break;
1338:                                    
1339:                  if(u instanceof LoadInst) {
1340:                  if(((LoadInst)u).getLocal() == local)
1341:                  loadCount++;
1342:                  else
1343:                  break;
1344:                  } else {
1345:                  break;
1346:                  }
1347:                  }
1348:                                
1349:
1350:                  if(loadCount > 1) {
1351:                  Type loadType = ((LoadInst)currentInst).getOpType();
1352:                    
1353:                                            // must leave at least one load on stack before dupping
1354:                                            Unit currentLoad = (Unit) mUnits.getSuccOf(currentInst);
1355:                                            loadCount--; 
1356:                              
1357:                                            if(loadType instanceof LongType || loadType instanceof DoubleType) {
1358:                                            
1359:                                     
1360:                                            
1361:                                            while(loadCount > 0) {
1362:                                            Unit nextLoad = (Unit) mUnits.getSuccOf(currentLoad); 
1363:                                            replaceUnit(currentLoad,  Baf.v().newDup1Inst(loadType));                                                
1364:                                                
1365:                                            currentLoad = nextLoad;                                 
1366:                                            loadCount--;
1367:                                            }                                
1368:                                            } else {
1369:                                            boolean canMakeDup2 = false;
1370:                                            if(loadCount >= 3) {
1371:                                            canMakeDup2 = true;
1372:                                            currentLoad = (Unit) mUnits.getSuccOf(currentLoad);
1373:                                            loadCount--;
1374:                                            }
1375:                                        
1376:                                            while(loadCount > 0) {
1377:                                            
1378:                                            if(loadCount == 1 || !canMakeDup2) {
1379:                                            Unit nextLoad = (Unit) mUnits.getSuccOf(currentLoad); 
1380:                                            replaceUnit(currentLoad,  Baf.v().newDup1Inst(loadType));                                                
1381:                                                
1382:                                            currentLoad = nextLoad;
1383:                                            loadCount--;        
1384:                                            } else {
1385:                                            if(canMakeDup2) {
1386:                                            Unit nextLoad = (Unit) mUnits.getSuccOf(mUnits.getSuccOf(currentLoad));
1387:                                            replaceUnit(currentLoad, (Unit) mUnits.getSuccOf(currentLoad),  Baf.v().newDup2Inst(loadType, loadType));                    
1388:                                            currentLoad = nextLoad;
1389:                                            loadCount -= 2;        
1390:                                            }
1391:                                            }                                                            
1392:                                            }
1393:                                            }
1394:                                            }                    
1395:                                            currentInst = u;
1396:                                            }                
1397:                                            }
1398:                                            }
1399:                                            }
1400:                
1401:                                            void peephole() {
1402:                                            boolean hasChanged = true;
1403:                   
1404:                                            while(hasChanged) {
1405:                                            hasChanged = false;
1406:                                            List tempList = new ArrayList();
1407:                                            tempList.addAll(mUnits);
1408:                       
1409:                                            Iterator it = tempList.iterator();
1410:                                            while(it.hasNext() ) {
1411:                                            Unit currentUnit = (Unit) it.next();
1412:                                            if(currentUnit instanceof PopInst) {
1413:                                            Block popBlock = (Block) mUnitToBlockMap.get(currentUnit);
1414:                                            Unit prev = (Unit) popBlock.getPredOf(currentUnit);
1415:                                            Unit succ = (Unit) popBlock.getSuccOf(currentUnit);
1416:                               
1417:                                            if(prev instanceof LoadInst || prev instanceof PushInst) 
1418:                                            if(((AbstractInst)prev).getOutMachineCount() == ((AbstractInst)currentUnit).getInMachineCount()) {
1419:                                            popBlock.remove(prev);
1420:                                            popBlock.remove(currentUnit);
1421:                                            }
1422:                                            else if(succ instanceof ReturnInst) {
1423:                                            popBlock.remove(currentUnit);
1424:                                            popBlock.remove(succ);
1425:                                            }                                   
1426:                                            }
1427:                                            }       
1428:                                            }
1429:                                            }  
1430:
1431:                            
1432:                                            private boolean propagateStoreForward(Unit aInst, Unit aUnitToReach, Unit aCurrentUnit, int aStackHeight) 
1433:                                            {
1434:                                            boolean res = false;
1435:                                            Unit currentUnit =  aCurrentUnit;           
1436:                                            Local storeLocal = ((StoreInst)aInst).getLocal();
1437:                                            Block block  = (Block) mUnitToBlockMap.get(aCurrentUnit);
1438:                    
1439:                                            while( currentUnit != block.getTail()) {
1440:                                            if(currentUnit == aUnitToReach) {
1441:                                            if(aStackHeight == 0)
1442:                                            return true;
1443:                                            else
1444:                                            return false;
1445:                                            }
1446:                        
1447:                                            if(!canMoveUnitOver(aInst, currentUnit)) {
1448:                                            res = false;
1449:                                            break;
1450:                                            }
1451:                        
1452:                                            aStackHeight -= ((Inst)currentUnit).getInCount();                
1453:                                            if(aStackHeight < 0){
1454:                                            res = false;
1455:                                            break;
1456:                                            }            
1457:                                            aStackHeight += ((Inst)currentUnit).getOutCount();
1458:                        
1459:                                            currentUnit = (Unit) block.getSuccOf(currentUnit);
1460:                                            }        
1461:
1462:                                            // if we hit the block boundry 
1463:                                            if( currentUnit == block.getTail()) {
1464:                                            Iterator it = block.getSuccessors().iterator();        
1465:                                            while(it.hasNext()) {
1466:                                            Block b = (Block) it.next();
1467:                                            if(!propagateStoreForward(aInst, aUnitToReach,  b.getHead(), aStackHeight))
1468:                                            return false;                
1469:                                            }
1470:                                            res = true;
1471:                                            }        
1472:                                            return res;
1473:                                            }
1474:
1475:                 */
1476:
1477:            }
1478:
1479:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.