Skip to content

Commit 9f4ad1a

Browse files
Merge pull request #44 from CompilerProgramming/son21
Sync upstream Simple project
2 parents 87ee25e + a857461 commit 9f4ad1a

File tree

124 files changed

+1274
-781
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+1274
-781
lines changed

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/IterPeeps.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class IterPeeps {
4949

5050
public IterPeeps( long seed ) { _work = new WorkList<>(seed); }
5151

52+
@SuppressWarnings("unchecked")
5253
public <N extends Node> N add( N n ) { return (N)_work.push(n); }
5354

5455
public void addAll( Ary<Node> ary ) { _work.addAll(ary); }
@@ -126,6 +127,7 @@ private boolean progressOnList(CodeGen code) {
126127
* Classic WorkList, with a fast add/remove, dup removal, random pull.
127128
* The Node's nid is used to check membership in the worklist.
128129
*/
130+
@SuppressWarnings("unchecked")
129131
public static class WorkList<E extends Node> {
130132

131133
private Node[] _es;

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/Coalesce.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,6 @@
1010
abstract public class Coalesce {
1111

1212
public static boolean coalesce( int round, RegAlloc alloc ) {
13-
// Convert the 2-D array of bits (a 1-D array of BitSets) into an
14-
// adjacency matrix.
15-
int maxlrg = alloc._LRGS.length;
16-
for( int i=1; i<maxlrg; i++ ) {
17-
BitSet ifg = IFG.IFG.atX(i);
18-
if( ifg != null ) {
19-
LRG lrg0 = alloc._LRGS[i];
20-
for( int lrg = ifg.nextSetBit(0); lrg>=0; lrg=ifg.nextSetBit(lrg+1) ) {
21-
LRG lrg1 = alloc._LRGS[lrg];
22-
lrg0.addNeighbor(lrg1);
23-
lrg1.addNeighbor(lrg0);
24-
}
25-
}
26-
}
2713

2814
// Walk all the splits, looking for coalesce chances
2915
boolean progress = false;
@@ -37,7 +23,7 @@ public static boolean coalesce( int round, RegAlloc alloc ) {
3723
if( v1 != v2 ) {
3824
LRG ov1 = v1, ov2 = v2;
3925
// Get the smaller neighbor count in v1
40-
if( (v1._adj==null ? 0 : v1._adj._len) > (v2._adj==null ? 0 : v2._adj._len) )
26+
if( v1.nadj() > v2.nadj() )
4127
{ v1 = v2; v2 = alloc.lrg(n); }
4228
int v2len = v2._adj==null ? 0 : v2._adj._len;
4329
// See that they do not conflict (coalescing would make a self-conflict)
@@ -58,9 +44,9 @@ public static boolean coalesce( int round, RegAlloc alloc ) {
5844
// Most constrained mask
5945
RegMask mask = v1._mask==v2._mask ? v1._mask : v1._mask.copy().and(v2._mask);
6046
// Check for capacity
61-
if( (v2._adj==null ? 0 : v2._adj._len) >= mask.size() ) {
47+
if( v2.nadj() >= mask.size() ) {
6248
// Fails capacity, will not be trivial colorable
63-
v2._adj.setLen(v2len);
49+
if( v2._adj!=null ) v2._adj.setLen(v2len);
6450
continue;
6551
}
6652

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/CodeGen.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
import java.util.HashMap;
1212
import java.util.IdentityHashMap;
1313

14+
@SuppressWarnings("unchecked")
1415
public class CodeGen {
16+
public static final String PORTS = "com.compilerprogramming.ezlang.compiler.nodes.cpus";
1517
// Last created CodeGen as a global; used all over to avoid passing about a
1618
// "context".
1719
public static CodeGen CODE;
@@ -187,7 +189,8 @@ public CodeGen typeCheck() {
187189

188190
// Convert to target hardware nodes
189191
public int _tInsSel;
190-
public CodeGen instSelect( String base, String cpu, String callingConv ) {
192+
public CodeGen instSelect( String cpu, String callingConv ) { return instSelect(cpu,callingConv,PORTS); }
193+
public CodeGen instSelect( String cpu, String callingConv, String base ) {
191194
assert _phase.ordinal() <= Phase.TypeCheck.ordinal();
192195
_phase = Phase.InstSelect;
193196

@@ -313,16 +316,21 @@ public String reg(Node n) {
313316
// ---------------------------
314317
// Encoding
315318
public int _tEncode;
319+
public boolean _JIT;
316320
public Encoding _encoding;
317-
public CodeGen encode() {
321+
public CodeGen encode(boolean jit) {
318322
assert _phase == Phase.RegAlloc;
319323
_phase = Phase.Encoding;
320324
long t0 = System.currentTimeMillis();
321325
_encoding = new Encoding(this);
326+
_JIT = jit;
322327
_encoding.encode();
323328
_tEncode = (int)(System.currentTimeMillis() - t0);
324329
return this;
325330
}
331+
public CodeGen encode() {
332+
return encode(false);
333+
}
326334
// Encoded binary, no relocation info
327335
public byte[] binary() { return _encoding.bits(); }
328336

@@ -331,12 +339,13 @@ public CodeGen encode() {
331339
public CodeGen exportELF(String fname) throws IOException {
332340
assert _phase == Phase.Encoding;
333341
_phase = Phase.Export;
334-
ElfFile obj = new ElfFile(this);
335-
obj.export(fname);
342+
if( fname == null ) new LinkMem(this).link(); // In memory patching
343+
else new ElfFile(this).export(fname); // External ELF file
336344
return this;
337345
}
338346

339347
// ---------------------------
348+
public boolean _asmLittle=true;
340349
SB asm(SB sb) { return ASMPrinter.print(sb,this); }
341350
public String asm() { return asm(new SB()).toString(); }
342351

seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/codegen/ElfFile.java

Lines changed: 81 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
import com.compilerprogramming.ezlang.compiler.nodes.*;
55
import com.compilerprogramming.ezlang.compiler.sontypes.*;
66

7-
import java.util.Map;
8-
import java.util.HashMap;
7+
import java.io.*;
8+
99
import java.nio.ByteBuffer;
1010
import java.nio.ByteOrder;
11-
import java.io.IOException;
12-
import java.io.FileOutputStream;
13-
import java.io.ByteArrayOutputStream;
14-
import java.io.BufferedOutputStream;
11+
import java.util.HashMap;
12+
import java.util.Map;
1513

1614
public class ElfFile {
1715

@@ -69,6 +67,10 @@ public static class Symbol {
6967
// top 4bits are the "bind", bottom 4 are "type"
7068
int _info;
7169

70+
// bind 1011
71+
// 00001111
72+
// 10110000
73+
7274
Symbol(String name, int parent, int bind, int type) {
7375
_name = name;
7476
_parent = parent;
@@ -78,6 +80,7 @@ public static class Symbol {
7880
void writeHeader(ByteBuffer out) {
7981
out.putInt(_name_pos); // name
8082
out.put((byte) _info); // info
83+
// default visibility
8184
out.put((byte) 0); // other
8285
out.putShort((short) _parent); // shndx
8386
out.putLong(_value); // value
@@ -117,7 +120,7 @@ void writeHeader(ByteBuffer out) {
117120
out.putLong(size()); // size
118121
out.putInt(_link); // link
119122
out.putInt(_info); // info
120-
out.putLong(1); // addralign
123+
out.putLong(16); // addralign
121124
if (_type == 2) {
122125
out.putLong(SYMBOL_SIZE);// entsize
123126
} else if (_type == 4) {
@@ -140,7 +143,7 @@ public static class SymbolSection extends Section {
140143
}
141144

142145
@Override
143-
void writeHeader(ByteBuffer out) {
146+
void writeHeader(ByteBuffer out) {
144147
// points to string table section
145148
_link = 1;
146149

@@ -159,23 +162,22 @@ void push(Symbol s) {
159162
}
160163

161164
@Override
162-
void write(ByteBuffer out) {
165+
void write(ByteBuffer out) {
166+
// Index 0 both designates the first entry in the table and serves as the undefined symbol index
163167
for( int i = 0; i < SYMBOL_SIZE/4; i++ ) {
164168
out.putInt(0);
165169
}
166-
int num=1;
170+
// index is already set
167171
for( Symbol s : _loc ) {
168-
s._index = num++;
169172
s.writeHeader(out);
170173
}
171174
for( Symbol s : _symbols ) {
172-
s._index = num++;
173175
s.writeHeader(out);
174176
}
175177
}
176178

177179
@Override
178-
int size() {
180+
int size() {
179181
return (1 + _symbols.len() + _loc.len()) * SYMBOL_SIZE;
180182
}
181183
}
@@ -210,54 +212,21 @@ private void pushSection(Section s) {
210212
s._index = _sections._len;
211213
}
212214

215+
/* creates function and stores where it starts*/
213216
private final HashMap<SONTypeFunPtr,Symbol> _funcs = new HashMap<>();
214217
private void encodeFunctions(SymbolSection symbols, DataSection text) {
215-
int func_start = 0;
216218
for( int i=0; i<_code._cfg._len; i++ ) {
217-
Node bb = _code._cfg.at(i);
218-
if( bb instanceof FunNode f ) {
219-
// skip until the function ends
220-
while( !(_code._cfg.at(i) instanceof ReturnNode) ) {
221-
i++;
222-
}
223-
224-
Node r = _code._cfg.at(i);
225-
int end = _code._encoding._opStart[r._nid] + _code._encoding._opLen[r._nid];
226-
227-
Symbol func = new Symbol(f._name, text._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
228-
func._size = end - func_start;
229-
func._value = func_start;
230-
symbols.push(func);
231-
_funcs.put(f.sig(), func);
232-
233-
// next function starts where the last one ends
234-
func_start = end;
235-
}
236-
}
237-
}
238-
239-
public final HashMap<SONType,Symbol> _bigCons = new HashMap<>();
240-
private void encodeConstants(SymbolSection symbols, DataSection rdata) {
241-
int cnt = 0;
242-
for (Map.Entry<Node,SONType> e : _code._encoding._bigCons.entrySet()) {
243-
if (_bigCons.get(e.getValue()) != null) {
244-
continue;
245-
}
246-
247-
Symbol glob = new Symbol("GLOB$"+cnt, rdata._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
248-
glob._value = rdata._contents.size();
249-
symbols.push(glob);
250-
251-
SONType t = e.getValue();
252-
if ( t instanceof SONTypeFloat tf ) {
253-
write8(rdata._contents, Double.doubleToLongBits(tf._con));
254-
} else {
255-
throw Utils.TODO();
256-
}
257-
258-
glob._size = rdata._contents.size() - glob._value;
259-
_bigCons.put(e.getValue(), glob);
260-
cnt++;
219+
if( !(_code._cfg.at(i) instanceof FunNode fun) ) continue;
220+
// skip until the function ends
221+
while( !(_code._cfg.at(i) instanceof ReturnNode ret) )
222+
i++;
223+
int end = _code._encoding._opStart[ret._nid] + _code._encoding._opLen[ret._nid];
224+
225+
Symbol func = new Symbol(fun._name, text._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
226+
func._value = _code._encoding._opStart[fun._nid];
227+
func._size = end - func._value;
228+
symbols.push(func);
229+
_funcs.put(fun.sig(), func);
261230
}
262231
}
263232

@@ -271,67 +240,90 @@ public void export(String fname) throws IOException {
271240
SymbolSection symbols = new SymbolSection(".symtab", 2 /* SHT_STRTAB */);
272241
pushSection(symbols);
273242

243+
// zero flag by default
274244
// we've already constructed this entire section in the encoding phase
275245
DataSection text = new DataSection(".text", 1 /* SHT_PROGBITS */, _code._encoding._bits);
276246
text._flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
277247
pushSection(text);
278248

279-
DataSection rdata = new DataSection(".rodata", 1 /* SHT_PROGBITS */);
249+
// Build and write constant pool
250+
Encoding.BAOS cpool = new Encoding.BAOS();
251+
Encoding enc = _code._encoding;
252+
enc.writeConstantPool(cpool,false);
253+
DataSection rdata = new DataSection(".rodata", 1 /* SHT_PROGBITS */, cpool);
280254
rdata._flags = SHF_ALLOC;
281255
pushSection(rdata);
282256

283257
// populate function symbols
284258
encodeFunctions(symbols, text);
285-
// populate big constants
286-
// encodeConstants(symbols, rdata);
259+
260+
int idx = 1;
261+
for( Section s : _sections ) {
262+
Symbol sym = new Symbol(s._name, idx++, SYM_BIND_LOCAL, SYM_TYPE_SECTION);
263+
// we can reuse the same name pos from the actual section
264+
sym._name_pos = s._name_pos;
265+
sym._size = s.size();
266+
symbols.push(sym);
267+
}
268+
269+
// calculate local index
270+
int num = 1;
271+
for( Symbol s : symbols._loc )
272+
s._index = num++;
273+
// extra space for .rela.text
274+
int start_global = num+1; // Add one to skip the final .rela.text local symbol
275+
for( Symbol a: symbols._symbols )
276+
a._index = start_global++;
277+
int bigConIdx = start_global;
278+
start_global += enc._bigCons.size();
287279

288280
// create .text relocations
289281
DataSection text_rela = new DataSection(".rela.text", 4 /* SHT_RELA */);
290-
for( Node n : _code._encoding._externals.keySet()) {
282+
for( Node n : enc._externals.keySet()) {
291283
int nid = n._nid;
292-
String extern = _code._encoding._externals.get(n);
293-
int sym_id = _funcs.get(extern)._index;
294-
int offset = _code._encoding._opStart[nid] + _code._encoding._opLen[nid] - 4;
284+
String extern = enc._externals.get(n);
285+
286+
Symbol sym = new Symbol(extern, 0, SYM_BIND_GLOBAL, SYM_TYPE_NOTYPE);
287+
sym._index = start_global++;
288+
symbols.push(sym);
289+
290+
int offset = enc._opStart[nid] + enc._opLen[nid] - 4;
295291

296292
// u64 offset
297293
write8(text_rela._contents, offset);
298294
// u64 info
299-
write8(text_rela._contents, ((long)sym_id << 32L) | 4L /* PLT32 */);
295+
write8(text_rela._contents, ((long)sym._index << 32L) | 4L /* PLT32 */);
300296
// i64 addend
301297
write8(text_rela._contents, -4);
302298
}
303-
// relocations to constants
304-
if (false) for (Map.Entry<Node,SONType> e : _code._encoding._bigCons.entrySet()) {
305-
int nid = e.getKey()._nid;
306-
int sym_id = _bigCons.get(e.getValue())._index;
307-
int offset = _code._encoding._opStart[nid] + _code._encoding._opLen[nid] - 4;
308299

309-
// u64 offset
310-
write8(text_rela._contents, offset);
311-
// u64 info
312-
write8(text_rela._contents, ((long)sym_id << 32L) | 1L /* PC32 */);
313-
// i64 addend
300+
// Write relocations for the constant pool
301+
for( Encoding.Relo relo : enc._bigCons.values() ) {
302+
Symbol glob = new Symbol("GLOB$"+bigConIdx, rdata._index, SYM_BIND_GLOBAL, SYM_TYPE_FUNC);
303+
glob._value = relo._target;
304+
glob._size = 1 << relo._t.log_size();
305+
glob._index = bigConIdx++;
306+
symbols.push(glob);
307+
write8(text_rela._contents, relo._opStart+relo._off);
308+
write8(text_rela._contents, ((long)glob._index << 32L) | relo._elf );
314309
write8(text_rela._contents, -4);
315310
}
311+
316312
text_rela._flags = SHF_INFO_LINK;
317313
text_rela._link = 2;
318314
text_rela._info = text._index;
319315
pushSection(text_rela);
320316

317+
Symbol sym = new Symbol(text_rela._name, num++, SYM_BIND_LOCAL, SYM_TYPE_SECTION);
318+
sym._name_pos = text_rela._name_pos;
319+
sym._size = text_rela.size();
320+
symbols.push(sym);
321+
321322
// populate string table
322323
for( Section s : _sections ) { s._name_pos = writeCString(strtab, s._name); }
323324
for( Symbol s : symbols._symbols ) { s._name_pos = writeCString(strtab, s._name); }
324325
for( Symbol s : symbols._loc ) { s._name_pos = writeCString(strtab, s._name); }
325326

326-
int idx = 1;
327-
for( Section s : _sections ) {
328-
Symbol sym = new Symbol(s._name, idx++, SYM_BIND_LOCAL, SYM_TYPE_SECTION);
329-
// we can reuse the same name pos from the actual section
330-
sym._name_pos = s._name_pos;
331-
sym._size = s.size();
332-
symbols.push(sym);
333-
}
334-
335327
int size = 64; // ELF header
336328
// size of all section data
337329
for( Section s : _sections ) {
@@ -379,7 +371,10 @@ public void export(String fname) throws IOException {
379371
}
380372
assert out.position() == size;
381373

382-
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fname));
374+
File file = new File(fname);
375+
if( file.getParentFile()!=null )
376+
file.getParentFile().mkdirs();
377+
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
383378
bos.write(out.array());
384379
bos.close();
385380
}

0 commit comments

Comments
 (0)