KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > sc > Optimizer


1 /***
2  * Optimizer.java
3  *
4  * Description: Peep-hole optimizer for the assembler
5  */

6
7 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
8 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
9 * Use is subject to license terms. *
10 * J_LZ_COPYRIGHT_END *********************************************************/

11
12 package org.openlaszlo.sc;
13 import java.io.*;
14 import java.nio.*;
15 import java.util.*;
16 import org.openlaszlo.sc.Instructions.*;
17 import org.openlaszlo.sc.Emitter;
18 import org.openlaszlo.sc.StackModel;
19
20 public class Optimizer implements Emitter {
21   Emitter receiver;
22   List instrBlock;
23   StackModel stackModel;
24
25   public Optimizer (Emitter receiver) {
26     this.receiver = receiver;
27     // peephole block
28
this.instrBlock = new ArrayList();
29     // point to last instruction in block, if it is a push
30
// models the data on the stack
31
this.stackModel = new StackModel();
32   }
33
34   public void flush() {
35     if (this.instrBlock.size() != 0) {
36       for (Iterator i = instrBlock.iterator(); i.hasNext(); ) {
37         this.receiver.emit((Instruction)i.next());
38       }
39       this.instrBlock.clear();
40       if (this.stackModel != null) {
41         this.stackModel.clear();
42       } else {
43         this.stackModel = new StackModel();
44       }
45     }
46   }
47
48   public byte[] assemble(List instrs) {
49     for (Iterator i = instrs.iterator(); i.hasNext(); ) {
50       this.emit((Instruction)i.next());
51     }
52     this.flush();
53     return this.receiver.assemble(Collections.EMPTY_LIST);
54   }
55
56   public void emit(Instruction instr) {
57     // Peephole optimizations.
58
// System.out.println("" + this.instrBlock);
59
// System.out.println("" + this.stackModel);
60

61     // The push optimizations create an instruction block across
62
// which pushes may be moved and depend on the model of the
63
// stack which records the instruction that created the data at
64
// the top of the stack. This model is created when a push
65
// instruction is encountered and maintained until no further
66
// optimizations can be made. In the interim, instructions are
67
// passed straight through, without modelling, for efficiency.
68
StackModel model = this.stackModel;
69     List instrBlock = this.instrBlock;
70
71     if (instr instanceof PUSHInstruction) {
72       PUSHInstruction push = (PUSHInstruction)instr;
73       PUSHInstruction last = model.lastPush();
74       // System.out.println("last = " + last);
75
if (last != null) {
76         // PUSH a; PUSH b -> PUSH a, b
77
// a push of a register cannot be moved across other
78
// instructions
79
if ((Instruction)last != (Instruction)instrBlock.get(instrBlock.size() - 1) && push.isVolatile()) {
80           // System.out.println("last: " + last + " instrBlock.get(-1): " + instrBlock.get(instrBlock.size() - 1));
81
;
82         } else if (last.merge(push, model)) {
83           return;
84         }
85       }
86       // Accumulate the instruction and update the model
87
// Copy push, since you will smash it
88
push = new PUSHInstruction(push.args);
89       instrBlock.add(push);
90       this.stackModel = push.updateStackModel(model);
91     } else if (instr instanceof ConcreteInstruction &&
92                ((ConcreteInstruction)instr).op == Actions.DUP) {
93       // PUSH a; DUP -> PUSH a,a
94
PUSHInstruction last = model.lastPush();
95       if (last != null) {
96 // System.out.println("" + this.instrBlock);
97
// System.out.println("" + this.stackModel);
98
if (last.dup(model)) {
99           return;
100         }
101       }
102       // if accumulating, accumulate, else emit straight
103
if (instrBlock.size() != 0) {
104         // Accumulate the instruction and update the model
105
instrBlock.add(instr);
106         this.stackModel = instr.updateStackModel(model);
107       } else {
108         this.receiver.emit(instr);
109       }
110       // TBD: INC, DEC
111
} else {
112       // if accumulating, accumulate, else emit straight
113
if (instrBlock.size() != 0) {
114         // Accumulate the instruction and update the model
115
instrBlock.add(instr);
116         this.stackModel = instr.updateStackModel(model);
117       } else {
118         this.receiver.emit(instr);
119       }
120     }
121     // If the stackModel becomes unknown, flush the block
122
if (this.stackModel == null) {
123       this.flush();
124     }
125   }
126 }
127
Popular Tags