[Soot-list] How can cancel other default optimization?

Eric Bodden eric.bodden at mail.mcgill.ca
Thu Nov 13 14:30:05 EST 2008


Can you try to explicitly disable the eight phases shown below on your
Soot command line? Maybe that helps. So for instance, use "-p gb.a1
enabled:false".

Eric

        // Grimp body creation
        addPack(p = new BodyPack("gb"));
        {
            p.add(new Transform("gb.a1", Aggregator.v()));
            p.add(new Transform("gb.cf", ConstructorFolder.v()));
            p.add(new Transform("gb.a2", Aggregator.v()));
            p.add(new Transform("gb.ule", UnusedLocalEliminator.v()));
        }

        // Grimp optimization pack
        addPack(p = new BodyPack("gop"));

        // Baf body creation
        addPack(p = new BodyPack("bb"));
        {
            p.add(new Transform("bb.lso", LoadStoreOptimizer.v()));
            p.add(new Transform("bb.pho", PeepholeOptimizer.v()));
            p.add(new Transform("bb.ule", UnusedLocalEliminator.v()));
            p.add(new Transform("bb.lp", LocalPacker.v()));
        }

2008/11/12 Jian Xu <fightmyway at gmail.com>:
> Hi Eric:
>
> For example, I construct the testing class A.
>
> import java.io.BufferedReader;
> import java.io.FileReader;
> import java.io.IOException;
> import java.util.StringTokenizer;
>
>
>
> public class A {
>
>     public static void main(String args[]){
>
>         try {
>             BufferedReader br = new BufferedReader(new FileReader("a.txt"));
>             String line = br.readLine();
>             while (line != null) {
>                 StringTokenizer st = new StringTokenizer(line);
>                 double x = Double.parseDouble(st.nextToken());
>                 double y = Double.parseDouble(st.nextToken());
>                 line = br.readLine();
>             }
>             br.close();
>         } catch (IOException e) {
>             System.out.println(e);
>             System.exit(1);
>         }
>     }
> }
>
>
> This is my Transform class. It's used to insert one probe in every A's
> ExceptionalBlockGraph's block. In process, I print last unit of one block
> with lineNumberTag.
>
> package hku.instrument;
>
> import java.util.ArrayList;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Map;
>
> import soot.Body;
> import soot.BodyTransformer;
> import soot.Local;
> import soot.PackManager;
> import soot.Scene;
> import soot.SootClass;
> import soot.SootMethod;
> import soot.Transform;
> import soot.Unit;
> import soot.jimple.IdentityStmt;
> import soot.jimple.IntConstant;
> import soot.jimple.InvokeExpr;
> import soot.jimple.InvokeStmt;
> import soot.jimple.Jimple;
> import soot.jimple.StringConstant;
> import soot.options.Options;
> import soot.toolkits.graph.Block;
> import soot.toolkits.graph.ExceptionalBlockGraph;
>
> public class Instrument {
>
>     public static void main(String[] args) {
>         Options.v().set_keep_line_number(true);
>         PackManager.v().getPack("jap").add(
>                 new Transform("jap.instrumenter", StmtInstrument.v()));
>         Scene.v().loadBasicClasses();
>         Scene.v().addBasicClass("hku.profile.Counter",
> SootClass.SIGNATURES);
>
>         String ss[] = new String[]{ "A" };
>         soot.Main.main(ss);
>         System.out.println("Over --------- ");
>     }
>
>
> }
>
> class StmtInstrument extends BodyTransformer {
>     private static StmtInstrument instance = new StmtInstrument();
>     private StmtInstrument() {
>     }
>
>     public static StmtInstrument v() {
>         return instance;
>     }
>
>
>     static SootClass counterClass;
>     static SootMethod increaseCounter, reportCounter;
>     static {
>         counterClass =
> Scene.v().loadClassAndSupport("hku.instrument.Counter");
>         increaseCounter = counterClass.getMethod("void
> increase(java.lang.String,java.lang.String,int)");
>     }
>
>
>     @Override
>     protected void internalTransform(Body b, String phaseName, Map options)
> {
>         // TODO Auto-generated method stub
>
>         ExceptionalBlockGraph bGraph = new ExceptionalBlockGraph(b);
>
>         Iterator<Block> blockIt = bGraph.getBlocks().iterator();
>         Local counterLocal = Jimple.v().newLocal("counterRef",
>                 counterClass.getType());
>         b.getLocals().add(counterLocal);
>         String methodName = b.getMethod().toString();
>         String className = methodName.substring(1, methodName.indexOf(":"));
>         methodName = methodName.substring(methodName.indexOf(":")+2,
> methodName.length()-1);
>
>         while (blockIt.hasNext()) {
>             Block block = (Block) blockIt.next();
>             int blkIdx = block.getIndexInMethod();
>
>             List args = new ArrayList();
>             args.add(StringConstant.v(className));
>             args.add(StringConstant.v(methodName));
>             args.add(IntConstant.v(blkIdx));
>             InvokeExpr incExpr = Jimple.v().newStaticInvokeExpr(
>                     increaseCounter.makeRef(), args);
>             InvokeStmt incStmt = Jimple.v().newInvokeStmt(incExpr);
>             Unit uh = block.getTail();
>             incStmt.addTag(uh.getTag("LineNumberTag"));
>
>             if (uh instanceof IdentityStmt) {
>                 block.insertAfter(incStmt, uh);
>             }else{
>                 block.insertBefore(incStmt, uh);
>                 uh.redirectJumpsToThisTo(incStmt);
>             }
>
>             System.out.print(uh.getTag("LineNumberTag")+": ");
>             System.out.println(uh.toString()+"\n");
>
>         }
>
>     }
> }
>
> The output is like this
> Soot started on Wed Nov 12 17:42:27 CST 2008
> Transforming A...
> 10: return
>
> 15: r0 := @parameter0: java.lang.String[]
>
> 15: $r1 = new java.io.BufferedReader
>
> 15: $r2 = new java.io.FileReader
>
> 15: specialinvoke $r2.<java.io.FileReader: void
> <init>(java.lang.String)>("a.txt")
>
> 15: specialinvoke $r1.<java.io.BufferedReader: void
> <init>(java.io.Reader)>($r2)
>
> 15: r3 = $r1
>
> 16: r4 = virtualinvoke r3.<java.io.BufferedReader: java.lang.String
> readLine()>()
>
> 17: goto [?= (branch)]
>
> 18: $r6 = new java.util.StringTokenizer
>
> 18: specialinvoke $r6.<java.util.StringTokenizer: void
> <init>(java.lang.String)>(r4)
>
> 18: r5 = $r6
>
> 19: $r7 = virtualinvoke r5.<java.util.StringTokenizer: java.lang.String
> nextToken()>()
>
> 19: staticinvoke <java.lang.Double: double
> parseDouble(java.lang.String)>($r7)
>
> 20: $r8 = virtualinvoke r5.<java.util.StringTokenizer: java.lang.String
> nextToken()>()
>
> 20: staticinvoke <java.lang.Double: double
> parseDouble(java.lang.String)>($r8)
>
> 21: r4 = virtualinvoke r3.<java.io.BufferedReader: java.lang.String
> readLine()>()
>
> 17: if r4 != null goto staticinvoke <hku.instrument.Counter: void
> increase(java.lang.String,java.lang.String,int)>("xx.A", "void
> main(java.lang.String[])", 8)
>
> 23: virtualinvoke r3.<java.io.BufferedReader: void close()>()
>
> 23: goto [?= return]
>
> 26: staticinvoke <java.lang.System: void exit(int)>(1)
>
> 28: return
>
> Writing to sootOutput/srcbin/xx/A.class
> Soot finished on Wed Nov 12 17:42:29 CST 2008
> Soot has run for 0 min. 1 sec.
> Over ---------
>
>
> Look at the line 18: r5 = $r6. when in instrument, it is a last line of one
> block, actually the only unit in that block. But at last bytecode, if we
> inpect the blocks of the exceptionalBlockGraph, this block is optimized
> away. Because I insert my probe in this block, but other units has been
> moved away, this probe is useless. So...
>
>
>
> On Wed, Nov 12, 2008 at 1:19 PM, Eric Bodden <eric.bodden at mail.mcgill.ca>
> wrote:
>>
>> Hmmm, I don't really know. What particular differences in the bytecode
>> are you seeing?
>>
>> I think that there are some last-minute optimizations that Soot always
>> runs, but it would help if you could give me some concrete examples so
>> that I could try to determine what's actually going on.
>>
>> Eric
>>
>> 2008/11/11 Jian Xu <fightmyway at gmail.com>:
>> > Hi Eric:
>> > I find when I add my transformer to the "jap" pack, the target is still
>> > moving on. The problem is about "unused local eliminate". this options
>> > can
>> > disabled, but I wonder whether the other optimization will disturb the
>> > bytecode?
>> >
>> > On Mon, Nov 10, 2008 at 10:49 PM, Eric Bodden
>> > <eric.bodden at mail.mcgill.ca>
>> > wrote:
>> >>
>> >> Hi Jian.
>> >>
>> >> Yes, you are basically trying to shoot at a moving target, so it's
>> >> best to not shoot until the target isn't moving any more ;-)
>> >>
>> >> Try adding your transformer to the "jap" pack instead:
>> >>
>> >>        PackManager.v().getPack("jap").add(
>> >>                new Transform("jap.instrumenter", Mystrument.v()));
>> >>
>> >> The "jap" pack is executed after all optimizations and little to no
>> >> transformations should take place after it.
>> >>
>> >> Maybe that's good enough in your case.
>> >>
>> >> Eric
>> >>
>> >> 2008/11/10 Jian Xu <fightmyway at gmail.com>:
>> >> > Hi Eric:
>> >> > Thank you for your reply.
>> >> >
>> >> > I do instrumentation, and insert instrument one instruction into
>> >> > every
>> >> > ExceptionalBlockGraph's node --- Block.
>> >> >         PackManager.v().getPack("jtp").add(
>> >> >                 new Transform("jtp.instrumenter", Mystrument.v()));
>> >> >         soot.Main.main();
>> >> >
>> >> > when I implement my Mystrument, soot read body which is a parameter
>> >> > of
>> >> > "internalTransform(Body b, String phaseName, Map options)". I find
>> >> > the
>> >> > body
>> >> > is generated by javac and not have optimized. At last, soot create
>> >> > new
>> >> > optimized bytecode. Of course, this is the power of soot. because I
>> >> > insert
>> >> > instruction into every Block, but at last the new bytecode optimized
>> >> > the
>> >> > Block. The jimple code doesn't have any statement of that Block in
>> >> > the
>> >> > original bytecode, except my instrument instruction. So this
>> >> > instrument
>> >> > instruction is useless and strange.
>> >> >
>> >> > for example original code is
>> >> > Block 0:
>> >> > statement 1
>> >> > statement 2
>> >> >
>> >> > Block 1:
>> >> > statement 3
>> >> >
>> >> > Block 2:
>> >> > statement 4
>> >> >
>> >> > then do instrumentation and I expect the code generated at last is
>> >> > Block 0:
>> >> > statement 1
>> >> > statement 2
>> >> > my instruction0
>> >> >
>> >> > Block 1:
>> >> > statement 3
>> >> > my instruction1
>> >> >
>> >> > Block 2:
>> >> > statement 4
>> >> > my instruction2
>> >> >
>> >> > but actually
>> >> > Block 0:
>> >> > statement 1
>> >> > statement 2
>> >> > my instruction0
>> >> > my instruction1
>> >> >
>> >> > Block 1:
>> >> > statement 4
>> >> > my instruction2
>> >> >
>> >> > so all the Block index change. And the " my instruction1" in the
>> >> > actual
>> >> > code
>> >> > is useless. Is there a way to solve the problem?
>> >> >
>> >> > Now I reach my goal by changing the bytecode created by javac first
>> >> > using
>> >> > soot.
>> >> > So the original code above is like:
>> >> > Block 0:
>> >> > statement 1
>> >> > statement 2
>> >> >
>> >> > Block 1:
>> >> > statement 4
>> >> >
>> >> > the new code
>> >> > Block 0:
>> >> > statement 1
>> >> > statement 2
>> >> > my instruction0
>> >> >
>> >> > Block 1:
>> >> > statement 4
>> >> > my instruction1
>> >> >
>> >> > Then every "my instruction " is useful. But you know when there are
>> >> > too
>> >> > many
>> >> > bytecodes, this way is time consuming.
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > On Sun, Nov 9, 2008 at 10:25 PM, Eric Bodden
>> >> > <eric.bodden at mail.mcgill.ca>
>> >> > wrote:
>> >> >>
>> >> >> Hi Jian.
>> >> >>
>> >> >> This came up on the list just recently. See here:
>> >> >>
>> >> >>
>> >> >> http://www.sable.mcgill.ca/pipermail/soot-list/2008-October/002012.html
>> >> >>
>> >> >> In a nutshell, you can disable most but not all optimizations, using
>> >> >> phase options:
>> >> >> http://www.sable.mcgill.ca/soot/tutorial/phase/index.html
>> >> >>
>> >> >>
>> >> >> Eric
>> >> >>
>> >> >> 2008/11/9 Jian Xu <fightmyway at gmail.com>:
>> >> >> > Hi:
>> >> >> > I make instrument to bytecode, so I add my transfer object into
>> >> >> > "jtp"
>> >> >> > pack
>> >> >> > then call Soot.Main.main() in my main function. But I find the
>> >> >> > bytecode
>> >> >> > which generated by soot do more modification than my transfer
>> >> >> > object
>> >> >> > do.
>> >> >> > I
>> >> >> > know when I call Soot.Main.main(), Soot do more optimization
>> >> >> > besides
>> >> >> > what I
>> >> >> > want to. So is there one way to do my transfer only but don't do
>> >> >> > others?
>> >> >> >
>> >> >> > Regards
>> >> >> > Jan
>> >> >> >
>> >> >> > _______________________________________________
>> >> >> > Soot-list mailing list
>> >> >> > Soot-list at sable.mcgill.ca
>> >> >> > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >>
>> >> >> --
>> >> >> Eric Bodden
>> >> >> Sable Research Group, McGill University, Montréal, Canada
>> >> >> Got an interesting job offer? http://www.bodden.de/hire-me/
>> >> >
>> >> >
>> >>
>> >>
>> >>
>> >> --
>> >> Eric Bodden
>> >> Sable Research Group, McGill University, Montréal, Canada
>> >> Got an interesting job offer? http://www.bodden.de/hire-me/
>> >
>> >
>>
>>
>>
>> --
>> Eric Bodden
>> Sable Research Group, McGill University, Montréal, Canada
>> Got an interesting job offer? http://www.bodden.de/hire-me/
>
>



-- 
Eric Bodden
Sable Research Group, McGill University, Montréal, Canada
Got an interesting job offer? http://www.bodden.de/hire-me/


More information about the Soot-list mailing list