Skip to content

Commit

Permalink
[GR-15684] First steps in cross-compilation from Darwin to Aarch64 fo…
Browse files Browse the repository at this point in the history
…r LLVM.

PullRequest: graal/3527
  • Loading branch information
vjovanov committed May 4, 2019
2 parents af03ea8 + 57f0348 commit f7bd11a
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 26 deletions.
2 changes: 2 additions & 0 deletions compiler/mx.compiler/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@
"sourceDirs" : ["src"],
"dependencies" : [
"org.graalvm.compiler.core",
"org.graalvm.compiler.lir.aarch64",
"LLVM_WRAPPER",
"LLVM_PLATFORM_SPECIFIC",
],
Expand Down Expand Up @@ -2478,6 +2479,7 @@

"GRAAL_LLVM" : {
"subDir" : "src",
"description" : "LLVM compiler backend",
"dependencies" : ["org.graalvm.compiler.core.llvm"],
"distDependencies" : [
"GRAAL",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@
import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.VirtualStackSlot;
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.phases.util.Providers;

import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterAttributes;
Expand Down Expand Up @@ -946,7 +948,8 @@ public LIRKind getLIRKind(Stamp stamp) {

@Override
public void emitPause() {
throw unimplemented();
// this will be implemented as part of issue #1126. For now, we just do nothing.
// throw unimplemented();
}

@Override
Expand Down Expand Up @@ -1038,7 +1041,7 @@ int getDebugLevel() {
return debugLevel;
}

public static class ArithmeticLLVMGenerator implements ArithmeticLIRGeneratorTool {
public static class ArithmeticLLVMGenerator implements ArithmeticLIRGeneratorTool, AArch64ArithmeticLIRGeneratorTool {
private final LLVMIRBuilder builder;

ArithmeticLLVMGenerator(LLVMIRBuilder builder) {
Expand Down Expand Up @@ -1287,7 +1290,10 @@ public Value emitMathPow(Value x, Value y) {

@Override
public Value emitBitCount(Value operand) {
throw unimplemented();
LLVMValueRef op = getVal(operand);
LLVMValueRef answer = builder.buildCtpop(op);
answer = builder.buildIntegerConvert(answer, LLVMIRBuilder.integerTypeWidth(builder.intType()));
return new LLVMVariable(answer);
}

@Override
Expand Down Expand Up @@ -1333,5 +1339,33 @@ public Variable emitLoad(LIRKind kind, Value address, LIRFrameState state) {
public void emitStore(ValueKind<?> kind, Value address, Value input, LIRFrameState state) {
builder.buildStore(getVal(input), getVal(address));
}

@Override
public Value emitCountLeadingZeros(Value value) {
LLVMValueRef op = getVal(value);
LLVMValueRef answer = builder.buildCtlz(op);
answer = builder.buildIntegerConvert(answer, LLVMIRBuilder.integerTypeWidth(builder.intType()));
return new LLVMVariable(answer);
}

@Override
public Value emitCountTrailingZeros(Value value) {
LLVMValueRef op = getVal(value);
LLVMValueRef answer = builder.buildCttz(op);
answer = builder.buildIntegerConvert(answer, LLVMIRBuilder.integerTypeWidth(builder.intType()));
return new LLVMVariable(answer);
}

@Override
@SuppressWarnings("unused")
public Value emitRound(Value value, RoundingMode mode) {
// This should be implemented, see #1168
return null;
}

@SuppressWarnings("unused")
public void emitCompareOp(AArch64Kind cmpKind, Variable left, Value right) {
// This should be implemented, see #1168
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ LLVMValueRef buildCall(LLVMValueRef callee, long statepointId, LLVMValueRef... a
result = buildCall(callee, args);
addCallSiteAttribute(result, "statepoint-id", Long.toString(statepointId));
} else {

LLVMTypeRef calleeType = typeOf(callee);
LLVMTypeRef statepointType = functionType(tokenType(), true, longType(), intType(), calleeType, intType(), intType());

Expand All @@ -566,6 +567,7 @@ LLVMValueRef buildCall(LLVMValueRef callee, long statepointId, LLVMValueRef... a
LLVMTypeRef resultType = getReturnType(LLVM.LLVMGetElementType(calleeType));
LLVMTypeRef gcResultType = functionType(resultType, tokenType());
result = buildIntrinsicCall("llvm.experimental.gc.result." + intrinsicType(resultType), gcResultType, token);

}
return result;
}
Expand Down Expand Up @@ -858,6 +860,10 @@ LLVMValueRef buildCttz(LLVMValueRef a) {
return buildIntrinsicOp("cttz", a, constantBoolean(true));
}

LLVMValueRef buildCtpop(LLVMValueRef a) {
return buildIntrinsicOp("ctpop", a);
}

/* Conversions */

public LLVMValueRef buildBitcast(LLVMValueRef value, LLVMTypeRef type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@

public class AArch64GraphBuilderPlugins {

public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, boolean registerMathPlugins) {
public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
boolean registerMathPlugins) {
register(plugins, bytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, true);
}

public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
boolean registerMathPlugins, boolean emitJDK9StringSubstitutions) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
Expand All @@ -69,8 +75,10 @@ public void run() {
if (registerMathPlugins) {
registerMathPlugins(invocationPlugins);
}
registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
if (emitJDK9StringSubstitutions) {
registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
}
registerUnsafePlugins(invocationPlugins, bytecodeProvider);
// This is temporarily disabled until we implement correct emitting of the CAS
// instructions of the proper width.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,22 @@ class DARWIN_AMD64 implements DARWIN, InternalPlatform.DARWIN_AND_JNI, AMD64 {
*/
public DARWIN_AMD64() {
}
}

/**
* Supported leaf platform: Darwin (MacOS) on AArch 64-bit.
*
* @since 2.0
*/
final class DARWIN_AArch64 implements DARWIN, InternalPlatform.DARWIN_AND_JNI, AArch64 {

/**
* Instantiates a marker instance of this platform.
*
* @since 2.0
*/
public DARWIN_AArch64() {
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,7 @@

"SVM_LLVM" : {
"subDir" : "src",
"description" : "LLVM backend for Native Image",
"dependencies" : ["com.oracle.svm.core.graal.llvm"],
"distDependencies" : [
"SVM",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public SubstrateBackend newBackend(Providers newProviders) {
});
ImageSingletons.add(NativeImageCodeCacheFactory.class, new NativeImageCodeCacheFactory() {
@Override
public NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap) {
return new LLVMNativeImageCodeCache(compileQueue.getCompilations(), heap);
public NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap, Platform platform) {
return new LLVMNativeImageCodeCache(compileQueue.getCompilations(), heap, platform);
}
});
ImageSingletons.add(SnippetRuntime.ExceptionStackFrameVisitor.class, new SnippetRuntime.ExceptionStackFrameVisitor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -100,8 +102,8 @@ public class LLVMNativeImageCodeCache extends NativeImageCodeCache {
private LLVMStackMapInfo info;
private HostedMethod firstMethod;

public LLVMNativeImageCodeCache(Map<HostedMethod, CompilationResult> compilations, NativeImageHeap imageHeap) {
super(compilations, imageHeap);
public LLVMNativeImageCodeCache(Map<HostedMethod, CompilationResult> compilations, NativeImageHeap imageHeap, Platform targetPlatform) {
super(compilations, imageHeap, targetPlatform);
}

@Override
Expand Down Expand Up @@ -401,21 +403,22 @@ private Path writeBitcode(DebugContext debug, Path basePath, String imageName) {
return outputPath;
}

private static void llvmOptimize(DebugContext debug, String outputPath, String inputPath) {
private void llvmOptimize(DebugContext debug, String outputPath, String inputPath) {
try {
List<String> cmd = new ArrayList<>();
cmd.add("opt");
/*
* Mem2reg has to be run before rewriting statepoints as it promotes allocas, which are
* not supported for statepoints.
*/
cmd.add("-mem2reg");
cmd.add("-rewrite-statepoints-for-gc");
cmd.add("-always-inline");
if (Platform.AMD64.class.isInstance(targetPlatform)) {
cmd.add("-mem2reg");
cmd.add("-rewrite-statepoints-for-gc");
cmd.add("-always-inline");
}
cmd.add("-o");
cmd.add(outputPath);
cmd.add(inputPath);

ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
Expand All @@ -433,20 +436,24 @@ private static void llvmOptimize(DebugContext debug, String outputPath, String i
}
}

private static void llvmCompile(DebugContext debug, String outputPath, String inputPath) {
private void llvmCompile(DebugContext debug, String outputPath, String inputPath) {
try {
List<String> cmd = new ArrayList<>();
cmd.add("llc");
cmd.add("-relocation-model=pic");

/* X86 call frame optimization causes variable sized stack frames */
cmd.add("-no-x86-call-frame-opt");
if (Platform.AMD64.class.isInstance(targetPlatform)) {
cmd.add("-no-x86-call-frame-opt");
}
if (Platform.AArch64.class.isInstance(targetPlatform)) {
cmd.add("-march=arm64");
}
cmd.add("-O2");
cmd.add("-filetype=obj");
cmd.add("-o");
cmd.add(outputPath);
cmd.add(inputPath);

ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
Expand Down Expand Up @@ -503,6 +510,16 @@ protected void defineMethodSymbol(String name, Element section, HostedMethod met
@Override
public String[] getCCInputFiles(Path tempDirectory, String imageName) {
String relocatableFileName = tempDirectory.resolve(imageName + ObjectFile.getFilenameSuffix()).toString();
try {
Path src = Paths.get(bitcodeFileName);
Path parent = Paths.get(relocatableFileName).getParent();
if (parent != null) {
Path dst = parent.resolve(src.getFileName());
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new GraalError("Error copying " + bitcodeFileName + ": " + e);
}
return new String[]{relocatableFileName, bitcodeFileName};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ public class NativeImageGenerator {
private AbstractBootImage image;
private AtomicBoolean buildStarted = new AtomicBoolean();

private Platform targetPlatform;

public NativeImageGenerator(ImageClassLoader loader, HostedOptionProvider optionProvider) {
this.loader = loader;
this.featureHandler = new FeatureHandler();
Expand Down Expand Up @@ -600,7 +602,7 @@ private void doRun(Map<Method, CEntryPointData> entryPoints, Method mainEntryPoi
/* release memory taken by graphs for the image writing */
hUniverse.getMethods().forEach(HostedMethod::clear);

codeCache = NativeImageCodeCacheFactory.get().newCodeCache(compileQueue, heap);
codeCache = NativeImageCodeCacheFactory.get().newCodeCache(compileQueue, heap, targetPlatform);
codeCache.layoutConstants();
codeCache.layoutMethods(debug, imageName);

Expand Down Expand Up @@ -789,9 +791,9 @@ private void setupNativeImage(String imageName, OptionValues options, Map<Method
ForkJoinPool analysisExecutor, SnippetReflectionProvider originalSnippetReflection, DebugContext debug) {
try (Indent ignored = debug.logAndIndent("setup native-image builder")) {
try (StopTimer ignored1 = new Timer(imageName, "setup").start()) {
Platform platform = defaultPlatform(loader.getClassLoader());
SubstrateTargetDescription target = createTarget(platform);
ImageSingletons.add(Platform.class, platform);
this.targetPlatform = defaultPlatform(loader.getClassLoader());
SubstrateTargetDescription target = createTarget(targetPlatform);
ImageSingletons.add(Platform.class, targetPlatform);
ImageSingletons.add(SubstrateTargetDescription.class, target);

if (javaMainSupport != null) {
Expand All @@ -818,7 +820,7 @@ private void setupNativeImage(String imageName, OptionValues options, Map<Method

AnnotationSubstitutionProcessor annotationSubstitutions = createDeclarativeSubstitutionProcessor(originalMetaAccess, loader, classInitializaitonSupport);
CEnumCallWrapperSubstitutionProcessor cEnumProcessor = new CEnumCallWrapperSubstitutionProcessor();
aUniverse = createAnalysisUniverse(options, platform, target, loader, originalMetaAccess, originalSnippetReflection, annotationSubstitutions, cEnumProcessor,
aUniverse = createAnalysisUniverse(options, targetPlatform, target, loader, originalMetaAccess, originalSnippetReflection, annotationSubstitutions, cEnumProcessor,
classInitializaitonSupport, Collections.singletonList(harnessSubstitutions));

AnalysisMetaAccess aMetaAccess = new SVMAnalysisMetaAccess(aUniverse, originalMetaAccess);
Expand Down Expand Up @@ -1153,7 +1155,7 @@ public <T> T getInjectedArgument(Class<T> type) {
SubstrateOptions.EmitStringEncodingSubstitutions.getValue() && JAVA_SPECIFICATION_VERSION >= 9);
} else if (architecture instanceof AArch64) {
AArch64GraphBuilderPlugins.register(plugins, replacementBytecodeProvider, explicitUnsafeNullChecks, //
/* registerMathPlugins */false);
/* registerMathPlugins */false, SubstrateOptions.EmitStringEncodingSubstitutions.getValue() && JAVA_SPECIFICATION_VERSION >= 9);
} else {
throw GraalError.shouldNotReachHere("Unimplemented GraphBuilderPlugin for architecture " + architecture);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.oracle.svm.hosted.image.NativeImageCodeCache;
import com.oracle.svm.hosted.image.NativeImageCodeCacheFactory;
import com.oracle.svm.hosted.image.NativeImageHeap;
import org.graalvm.nativeimage.Platform;

@AutomaticFeature
class SubstrateLIRBackendFeature implements Feature {
Expand All @@ -47,7 +48,7 @@ public boolean isInConfiguration(IsInConfigurationAccess access) {
public void afterRegistration(AfterRegistrationAccess access) {
ImageSingletons.add(NativeImageCodeCacheFactory.class, new NativeImageCodeCacheFactory() {
@Override
public NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap) {
public NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap, Platform targetPlatform) {
return new LIRNativeImageCodeCache(compileQueue.getCompilations(), heap);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.options.Option;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.c.function.CFunctionPointer;
import org.graalvm.word.UnsignedWord;

Expand Down Expand Up @@ -89,14 +90,21 @@ public static class Options {

protected final NavigableMap<Integer, CompilationResult> compilationsByStart = new TreeMap<>();

protected final Platform targetPlatform;

private final DataSection dataSection;

private final Map<JavaConstant, String> constantReasons = new HashMap<>();

public NativeImageCodeCache(Map<HostedMethod, CompilationResult> compilations, NativeImageHeap imageHeap) {
this(compilations, imageHeap, ImageSingletons.lookup(Platform.class));
}

public NativeImageCodeCache(Map<HostedMethod, CompilationResult> compilations, NativeImageHeap imageHeap, Platform targetPlatform) {
this.compilations = compilations;
this.imageHeap = imageHeap;
this.dataSection = new DataSection();
this.targetPlatform = targetPlatform;
}

public abstract int getCodeCacheSize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,15 @@

import com.oracle.svm.hosted.code.CompileQueue;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;

public abstract class NativeImageCodeCacheFactory {
public abstract NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap);

public NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap) {
return newCodeCache(compileQueue, heap, ImageSingletons.lookup(Platform.class));
}

public abstract NativeImageCodeCache newCodeCache(CompileQueue compileQueue, NativeImageHeap heap, Platform target);

public static NativeImageCodeCacheFactory get() {
return ImageSingletons.lookup(NativeImageCodeCacheFactory.class);
Expand Down

0 comments on commit f7bd11a

Please sign in to comment.