Skip to content

Commit ec3390d

Browse files
committed
Cleanup main handling
1 parent 90c41e4 commit ec3390d

5 files changed

Lines changed: 37 additions & 32 deletions

File tree

chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@ public CodeGen driver( Phase phase, String cpu, String callingConv ) {
135135
return driver(phase,cpu,callingConv,false,false,0);
136136
if( _srcName == null )
137137
throw new RuntimeException("No source filename provided, so do not know how to name the obj file");
138-
boolean main = !_srcName.contains(".");
139-
return driver( phase, cpu, callingConv, false, main, 0 );
138+
boolean emitEntrySymbol = !_srcName.contains(".");
139+
return driver( phase, cpu, callingConv, false, emitEntrySymbol, 0 );
140140
}
141141
// Write an object file for a specific cpu/os pair
142142

143-
public CodeGen driver( String cpu, String callingConv, boolean inMemory, boolean main ) { return driver(Phase.Export,cpu,callingConv,inMemory,main,0); }
143+
public CodeGen driver( String cpu, String callingConv, boolean inMemory, boolean emitEntrySymbol ) { return driver(Phase.Export,cpu,callingConv,inMemory,emitEntrySymbol,0); }
144144
// Generic driver
145-
public CodeGen driver( Phase phase, String cpu, String callingConv, boolean inMemory, boolean main, int dump ) {
145+
public CodeGen driver( Phase phase, String cpu, String callingConv, boolean inMemory, boolean emitEntrySymbol, int dump ) {
146146
int p1 = phase.ordinal(), p2 = _phase==null ? -1 : _phase.ordinal();
147147
if( p2 < p1 && p2 < Phase.Parse .ordinal() ) { parse(); p2 = dump(dump); }
148148
if( p2 < p1 && p2 < Phase.Iter .ordinal() ) { iter(); p2 = dump(dump); }
@@ -156,10 +156,14 @@ public CodeGen driver( Phase phase, String cpu, String callingConv, boolean inMe
156156
if( p2 < p1 && p2 < Phase.LocalSched.ordinal() ) { localSched();p2 = dump(dump); }
157157
if( p2 < p1 && p2 < Phase.RegAlloc .ordinal() ) { regAlloc(); p2 = dump(dump); }
158158
if( p2 < p1 && p2 < Phase.Encoding .ordinal() ) { encode(); p2 = dump(dump); }
159-
if( p2 < p1 && p2 < Phase.Export .ordinal() ) { exportELF(inMemory,main); p2 = dump(dump); }
159+
if( p2 < p1 && p2 < Phase.Export .ordinal() ) { exportELF(inMemory,emitEntrySymbol); p2 = dump(dump); }
160160
return this;
161161
}
162162

163+
public String entryClinitName() {
164+
return Parser.addClzPrefix(_srcName==null ? "Test" : _srcName)+".<clinit>";
165+
}
166+
163167
// Verbose printing during compilation
164168
private int dump(int dump) {
165169
int p2 = _phase.ordinal();
@@ -672,15 +676,15 @@ public CodeGen encode() {
672676
// ---------------------------
673677
// Exporting to external formats
674678
ElfWriter _elf;
675-
public CodeGen exportELF( boolean inMemory, boolean main ) {
679+
public CodeGen exportELF( boolean inMemory, boolean emitEntrySymbol ) {
676680
assert _phase == Phase.Encoding;
677681
_phase = Phase.Export;
678682
long t0 = System.currentTimeMillis();
679683
if( _encoding!=null ) {
680684
if( inMemory )
681685
new LinkMem(this).link(_encoding); // In memory patching
682686
else
683-
_elf = new ElfWriter(this).export(main);
687+
_elf = new ElfWriter(this).export(emitEntrySymbol);
684688
}
685689
_times[Phase.Export.ordinal()] = System.currentTimeMillis() - t0;
686690
return this;

chapter25/src/main/java/com/seaofnodes/simple/codegen/ElfWriter.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.seaofnodes.simple.codegen;
22

3-
import com.seaofnodes.simple.Parser;
43
import com.seaofnodes.simple.node.*;
54
import com.seaofnodes.simple.type.TypeStruct;
65
import com.seaofnodes.simple.util.Ary;
@@ -196,14 +195,15 @@ void encodeFunctions(StopNode stop, Encoding enc, int text_idx) {
196195
}
197196
}
198197

199-
void symbolMain(int text_idx, Encoding enc) {
200-
String mainName = Parser.addClzPrefix(_code._srcName==null ? "Test" : _code._srcName)+".<clinit>";
198+
void symbolEntryClinit(int text_idx, Encoding enc) {
199+
String entryName = _code.entryClinitName();
201200
for( FunNode fun : _code._linker )
202-
if( fun != null && mainName.equals(fun._name) ) {
201+
if( fun != null && entryName.equals(fun._name) ) {
202+
assert enc.opStart(fun) == 0;
203203
symbol("main",text_idx, SYM_BIND_GLOBAL, SYM_TYPE_FUNC, enc.opStart(fun), 0);
204204
return;
205205
}
206-
throw new IllegalStateException("Missing main function "+mainName);
206+
throw new IllegalStateException("Missing entry <clinit> "+entryName);
207207
}
208208

209209
static void write2( BAOS bits, int op ) {
@@ -256,7 +256,7 @@ public class SimpleSection extends DataSection {
256256

257257
// ------------------------------------------------------------------------
258258

259-
public ElfWriter export(boolean main) {
259+
public ElfWriter export(boolean emitEntrySymbol) {
260260
// Sections are created in the order they are emitted.
261261
_sections = new Ary<>(Section.class);
262262

@@ -282,9 +282,10 @@ public ElfWriter export(boolean main) {
282282

283283
// populate function symbols
284284
symbols.encodeFunctions(_code._stop, _code._encoding, text._index);
285-
// The "main" symbol, starting code is always location 0
286-
if( main )
287-
symbols.symbolMain(text._index,enc);
285+
// Export the source compilation unit <clinit> as the C runtime "main".
286+
// Encoding keeps this function at text offset zero.
287+
if( emitEntrySymbol )
288+
symbols.symbolEntryClinit(text._index,enc);
288289

289290
// create external .text relocations
290291
ReloSection relocations = new ReloSection(text._index);

chapter25/src/main/java/com/seaofnodes/simple/codegen/Encoding.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,13 @@ private void basicBlockLayout( ) {
217217

218218
// Do them all except the <clinit>s
219219
Ary<FunNode> clinits = new Ary<>(FunNode.class);
220-
FunNode main = null;
221-
String mainName = Parser.addClzPrefix(_code._srcName==null ? "Test" : _code._srcName)+".<clinit>";
220+
FunNode entry = null;
221+
String entryName = _code.entryClinitName();
222222
for( FunNode fun : _code._linker ) {
223223
if( fun != null && !fun.isDead() ) {
224224
if( fun.isClz() ) {
225-
if( fun._name.equals(mainName) )
226-
main = fun;
225+
if( fun._name.equals(entryName) )
226+
entry = fun;
227227
else
228228
clinits.add(fun);
229229
} else {
@@ -240,9 +240,9 @@ private void basicBlockLayout( ) {
240240
_rpo_cfg(clinit,visit,rpos);
241241
assert _cfg.at(x) instanceof ReturnNode;
242242
}
243-
if( main != null ) {
243+
if( entry != null ) {
244244
int x = _cfg._len;
245-
_rpo_cfg(main,visit,rpos);
245+
_rpo_cfg(entry,visit,rpos);
246246
assert _cfg.at(x) instanceof ReturnNode;
247247
}
248248

chapter25/src/main/java/com/seaofnodes/simple/node/FunNode.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ public Type compute() {
126126
return Type.CONTROL;
127127
Type t = Type.XCONTROL;
128128
for (int i = 1; i < nIns(); i++) {
129-
// Since no unknown callers, we are not main and the Start input
130-
// will be a Tuple with XControl, so ignore it. Need to be called
131-
// from someplace other than Start
129+
// Since there are no unknown callers, the Start input is only a
130+
// fake hook and will be a Tuple with XControl, so ignore it. Need
131+
// to be called from someplace other than Start.
132132
if( !(in(i) instanceof StartNode) )
133133
t = t.meet(in(i)._type);
134134
}
@@ -138,7 +138,7 @@ public Type compute() {
138138
@Override
139139
public Node idealize() {
140140

141-
// Some linked path dies, except main never kills Start
141+
// Some linked path dies, except unknown caller hooks never kill Start.
142142
Node progress = deadPath(unknownCallers());
143143
if( progress!=null ) {
144144
if( nIns()==2 && in(1) instanceof CallNode call )

chapter25/src/main/java/com/seaofnodes/simple/node/StartNode.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@
99
import java.util.HashSet;
1010

1111
/**
12-
* The Start node represents the external world calling, be it calling main or
13-
* just some linked caller calling.
12+
* The Start node represents the external world calling, be it calling the
13+
* entry <clinit> or just some linked caller calling.
1414
* <p>
1515
* Start initially has 1 input (arg) from outside and the initial control.
1616
* In ch10 we also add mem aliases as structs get defined; each field in struct
1717
* adds a distinct alias to Start's tuple.
1818
* <p>
1919
* By ch25, Start is the external world (or linker) calling with everything
20-
* that has escaped. Start is NOT the FunNode called *main* (which can assume
21-
* no memory nor fidxs exist nor escaped). Start gets escaped things from
22-
* Stop; together these close the Grand Cycle between the code we know and the
23-
* code we don't.
20+
* that has escaped. Start is NOT the entry <clinit> itself, which can assume
21+
* no memory nor fidxs exist nor escaped. Start gets escaped things from Stop;
22+
* together these close the Grand Cycle between the code we know and the code
23+
* we don't.
2424
*/
2525
public class StartNode extends LoopNode implements MultiNode {
2626

0 commit comments

Comments
 (0)