mirror of https://gitlab.com/camelot/kickc.git
Working on ASM fragment template interface and implementation. Currently synthesizing even simple fragments uses up all memory.
This commit is contained in:
parent
7234060c41
commit
03150c83c3
|
@ -23,15 +23,7 @@ public interface AsmFragmentTemplate {
|
|||
* @return The target CPU
|
||||
*/
|
||||
TargetCpu getTargetCpu();
|
||||
|
||||
/**
|
||||
* Get the ASM body as a string.
|
||||
* The ASM body contains parameter placeholders where bindings will be used to place actual values.
|
||||
*
|
||||
* @return The ASM body
|
||||
*/
|
||||
String getBody();
|
||||
|
||||
|
||||
/**
|
||||
* Get the ASM body as parsed ASM.
|
||||
* The ASM body contains parameter placeholders where bindings will be used to place actual values.
|
||||
|
|
|
@ -47,7 +47,7 @@ public class AsmFragmentTemplateCache {
|
|||
|
||||
/** Special singleton representing that the fragment can not be synthesized or loaded. */
|
||||
public static AsmFragmentTemplate NO_SYNTHESIS =
|
||||
new AsmFragmentTemplateImpl(new AsmFragmentSignature.Singleton("NO_SYNTHESIS"), "NO_SYNTHESIS", null, null, null, null);
|
||||
new AsmFragmentTemplateImpl(new AsmFragmentSignature.Singleton("NO_SYNTHESIS"), null, null, null, null);
|
||||
|
||||
/** Prefix for the fragment hash file header. */
|
||||
public static final String HASH_HEADER = "//KICKC FRAGMENT CACHE ";
|
||||
|
@ -184,7 +184,7 @@ public class AsmFragmentTemplateCache {
|
|||
private static void addFragment(LinkedHashMap<AsmFragmentSignature, AsmFragmentTemplate> cache, String signatureText, StringBuilder body, TargetCpu targetCpu) {
|
||||
AsmFragmentSignature signature = AsmFragmentSignature.parse(signatureText);
|
||||
final String bodyString = body.toString();
|
||||
if(bodyString.startsWith(NO_SYNTHESIS.getBody())) {
|
||||
if(bodyString.startsWith("NO_SYNTHESIS")) {
|
||||
cache.put(signature, NO_SYNTHESIS);
|
||||
} else {
|
||||
AsmFragmentTemplate template = AsmFragmentTemplateParser.parse(signature, AsmFragmentTemplateParser.fixNewlines(bodyString), targetCpu);
|
||||
|
@ -215,10 +215,12 @@ public class AsmFragmentTemplateCache {
|
|||
AsmFragmentTemplate fragmentTemplate = this.cache.get(signature);
|
||||
fragmentFilePrint.println(FRAGMENT_HEADER + signature);
|
||||
if(fragmentTemplate == NO_SYNTHESIS) {
|
||||
fragmentFilePrint.println(NO_SYNTHESIS.getBody());
|
||||
fragmentFilePrint.println("NO_SYNTHESIS");
|
||||
} else {
|
||||
if(fragmentTemplate.getBody() != null)
|
||||
fragmentFilePrint.println(fragmentTemplate.getBody());
|
||||
if(fragmentTemplate.getBodyAsm() != null) {
|
||||
final String bodyString = AsmTemplateBodyPrinter.print(fragmentTemplate.getBodyAsm());
|
||||
fragmentFilePrint.println(bodyString);
|
||||
}
|
||||
}
|
||||
}
|
||||
fragmentFilePrint.close();
|
||||
|
|
|
@ -16,8 +16,6 @@ public class AsmFragmentTemplateImpl implements AsmFragmentTemplate {
|
|||
private final AsmFragmentSignature signature;
|
||||
/** The target CPU. */
|
||||
private final TargetCpu targetCpu;
|
||||
/** The fragment template body */
|
||||
private final String body;
|
||||
|
||||
/** The parsed ASM lines. Initially null. Non-null after the template is used to generate ASM code. */
|
||||
private final KickCParser.AsmLinesContext bodyAsm;
|
||||
|
@ -26,9 +24,8 @@ public class AsmFragmentTemplateImpl implements AsmFragmentTemplate {
|
|||
/** The cycles consumed by the ASM of the fragment. Initially null. Non-null after the template is used to generate ASM code. */
|
||||
private final Double cycles;
|
||||
|
||||
AsmFragmentTemplateImpl(AsmFragmentSignature signature, String body, TargetCpu targetCpu, KickCParser.AsmLinesContext bodyAsm, AsmFragmentClobber clobber, Double cycles) {
|
||||
AsmFragmentTemplateImpl(AsmFragmentSignature signature, TargetCpu targetCpu, KickCParser.AsmLinesContext bodyAsm, AsmFragmentClobber clobber, Double cycles) {
|
||||
this.signature = signature;
|
||||
this.body = body;
|
||||
this.targetCpu = targetCpu;
|
||||
this.bodyAsm = bodyAsm;
|
||||
this.clobber = clobber;
|
||||
|
@ -39,10 +36,6 @@ public class AsmFragmentTemplateImpl implements AsmFragmentTemplate {
|
|||
return signature;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KickCParser.AsmLinesContext getBodyAsm() {
|
||||
return bodyAsm;
|
||||
|
@ -65,11 +58,11 @@ public class AsmFragmentTemplateImpl implements AsmFragmentTemplate {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AsmFragmentTemplateImpl that = (AsmFragmentTemplateImpl) o;
|
||||
return Objects.equals(signature, that.signature) && targetCpu == that.targetCpu && Objects.equals(body, that.body);
|
||||
return signature.equals(that.signature) && targetCpu == that.targetCpu && Objects.equals(bodyAsm, that.bodyAsm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(signature, targetCpu, body);
|
||||
return Objects.hash(signature, targetCpu, bodyAsm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class AsmFragmentTemplateParser {
|
|||
*/
|
||||
public static AsmFragmentTemplate parse(AsmFragmentSignature signature, String body, TargetCpu targetCpu) {
|
||||
final ParsedAsmBody parsedAsmBody = parseAsm(signature, targetCpu, body);
|
||||
final AsmFragmentTemplateImpl asmFragmentTemplate = new AsmFragmentTemplateImpl(signature, body, targetCpu, parsedAsmBody.bodyAsm, parsedAsmBody.clobber, parsedAsmBody.cycles);
|
||||
final AsmFragmentTemplateImpl asmFragmentTemplate = new AsmFragmentTemplateImpl(signature, targetCpu, parsedAsmBody.bodyAsm, parsedAsmBody.clobber, parsedAsmBody.cycles);
|
||||
// assertBodyPrint(signature, body, parsedAsmBody.bodyAsm);
|
||||
return asmFragmentTemplate;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ public class AsmFragmentTemplateParser {
|
|||
* @return The ASM fragment template
|
||||
*/
|
||||
public static AsmFragmentTemplate inline(AsmFragmentSignature signature, KickCParser.AsmLinesContext asmBody, TargetCpu targetCpu) {
|
||||
return new AsmFragmentTemplateImpl(signature, null, targetCpu, asmBody, null, null);
|
||||
return new AsmFragmentTemplateImpl(signature, targetCpu, asmBody, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -207,7 +207,7 @@ public class AsmFragmentTemplateParser {
|
|||
if (signatureName.contains("c6")) bindings.put("c6", new ConstantInteger(360L));
|
||||
if (signatureName.contains("la1")) bindings.put("la1", new Label("@1", scope, true));
|
||||
if (signatureName.startsWith("call_")) bindings.put("la1", new Label("@1", scope, true));
|
||||
final AsmFragmentTemplateImpl fragmentTemplate = new AsmFragmentTemplateImpl(signature, body, targetCpu, bodyAsm, null, null);
|
||||
final AsmFragmentTemplateImpl fragmentTemplate = new AsmFragmentTemplateImpl(signature, targetCpu, bodyAsm, null, null);
|
||||
AsmFragmentInstance fragmentInstance =
|
||||
new AsmFragmentInstance(new Program(), signature, ScopeRef.ROOT, fragmentTemplate, bindings);
|
||||
AsmProgram asm = new AsmProgram(targetCpu);
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||
*/
|
||||
public class AsmTemplateBodyPrinter extends KickCParserBaseVisitor {
|
||||
|
||||
private StringBuffer out;
|
||||
private final StringBuffer out;
|
||||
|
||||
private AsmTemplateBodyPrinter(StringBuffer out) {
|
||||
this.out = out;
|
||||
|
@ -25,7 +25,7 @@ public class AsmTemplateBodyPrinter extends KickCParserBaseVisitor {
|
|||
}
|
||||
|
||||
private void printTags(List<TerminalNode> tags) {
|
||||
tags.stream().forEach(tag -> out.append(" ").append(tag));
|
||||
tags.forEach(tag -> out.append(" ").append(tag));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,6 +2,8 @@ package dk.camelot64.kickc.fragment.synthesis;
|
|||
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentClobber;
|
||||
import dk.camelot64.kickc.fragment.signature.AsmFragmentSignature;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -12,159 +14,187 @@ import java.util.*;
|
|||
*/
|
||||
public class AsmFragmentSynthesis {
|
||||
|
||||
/**
|
||||
* The signature of the fragment template being synthesized.
|
||||
*/
|
||||
private final AsmFragmentSignature signature;
|
||||
/**
|
||||
* The signature of the fragment template being synthesized.
|
||||
*/
|
||||
private final AsmFragmentSignature signature;
|
||||
|
||||
/**
|
||||
* The best template loaded/synthesized so far for each clobber profile
|
||||
*/
|
||||
private final Map<AsmFragmentClobber, AsmFragmentSynthesisResult> bestTemplates;
|
||||
/**
|
||||
* The best template loaded/synthesized so far for each clobber profile
|
||||
*/
|
||||
private final Map<AsmFragmentClobber, AsmFragmentSynthesisResult> bestTemplates;
|
||||
|
||||
/**
|
||||
* Options for synthesizing the template from sub-fragments using a specific synthesis rule. Forward edges in the synthesis graph.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisOption> synthesisOptions;
|
||||
/**
|
||||
* Options for synthesizing the template from sub-fragments using a specific synthesis rule. Forward edges in the synthesis graph.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisOption> synthesisOptions;
|
||||
|
||||
/**
|
||||
* Options for synthesizing the other templates from this template using a specific synthesis rule. Backward edges in the synthesis graph.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisOption> parentOptions;
|
||||
/**
|
||||
* Options for synthesizing the other templates from this template using a specific synthesis rule. Backward edges in the synthesis graph.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisOption> parentOptions;
|
||||
|
||||
/**
|
||||
* The templates loaded from a file. Empty if no file exists for the signature.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisResult> fileTemplates;
|
||||
/**
|
||||
* The templates loaded from a file. Empty if no file exists for the signature.
|
||||
*/
|
||||
private final List<AsmFragmentSynthesisResult> fileTemplates;
|
||||
|
||||
/**
|
||||
* Create a new synthesis
|
||||
*
|
||||
* @param signature The signature of the fragment template to load/synthesize
|
||||
*/
|
||||
AsmFragmentSynthesis(AsmFragmentSignature signature) {
|
||||
this.signature = signature;
|
||||
this.bestTemplates = new LinkedHashMap<>();
|
||||
this.synthesisOptions = new ArrayList<>();
|
||||
this.parentOptions = new ArrayList<>();
|
||||
this.fileTemplates = new ArrayList<>();
|
||||
}
|
||||
/**
|
||||
* Create a new synthesis
|
||||
*
|
||||
* @param signature The signature of the fragment template to load/synthesize
|
||||
*/
|
||||
AsmFragmentSynthesis(AsmFragmentSignature signature) {
|
||||
this.signature = signature;
|
||||
this.bestTemplates = new LinkedHashMap<>();
|
||||
this.synthesisOptions = new ArrayList<>();
|
||||
this.parentOptions = new ArrayList<>();
|
||||
this.fileTemplates = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a synthesis option to the template synthesis.
|
||||
* The synthesis options can be used for synthesizing the template from sub-fragments using a specific synthesis rule.
|
||||
*
|
||||
* @param synthesisOption The option to add
|
||||
*/
|
||||
void addSynthesisOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||
this.synthesisOptions.add(synthesisOption);
|
||||
}
|
||||
/**
|
||||
* Add a synthesis option to the template synthesis.
|
||||
* The synthesis options can be used for synthesizing the template from sub-fragments using a specific synthesis rule.
|
||||
*
|
||||
* @param synthesisOption The option to add
|
||||
*/
|
||||
void addSynthesisOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||
this.synthesisOptions.add(synthesisOption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options for synthesizing the template from sub-fragments using a specific synthesis rule. Forward edges in the synthesis graph.
|
||||
*
|
||||
* @return The options
|
||||
*/
|
||||
Collection<AsmFragmentSynthesisOption> getSynthesisOptions() {
|
||||
return synthesisOptions;
|
||||
}
|
||||
/**
|
||||
* Get the options for synthesizing the template from sub-fragments using a specific synthesis rule. Forward edges in the synthesis graph.
|
||||
*
|
||||
* @return The options
|
||||
*/
|
||||
Collection<AsmFragmentSynthesisOption> getSynthesisOptions() {
|
||||
return synthesisOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a parent. The parent is an option for synthesizing another fragment template from this one using a specific synthesis rule.
|
||||
*
|
||||
* @param synthesisOption Thew parent option to add
|
||||
*/
|
||||
void addParentOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||
this.parentOptions.add(synthesisOption);
|
||||
}
|
||||
/**
|
||||
* Add a parent. The parent is an option for synthesizing another fragment template from this one using a specific synthesis rule.
|
||||
*
|
||||
* @param synthesisOption Thew parent option to add
|
||||
*/
|
||||
void addParentOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||
this.parentOptions.add(synthesisOption);
|
||||
}
|
||||
|
||||
void addFileTemplate(AsmFragmentSynthesisResult fileTemplate) {
|
||||
this.fileTemplates.add(fileTemplate);
|
||||
}
|
||||
void addFileTemplate(AsmFragmentSynthesisResult fileTemplate) {
|
||||
this.fileTemplates.add(fileTemplate);
|
||||
}
|
||||
|
||||
List<AsmFragmentSynthesisResult> getFileTemplates() {
|
||||
return fileTemplates;
|
||||
}
|
||||
List<AsmFragmentSynthesisResult> getFileTemplates() {
|
||||
return fileTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a candidate for best template.
|
||||
* If the candidate is better than the current best for its clobber profile update the best template
|
||||
*
|
||||
* @param candidate The template candidate to examine
|
||||
* @return true if the best template was updated
|
||||
*/
|
||||
boolean bestTemplateCandidate(AsmFragmentSynthesisResult candidate) {
|
||||
AsmFragmentClobber candidateClobber = candidate.getClobber();
|
||||
double candidateCycles = candidate.getCycles();
|
||||
/**
|
||||
* Handle a candidate for best template.
|
||||
* If the candidate is better than the current best for its clobber profile update the best template
|
||||
*
|
||||
* @param candidate The template candidate to examine
|
||||
* @return true if the best template was updated
|
||||
*/
|
||||
boolean bestTemplateCandidate(AsmFragmentSynthesisResult candidate) {
|
||||
|
||||
// Check if any current best templates are better
|
||||
Set<AsmFragmentClobber> bestClobbers = new LinkedHashSet<>(bestTemplates.keySet());
|
||||
for (AsmFragmentClobber bestClobber : bestClobbers) {
|
||||
AsmFragmentSynthesisResult bestTemplate = bestTemplates.get(bestClobber);
|
||||
double bestCycles = bestTemplate.getCycles();
|
||||
if (bestClobber.isTrueSubset(candidateClobber) && bestCycles <= candidateCycles) {
|
||||
// A better template already found - don't update
|
||||
return false;
|
||||
}
|
||||
if (bestClobber.isSubset(candidateClobber) && bestCycles < candidateCycles) {
|
||||
// A better template already found - don't update
|
||||
return false;
|
||||
}
|
||||
if (bestClobber.equals(candidateClobber) && bestCycles == candidateCycles && bestTemplate.getBody().compareTo(candidate.getBody()) <= 0) {
|
||||
// A better template already found - don't update
|
||||
return false;
|
||||
}
|
||||
// Check if any current best templates are better
|
||||
Set<AsmFragmentClobber> bestClobbers = new LinkedHashSet<>(bestTemplates.keySet());
|
||||
for(AsmFragmentClobber bestClobber : bestClobbers) {
|
||||
AsmFragmentSynthesisResult bestTemplate = bestTemplates.get(bestClobber);
|
||||
if(isBetter(bestTemplate, candidate)) return false;
|
||||
}
|
||||
|
||||
}
|
||||
// The candidate is better than some current best!
|
||||
|
||||
// The candidate is better than some of the current best!
|
||||
// Remove any current templates that are worse
|
||||
for(AsmFragmentClobber bestClobber : bestClobbers) {
|
||||
AsmFragmentSynthesisResult bestTemplate = bestTemplates.get(bestClobber);
|
||||
double bestCycles = bestTemplate.getCycles();
|
||||
if(isBetter(candidate, bestTemplate)) {
|
||||
// The candidate is better - remove the current template
|
||||
bestTemplates.remove(bestClobber);
|
||||
}
|
||||
}
|
||||
// Update the current best
|
||||
bestTemplates.put(candidate.getClobber(), candidate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remove any current templates that are worse
|
||||
for (AsmFragmentClobber bestClobber : bestClobbers) {
|
||||
AsmFragmentSynthesisResult bestTemplate = bestTemplates.get(bestClobber);
|
||||
double bestCycles = bestTemplate.getCycles();
|
||||
/**
|
||||
* Determines if a candidate ASM fragment template is better than another template.
|
||||
* <p>
|
||||
* The candidate is better if either
|
||||
* <ul>
|
||||
* <li>The clobber of the candidate is a true subset of the other and the number of cycles spent is smaller</li>
|
||||
* <li>The clobber of the candidate is the same as the other and the number of cycles spent is smaller</li>
|
||||
* <li>The clobber and number of cycles spent is the same but the body is shorter</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param candidate The candidate template
|
||||
* @param other The other template
|
||||
* @return true if the candidate is better
|
||||
*/
|
||||
private boolean isBetter(AsmFragmentSynthesisResult candidate, AsmFragmentSynthesisResult other) {
|
||||
final AsmFragmentClobber candidateClobber = candidate.getClobber();
|
||||
final double candidateCycles = candidate.getCycles();
|
||||
final double otherCycles = other.getCycles();
|
||||
final AsmFragmentClobber otherClobber = other.getClobber();
|
||||
if(candidateClobber.isTrueSubset(otherClobber) && candidateCycles <= otherCycles) {
|
||||
// The candidate template is better
|
||||
return true;
|
||||
}
|
||||
if(candidateClobber.isSubset(otherClobber) && candidateCycles < otherCycles) {
|
||||
// The candidate template is better
|
||||
return false;
|
||||
}
|
||||
if(candidateClobber.equals(otherClobber) && candidateCycles == otherCycles && asmSize(candidate.fragment.getBodyAsm()) < asmSize(other.getFragment().getBodyAsm())) {
|
||||
// The candidate template is better
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (candidateClobber.isTrueSubset(bestClobber) && candidateCycles <= bestCycles) {
|
||||
// The candidate is better - remove the current template
|
||||
bestTemplates.remove(bestClobber);
|
||||
}
|
||||
if (candidateClobber.isSubset(bestClobber) && candidateCycles < bestCycles) {
|
||||
// The candidate is better - remove the current template
|
||||
bestTemplates.remove(bestClobber);
|
||||
}
|
||||
if (candidateClobber.equals(bestClobber) && candidateCycles == bestCycles && candidate.getBody().compareTo(bestTemplate.getBody()) <= 0) {
|
||||
// The candidate is better - remove the current template
|
||||
bestTemplates.remove(bestClobber);
|
||||
}
|
||||
/**
|
||||
* Find the size of some ASM
|
||||
*
|
||||
* @param asm The ASM
|
||||
* @return The size of the ASM represented as the number of "nodes" in the ASM body
|
||||
*/
|
||||
private static int asmSize(ParseTree asm) {
|
||||
int size = 1;
|
||||
if(asm instanceof ParserRuleContext) {
|
||||
ParserRuleContext parent = (ParserRuleContext) asm;
|
||||
if(parent.children != null) {
|
||||
for(ParseTree child : parent.children) {
|
||||
size += asmSize(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
// Update the current best
|
||||
bestTemplates.put(candidateClobber, candidate);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Get the parent options.
|
||||
* These are options for synthesizing other templates
|
||||
* from this template using a specific synthesis rule. Backward edges in the synthesis graph.
|
||||
*
|
||||
* @return The parent options.
|
||||
*/
|
||||
List<AsmFragmentSynthesisOption> getParentOptions() {
|
||||
return parentOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent options.
|
||||
* These are options for synthesizing other templates
|
||||
* from this template using a specific synthesis rule. Backward edges in the synthesis graph.
|
||||
*
|
||||
* @return The parent options.
|
||||
*/
|
||||
List<AsmFragmentSynthesisOption> getParentOptions() {
|
||||
return parentOptions;
|
||||
}
|
||||
/**
|
||||
* Get the best fragment templates of the synthesis.
|
||||
* Multiple templates are returned if templates with different clobber profiles exist.
|
||||
*
|
||||
* @return The best templates of the synthesis.
|
||||
*/
|
||||
public Collection<AsmFragmentSynthesisResult> getBestTemplates() {
|
||||
return bestTemplates.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the best fragment templates of the synthesis.
|
||||
* Multiple templates are returned if templates with different clobber profiles exist.
|
||||
*
|
||||
* @return The best templates of the synthesis.
|
||||
*/
|
||||
public Collection<AsmFragmentSynthesisResult> getBestTemplates() {
|
||||
return bestTemplates.values();
|
||||
}
|
||||
|
||||
public AsmFragmentSignature getSignature() {
|
||||
return signature;
|
||||
}
|
||||
public AsmFragmentSignature getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.fragment.synthesis;
|
|||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentClobber;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||
import dk.camelot64.kickc.fragment.AsmTemplateBodyPrinter;
|
||||
import dk.camelot64.kickc.fragment.signature.AsmFragmentSignature;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -91,7 +92,7 @@ public class AsmFragmentSynthesisResult {
|
|||
prefix = "synthesized ";
|
||||
}
|
||||
log.append(indent + prefix + this.getSynthesisDescription() + " - clobber:" + fragment.getClobber().toString() + " cycles:" + fragment.getCycles());
|
||||
log.append(indent + " " + fragment.getBody().replace("\n", "\n" + indent + " "));
|
||||
log.append(indent + " " + getBodyString().replace("\n", "\n" + indent + " "));
|
||||
}
|
||||
|
||||
public AsmFragmentClobber getClobber() {
|
||||
|
@ -102,8 +103,8 @@ public class AsmFragmentSynthesisResult {
|
|||
return fragment.getCycles();
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return fragment.getBody();
|
||||
public String getBodyString() {
|
||||
return AsmTemplateBodyPrinter.print(fragment.getBodyAsm());
|
||||
}
|
||||
|
||||
public AsmFragmentSignature getSignature() {
|
||||
|
|
|
@ -2,6 +2,7 @@ package dk.camelot64.kickc.fragment.synthesis;
|
|||
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateParser;
|
||||
import dk.camelot64.kickc.fragment.AsmTemplateBodyPrinter;
|
||||
import dk.camelot64.kickc.fragment.signature.AsmFragmentSignature;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -127,7 +128,7 @@ class AsmFragmentTemplateSynthesisRuleRegex implements AsmFragmentTemplateSynthe
|
|||
if(asmPrefix != null) {
|
||||
newFragment.append(asmPrefix).append("\n");
|
||||
}
|
||||
String subFragment = subTemplate.getBody();
|
||||
String subFragment = AsmTemplateBodyPrinter.print(subTemplate.getBodyAsm());
|
||||
if(bindMappings != null) {
|
||||
if(mapSignature) {
|
||||
// When mapping the signature we do the reverse replacement in the ASM
|
||||
|
|
|
@ -251,7 +251,7 @@ public class TestFragments {
|
|||
}
|
||||
|
||||
log.append(prefix + template.getSynthesisDescription() + " - clobber:" + template.getClobber().toString() + " cycles:" + template.getCycles());
|
||||
log.append(" " + template.getBody().replace("\n", "\n "));
|
||||
log.append(" " + template.getBodyString().replace("\n", "\n "));
|
||||
}
|
||||
}
|
||||
// Print some information about the testing to stdout
|
||||
|
|
|
@ -3131,7 +3131,7 @@ public class TestProgramsFast extends TestPrograms {
|
|||
|
||||
@Test
|
||||
public void testSimpleLoop() throws IOException {
|
||||
compileAndCompare("simple-loop.c");
|
||||
compileAndCompare("simple-loop.c", log());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue