308 lines
8.6 KiB
Java
308 lines
8.6 KiB
Java
// Copyright 2011-2021 XMOS LIMITED.
|
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
|
import java.io.*;
|
|
import java.util.*;
|
|
|
|
class Arrange {
|
|
String labels[] = {
|
|
// "L11d",
|
|
// "L1d",
|
|
// "L111d",
|
|
"L1000",
|
|
"L100",
|
|
"L10",
|
|
"L11100",
|
|
"L11000",
|
|
"L1110",
|
|
"L1100",
|
|
"L110",
|
|
"L111",
|
|
"L1111",
|
|
"L11111",
|
|
"L11111a",
|
|
"L1111111",
|
|
"L111111",
|
|
"L1",
|
|
"L11",
|
|
"L1_S",
|
|
"L11100_S",
|
|
"L11_S",
|
|
"L111_S",
|
|
"L1111_S",
|
|
"L11111_S",
|
|
"L111111_S",
|
|
"L1111111_S",
|
|
"L1_U",
|
|
"L11_U",
|
|
"L111_U",
|
|
"L1111_U",
|
|
"L11111_U",
|
|
"L111111_U",
|
|
"L1111111_U",
|
|
"L1_T",
|
|
"L11_T",
|
|
"L111_T",
|
|
// "L1110_S",
|
|
"L1111100_S",
|
|
"L111110_S",
|
|
};
|
|
|
|
static HashMap<String,Block> entryPoints = new HashMap<String,Block>();
|
|
static Vector<Block> blockVector = new Vector<Block>();
|
|
static int blockCount = 0;
|
|
static int cutOff = 50;
|
|
static Block error =null;
|
|
|
|
void run() {
|
|
entryPoints.put("ERROR", new Block("ERROR", -1));
|
|
entryPoints.put("FASTER", new Block("FASTER", -2));
|
|
entryPoints.put("SLOWER", error = new Block("SLOWER", -3));
|
|
for (String s: labels) {
|
|
Block b = new Block(s, blockCount);
|
|
blockVector.add(b);
|
|
blockCount++;
|
|
b = new Block(b, blockCount);
|
|
blockVector.add(b);
|
|
blockCount++;
|
|
}
|
|
for(Block b: blockVector) {
|
|
b.patchReferences();
|
|
}
|
|
for(Block b: blockVector) {
|
|
if (!b.used) {
|
|
System.err.println("No reference to " + b.bbName);
|
|
}
|
|
}
|
|
for(int i = 0; i < 15; i++) { // 15
|
|
optimise(20); // 20
|
|
System.err.println("Cost " + cost() + " (cutoff " + cutOff + ")");
|
|
if (cost() < 100000) {
|
|
cutOff--;
|
|
}
|
|
}
|
|
copy("headerS");
|
|
for(Block b: blockVector) {
|
|
System.out.println(b.theCode());
|
|
}
|
|
copy("trailerS");
|
|
}
|
|
|
|
int cost() {
|
|
int costs = 0;
|
|
for(int loc = 0; loc < blockCount; loc++) {
|
|
Block b = blockVector.get(loc);
|
|
costs += b.cost();
|
|
}
|
|
return costs;
|
|
}
|
|
|
|
void swapBlocks(int j, int k) {
|
|
Block a = blockVector.get(j);
|
|
Block b = blockVector.get(k);
|
|
blockVector.set(j, b);
|
|
blockVector.set(k, a);
|
|
a.location = k;
|
|
b.location = j;
|
|
}
|
|
|
|
void optimise(int n) {
|
|
|
|
int minCost = cost();
|
|
int minJ = -1;
|
|
int minK = -1;
|
|
for(int i = 0; i < n; i++) {
|
|
System.err.println(" -- Cost " + minCost);
|
|
for(int j = 0; j < blockCount; j++) {
|
|
for(int k = j+1; k < blockCount; k++) {
|
|
swapBlocks(j, k);
|
|
if (cost() < minCost) {
|
|
minJ = j;
|
|
minK = k;
|
|
minCost = cost();
|
|
}
|
|
swapBlocks(j, k);
|
|
}
|
|
}
|
|
if (minJ != -1) {
|
|
swapBlocks(minJ, minK);
|
|
} else {
|
|
break;
|
|
}
|
|
if (minCost < 100000) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void copy(String s) {
|
|
try {
|
|
BufferedReader bi = new BufferedReader(new FileReader("states/" + s));
|
|
while(true) {
|
|
String line = bi.readLine();
|
|
if (line == null) {
|
|
return;
|
|
}
|
|
System.out.println(line);
|
|
}
|
|
} catch (Exception e) {
|
|
System.err.println("Exception " + e + " on " + s);
|
|
}
|
|
}
|
|
|
|
public static void main(String args[]) {
|
|
new Arrange().run();
|
|
}
|
|
}
|
|
|
|
class Block {
|
|
Vector<Block> refs = new Vector<Block>();
|
|
Vector<String> refsI = new Vector<String>();
|
|
String bbName;
|
|
int location;
|
|
boolean used = false;
|
|
String code = "";
|
|
|
|
Block(String s, int location) {
|
|
boolean beforeBru= true;
|
|
bbName = s;
|
|
this.location = location;
|
|
if (!s.startsWith("L")) {
|
|
return;
|
|
}
|
|
try {
|
|
BufferedReader bi = new BufferedReader(new FileReader("states/" + s));
|
|
while(true) {
|
|
String line = bi.readLine();
|
|
if (line == null) {
|
|
return;
|
|
}
|
|
if (beforeBru) {
|
|
code = code + line + "\n";
|
|
}
|
|
if (line.contains("BRU")) {
|
|
beforeBru= false;
|
|
}
|
|
if (line.contains(":")) {
|
|
addEntrypoint(line,this);
|
|
}
|
|
if (!beforeBru) {
|
|
if (line.contains("SLOWER")) {
|
|
addReference("SLOWER");
|
|
} else if (line.contains("FASTER")) {
|
|
addReference("FASTER");
|
|
} else if (line.contains("ERROR")) {
|
|
addReference("ERROR");
|
|
} else if ((line.contains(" BL") || line.contains(" BR")) && line.contains(" L")) {
|
|
addReference(line);
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
System.err.println("Exception " + e + " in " + s);
|
|
}
|
|
}
|
|
|
|
Block(Block b, int location) {
|
|
bbName = inverse(b.bbName);
|
|
String lines[] = b.code.split("\n");
|
|
for(String l: lines) {
|
|
if (l.contains(":")) {
|
|
String i = inverse(l);
|
|
code += i + "\n";
|
|
addEntrypoint(i,this);
|
|
} else if (l.contains(" bf ") || l.contains(" bt ") || l.contains(" bu ") ) {
|
|
code += inverse(l) + "\n";
|
|
} else if (l.contains(" BR")) {
|
|
code += inverse(l) + "\n";
|
|
} else {
|
|
code += l + "\n";
|
|
}
|
|
}
|
|
this.location = location;
|
|
for(String s: b.refsI) {
|
|
refsI.add(0, inverse(s));
|
|
}
|
|
}
|
|
|
|
String inverse(String s) {
|
|
boolean inversing = true;
|
|
String r = "";
|
|
for(int i = 0; i < s.length(); i++) {
|
|
if (inversing && s.charAt(i) == '0') {
|
|
r += '1';
|
|
} else if (inversing && s.charAt(i) == '1') {
|
|
r += '0';
|
|
} else if (s.charAt(i) == '_') {
|
|
r += '_';
|
|
inversing = false;
|
|
} else {
|
|
r += s.charAt(i);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
void addEntrypoint(String line, Block b) {
|
|
String label = line.replaceAll(".* L","L").replaceAll(":.*","");
|
|
Arrange.entryPoints.put(label, b);
|
|
}
|
|
|
|
void addReference(String line) {
|
|
String label1 = line.replaceFirst(".* L","L").replaceAll("[ /].*","");
|
|
String label = label1.replaceAll("[ /].*","").replaceAll("z","");
|
|
// System.out.println("Line " + line + " label " + label1 + " -- " + label);
|
|
refsI.add(label);
|
|
}
|
|
|
|
void patchReferences() {
|
|
for(String s: refsI) {
|
|
Block b = Arrange.entryPoints.get(s);
|
|
if (b == null) {
|
|
System.err.println("Label " + s + " not found in " + bbName);
|
|
refs.add(Arrange.error);
|
|
} else {
|
|
// System.err.println("Label " + s + " found in " + bbName);
|
|
b.used = true;
|
|
refs.add(b);
|
|
}
|
|
}
|
|
}
|
|
|
|
int cost() {
|
|
int costs = 0;
|
|
for(Block b: refs) {
|
|
if (b.location < 0) {
|
|
continue;
|
|
}
|
|
int c = location - b.location;
|
|
if (c < 0) {
|
|
c = -c;
|
|
}
|
|
if (c > Arrange.cutOff) {
|
|
c += 100000;
|
|
}
|
|
costs += c;
|
|
}
|
|
return costs;
|
|
}
|
|
|
|
String theCode() {
|
|
int k =0;
|
|
for(Block b : refs) {
|
|
if (b.location < 0) {
|
|
if (location < Arrange.blockCount / 2) {
|
|
code += " BLRB_u10 B" + b.bbName + "\n";
|
|
} else {
|
|
code += " BLRF_u10 F" + b.bbName + "\n";
|
|
}
|
|
} else if (b.location <= location) {
|
|
code += " BLRB_u10 " + refsI.get(k) + "\n";
|
|
} else {
|
|
code += " BLRF_u10 " + refsI.get(k) + "\n";
|
|
}
|
|
k++;
|
|
}
|
|
return code;
|
|
}
|
|
}
|