Search in sources :

Example 6 with LLVMStatementNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode in project graal by oracle.

the class LazyToTruffleConverterImpl method copyStructArgumentsToFrame.

/**
 * This function creates a list of statements that, together, copy a value of type
 * {@code topLevelPointerType} from argument {@code argIndex} to the frame slot {@code
 * slot} by recursing over the structure of {@code topLevelPointerType}.
 *
 * The recursive cases go over the elements (for arrays) and over the members (for structs). The
 * base case is for everything else ("primitives"), where cascades of getelementptrs are created
 * for reading from the source and writing into the target frame slot. The cascades of
 * getelementptr nodes are created by the calls to
 * {@link LazyToTruffleConverterImpl#getTargetAddress} and then used to load or store from the
 * source and into the destination respectively.
 *
 * @param initializers The accumulator where copy statements are going to be inserted.
 * @param slot Target frame slot.
 * @param currentType Current member (for structs) or element (for arrays) type.
 * @param indices List of indices to reach this member or element from the toplevel object.
 */
private void copyStructArgumentsToFrame(List<LLVMStatementNode> initializers, NodeFactory nodeFactory, int slot, int argIndex, PointerType topLevelPointerType, Type currentType, ArrayDeque<Long> indices) {
    if (currentType instanceof StructureType || currentType instanceof ArrayType) {
        AggregateType t = (AggregateType) currentType;
        for (long i = 0; i < t.getNumberOfElements(); i++) {
            indices.push(i);
            copyStructArgumentsToFrame(initializers, nodeFactory, slot, argIndex, topLevelPointerType, t.getElementType(i), indices);
            indices.pop();
        }
    } else {
        LLVMExpressionNode targetAddress = getTargetAddress(CommonNodeFactory.createFrameRead(topLevelPointerType, slot), topLevelPointerType.getPointeeType(), indices);
        /*
             * In case the source is a varargs list (va_list), we need to create a node that would
             * unpack it if it is, and do nothing if it isn't.
             */
        LLVMExpressionNode argMaybeUnpack = LLVMUnpackVarargsNodeGen.create(nodeFactory.createFunctionArgNode(argIndex, topLevelPointerType));
        LLVMExpressionNode sourceAddress = getTargetAddress(argMaybeUnpack, topLevelPointerType.getPointeeType(), indices);
        LLVMExpressionNode sourceLoadNode = nodeFactory.createLoad(currentType, sourceAddress);
        LLVMStatementNode storeNode = nodeFactory.createStore(targetAddress, sourceLoadNode, currentType);
        initializers.add(storeNode);
    }
}
Also used : ArrayType(com.oracle.truffle.llvm.runtime.types.ArrayType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode) AggregateType(com.oracle.truffle.llvm.runtime.types.AggregateType)

Example 7 with LLVMStatementNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode in project graal by oracle.

the class LazyToTruffleConverterImpl method copyArgumentsToFrame.

/**
 * Copies arguments to the current frame, handling normal "primitives" and byval pointers (e.g.
 * for structs).
 */
private List<LLVMStatementNode> copyArgumentsToFrame(LLVMSymbolReadResolver symbols) {
    NodeFactory nodeFactory = runtime.getNodeFactory();
    List<FunctionParameter> parameters = method.getParameters();
    List<LLVMStatementNode> formalParamInits = new ArrayList<>();
    // There's a struct return type.
    int argIndex = 1;
    if (method.getType().getReturnType() instanceof StructureType) {
        argIndex++;
    }
    for (FunctionParameter parameter : parameters) {
        int slot = symbols.findOrAddFrameSlot(parameter);
        if (parameter.getType() instanceof PointerType && functionParameterHasByValueAttribute(parameter)) {
            // It's a struct passed as a pointer but originally passed by value (because LLVM
            // and/or ABI), treat it as such.
            PointerType pointerType = (PointerType) parameter.getType();
            Type pointeeType = pointerType.getPointeeType();
            GetStackSpaceFactory allocaFactory = GetStackSpaceFactory.createAllocaFactory();
            LLVMExpressionNode allocation = allocaFactory.createGetStackSpace(nodeFactory, pointeeType);
            formalParamInits.add(CommonNodeFactory.createFrameWrite(pointerType, allocation, slot));
            ArrayDeque<Long> indices = new ArrayDeque<>();
            copyStructArgumentsToFrame(formalParamInits, nodeFactory, slot, argIndex++, pointerType, pointeeType, indices);
        } else {
            LLVMExpressionNode parameterNode = nodeFactory.createFunctionArgNode(argIndex++, parameter.getType());
            formalParamInits.add(CommonNodeFactory.createFrameWrite(parameter.getType(), parameterNode, slot));
        }
    }
    return formalParamInits;
}
Also used : ArrayList(java.util.ArrayList) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) ArrayDeque(java.util.ArrayDeque) GetStackSpaceFactory(com.oracle.truffle.llvm.runtime.GetStackSpaceFactory) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) ArrayType(com.oracle.truffle.llvm.runtime.types.ArrayType) AggregateType(com.oracle.truffle.llvm.runtime.types.AggregateType) Type(com.oracle.truffle.llvm.runtime.types.Type) LLVMSourceFunctionType(com.oracle.truffle.llvm.runtime.debug.type.LLVMSourceFunctionType) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) CommonNodeFactory(com.oracle.truffle.llvm.runtime.CommonNodeFactory) NodeFactory(com.oracle.truffle.llvm.runtime.NodeFactory) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode) FunctionParameter(com.oracle.truffle.llvm.parser.model.functions.FunctionParameter)

Example 8 with LLVMStatementNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode in project graal by oracle.

the class InitializeModuleNode method createDestructor.

public static RootCallTarget createDestructor(LLVMParserResult parserResult, String moduleName, LLVMLanguage language) {
    LLVMStatementNode[] destructors = createStructor(DESTRUCTORS_VARNAME, parserResult, DESCENDING_PRIORITY);
    if (destructors.length > 0) {
        NodeFactory nodeFactory = parserResult.getRuntime().getNodeFactory();
        FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
        nodeFactory.addStackSlots(builder);
        FrameDescriptor frameDescriptor = builder.build();
        LLVMStatementRootNode root = new LLVMStatementRootNode(language, StaticInitsNodeGen.create(destructors, "fini", moduleName), frameDescriptor, nodeFactory.createStackAccess());
        return root.getCallTarget();
    } else {
        return null;
    }
}
Also used : FrameDescriptor(com.oracle.truffle.api.frame.FrameDescriptor) CommonNodeFactory(com.oracle.truffle.llvm.runtime.CommonNodeFactory) NodeFactory(com.oracle.truffle.llvm.runtime.NodeFactory) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) LLVMStatementRootNode(com.oracle.truffle.llvm.runtime.nodes.others.LLVMStatementRootNode)

Example 9 with LLVMStatementNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode in project graal by oracle.

the class InitializeGlobalNode method createGlobalVariableInitializer.

private static StaticInitsNode createGlobalVariableInitializer(LLVMParserResult parserResult, Object moduleName) {
    LLVMParserRuntime runtime = parserResult.getRuntime();
    GetStackSpaceFactory stackFactory = GetStackSpaceFactory.createAllocaFactory();
    List<GlobalVariable> globals = parserResult.getDefinedGlobals();
    DataLayout dataLayout = parserResult.getDataLayout();
    LLVMStatementNode initNode;
    int totalSize = 0;
    try {
        int[] sizes = new int[globals.size()];
        int nonEmptyGlobals = 0;
        for (int i = 0; i < sizes.length; i++) {
            GlobalVariable global = globals.get(i);
            if (global == null || global.getValue() == null) {
                continue;
            }
            long size = globals.get(i).getType().getPointeeType().getSize(dataLayout);
            if (size > Integer.MAX_VALUE || (totalSize + size) > Integer.MAX_VALUE) {
                throw new TypeOverflowException("globals section > 2GB is not supported");
            }
            if (size == 0) {
                continue;
            }
            sizes[i] = (int) size;
            totalSize += (int) size;
            nonEmptyGlobals++;
        }
        int[] bufferOffsets = new int[nonEmptyGlobals];
        LLVMGlobal[] descriptors = new LLVMGlobal[nonEmptyGlobals];
        Buffer buffer = new Buffer(totalSize, runtime, dataLayout);
        int globalIndex = 0;
        totalSize = 0;
        for (int i = 0; i < sizes.length; i++) {
            if (sizes[i] == 0) {
                continue;
            }
            GlobalVariable global = globals.get(i);
            /*
                 * For fetching the address of the global that we want to initialize, we must use
                 * the file scope because we are initializing the globals of the current file.
                 */
            descriptors[globalIndex] = runtime.getFileScope().getGlobalVariable(global.getName());
            assert descriptors[globalIndex] != null;
            bufferOffsets[globalIndex] = totalSize;
            global.getValue().addToBuffer(buffer, runtime, dataLayout, stackFactory);
            totalSize += sizes[i];
            globalIndex++;
        }
        initNode = buffer.createNode(bufferOffsets, descriptors);
    } catch (TypeOverflowException e) {
        initNode = Type.handleOverflowStatement(e);
    }
    return StaticInitsNodeGen.create(new LLVMStatementNode[] { initNode }, "global variable initializers", moduleName);
}
Also used : DataLayout(com.oracle.truffle.llvm.runtime.datalayout.DataLayout) ByteBuffer(java.nio.ByteBuffer) TypeOverflowException(com.oracle.truffle.llvm.runtime.types.Type.TypeOverflowException) LLVMGlobal(com.oracle.truffle.llvm.runtime.global.LLVMGlobal) LLVMParserRuntime(com.oracle.truffle.llvm.parser.LLVMParserRuntime) GetStackSpaceFactory(com.oracle.truffle.llvm.runtime.GetStackSpaceFactory) GlobalVariable(com.oracle.truffle.llvm.parser.model.symbols.globals.GlobalVariable) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode)

Example 10 with LLVMStatementNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode in project graal by oracle.

the class LLVMBitcodeInstructionVisitor method visit.

@Override
public void visit(StoreInstruction store) {
    SymbolImpl value = store.getSource();
    SymbolImpl pointer = store.getDestination();
    LLVMExpressionNode valueNode = resolveOptimized(value, pointer);
    LLVMExpressionNode pointerNode = resolveOptimized(pointer, value);
    SourceInstrumentationStrategy intention = SourceInstrumentationStrategy.DISABLED;
    if (!(store.getSource() instanceof CallInstruction || store.getSource() instanceof InvokeInstruction) || context.getEnv().getOptions().get(SulongEngineOption.LL_DEBUG)) {
        // otherwise the debugger would stop on both the call and the store of the return value
        intention = SourceInstrumentationStrategy.ONLY_FIRST_STATEMENT_ON_LOCATION;
    }
    Type type = value.getType();
    LLVMStatementNode node = nodeFactory.createStore(pointerNode, valueNode, type);
    addStatement(node, store, intention);
}
Also used : SymbolImpl(com.oracle.truffle.llvm.parser.model.SymbolImpl) CallInstruction(com.oracle.truffle.llvm.parser.model.symbols.instructions.CallInstruction) VoidCallInstruction(com.oracle.truffle.llvm.parser.model.symbols.instructions.VoidCallInstruction) VoidInvokeInstruction(com.oracle.truffle.llvm.parser.model.symbols.instructions.VoidInvokeInstruction) InvokeInstruction(com.oracle.truffle.llvm.parser.model.symbols.instructions.InvokeInstruction) PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) ArrayType(com.oracle.truffle.llvm.runtime.types.ArrayType) AggregateType(com.oracle.truffle.llvm.runtime.types.AggregateType) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) FunctionType(com.oracle.truffle.llvm.runtime.types.FunctionType) MetaType(com.oracle.truffle.llvm.runtime.types.MetaType) Type(com.oracle.truffle.llvm.runtime.types.Type) LLVMSourceType(com.oracle.truffle.llvm.runtime.debug.type.LLVMSourceType) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Aggregations

LLVMStatementNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode)14 LLVMExpressionNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)10 PointerType (com.oracle.truffle.llvm.runtime.types.PointerType)6 StructureType (com.oracle.truffle.llvm.runtime.types.StructureType)6 ArrayList (java.util.ArrayList)6 Type (com.oracle.truffle.llvm.runtime.types.Type)5 SymbolImpl (com.oracle.truffle.llvm.parser.model.SymbolImpl)4 LLVMControlFlowNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode)4 AggregateType (com.oracle.truffle.llvm.runtime.types.AggregateType)4 ArrayType (com.oracle.truffle.llvm.runtime.types.ArrayType)4 FunctionType (com.oracle.truffle.llvm.runtime.types.FunctionType)4 PrimitiveType (com.oracle.truffle.llvm.runtime.types.PrimitiveType)4 Phi (com.oracle.truffle.llvm.parser.LLVMPhiManager.Phi)3 CommonNodeFactory (com.oracle.truffle.llvm.runtime.CommonNodeFactory)3 GetStackSpaceFactory (com.oracle.truffle.llvm.runtime.GetStackSpaceFactory)3 NodeFactory (com.oracle.truffle.llvm.runtime.NodeFactory)3 FrameDescriptor (com.oracle.truffle.api.frame.FrameDescriptor)2 LLVMPhiManager (com.oracle.truffle.llvm.parser.LLVMPhiManager)2 AttributesGroup (com.oracle.truffle.llvm.parser.model.attributes.AttributesGroup)2 FunctionParameter (com.oracle.truffle.llvm.parser.model.functions.FunctionParameter)2