Instruction last = sourceBlock.getFirstInstruction(); for (Instruction insn : sourceBlock) { if (insn instanceof InvokeInstruction) { if (sourceBlock.getExceptionVariable() != null) { targetBlock.setExceptionVariable(targetBlock.getProgram().variableAt( sourceBlock.getExceptionVariable().getIndex())); targetBlock.addAll(ProgramUtils.copyInstructions(last, insn, targetBlock.getProgram())); targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock, targetBlock.getProgram())); for (TryCatchBlock tryCatch : targetBlock.getTryCatchBlocks()) { if (tryCatch.getHandler() != null) { Step next = new Step(); next.source = tryCatch.getHandler().getIndex(); next.targetPart = step.targetPart; queue.add(next); step.targetPart.splitPoints[targetBlock.getIndex()] = insn; step.targetPart.blockSuccessors[targetBlock.getIndex()] = partMap.get(insn); continue taskLoop; step.targetPart.blockSuccessors[targetBlock.getIndex()] = partId; if (targetBlock.getIndex() > 0) { JumpInstruction jumpToNextBlock = new JumpInstruction(); jumpToNextBlock.setTarget(targetBlock); nextProgram.basicBlockAt(0).add(jumpToNextBlock);
public static void copyBasicBlock(BasicBlockReader block, BasicBlock target) { Program targetProgram = target.getProgram(); if (block.getExceptionVariable() != null) { target.setExceptionVariable(targetProgram.variableAt(block.getExceptionVariable().getIndex())); } InstructionCopyReader copyReader = new InstructionCopyReader(targetProgram); for (InstructionIterator iterator = block.iterateInstructions(); iterator.hasNext();) { iterator.next(); iterator.read(copyReader); target.add(copyReader.getCopy()); } target.getPhis().addAll(copyPhis(block, targetProgram)); target.getTryCatchBlocks().addAll(copyTryCatches(block, targetProgram)); }
private boolean isTrivialBlock(BasicBlock block) { if (exceptionHandlers[block.getIndex()]) { return false; } if (block.instructionCount() != 1 || block.getExceptionVariable() != null) { return false; } Instruction instruction = block.getLastInstruction(); return instruction instanceof JumpInstruction || instruction instanceof BranchingInstruction || instruction instanceof BinaryBranchingInstruction; }
public void apply(BasicBlock block) { if (block.getExceptionVariable() != null) { block.setExceptionVariable(map(block.getExceptionVariable())); } applyToInstructions(block); applyToPhis(block); }
public BasicBlockMapper(IntUnaryOperator mapFunction) { this((BasicBlock block) -> block.getProgram().basicBlockAt(mapFunction.applyAsInt(block.getIndex()))); }
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { for (Phi phi : tryCatch.getHandler().getPhis()) { List<Variable> sourceVariables = phi.getIncomings().stream() .filter(incoming -> incoming.getSource() == tryCatch.getProtectedBlock()) BasicBlock sourceVarDefinedAt = variableDefinitionPlaces[sourceVar.getIndex()]; if (sourceVar.getIndex() < parameterCount || dom.dominates(sourceVarDefinedAt.getIndex(), block.getIndex())) { currentJointSources[phi.getReceiver().getIndex()] = sourceVar.getIndex(); break; } else { next = program.createBasicBlock(); next.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program)); blocksToClearHandlers.add(next); Instruction nextInsn = insn.getNext(); nextInsn.delete(); next.add(nextInsn); currentJointSources, outgoingVariablesToRemove, variablesDefinedHere); post = setLocation(post, insn.getLocation()); block.getLastInstruction().insertPreviousAll(pre); block.addAll(post); hasExceptionHandlers = true; blockToClear.getTryCatchBlocks().clear(); return block.getIndex();
Instruction insn = planEntry.targetInstruction.getNext(); insn.delete(); splitBlock.add(insn); splitBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program)); InitClassInstruction clinit = new InitClassInstruction(); clinit.setClassName(invoke.getMethod().getClassName()); block.add(clinit); block.add(jumpToInlinedProgram); BasicBlock inlineBlock = program.basicBlockAt(firstInlineBlock.getIndex() + i); while (blockToInline.getFirstInstruction() != null) { Instruction insn = blockToInline.getFirstInstruction(); insn.delete(); inlineBlock.add(insn); List<Phi> phis = new ArrayList<>(blockToInline.getPhis()); blockToInline.getPhis().clear(); inlineBlock.getPhis().addAll(phis); List<TryCatchBlock> tryCatches = new ArrayList<>(blockToInline.getTryCatchBlocks()); blockToInline.getTryCatchBlocks().clear(); inlineBlock.getTryCatchBlocks().addAll(tryCatches); inlineBlock.setExceptionVariable(blockToInline.getExceptionVariable()); program.basicBlockAt(b.getIndex() + firstInlineBlock.getIndex()));
targetBlock.setExceptionVariable(sourceBlock.getExceptionVariable()); List<Instruction> instructionCopies = ProgramUtils.copyInstructions(sourceBlock.getFirstInstruction(), null, targetBlock.getProgram()); for (Instruction insn : instructionCopies) { insn.acceptVisitor(blockMapper); targetBlock.add(insn); for (Phi phi : sourceBlock.getPhis()) { Phi phiCopy = new Phi(); phiCopy.setReceiver(phi.getReceiver()); for (Incoming incoming : phi.getIncomings()) { Incoming incomingCopy = new Incoming(); int source = incoming.getSource().getIndex(); incomingCopy.setSource(program.basicBlockAt(copiedNodes.getOrDefault(source, source))); incomingCopy.setValue(incoming.getValue()); phiCopy.getIncomings().add(incomingCopy); targetBlock.getPhis().add(phiCopy); for (TryCatchBlock tryCatch : sourceBlock.getTryCatchBlocks()) { TryCatchBlock tryCatchCopy = new TryCatchBlock(); int handler = tryCatch.getHandler().getIndex(); tryCatchCopy.setExceptionType(tryCatch.getExceptionType()); tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler))); targetBlock.getTryCatchBlocks().add(tryCatchCopy); if (copiedNodes.containsKey(block.getIndex())) { continue;
public void addAll(Iterable<Instruction> instructions) { for (Instruction instruction : instructions) { add(instruction); } }
private void insertCopy(Incoming incoming, Map<BasicBlock, BasicBlock> blockMap) { Phi phi = incoming.getPhi(); Program program = phi.getBasicBlock().getProgram(); AssignInstruction copyInstruction = new AssignInstruction(); Variable firstCopy = program.createVariable(); firstCopy.setLabel(phi.getReceiver().getLabel()); firstCopy.setDebugName(phi.getReceiver().getDebugName()); copyInstruction.setReceiver(firstCopy); copyInstruction.setAssignee(incoming.getValue()); BasicBlock source = blockMap.get(incoming.getSource()); if (source == null) { source = incoming.getSource(); } else { incoming.setSource(source); } if (!(incoming.getSource().getLastInstruction() instanceof JumpInstruction)) { BasicBlock copyBlock = program.createBasicBlock(); JumpInstruction jumpInstruction = new JumpInstruction(); jumpInstruction.setLocation(incoming.getSource().getLastInstruction().getLocation()); jumpInstruction.setTarget(phi.getBasicBlock()); copyBlock.add(jumpInstruction); incoming.getSource().getLastInstruction().acceptVisitor(new BasicBlockMapper((int block) -> block == phi.getBasicBlock().getIndex() ? copyBlock.getIndex() : block)); blockMap.put(source, copyBlock); incoming.setSource(copyBlock); source = copyBlock; } source.getLastInstruction().insertPrevious(copyInstruction); incoming.setValue(copyInstruction.getReceiver()); }
basicBlock.addAll(marshallInstructions); marshallInstructions.clear(); invocation.setMethod(methodRef); invocation.setArguments(variablesToPass); basicBlock.add(invocation); exit.setValueToReturn(marshaller.wrapArgument(callLocation, invocation.getReceiver(), method.getResultType(), false)); basicBlock.addAll(marshallInstructions); marshallInstructions.clear(); basicBlock.add(exit);
int blockCount = program.basicBlockCount(); for (int i = 0; i < blockCount; ++i) { allPhis.addAll(program.basicBlockAt(i).getPhis()); for (int i = 0; i < blockCount; ++i) { BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers.add(tryCatch.getHandler()); if (block.getExceptionVariable() != null) { InvokeInstruction catchCall = new InvokeInstruction(); catchCall.setType(InvocationType.SPECIAL); catchCall.setMethod(new MethodReference(ExceptionHandling.class, "catchException", Throwable.class)); catchCall.setReceiver(block.getExceptionVariable()); block.addFirst(catchCall); block.setExceptionVariable(null); if (!exceptionHandlers.contains(phi.getBasicBlock())) { for (Incoming incoming : phi.getIncomings()) { int mappedSource = blockMapping[incoming.getSource().getIndex()]; incoming.setSource(program.basicBlockAt(mappedSource));
JumpInstruction insn = new JumpInstruction(); insn.setTarget(newBasicBlock); basicBlock.add(insn); if (basicBlock.instructionCount() > 0) { Map<Integer, String> debugNames = new HashMap<>(accumulatedDebugNames); variableDebugNames.put(basicBlock.getFirstInstruction(), debugNames); insn.setLocation(lastLocation); basicBlock.addAll(builtInstructions);
Instruction toMove = instruction.getNext(); toMove.delete(); continueBlock.add(toMove); continueBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program)); initBlock.add(instruction); JumpInstruction jumpToContinue = new JumpInstruction(); jumpToContinue.setTarget(continueBlock); initBlock.add(jumpToContinue); basicBlockMap[i] = continueBlock.getIndex(); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { int source = incoming.getSource().getIndex(); BasicBlock mappedSource = program.basicBlockAt(basicBlockMap[source]); incoming.setSource(mappedSource);
BasicBlock header = program.basicBlockAt(headerIndex); escapeInsn.setTarget(header); preheader.add(escapeInsn); for (Phi phi : header.getPhis()) { Phi preheaderPhi = null; for (int i = 0; i < phi.getIncomings().size(); ++i) { Incoming incoming = phi.getIncomings().get(i); if (!dom.dominates(headerIndex, incoming.getSource().getIndex())) { phi.getIncomings().remove(i--); if (preheaderPhi == null) { preheaderPhi.getReceiver().setLabel(phi.getReceiver().getLabel()); preheaderPhi.getReceiver().setDebugName(phi.getReceiver().getDebugName()); preheader.getPhis().add(preheaderPhi); if (!dom.dominates(headerIndex, predIndex)) { BasicBlock pred = program.basicBlockAt(predIndex); pred.getLastInstruction().acceptVisitor(new BasicBlockMapper( (int block) -> block == header.getIndex() ? preheader.getIndex() : block)); return preheader.getIndex();
public BasicBlock split(BasicBlock block, Instruction afterInstruction) { initIfNecessary(); if (afterInstruction.getBasicBlock() != block) { throw new IllegalArgumentException(); } if (isLastInSequence.get(block.getIndex()) == 0) { throw new IllegalArgumentException(); } BasicBlock splitBlock = program.createBasicBlock(); while (previousPtr.size() < splitBlock.getIndex()) { previousPtr.add(previousPtr.size()); firstPtr.add(firstPtr.size()); isLastInSequence.add((byte) 1); } isLastInSequence.set(block.getIndex(), (byte) 0); previousPtr.add(block.getIndex()); firstPtr.add(firstPtr.get(block.getIndex())); mappings[firstPtr.get(block.getIndex())] = splitBlock.getIndex(); isLastInSequence.add((byte) 1); splitBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(block, program)); while (afterInstruction.getNext() != null) { Instruction nextInstruction = afterInstruction.getNext(); nextInstruction.delete(); splitBlock.add(nextInstruction); } return splitBlock; }
private Variable createVariable(ValueImpl<?> value, CallLocation location) { if (value.context == this) { return value.innerValue; } Variable outerVar = getParent().emitVariable(value, location); CapturedValue capturedValue = capturedValueMap.computeIfAbsent(outerVar, v -> { FieldHolder field = new FieldHolder("proxyCapture" + suffixGenerator++); field.setLevel(AccessLevel.PUBLIC); field.setType(value.type); proxyClass.addField(field); CapturedValue result = new CapturedValue(field, v); capturedValues.add(result); return result; }); Program program = startBlock.getProgram(); Variable var = program.createVariable(); GetFieldInstruction insn = new GetFieldInstruction(); insn.setInstance(program.variableAt(0)); insn.setField(capturedValue.field.getReference()); insn.setFieldType(capturedValue.field.getType()); insn.setReceiver(var); startBlock.add(insn); return var; }
private BitSet getUsedVarsInBlock(LivenessAnalyzer liveness, BasicBlock block) { BitSet usedVars = new BitSet(); TransitionExtractor transitionExtractor = new TransitionExtractor(); block.getLastInstruction().acceptVisitor(transitionExtractor); for (BasicBlock successor : transitionExtractor.getTargets()) { usedVars.or(liveness.liveIn(successor.getIndex())); } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { usedVars.or(liveness.liveIn(tryCatch.getHandler().getIndex())); } return usedVars; }
JumpInstruction insn = new JumpInstruction(); insn.setTarget(program.basicBlockAt(1)); program.basicBlockAt(0).add(insn); doAnalyze(method); assemble(method); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (int j = 0; j < block.getTryCatchBlocks().size(); ++j) { TryCatchBlock tryCatch = block.getTryCatchBlocks().get(j); if (tryCatch.getHandler() == block) { block.getTryCatchBlocks().remove(j--); program.createVariable(); program.basicBlockAt(0).getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches( program.basicBlockAt(1), program)); return program;
public void fixProgram() { if (mappings == null) { return; } for (BasicBlock block : program.getBasicBlocks()) { Map<BasicBlock, List<Incoming>> incomingsBySource = new LinkedHashMap<>(); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { if (mappings[incoming.getSource().getIndex()] == incoming.getSource().getIndex()) { continue; } incomingsBySource.computeIfAbsent(incoming.getSource(), b -> new ArrayList<>()).add(incoming); } } for (BasicBlock source : incomingsBySource.keySet()) { boolean isExceptionHandler = source.getTryCatchBlocks().stream() .anyMatch(tryCatch -> tryCatch.getHandler() == block); if (isExceptionHandler) { fixIncomingsInExceptionHandler(source, incomingsBySource.get(source)); } else { BasicBlock newSource = program.basicBlockAt(mappings[source.getIndex()]); for (Incoming incoming : incomingsBySource.get(source)) { incoming.setSource(newSource); } } } } RedundantJumpElimination.optimize(program); }