Skip to content

Commit

Permalink
Imclin: Reorder basic blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Lenart12 committed Apr 12, 2023
1 parent a3eb49b commit 7cb4de5
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 7 deletions.
21 changes: 16 additions & 5 deletions prev23/src/prev23/phase/imcgen/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -283,22 +283,28 @@ public ImcInstr visit(AstExprStmt exprStmt, Boolean is_return) {

@Override
public ImcInstr visit(AstIfStmt ifStmt, Boolean is_return) {
var start_label = new MemLabel();
var positive_label = new MemLabel();
var negative_label = new MemLabel();
var end_label = new MemLabel();
var negative_label = (ifStmt.elseStmt != null) ? new MemLabel() : end_label;

var stmts = new Vector<>(List.of(
new ImcJUMP(start_label),
new ImcLABEL(start_label),
new ImcCJUMP(accept_expr(ifStmt.cond), positive_label, negative_label),
new ImcLABEL(positive_label),
accept_stmt(ifStmt.thenStmt, false),
new ImcJUMP(end_label),
new ImcLABEL(negative_label)
));

if (ifStmt.elseStmt != null) stmts.addAll(List.of(
accept_stmt(ifStmt.elseStmt, false),
new ImcJUMP(end_label),
new ImcLABEL(end_label)
if (ifStmt.elseStmt != null) stmts.add(
accept_stmt(ifStmt.elseStmt, false)
);

stmts.addAll(List.of(
new ImcJUMP(end_label),
new ImcLABEL(end_label)
));

return declare_stmt(ifStmt, new ImcSTMTS(stmts), is_return);
Expand All @@ -316,10 +322,15 @@ public ImcInstr visit(AstStmts stmts, Boolean is_return) {

@Override
public ImcInstr visit(AstWhileStmt whileStmt, Boolean is_return) {
var start_label = new MemLabel();
var condition_label = new MemLabel();
var body_label = new MemLabel();
var end_label = new MemLabel();

return declare_stmt(whileStmt, new ImcSTMTS(new Vector<>(List.of(
new ImcJUMP(start_label),
new ImcLABEL(start_label),
new ImcJUMP(condition_label),
new ImcLABEL(condition_label),
new ImcCJUMP(accept_expr(whileStmt.cond), body_label, end_label),
new ImcLABEL(body_label),
Expand Down
93 changes: 92 additions & 1 deletion prev23/src/prev23/phase/imclin/ChunkGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.*;

import prev23.common.report.Report;
import prev23.data.ast.tree.decl.*;
import prev23.data.ast.tree.expr.*;
import prev23.data.ast.visitor.*;
Expand All @@ -26,7 +27,9 @@ public Object visit(AstFunDecl funDecl, Object o) {
body.add(0, new ImcLABEL(entry_label));
body.add(new ImcJUMP(exit_label));

ImcLin.addCodeChunk(new LinCodeChunk(frame, body, entry_label, exit_label));
var fixed = fix_basic_blocks(body, entry_label, exit_label);

ImcLin.addCodeChunk(new LinCodeChunk(frame, fixed, entry_label, exit_label));

funDecl.stmt.accept(this, o);

Expand All @@ -53,4 +56,92 @@ public Object visit(AstAtomExpr atomExpr, Object o) {
}
return null;
}

private Vector<ImcStmt> fix_basic_blocks(Vector<ImcStmt> stmts, MemLabel entry_label, MemLabel exit_label) {
HashMap<MemLabel, Vector<ImcStmt>> basic_blocks = new HashMap<>();

Vector<ImcStmt> block = null;

for (var stmt : stmts) {
if (stmt instanceof ImcLABEL label) {
if (block != null) {
throw new Report.InternalError();
}
block = new Vector<>();
basic_blocks.put(label.label, block);
}

// Skip dead code
if (block == null) continue;

block.add(stmt);

if (stmt instanceof ImcJUMP || stmt instanceof ImcCJUMP) {
block = null;
}
}

if (block != null) {
throw new Report.InternalError();
}

var fixed = new Vector<ImcStmt>();

// Insert basic blocks starting with entry_label
var next_blocks = new LinkedList<MemLabel>();
next_blocks.addFirst(entry_label);
while(!next_blocks.isEmpty()) {
var next_block_label = next_blocks.removeFirst();

// Skip exit block
if (next_block_label.name.equals(exit_label.name)) continue;

var next_block = basic_blocks.get(next_block_label);

if (next_block == null) {
continue;
}

fixed.addAll(next_block);
basic_blocks.remove(next_block_label);

var next_jump = next_block.lastElement();

if (next_jump instanceof ImcJUMP jump) {
next_blocks.addFirst(jump.label);
} else if (next_jump instanceof ImcCJUMP cjump) {
next_blocks.addFirst(cjump.posLabel);
next_blocks.addFirst(cjump.negLabel);
}
}

var targeted_labels = new HashSet<MemLabel>();
targeted_labels.add(entry_label);
// Remove sequential JUMP L -> LABEL L
for (int i = 0; i < fixed.size(); i++) {
if (fixed.get(i) instanceof ImcCJUMP cjump) {
targeted_labels.add(cjump.posLabel);
targeted_labels.add(cjump.negLabel);
} else if (fixed.get(i) instanceof ImcJUMP jump) {
if (i + 1 < fixed.size() && fixed.get(i + 1) instanceof ImcLABEL label && jump.label == label.label) {
fixed.remove(i--);
} else {
targeted_labels.add(jump.label);
}
}
}

var removed = 0;
// Remove unused labels
for (int i = 0; i < fixed.size(); i++) {
if (fixed.get(i) instanceof ImcLABEL label) {
if (!targeted_labels.contains(label.label)) {
fixed.remove(i--);
removed++;
}
}
}

return fixed;
}
}
2 changes: 1 addition & 1 deletion prev23/src/prev23/phase/memory/MemEvaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public Object visit(AstAtomExpr atomExpr, MemScope scope) {
return null;

var value = atomExpr.value.replace("\\\"", "\"");
var const_size = (value.length() + 1) * (new SemChar().size());
var const_size = (value.length() - 1) * (new SemChar().size());

Memory.strings.put(atomExpr, new MemAbsAccess(const_size, new MemLabel(), value));
return null;
Expand Down

0 comments on commit 7cb4de5

Please sign in to comment.