use of com.oracle.svm.shadowed.org.bytedeco.llvm.LLVM.LLVMValueRef in project graal by oracle.
the class LLVMGenerator method createJNIWrapper.
/*
* Calling a native function from Java code requires filling the JavaFrameAnchor with the return
* address of the call. This wrapper allows this by creating an intermediary call frame from
* which the return address can be accessed. The parameters to this wrapper are the anchor, the
* native callee, and the arguments to the callee.
*/
LLVMValueRef createJNIWrapper(LLVMValueRef callee, boolean nativeABI, int numArgs, int anchorIPOffset) {
LLVMTypeRef calleeType = LLVMIRBuilder.getElementType(LLVMIRBuilder.typeOf(callee));
String wrapperName = JNI_WRAPPER_BASE_NAME + LLVMIRBuilder.intrinsicType(calleeType) + (nativeABI ? "_native" : "");
LLVMValueRef transitionWrapper = builder.getNamedFunction(wrapperName);
if (transitionWrapper == null) {
try (LLVMIRBuilder tempBuilder = new LLVMIRBuilder(builder)) {
LLVMTypeRef wrapperType = prependArgumentTypes(calleeType, nativeABI ? 0 : SpecialRegister.count(), tempBuilder.rawPointerType(), LLVMIRBuilder.typeOf(callee));
transitionWrapper = tempBuilder.addFunction(wrapperName, wrapperType);
LLVMIRBuilder.setLinkage(transitionWrapper, LinkageType.LinkOnce);
tempBuilder.setGarbageCollector(transitionWrapper, GCStrategy.CompressedPointers);
tempBuilder.setFunctionAttribute(transitionWrapper, Attribute.NoInline);
LLVMBasicBlockRef block = tempBuilder.appendBasicBlock(transitionWrapper, "main");
tempBuilder.positionAtEnd(block);
LLVMValueRef anchor = LLVMIRBuilder.getParam(transitionWrapper, 0 + (nativeABI ? 0 : SpecialRegister.count()));
LLVMValueRef lastIPAddr = tempBuilder.buildGEP(anchor, tempBuilder.constantInt(anchorIPOffset));
LLVMValueRef callIP = tempBuilder.buildReturnAddress(tempBuilder.constantInt(0));
LLVMValueRef castedLastIPAddr = tempBuilder.buildBitcast(lastIPAddr, tempBuilder.pointerType(tempBuilder.rawPointerType()));
tempBuilder.buildStore(callIP, castedLastIPAddr);
LLVMValueRef[] args = new LLVMValueRef[numArgs];
for (int i = 0; i < numArgs; ++i) {
if (!nativeABI && i < SpecialRegister.count()) {
args[i] = LLVMIRBuilder.getParam(transitionWrapper, i);
} else {
args[i] = LLVMIRBuilder.getParam(transitionWrapper, i + 2);
}
}
LLVMValueRef target = LLVMIRBuilder.getParam(transitionWrapper, 1 + (nativeABI ? 0 : SpecialRegister.count()));
LLVMValueRef ret = tempBuilder.buildCall(target, args);
tempBuilder.setCallSiteAttribute(ret, Attribute.GCLeafFunction);
if (LLVMIRBuilder.isVoidType(LLVMIRBuilder.getReturnType(calleeType))) {
tempBuilder.buildRetVoid();
} else {
tempBuilder.buildRet(ret);
}
}
}
return transitionWrapper;
}
use of com.oracle.svm.shadowed.org.bytedeco.llvm.LLVM.LLVMValueRef in project graal by oracle.
the class LLVMGenerator method allocateStackMemory.
@Override
public VirtualStackSlot allocateStackMemory(int sizeInBytes, int alignmentInBytes) {
builder.positionAtStart();
LLVMValueRef alloca = builder.buildArrayAlloca(builder.byteType(), sizeInBytes, alignmentInBytes);
builder.positionAtEnd(getBlockEnd(currentBlock));
return new LLVMStackSlot(alloca);
}
use of com.oracle.svm.shadowed.org.bytedeco.llvm.LLVM.LLVMValueRef in project graal by oracle.
the class LLVMGenerator method createJNITrampoline.
void createJNITrampoline(RegisterValue threadArg, int threadIsolateOffset, RegisterValue methodIdArg, int methodObjEntryPointOffset) {
builder.setFunctionAttribute(Attribute.Naked);
LLVMBasicBlockRef block = builder.appendBasicBlock("main");
builder.positionAtEnd(block);
long startPatchpointId = LLVMGenerator.nextPatchpointId.getAndIncrement();
builder.buildStackmap(builder.constantLong(startPatchpointId));
compilationResult.recordInfopoint(NumUtil.safeToInt(startPatchpointId), null, InfopointReason.METHOD_START);
LLVMValueRef jumpAddressAddress;
if (SubstrateOptions.SpawnIsolates.getValue()) {
LLVMValueRef thread = buildInlineGetRegister(threadArg.getRegister().name);
LLVMValueRef heapBaseAddress = builder.buildGEP(builder.buildIntToPtr(thread, builder.rawPointerType()), builder.constantInt(threadIsolateOffset));
LLVMValueRef heapBase = builder.buildLoad(heapBaseAddress, builder.rawPointerType());
LLVMValueRef methodId = buildInlineGetRegister(methodIdArg.getRegister().name);
LLVMValueRef methodBase = builder.buildGEP(builder.buildIntToPtr(heapBase, builder.rawPointerType()), builder.buildPtrToInt(methodId));
jumpAddressAddress = builder.buildGEP(methodBase, builder.constantInt(methodObjEntryPointOffset));
} else {
LLVMValueRef methodBase = buildInlineGetRegister(methodIdArg.getRegister().name);
jumpAddressAddress = builder.buildGEP(builder.buildIntToPtr(methodBase, builder.rawPointerType()), builder.constantInt(methodObjEntryPointOffset));
}
LLVMValueRef jumpAddress = builder.buildLoad(jumpAddressAddress, builder.rawPointerType());
buildInlineJump(jumpAddress);
builder.buildUnreachable();
}
use of com.oracle.svm.shadowed.org.bytedeco.llvm.LLVM.LLVMValueRef in project graal by oracle.
the class NodeLLVMBuilder method emitCondition.
private LLVMValueRef emitCondition(LogicNode condition) {
if (condition instanceof IsNullNode) {
return builder.buildIsNull(llvmOperand(((IsNullNode) condition).getValue()));
}
if (condition instanceof LogicConstantNode) {
return builder.constantBoolean(((LogicConstantNode) condition).getValue());
}
if (condition instanceof CompareNode) {
CompareNode compareNode = (CompareNode) condition;
return builder.buildCompare(compareNode.condition().asCondition(), llvmOperand(compareNode.getX()), llvmOperand(compareNode.getY()), compareNode.unorderedIsTrue());
}
if (condition instanceof IntegerTestNode) {
IntegerTestNode integerTestNode = (IntegerTestNode) condition;
LLVMValueRef and = builder.buildAnd(llvmOperand(integerTestNode.getX()), llvmOperand(integerTestNode.getY()));
return builder.buildIsNull(and);
}
if (condition instanceof SafepointCheckNode) {
LLVMValueRef threadData = gen.getSpecialRegisterValue(SpecialRegister.ThreadPointer);
threadData = builder.buildIntToPtr(threadData, builder.rawPointerType());
LLVMValueRef safepointCounterAddr = builder.buildGEP(threadData, builder.constantInt(Safepoint.getThreadLocalSafepointRequestedOffset()));
LLVMValueRef safepointCount = builder.buildLoad(safepointCounterAddr, builder.intType());
if (ThreadingSupportImpl.isRecurringCallbackSupported()) {
safepointCount = builder.buildSub(safepointCount, builder.constantInt(1));
builder.buildStore(safepointCount, builder.buildBitcast(safepointCounterAddr, builder.pointerType(builder.intType())));
}
return builder.buildICmp(Condition.LE, safepointCount, builder.constantInt(0));
}
throw shouldNotReachHere("logic node: " + condition.getClass().getName());
}
use of com.oracle.svm.shadowed.org.bytedeco.llvm.LLVM.LLVMValueRef in project graal by oracle.
the class NodeLLVMBuilder method emitTypeSwitch.
private void emitTypeSwitch(TypeSwitchNode switchNode) {
int numCases = switchNode.keyCount();
LLVMValueRef value = llvmOperand(switchNode.value());
LLVMBasicBlockRef defaultSuccessor = gen.getBlock(switchNode.defaultSuccessor());
switch(numCases) {
case 0:
builder.buildBranch(defaultSuccessor);
break;
case 1:
LLVMValueRef hub = gen.emitLLVMConstant(builder.objectType(false), (JavaConstant) switchNode.keyAt(0));
LLVMValueRef cond = builder.buildCompare(Condition.EQ, value, hub, false);
builder.buildIf(cond, gen.getBlock(switchNode.keySuccessor(0)), defaultSuccessor);
break;
default:
throw unimplemented();
}
}
Aggregations