private void putLiveInGCRoots(Program program, List<Map<Instruction, int[]>> updateInformation) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); Map<Instruction, int[]> updatesByIndex = updateInformation.get(i); Instruction[] callSiteLocations = updatesByIndex.keySet().toArray(new Instruction[0]); ObjectIntMap<Instruction> instructionIndexes = getInstructionIndexes(block); Arrays.sort(callSiteLocations, Comparator.comparing(instructionIndexes::get)); for (Instruction callSiteLocation : updatesByIndex.keySet()) { int[] updates = updatesByIndex.get(callSiteLocation); storeLiveIns(block, callSiteLocation, updates); } } }
public static List<List<Incoming>> getPhiOutputs(Program program) { List<List<Incoming>> outputs = new ArrayList<>(program.basicBlockCount()); for (int i = 0; i < program.basicBlockCount(); ++i) { outputs.add(new ArrayList<>()); } for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { outputs.get(incoming.getSource().getIndex()).add(incoming); } } } return outputs; }
@Override public boolean optimize(MethodOptimizationContext context, Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { optimize(program.basicBlockAt(i)); } return false; }
public void transformProgram() { for (int i = 0; i < program.basicBlockCount(); ++i) { transformBasicBlock(program.basicBlockAt(i)); } }
public void transform(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { transform(program.basicBlockAt(i)); } }
private void initIfNecessary() { if (mappings != null) { return; } mappings = new int[program.basicBlockCount()]; previousPtr = new IntArrayList(program.basicBlockCount() * 2); firstPtr = new IntArrayList(program.basicBlockCount() * 2); isLastInSequence = new ByteArrayList(program.basicBlockCount() * 2); for (int i = 0; i < mappings.length; ++i) { mappings[i] = i; previousPtr.add(i); firstPtr.add(i); isLastInSequence.add((byte) 1); } variableDefinedAt = ProgramUtils.getVariableDefinitionPlaces(program); }
private void addSynthesizedPhis() { for (int i = 0; i < program.basicBlockCount(); ++i) { for (Phi phi : synthesizedPhisByBlock.get(i)) { if (!usedPhis.get(phi.getReceiver().getIndex())) { continue; } if (!phi.getIncomings().isEmpty()) { program.basicBlockAt(i).getPhis().add(phi); synthesizedPhis.add(phi); } } } }
public void apply(Program program, MethodReference method) { depthsByBlock = new IntArrayList(program.basicBlockCount()); for (int i = 0; i < program.basicBlockCount(); ++i) { depthsByBlock.add(0); } instructionsToSkip = new HashSet<>(); while (applyOnce(program)) { devirtualize(program, method, dependencyInfo); } depthsByBlock = null; instructionsToSkip = null; new UnreachableBasicBlockEliminator().optimize(program); }
private List<Set<Phi>> getDestinationPhis(Program program) { List<Set<Phi>> destinationPhis = new ArrayList<>(); destinationPhis.addAll(Collections.nCopies(program.variableCount(), null)); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { Set<Phi> phis = destinationPhis.get(incoming.getValue().getIndex()); if (phis == null) { phis = new LinkedHashSet<>(); destinationPhis.set(incoming.getValue().getIndex(), phis); } phis.add(phi); } } } return destinationPhis; }
public static boolean[] findEscapingVariables(Program program) { boolean[] escaping = new boolean[program.variableCount()]; InstructionAnalyzer analyzer = new InstructionAnalyzer(escaping); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Instruction insn : block) { insn.acceptVisitor(analyzer); } } return escaping; }
private void fillExceptionHandlers(Program program) { exceptionHandlers = new boolean[program.basicBlockCount()]; for (int i = 0; i < exceptionHandlers.length; ++i) { BasicBlock block = program.basicBlockAt(i); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { exceptionHandlers[tryCatch.getHandler().getIndex()] = true; } } }
public void apply(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Instruction insn : block) { if (insn instanceof InitClassInstruction) { if (!filter(((InitClassInstruction) insn).getClassName())) { insn.delete(); } } } } }
private int[] getInputCount(Program program) { int[] inputCount = new int[program.variableCount()]; for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Phi phi : block.getPhis()) { inputCount[phi.getReceiver().getIndex()] = phi.getIncomings().size(); } } return inputCount; }
public void submit(ClassHolder cls) { if (innerSource.get(cls.getName()) != null || generatedClasses.containsKey(cls.getName())) { throw new IllegalArgumentException("Class " + cls.getName() + " is already defined"); } if (!transformers.isEmpty()) { for (ClassHolderTransformer transformer : transformers) { transformer.transformClass(cls, transformContext); } cls = ModelUtils.copyClass(cls); } generatedClasses.put(cls.getName(), cls); for (MethodHolder method : cls.getMethods()) { if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) { new UnreachableBasicBlockEliminator().optimize(method.getProgram()); } } cache.remove(cls.getName()); }
private void insertPhiArgumentsCopies(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { Map<BasicBlock, BasicBlock> blockMap = new HashMap<>(); for (Phi phi : program.basicBlockAt(i).getPhis()) { for (Incoming incoming : phi.getIncomings()) { insertCopy(incoming, blockMap); } } for (Phi phi : program.basicBlockAt(i).getPhis()) { for (Incoming incoming : phi.getIncomings()) { insertCopy(incoming, blockMap); } } } }
public void rename(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock basicBlock = program.basicBlockAt(i); for (Instruction insn : basicBlock) { insn.acceptVisitor(this); } for (TryCatchBlock tryCatch : basicBlock.getTryCatchBlocks()) { if (tryCatch.getExceptionType() != null) { tryCatch.setExceptionType(classNameMapper.map(tryCatch.getExceptionType())); } } } }
private DisjointSet buildPhiCongruenceClasses(Program program) { DisjointSet classes = new DisjointSet(); for (int i = 0; i < program.variableCount(); ++i) { classes.create(); } for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { classes.union(phi.getReceiver().getIndex(), incoming.getValue().getIndex()); } } } return classes; } }
private Program createStubCopy(Program program) { Program copy = new Program(); for (int i = 0; i < program.basicBlockCount(); ++i) { copy.createBasicBlock(); } for (int i = 0; i < program.variableCount(); ++i) { Variable var = program.variableAt(i); copy.createVariable(); Variable varCopy = copy.variableAt(i); varCopy.setRegister(var.getRegister()); varCopy.setDebugName(var.getDebugName()); varCopy.setLabel(var.getLabel()); } return copy; }
public static Graph build(Program program) { GraphBuilder builder = new GraphBuilder(program.variableCount()); InstructionAnalyzer analyzer = new InstructionAnalyzer(builder); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Instruction insn : block) { insn.acceptVisitor(analyzer); } for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } } return builder.build(); }
private void renameVariables(Program program, int[] varMap) { InstructionVariableMapper mapper = new InstructionVariableMapper(var -> program.variableAt(varMap[var.getIndex()])); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); mapper.apply(block); } String[] originalNames = getVariableNames(program, false); for (int i = 0; i < program.variableCount(); ++i) { program.variableAt(i).setDebugName(null); } for (int i = 0; i < program.variableCount(); ++i) { Variable var = program.variableAt(varMap[i]); if (originalNames[i] != null) { var.setDebugName(originalNames[i]); } } }