Search in sources :

Example 1 with GetStackSpaceFactory

use of com.oracle.truffle.llvm.runtime.GetStackSpaceFactory in project graal by oracle.

the class LazyToTruffleConverterImpl method generateCallTarget.

private RootCallTarget generateCallTarget() {
    LLVMContext context = LLVMLanguage.getContext();
    NodeFactory nodeFactory = runtime.getNodeFactory();
    OptionValues options = context.getEnv().getOptions();
    boolean printAST = false;
    if (LLVMContext.printAstEnabled()) {
        String printASTOption = options.get(SulongEngineOption.PRINT_AST_FILTER);
        if (!printASTOption.isEmpty()) {
            String[] regexes = printASTOption.split(",");
            for (String regex : regexes) {
                if (method.getName().matches(regex)) {
                    printAST = true;
                    LLVMContext.printAstLog("========== " + method.getName());
                    break;
                }
            }
        }
    }
    doParse();
    // prepare the phis
    final Map<InstructionBlock, List<Phi>> phis = LLVMPhiManager.getPhis(method);
    LLVMLivenessAnalysisResult liveness = LLVMLivenessAnalysis.computeLiveness(phis, method);
    // setup the frameDescriptor
    FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
    nodeFactory.addStackSlots(builder);
    UniquesRegion uniquesRegion = new UniquesRegion();
    GetStackSpaceFactory getStackSpaceFactory = GetStackSpaceFactory.createGetUniqueStackSpaceFactory(uniquesRegion);
    LLVMSymbolReadResolver symbols = new LLVMSymbolReadResolver(runtime, builder, getStackSpaceFactory, dataLayout, options.get(SulongEngineOption.LL_DEBUG));
    int exceptionSlot = builder.addSlot(FrameSlotKind.Object, null, null);
    for (FunctionParameter parameter : method.getParameters()) {
        symbols.findOrAddFrameSlot(parameter);
    }
    HashSet<SSAValue> neededForDebug = getDebugValues();
    // create blocks and translate instructions
    boolean initDebugValues = true;
    LLVMRuntimeDebugInformation info = new LLVMRuntimeDebugInformation(method.getBlocks().size());
    LLVMBasicBlockNode[] blockNodes = new LLVMBasicBlockNode[method.getBlocks().size()];
    for (InstructionBlock block : method.getBlocks()) {
        List<Phi> blockPhis = phis.get(block);
        ArrayList<LLVMLivenessAnalysis.NullerInformation> blockNullerInfos = liveness.getNullableWithinBlock()[block.getBlockIndex()];
        LLVMBitcodeInstructionVisitor visitor = new LLVMBitcodeInstructionVisitor(exceptionSlot, uniquesRegion, blockPhis, method.getParameters().size(), symbols, context, blockNullerInfos, neededForDebug, dataLayout, nodeFactory);
        if (initDebugValues) {
            for (SourceVariable variable : method.getSourceFunction().getVariables()) {
                if (variable.hasFragments()) {
                    visitor.initializeAggregateLocalVariable(variable);
                }
            }
            initDebugValues = false;
        }
        for (int i = 0; i < block.getInstructionCount(); i++) {
            visitor.setInstructionIndex(i);
            block.getInstruction(i).accept(visitor);
        }
        LLVMStatementNode[] nodes = visitor.finish();
        info.setBlockDebugInfo(block.getBlockIndex(), visitor.getDebugInfo());
        blockNodes[block.getBlockIndex()] = LLVMBasicBlockNode.createBasicBlockNode(options, nodes, visitor.getControlFlowNode(), block.getBlockIndex(), block.getName());
    }
    for (int j = 0; j < blockNodes.length; j++) {
        int[] nullableBeforeBlock = getNullableFrameSlots(liveness.getFrameSlots(), liveness.getNullableBeforeBlock()[j]);
        int[] nullableAfterBlock = getNullableFrameSlots(liveness.getFrameSlots(), liveness.getNullableAfterBlock()[j]);
        blockNodes[j].setNullableFrameSlots(nullableBeforeBlock, nullableAfterBlock);
    }
    info.setBlocks(blockNodes);
    int loopSuccessorSlot = -1;
    if (options.get(SulongEngineOption.OSR_MODE) == SulongEngineOption.OSRMode.CFG && !options.get(SulongEngineOption.AOTCacheStore)) {
        LLVMControlFlowGraph cfg = new LLVMControlFlowGraph(method.getBlocks().toArray(FunctionDefinition.EMPTY));
        cfg.build();
        if (cfg.isReducible() && cfg.getCFGLoops().size() > 0) {
            loopSuccessorSlot = builder.addSlot(FrameSlotKind.Int, null, null);
            resolveLoops(blockNodes, cfg, loopSuccessorSlot, exceptionSlot, info, options);
        }
    }
    LLVMSourceLocation location = method.getLexicalScope();
    rootFunction.setSourceLocation(LLVMSourceLocation.orDefault(location));
    LLVMStatementNode[] copyArgumentsToFrameArray = copyArgumentsToFrame(symbols).toArray(LLVMStatementNode.NO_STATEMENTS);
    FrameDescriptor frame = builder.build();
    RootNode rootNode = nodeFactory.createFunction(exceptionSlot, blockNodes, uniquesRegion, copyArgumentsToFrameArray, frame, loopSuccessorSlot, info, method.getName(), method.getSourceName(), method.getParameters().size(), source, location, rootFunction);
    method.onAfterParse();
    if (printAST) {
        printCompactTree(rootNode);
        LLVMContext.printAstLog("");
    }
    return rootNode.getCallTarget();
}
Also used : RootNode(com.oracle.truffle.api.nodes.RootNode) OptionValues(org.graalvm.options.OptionValues) LLVMSymbolReadResolver(com.oracle.truffle.llvm.parser.nodes.LLVMSymbolReadResolver) LLVMSourceLocation(com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation) GetStackSpaceFactory(com.oracle.truffle.llvm.runtime.GetStackSpaceFactory) Phi(com.oracle.truffle.llvm.parser.LLVMPhiManager.Phi) SourceVariable(com.oracle.truffle.llvm.parser.metadata.debuginfo.SourceVariable) LLVMControlFlowGraph(com.oracle.truffle.llvm.parser.util.LLVMControlFlowGraph) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) List(java.util.List) ArrayList(java.util.ArrayList) InstructionBlock(com.oracle.truffle.llvm.parser.model.blocks.InstructionBlock) FunctionParameter(com.oracle.truffle.llvm.parser.model.functions.FunctionParameter) FrameDescriptor(com.oracle.truffle.api.frame.FrameDescriptor) LLVMContext(com.oracle.truffle.llvm.runtime.LLVMContext) LLVMLivenessAnalysisResult(com.oracle.truffle.llvm.parser.LLVMLivenessAnalysis.LLVMLivenessAnalysisResult) LLVMBitcodeInstructionVisitor(com.oracle.truffle.llvm.parser.nodes.LLVMBitcodeInstructionVisitor) SSAValue(com.oracle.truffle.llvm.runtime.types.symbols.SSAValue) UniquesRegion(com.oracle.truffle.llvm.runtime.memory.LLVMStack.UniquesRegion) CommonNodeFactory(com.oracle.truffle.llvm.runtime.CommonNodeFactory) NodeFactory(com.oracle.truffle.llvm.runtime.NodeFactory) LLVMRuntimeDebugInformation(com.oracle.truffle.llvm.parser.nodes.LLVMRuntimeDebugInformation) LLVMBasicBlockNode(com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode)

Example 2 with GetStackSpaceFactory

use of com.oracle.truffle.llvm.runtime.GetStackSpaceFactory 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 3 with GetStackSpaceFactory

use of com.oracle.truffle.llvm.runtime.GetStackSpaceFactory 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)

Aggregations

GetStackSpaceFactory (com.oracle.truffle.llvm.runtime.GetStackSpaceFactory)3 LLVMStatementNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode)3 FunctionParameter (com.oracle.truffle.llvm.parser.model.functions.FunctionParameter)2 CommonNodeFactory (com.oracle.truffle.llvm.runtime.CommonNodeFactory)2 NodeFactory (com.oracle.truffle.llvm.runtime.NodeFactory)2 ArrayList (java.util.ArrayList)2 FrameDescriptor (com.oracle.truffle.api.frame.FrameDescriptor)1 RootNode (com.oracle.truffle.api.nodes.RootNode)1 LLVMLivenessAnalysisResult (com.oracle.truffle.llvm.parser.LLVMLivenessAnalysis.LLVMLivenessAnalysisResult)1 LLVMParserRuntime (com.oracle.truffle.llvm.parser.LLVMParserRuntime)1 Phi (com.oracle.truffle.llvm.parser.LLVMPhiManager.Phi)1 SourceVariable (com.oracle.truffle.llvm.parser.metadata.debuginfo.SourceVariable)1 InstructionBlock (com.oracle.truffle.llvm.parser.model.blocks.InstructionBlock)1 GlobalVariable (com.oracle.truffle.llvm.parser.model.symbols.globals.GlobalVariable)1 LLVMBitcodeInstructionVisitor (com.oracle.truffle.llvm.parser.nodes.LLVMBitcodeInstructionVisitor)1 LLVMRuntimeDebugInformation (com.oracle.truffle.llvm.parser.nodes.LLVMRuntimeDebugInformation)1 LLVMSymbolReadResolver (com.oracle.truffle.llvm.parser.nodes.LLVMSymbolReadResolver)1 LLVMControlFlowGraph (com.oracle.truffle.llvm.parser.util.LLVMControlFlowGraph)1 LLVMContext (com.oracle.truffle.llvm.runtime.LLVMContext)1 DataLayout (com.oracle.truffle.llvm.runtime.datalayout.DataLayout)1