use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class AsmFactory method parseArguments.
private void parseArguments() {
argInfo = new ArrayList<>();
String[] tokens = asmFlags.substring(1, asmFlags.length() - 1).split(",");
int index = REG_START_INDEX + (retType instanceof StructureType ? 1 : 0);
int outIndex = 0;
for (String token : tokens) {
if (token.isEmpty()) {
continue;
}
boolean isTilde = false;
boolean isInput = true;
boolean isOutput = false;
boolean isMemory = false;
boolean isAnonymous = false;
String source = null;
String registerName = null;
int i;
for (i = 0; i < token.length() && source == null; i++) {
switch(token.charAt(i)) {
case '~':
isTilde = true;
isInput = false;
break;
case '+':
isInput = true;
isOutput = true;
break;
case '=':
isInput = false;
isOutput = true;
break;
case '*':
isMemory = true;
break;
case '&':
break;
default:
source = token.substring(i);
break;
}
}
if (isTilde) {
continue;
}
int start = source.indexOf('{');
int end = source.lastIndexOf('}');
if (start != -1 && end != -1) {
registerName = source.substring(start + 1, end);
} else if (source.equals(CONSTRAINT_REG) || source.equals(CONSTRAINT_REG_L)) {
registerName = TEMP_REGISTER_PREFIX + argInfo.size();
isAnonymous = true;
} else if (source.length() == 1 && Character.isDigit(source.charAt(0))) {
int id = Character.digit(source.charAt(0), 10);
Argument arg = argInfo.get(id);
assert isInput && !isOutput;
isInput = true;
isOutput = false;
if (arg.isRegister()) {
registerName = arg.getRegister();
}
isAnonymous = arg.isAnonymous();
}
assert registerName == null || AsmRegisterOperand.isRegister(registerName) || registerName.startsWith(TEMP_REGISTER_PREFIX);
int idIn = index;
int idOut = outIndex;
Type type;
if (isInput) {
type = argTypes[index++];
} else if (retType instanceof StructureType) {
if (isMemory) {
type = argTypes[index];
idOut = index++;
} else {
type = retTypes[outIndex++];
}
} else if (isOutput) {
type = retType;
if (isMemory) {
idOut = index++;
}
} else {
throw new AssertionError("neither input nor output");
}
if (isAnonymous && type instanceof PointerType) {
assert registerName != null;
addFrameSlot(registerName, type);
}
argInfo.add(new Argument(isInput, isOutput, isMemory, isAnonymous, type, argInfo.size(), idIn, idOut, source, registerName));
}
assert index == argTypes.length;
assert retType instanceof StructureType ? outIndex == retOffsets.length : outIndex == 0;
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class LLVMForeignCallNode method callIndirect.
@Specialization(replaces = "callDirectCached")
protected Object callIndirect(LLVMFunctionDescriptor function, Object[] arguments, @Cached("create()") IndirectCallNode callNode, @Cached("createSlowPackArguments()") SlowPackForeignArgumentsNode slowPack, @Cached("create()") LLVMGetStackNode getStack, @Cached("getLLVMMemory()") LLVMMemory memory) {
assert !(function.getType().getReturnType() instanceof StructureType);
LLVMStack stack = getStack.executeWithTarget(function.getContext().getThreadingStack(), Thread.currentThread());
Object result;
try (StackPointer stackPointer = stack.newFrame()) {
result = callNode.call(getCallTarget(function), slowPack.pack(function, memory, arguments, stackPointer));
}
return prepareValueForEscape.executeWithTarget(result);
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class LLVMSymbolReadResolver method resolveElementPointer.
public LLVMExpressionNode resolveElementPointer(SymbolImpl base, List<SymbolImpl> indices) {
LLVMExpressionNode currentAddress = resolve(base);
Type currentType = base.getType();
for (int i = 0, indicesSize = indices.size(); i < indicesSize; i++) {
final SymbolImpl indexSymbol = indices.get(i);
final Type indexType = indexSymbol.getType();
final Long indexInteger = evaluateLongIntegerConstant(indexSymbol);
if (indexInteger == null) {
// the index is determined at runtime
if (currentType instanceof StructureType) {
// according to http://llvm.org/docs/LangRef.html#getelementptr-instruction
throw new IllegalStateException("Indices on structs must be constant integers!");
}
AggregateType aggregate = (AggregateType) currentType;
final long indexedTypeLength = runtime.getContext().getIndexOffset(1, aggregate);
currentType = aggregate.getElementType(1);
final LLVMExpressionNode indexNode = resolve(indexSymbol);
currentAddress = runtime.getNodeFactory().createTypedElementPointer(runtime, currentAddress, indexNode, indexedTypeLength, currentType);
} else {
// the index is a constant integer
AggregateType aggregate = (AggregateType) currentType;
final long addressOffset = runtime.getContext().getIndexOffset(indexInteger, aggregate);
currentType = aggregate.getElementType(indexInteger);
// computed by getelementptr even if it is the same as the basepointer
if (addressOffset != 0 || i == indicesSize - 1) {
final LLVMExpressionNode indexNode;
if (indexType == PrimitiveType.I32) {
indexNode = runtime.getNodeFactory().createLiteral(runtime, 1, PrimitiveType.I32);
} else if (indexType == PrimitiveType.I64) {
indexNode = runtime.getNodeFactory().createLiteral(runtime, 1L, PrimitiveType.I64);
} else {
throw new AssertionError(indexType);
}
currentAddress = runtime.getNodeFactory().createTypedElementPointer(runtime, currentAddress, indexNode, addressOffset, currentType);
}
}
}
return currentAddress;
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method visit.
@Override
public void visit(InvokeInstruction call) {
final Type targetType = call.getType();
int argumentCount = getArgumentCount(call.getArgumentCount(), targetType);
final LLVMExpressionNode[] argNodes = new LLVMExpressionNode[argumentCount];
final Type[] argTypes = new Type[argumentCount];
int argIndex = 0;
argNodes[argIndex] = nodeFactory.createFrameRead(runtime, PointerType.VOID, getStackSlot());
argTypes[argIndex] = new PointerType(null);
argIndex++;
if (targetType instanceof StructureType) {
argTypes[argIndex] = new PointerType(targetType);
argNodes[argIndex] = nodeFactory.createAlloca(runtime, targetType);
argIndex++;
}
for (int i = 0; argIndex < argumentCount; i++, argIndex++) {
argNodes[argIndex] = symbols.resolve(call.getArgument(i));
argTypes[argIndex] = call.getArgument(i).getType();
final AttributesGroup paramAttr = call.getParameterAttributesGroup(i);
if (isByValue(paramAttr)) {
argNodes[argIndex] = capsuleAddressByValue(argNodes[argIndex], argTypes[argIndex], paramAttr);
}
}
final SymbolImpl target = call.getCallTarget();
int regularIndex = call.normalSuccessor().getBlockIndex();
int unwindIndex = call.unwindSuccessor().getBlockIndex();
List<FrameSlot> normalTo = new ArrayList<>();
List<FrameSlot> unwindTo = new ArrayList<>();
List<Type> normalType = new ArrayList<>();
List<Type> unwindType = new ArrayList<>();
List<LLVMExpressionNode> normalValue = new ArrayList<>();
List<LLVMExpressionNode> unwindValue = new ArrayList<>();
if (blockPhis != null) {
for (Phi phi : blockPhis) {
FrameSlot slot = getSlot(phi.getPhiValue().getName());
LLVMExpressionNode value = symbols.resolve(phi.getValue());
if (call.normalSuccessor() == phi.getBlock()) {
normalTo.add(slot);
normalType.add(phi.getValue().getType());
normalValue.add(value);
} else {
unwindTo.add(slot);
unwindType.add(phi.getValue().getType());
unwindValue.add(value);
}
}
}
LLVMExpressionNode normalPhi = nodeFactory.createPhi(runtime, normalValue.toArray(new LLVMExpressionNode[normalValue.size()]), normalTo.toArray(new FrameSlot[normalTo.size()]), normalType.toArray(Type.EMPTY_ARRAY));
LLVMExpressionNode unwindPhi = nodeFactory.createPhi(runtime, unwindValue.toArray(new LLVMExpressionNode[unwindValue.size()]), unwindTo.toArray(new FrameSlot[unwindTo.size()]), unwindType.toArray(Type.EMPTY_ARRAY));
final LLVMSourceLocation source = sourceFunction.getSourceLocation(call);
LLVMExpressionNode function = nodeFactory.createLLVMBuiltin(runtime, target, argNodes, argCount, null);
if (function == null) {
function = symbols.resolve(target);
}
LLVMControlFlowNode result = nodeFactory.createFunctionInvoke(runtime, getSlot(call.getName()), function, argNodes, new FunctionType(targetType, argTypes, false), regularIndex, unwindIndex, normalPhi, unwindPhi, source);
setControlFlowNode(result);
}
use of com.oracle.truffle.llvm.runtime.types.StructureType in project sulong by graalvm.
the class LLVMParserRuntime method resolveStructor.
private LLVMExpressionNode[] resolveStructor(GlobalValueSymbol globalVar, Comparator<Pair<Integer, ?>> priorityComparator) {
if (!(globalVar.getValue() instanceof ArrayConstant)) {
// array globals of length 0 may be initialized with scalar null
return LLVMExpressionNode.NO_EXPRESSIONS;
}
final Object globalVariableDescriptor = scope.getGlobalVariable(globalVar.getName());
final ArrayConstant arrayConstant = (ArrayConstant) globalVar.getValue();
final int elemCount = arrayConstant.getElementCount();
final StructureType elementType = (StructureType) arrayConstant.getType().getElementType();
final int structSize = getContext().getByteSize(elementType);
final FunctionType functionType = (FunctionType) ((PointerType) elementType.getElementType(1)).getPointeeType();
final int indexedTypeLength = getContext().getByteAlignment(functionType);
final ArrayList<Pair<Integer, LLVMExpressionNode>> structors = new ArrayList<>(elemCount);
for (int i = 0; i < elemCount; i++) {
final LLVMExpressionNode globalVarAddress = nodeFactory.createLiteral(this, globalVariableDescriptor, new PointerType(globalVar.getType()));
final LLVMExpressionNode iNode = nodeFactory.createLiteral(this, i, PrimitiveType.I32);
final LLVMExpressionNode structPointer = nodeFactory.createTypedElementPointer(this, globalVarAddress, iNode, structSize, elementType);
final LLVMExpressionNode loadedStruct = nodeFactory.createLoad(this, elementType, structPointer);
final LLVMExpressionNode oneLiteralNode = nodeFactory.createLiteral(this, 1, PrimitiveType.I32);
final LLVMExpressionNode functionLoadTarget = nodeFactory.createTypedElementPointer(this, loadedStruct, oneLiteralNode, indexedTypeLength, functionType);
final LLVMExpressionNode loadedFunction = nodeFactory.createLoad(this, functionType, functionLoadTarget);
final LLVMExpressionNode[] argNodes = new LLVMExpressionNode[] { nodeFactory.createFrameRead(this, PointerType.VOID, rootFrame.findFrameSlot(LLVMStack.FRAME_ID)) };
final LLVMExpressionNode functionCall = nodeFactory.createFunctionCall(this, loadedFunction, argNodes, functionType, null);
final StructureConstant structorDefinition = (StructureConstant) arrayConstant.getElement(i);
final SymbolImpl prioritySymbol = structorDefinition.getElement(0);
final Integer priority = LLVMSymbolReadResolver.evaluateIntegerConstant(prioritySymbol);
structors.add(new Pair<>(priority != null ? priority : LEAST_CONSTRUCTOR_PRIORITY, functionCall));
}
return structors.stream().sorted(priorityComparator).map(Pair::getSecond).toArray(LLVMExpressionNode[]::new);
}
Aggregations