1
1
package com .compilerprogramming .ezlang .compiler ;
2
2
3
+ import com .compilerprogramming .ezlang .exceptions .CompilerException ;
3
4
import com .compilerprogramming .ezlang .types .Type ;
4
5
5
6
import java .util .ArrayList ;
@@ -30,11 +31,10 @@ public abstract class Instruction {
30
31
protected Operand [] uses ;
31
32
public BasicBlock block ;
32
33
33
- protected Instruction (int opcode , Operand ... uses ) {
34
+ protected Instruction (int opcode ) {
34
35
this .opcode = opcode ;
35
36
this .def = null ;
36
- this .uses = new Operand [uses .length ];
37
- System .arraycopy (uses , 0 , this .uses , 0 , uses .length );
37
+ this .uses = new Operand [0 ];
38
38
}
39
39
protected Instruction (int opcode , Operand .RegisterOperand def , Operand ... uses ) {
40
40
this .opcode = opcode ;
@@ -49,9 +49,23 @@ public String toString() {
49
49
return toStr (new StringBuilder ()).toString ();
50
50
}
51
51
52
+ /**
53
+ * Does this instruction define a var?
54
+ */
52
55
public boolean definesVar () { return def != null ; }
56
+ /**
57
+ * If the instruction defines a var then return the Register else null
58
+ */
53
59
public Register def () { return def != null ? def .reg : null ; }
60
+ public void replaceDef (Register newDef ) {
61
+ if (def == null ) throw new IllegalStateException ();
62
+ def = def .copy (newDef );
63
+ }
54
64
65
+ /**
66
+ * Get the registers used by this instruction. Non register operands are
67
+ * not included.
68
+ */
55
69
public List <Register > uses () {
56
70
List <Register > useList = null ;
57
71
for (int i = 0 ; i < uses .length ; i ++) {
@@ -64,10 +78,14 @@ public List<Register> uses() {
64
78
if (useList == null ) useList = Collections .emptyList ();
65
79
return useList ;
66
80
}
67
- public void replaceDef (Register newReg ) {
68
- if (def == null ) throw new IllegalStateException ();
69
- def = def .copy (newReg );
70
- }
81
+
82
+ /**
83
+ * Replaces existing register uses with new ones. This api is not great
84
+ * as it requires user to supply registers in the same order as returned by
85
+ * the method {@link #uses()}.
86
+ *
87
+ * FIXME replace this with a better api
88
+ */
71
89
public void replaceUses (Register [] newUses ) {
72
90
int j = 0 ;
73
91
for (int i = 0 ; i < uses .length ; i ++) {
@@ -76,7 +94,14 @@ public void replaceUses(Register[] newUses) {
76
94
uses [i ] = registerOperand .copy (newUses [j ++]);
77
95
}
78
96
}
97
+ // Sanity check that we replaced the full set of registers
98
+ if (j != newUses .length )
99
+ throw new CompilerException ("Error - supplied registers do not replace all uses" );
79
100
}
101
+
102
+ /**
103
+ * Replaces all occurrences of source with target in the uses list of the instruction
104
+ */
80
105
public boolean replaceUse (Register source , Register target ) {
81
106
boolean replaced = false ;
82
107
for (int i = 0 ; i < uses .length ; i ++) {
@@ -88,23 +113,18 @@ public boolean replaceUse(Register source, Register target) {
88
113
}
89
114
return replaced ;
90
115
}
91
- public void replaceWithConstant (Register register , Operand .ConstantOperand constantOperand ) {
116
+
117
+ /**
118
+ * Replaces all uses of given register with the constant operand
119
+ */
120
+ public void replaceUseWithConstant (Register register , Operand .ConstantOperand constantOperand ) {
92
121
for (int i = 0 ; i < uses .length ; i ++) {
93
122
Operand operand = uses [i ];
94
123
if (operand != null && operand instanceof Operand .RegisterOperand registerOperand && registerOperand .reg .id == register .id ) {
95
124
uses [i ] = constantOperand ;
96
125
}
97
126
}
98
127
}
99
- public static class NoOp extends Instruction {
100
- public NoOp () {
101
- super (I_NOOP );
102
- }
103
- @ Override
104
- public StringBuilder toStr (StringBuilder sb ) {
105
- return sb .append ("noop" );
106
- }
107
- }
108
128
109
129
public static class Move extends Instruction {
110
130
public Move (Operand from , Operand to ) {
@@ -384,7 +404,7 @@ public Register def() {
384
404
throw new UnsupportedOperationException ();
385
405
}
386
406
@ Override
387
- public void replaceDef (Register newReg ) {
407
+ public void replaceDef (Register newDef ) {
388
408
throw new UnsupportedOperationException ();
389
409
}
390
410
@ Override
0 commit comments