C: improve incremental compiler performance. Generate text file with list of c files to compile

This commit is contained in:
Alexey Andreev 2019-05-24 12:10:18 +03:00
parent 28c0cc6ef2
commit fdb3f5edb1
3 changed files with 68 additions and 17 deletions

View File

@ -76,6 +76,8 @@ import org.teavm.backend.lowlevel.dependency.ExceptionHandlingDependencyListener
import org.teavm.backend.lowlevel.dependency.WeakReferenceDependencyListener;
import org.teavm.backend.lowlevel.transform.CoroutineTransformation;
import org.teavm.backend.lowlevel.transform.WeakReferenceTransformation;
import org.teavm.cache.EmptyMethodNodeCache;
import org.teavm.cache.MethodNodeCache;
import org.teavm.dependency.ClassDependency;
import org.teavm.dependency.DependencyAnalyzer;
import org.teavm.dependency.DependencyListener;
@ -148,6 +150,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
private List<GeneratorFactory> generatorFactories = new ArrayList<>();
private Characteristics characteristics;
private Set<MethodReference> asyncMethods;
private MethodNodeCache astCache = EmptyMethodNodeCache.INSTANCE;
private boolean incremental;
private boolean lineNumbersGenerated;
private SimpleStringPool stringPool;
@ -164,6 +167,10 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
this.lineNumbersGenerated = lineNumbersGenerated;
}
public void setAstCache(MethodNodeCache astCache) {
this.astCache = astCache;
}
@Override
public List<ClassHolderTransformer> getTransformers() {
List<ClassHolderTransformer> transformers = new ArrayList<>();
@ -352,7 +359,9 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
}
emitResource(runtimeHeaderWriter, "runtime.h");
ClassGenerator classGenerator = new ClassGenerator(context, tagRegistry, decompiler);
ClassGenerator classGenerator = new ClassGenerator(context, tagRegistry, decompiler,
controller.getCacheStatus());
classGenerator.setAstCache(astCache);
IntrinsicFactoryContextImpl intrinsicFactoryContext = new IntrinsicFactoryContextImpl(
controller.getUnprocessedClassSource(), controller.getClassLoader(), controller.getServices(),
controller.getProperties());
@ -642,6 +651,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
private void generateAllFile(ListableClassHolderSource classes, List<? extends ValueType> types,
BuildTarget buildTarget) throws IOException {
List<String> allFiles = getGeneratedFiles(classes, types);
BufferedCodeWriter writer = new BufferedCodeWriter(false);
writer.println("#define _XOPEN_SOURCE");
writer.println("#define __USE_XOPEN");
@ -649,23 +660,38 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
IncludeManager includes = new SimpleIncludeManager(writer);
includes.init("all.c");
includes.includePath("runtime.c");
includes.includePath("stringhash.c");
includes.includePath("strings.c");
includes.includePath("callsites.c");
includes.includePath("references.c");
includes.includePath("date.c");
for (String className : classes.getClassNames()) {
includes.includePath(ClassGenerator.fileName(className) + ".c");
for (String file : allFiles) {
includes.includePath(file);
}
for (ValueType type : types) {
includes.includePath(ClassGenerator.fileName(type) + ".c");
}
includes.includePath("main.c");
OutputFileUtil.write(writer, "all.c", buildTarget);
writer = new BufferedCodeWriter(false);
for (String file : allFiles) {
writer.println(file);
}
OutputFileUtil.write(writer, "all.txt", buildTarget);
}
private List<String> getGeneratedFiles(ListableClassHolderSource classes, List<? extends ValueType> types) {
List<String> files = new ArrayList<>();
files.add("runtime.c");
files.add("stringhash.c");
files.add("strings.c");
files.add("callsites.c");
files.add("references.c");
files.add("date.c");
for (String className : classes.getClassNames()) {
files.add(ClassGenerator.fileName(className) + ".c");
}
for (ValueType type : types) {
files.add(ClassGenerator.fileName(type) + ".c");
}
files.add("main.c");
return files;
}
private void generateArrayOfClassReferences(GenerationContext context, CodeWriter writer, IncludeManager includes,

View File

@ -25,10 +25,16 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.teavm.ast.ControlFlowEntry;
import org.teavm.ast.RegularMethodNode;
import org.teavm.ast.decompilation.Decompiler;
import org.teavm.backend.c.generators.Generator;
import org.teavm.backend.lowlevel.generate.ClassGeneratorUtil;
import org.teavm.cache.AstCacheEntry;
import org.teavm.cache.AstDependencyExtractor;
import org.teavm.cache.CacheStatus;
import org.teavm.cache.EmptyMethodNodeCache;
import org.teavm.cache.MethodNodeCache;
import org.teavm.interop.Address;
import org.teavm.interop.DelegateTo;
import org.teavm.interop.NoGcRoot;
@ -77,6 +83,7 @@ public class ClassGenerator {
private GenerationContext context;
private Decompiler decompiler;
private CacheStatus cacheStatus;
private TagRegistry tagRegistry;
private CodeGenerator codeGenerator;
private FieldReference[] staticGcRoots;
@ -87,11 +94,19 @@ public class ClassGenerator {
private CodeWriter headerWriter;
private IncludeManager includes;
private IncludeManager headerIncludes;
private MethodNodeCache astCache = EmptyMethodNodeCache.INSTANCE;
private AstDependencyExtractor dependencyExtractor = new AstDependencyExtractor();
public ClassGenerator(GenerationContext context, TagRegistry tagRegistry, Decompiler decompiler) {
public ClassGenerator(GenerationContext context, TagRegistry tagRegistry, Decompiler decompiler,
CacheStatus cacheStatus) {
this.context = context;
this.tagRegistry = tagRegistry;
this.decompiler = decompiler;
this.cacheStatus = cacheStatus;
}
public void setAstCache(MethodNodeCache astCache) {
this.astCache = astCache;
}
public void prepare(ListableClassHolderSource classes) {
@ -274,7 +289,16 @@ public class ClassGenerator {
}
generateMethodForwardDeclaration(method);
RegularMethodNode methodNode = decompiler.decompileRegular(method);
RegularMethodNode methodNode;
AstCacheEntry entry = astCache.get(method.getReference(), cacheStatus);
if (entry == null) {
methodNode = decompiler.decompileRegular(method);
astCache.store(method.getReference(), new AstCacheEntry(methodNode, new ControlFlowEntry[0]),
() -> dependencyExtractor.extract(methodNode));
} else {
methodNode = entry.method;
}
codeGenerator.generateMethod(methodNode);
if (context.isIncremental()) {

View File

@ -308,6 +308,7 @@ public class IncrementalCBuilder {
long startTime = System.currentTimeMillis();
CTarget cTarget = new CTarget();
cTarget.setAstCache(astCache);
TeaVM vm = new TeaVMBuilder(cTarget)
.setReferenceCache(referenceCache)