use of com.oracle.truffle.llvm.parser.model.functions.FunctionParameter in project sulong by graalvm.
the class LLVMBitcodeInstructionVisitor method visitDebugIntrinsic.
private void visitDebugIntrinsic(SymbolImpl value, SourceVariable variable, MDExpression expression, long index, boolean isDeclaration) {
FrameSlot valueSlot = null;
if (value instanceof ValueInstruction) {
valueSlot = frame.findFrameSlot(((ValueInstruction) value).getName());
} else if (value instanceof FunctionParameter) {
valueSlot = frame.findFrameSlot(((FunctionParameter) value).getName());
}
if (valueSlot != null) {
final LLVMExpressionNode typeNode = nodeFactory.registerSourceType(valueSlot, variable.getSourceType());
if (typeNode != null) {
addInstructionUnchecked(typeNode);
}
}
final LLVMExpressionNode dbgIntrinsic = dbgInfoHandler.handleDebugIntrinsic(value, variable, expression, index, isDeclaration);
if (dbgIntrinsic != null) {
addInstructionUnchecked(dbgIntrinsic);
}
handleNullerInfo();
}
use of com.oracle.truffle.llvm.parser.model.functions.FunctionParameter in project sulong by graalvm.
the class StackManager method createFrame.
public static FrameDescriptor createFrame(FunctionDefinition function) {
final FrameDescriptor frame = new FrameDescriptor();
frame.addFrameSlot(LLVMException.FRAME_SLOT_ID, null, FrameSlotKind.Object);
frame.addFrameSlot(LLVMStack.FRAME_ID, PointerType.VOID, FrameSlotKind.Object);
for (FunctionParameter parameter : function.getParameters()) {
Type type = parameter.getType();
if (parameter.isSourceVariable()) {
type = type.shallowCopy();
}
frame.addFrameSlot(parameter.getName(), type, Type.getFrameSlotKind(type));
}
final StackAllocationFunctionVisitor functionVisitor = new StackAllocationFunctionVisitor(frame);
function.accept((FunctionVisitor) functionVisitor);
return frame;
}
use of com.oracle.truffle.llvm.parser.model.functions.FunctionParameter in project sulong by graalvm.
the class LLVMLivenessAnalysis method initializeGenKill.
private static BlockInfo[] initializeGenKill(FrameDescriptor frame, Map<InstructionBlock, List<LLVMPhiManager.Phi>> phis, FunctionDefinition functionDefinition, List<InstructionBlock> blocks) {
BlockInfo[] result = new BlockInfo[blocks.size()];
for (int i = 0; i < blocks.size(); i++) {
InstructionBlock block = blocks.get(i);
BlockInfo blockInfo = result[i] = new BlockInfo(frame.getSize());
if (i == 0) {
// in the first block, the arguments are also always alive
for (FunctionParameter param : functionDefinition.getParameters()) {
processRead(blockInfo, frame.findFrameSlot(param.getName()).getIndex());
}
}
LLVMLivenessReadVisitor readVisitor = new LLVMLivenessReadVisitor(frame, blockInfo);
for (int j = 0; j < block.getInstructionCount(); j++) {
Instruction instruction = block.getInstruction(j);
if (instruction instanceof PhiInstruction) {
processPhiWrite(frame, (PhiInstruction) instruction, blockInfo);
} else {
processReads(readVisitor, instruction);
processWrite(frame, instruction, blockInfo);
}
}
List<LLVMPhiManager.Phi> bbPhis = phis.getOrDefault(block, Collections.emptyList());
for (LLVMPhiManager.Phi phi : bbPhis) {
processValueUsedInPhi(frame, phi.getValue(), blockInfo);
}
}
return result;
}
use of com.oracle.truffle.llvm.parser.model.functions.FunctionParameter in project sulong by graalvm.
the class LLVMLivenessAnalysis method computeLivenessAnalysisResult.
private static LLVMLivenessAnalysisResult computeLivenessAnalysisResult(FunctionDefinition functionDefinition, List<InstructionBlock> blocks, FrameDescriptor frame, BlockInfo[] blockInfos, ArrayList<InstructionBlock>[] predecessors) {
@SuppressWarnings("unchecked") ArrayList<NullerInformation>[] nullableWithinBlock = new ArrayList[blocks.size()];
BitSet[] nullableBeforeBlock = new BitSet[blocks.size()];
BitSet[] nullableAfterBlock = new BitSet[blocks.size()];
int[] lastInstructionIndexTouchingLocal = new int[frame.getSize()];
LLVMNullerReadVisitor nullerReadVisitor = new LLVMNullerReadVisitor(frame, lastInstructionIndexTouchingLocal);
for (int i = 0; i < blocks.size(); i++) {
ArrayList<NullerInformation> blockNullers = new ArrayList<>();
Arrays.fill(lastInstructionIndexTouchingLocal, -1);
BlockInfo blockInfo = blockInfos[i];
// we destroy the kill and phiDefs bitsets as they are no longer needed anyways
blockInfo.kill.clear();
blockInfo.phiDefs.clear();
if (i == 0) {
// instruction
for (FunctionParameter param : functionDefinition.getParameters()) {
int frameSlotIndex = frame.findFrameSlot(param.getName()).getIndex();
lastInstructionIndexTouchingLocal[frameSlotIndex] = 0;
}
}
InstructionBlock block = blocks.get(i);
for (int j = 0; j < block.getInstructionCount(); j++) {
Instruction instruction = block.getInstruction(j);
if (instruction instanceof PhiInstruction) {
// we need to skip the reads of phi nodes as they belong to a different block
} else {
nullerReadVisitor.setInstructionIndex(j);
instruction.accept(nullerReadVisitor);
}
int frameSlotIndex = resolve(frame, instruction);
if (frameSlotIndex >= 0) {
// the write)
if (lastInstructionIndexTouchingLocal[frameSlotIndex] != -1 && lastInstructionIndexTouchingLocal[frameSlotIndex] != j) {
blockNullers.add(new NullerInformation(frameSlotIndex, lastInstructionIndexTouchingLocal[frameSlotIndex]));
}
lastInstructionIndexTouchingLocal[frameSlotIndex] = j;
}
}
// compute the values that die in this block. we do that in place, i.e., we destroy the
// def bitset that is no longer needed anyways.
blockInfo.defs.or(blockInfo.in);
blockInfo.defs.andNot(blockInfo.out);
int terminatingInstructionIndex = block.getInstructionCount() - 1;
BitSet valuesThatDieInBlock = blockInfo.defs;
int bitIndex = -1;
while ((bitIndex = valuesThatDieInBlock.nextSetBit(bitIndex + 1)) >= 0) {
assert lastInstructionIndexTouchingLocal[bitIndex] >= 0 : "must have a last usage, otherwise the value would not be alive in this block";
if (blockInfo.phiUses.get(bitIndex) || lastInstructionIndexTouchingLocal[bitIndex] == terminatingInstructionIndex) {
// if a value dies that is used in a phi function or in a terminating
// instruction, it dies after the block
blockInfo.phiDefs.set(bitIndex);
} else {
blockNullers.add(new NullerInformation(bitIndex, lastInstructionIndexTouchingLocal[bitIndex]));
}
}
// compute the values that can be nulled out before we enter this block.
for (InstructionBlock predecessor : predecessors[i]) {
BlockInfo predInfo = blockInfos[predecessor.getBlockIndex()];
blockInfo.kill.or(predInfo.out);
}
blockInfo.kill.andNot(blockInfo.in);
// collect the results
Collections.sort(blockNullers);
nullableWithinBlock[i] = blockNullers;
nullableBeforeBlock[i] = blockInfo.kill;
nullableAfterBlock[i] = blockInfo.phiDefs;
}
return new LLVMLivenessAnalysisResult(nullableWithinBlock, nullableBeforeBlock, nullableAfterBlock);
}
use of com.oracle.truffle.llvm.parser.model.functions.FunctionParameter in project sulong by graalvm.
the class LazyToTruffleConverterImpl method copyArgumentsToFrame.
private List<LLVMExpressionNode> copyArgumentsToFrame(FrameDescriptor frame) {
List<FunctionParameter> parameters = method.getParameters();
List<LLVMExpressionNode> formalParamInits = new ArrayList<>();
LLVMExpressionNode stackPointerNode = nodeFactory.createFunctionArgNode(0, PrimitiveType.I64);
formalParamInits.add(nodeFactory.createFrameWrite(runtime, PointerType.VOID, stackPointerNode, frame.findFrameSlot(LLVMStack.FRAME_ID), null));
int argIndex = 1;
if (method.getType().getReturnType() instanceof StructureType) {
argIndex++;
}
for (FunctionParameter parameter : parameters) {
LLVMExpressionNode parameterNode = nodeFactory.createFunctionArgNode(argIndex++, parameter.getType());
FrameSlot slot = frame.findFrameSlot(parameter.getName());
if (isStructByValue(parameter)) {
Type type = ((PointerType) parameter.getType()).getPointeeType();
formalParamInits.add(nodeFactory.createFrameWrite(runtime, parameter.getType(), nodeFactory.createCopyStructByValue(runtime, type, parameterNode), slot, null));
} else {
formalParamInits.add(nodeFactory.createFrameWrite(runtime, parameter.getType(), parameterNode, slot, null));
}
}
return formalParamInits;
}
Aggregations