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