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();
}
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;
}
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);
}
Aggregations