use of com.oracle.truffle.llvm.parser.model.symbols.instructions.PhiInstruction 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.symbols.instructions.PhiInstruction 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);
}
Aggregations