2007-02-02 17:17:13 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* IBM Corporation - initial API and implementation
|
|
|
|
*****************************************************************************/
|
|
|
|
package com.ibm.wala.cast.ir.ssa;
|
|
|
|
|
2017-01-12 17:25:37 +00:00
|
|
|
import java.util.ArrayList;
|
2007-02-08 19:08:31 +00:00
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
import com.ibm.wala.ssa.IR;
|
2007-09-02 14:45:07 +00:00
|
|
|
import com.ibm.wala.ssa.ISSABasicBlock;
|
2007-02-08 19:08:31 +00:00
|
|
|
import com.ibm.wala.ssa.SSACFG;
|
2010-10-11 14:39:22 +00:00
|
|
|
import com.ibm.wala.ssa.SSACFG.BasicBlock;
|
2007-02-08 19:08:31 +00:00
|
|
|
import com.ibm.wala.ssa.SSAInstruction;
|
|
|
|
import com.ibm.wala.ssa.SSAOptions;
|
2010-10-11 14:39:22 +00:00
|
|
|
import com.ibm.wala.ssa.SSAOptions.DefaultValues;
|
2007-02-08 19:08:31 +00:00
|
|
|
import com.ibm.wala.ssa.SSAPhiInstruction;
|
|
|
|
import com.ibm.wala.ssa.SymbolTable;
|
2008-07-25 18:19:55 +00:00
|
|
|
import com.ibm.wala.util.collections.ArrayIterator;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.util.collections.IntStack;
|
|
|
|
import com.ibm.wala.util.graph.Graph;
|
2008-01-24 22:53:51 +00:00
|
|
|
import com.ibm.wala.util.graph.dominators.DominanceFrontiers;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Abstract core of traditional SSA conversion (Cytron et al.).
|
2007-02-08 20:45:07 +00:00
|
|
|
*
|
|
|
|
* This implementation is abstract in the sense that it is designed to work over
|
2007-09-02 14:45:07 +00:00
|
|
|
* the instructions and CFG of a Domo IR, but it is abstract with respect to
|
2007-02-08 20:45:07 +00:00
|
|
|
* several integral portions of the traditional algorithm:
|
2007-02-02 17:17:13 +00:00
|
|
|
* <UL>
|
2007-02-08 20:45:07 +00:00
|
|
|
* <LI> The notion of uses and defs of a given instruction.
|
|
|
|
* <LI> Assignments (<def> := <use>) that are be copy-propagated away
|
|
|
|
* <LI> Which values are constants---i.e. have no definition.
|
|
|
|
* <LI> Any value numbers to be skipped during SSA construction
|
|
|
|
* <LI> Special initialization and exit block processing.
|
2007-02-02 17:17:13 +00:00
|
|
|
* </UL>
|
2007-02-08 20:45:07 +00:00
|
|
|
*
|
2007-02-02 17:17:13 +00:00
|
|
|
* @author Julian dolby (dolby@us.ibm.com)
|
2007-02-08 20:45:07 +00:00
|
|
|
*
|
2007-02-02 17:17:13 +00:00
|
|
|
*/
|
|
|
|
public abstract class AbstractSSAConversion {
|
|
|
|
|
|
|
|
protected abstract int getNumberOfDefs(SSAInstruction inst);
|
|
|
|
|
|
|
|
protected abstract int getDef(SSAInstruction inst, int index);
|
|
|
|
|
|
|
|
protected abstract int getNumberOfUses(SSAInstruction inst);
|
|
|
|
|
|
|
|
protected abstract int getUse(SSAInstruction inst, int index);
|
|
|
|
|
|
|
|
protected abstract boolean isAssignInstruction(SSAInstruction inst);
|
|
|
|
|
|
|
|
protected abstract int getMaxValueNumber();
|
|
|
|
|
|
|
|
protected abstract boolean isLive(SSACFG.BasicBlock Y, int V);
|
|
|
|
|
|
|
|
protected abstract boolean skip(int vn);
|
|
|
|
|
|
|
|
protected abstract boolean isConstant(int valueNumber);
|
|
|
|
|
|
|
|
protected abstract int getNextNewValueNumber();
|
|
|
|
|
|
|
|
protected abstract void initializeVariables();
|
|
|
|
|
|
|
|
protected abstract void repairExit();
|
|
|
|
|
|
|
|
protected abstract void placeNewPhiAt(int value, SSACFG.BasicBlock Y);
|
|
|
|
|
|
|
|
protected abstract SSAPhiInstruction getPhi(SSACFG.BasicBlock B, int index);
|
|
|
|
|
|
|
|
protected abstract void setPhi(SSACFG.BasicBlock B, int index, SSAPhiInstruction inst);
|
|
|
|
|
|
|
|
protected abstract SSAPhiInstruction repairPhiDefs(SSAPhiInstruction phi, int[] newDefs);
|
|
|
|
|
|
|
|
protected abstract void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval);
|
|
|
|
|
|
|
|
protected abstract void repairInstructionUses(SSAInstruction inst, int index, int[] newUses);
|
|
|
|
|
|
|
|
protected abstract void repairInstructionDefs(SSAInstruction inst, int index, int[] newDefs, int[] newUses);
|
|
|
|
|
|
|
|
protected abstract void pushAssignment(SSAInstruction inst, int index, int newRhs);
|
|
|
|
|
|
|
|
protected abstract void popAssignment(SSAInstruction inst, int index);
|
|
|
|
|
|
|
|
protected final SSACFG CFG;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-09-02 14:45:07 +00:00
|
|
|
protected final DominanceFrontiers<ISSABasicBlock> DF;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-09-02 14:45:07 +00:00
|
|
|
private final Graph<ISSABasicBlock> dominatorTree;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected final int[] phiCounts;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected final SSAInstruction[] instructions;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
private final int flags[];
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected final SymbolTable symbolTable;
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected final DefaultValues defaultValues;
|
|
|
|
|
|
|
|
protected IntStack S[];
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected int C[];
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected int valueMap[];
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-09 15:33:45 +00:00
|
|
|
private Set<SSACFG.BasicBlock>[] assignmentMap;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
protected AbstractSSAConversion(IR ir, SSAOptions options) {
|
|
|
|
this.CFG = ir.getControlFlowGraph();
|
2017-03-12 03:20:51 +00:00
|
|
|
this.DF = new DominanceFrontiers<>(ir.getControlFlowGraph(), ir.getControlFlowGraph().entry());
|
2007-02-02 17:17:13 +00:00
|
|
|
this.dominatorTree = DF.dominatorTree();
|
|
|
|
this.flags = new int[2 * ir.getControlFlowGraph().getNumberOfNodes()];
|
2007-07-16 15:09:59 +00:00
|
|
|
this.instructions = getInstructions(ir);
|
2007-02-02 17:17:13 +00:00
|
|
|
this.phiCounts = new int[CFG.getNumberOfNodes()];
|
|
|
|
this.symbolTable = ir.getSymbolTable();
|
|
|
|
this.defaultValues = options.getDefaultValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// top-level control
|
|
|
|
//
|
|
|
|
protected void perform() {
|
|
|
|
init();
|
|
|
|
placePhiNodes();
|
|
|
|
renameVariables();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// initialization
|
|
|
|
//
|
2007-07-16 15:09:59 +00:00
|
|
|
protected SSAInstruction[] getInstructions(IR ir) {
|
|
|
|
return ir.getInstructions();
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:32:04 +00:00
|
|
|
protected final Iterator<SSAInstruction> iterateInstructions(IR ir) {
|
2017-03-12 03:20:51 +00:00
|
|
|
return new ArrayIterator<>(getInstructions(ir));
|
2008-07-25 18:19:55 +00:00
|
|
|
}
|
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
protected void init() {
|
|
|
|
this.S = new IntStack[getMaxValueNumber() + 1];
|
|
|
|
this.C = new int[getMaxValueNumber() + 1];
|
|
|
|
this.valueMap = new int[getMaxValueNumber() + 1];
|
|
|
|
makeAssignmentMap();
|
|
|
|
}
|
|
|
|
|
2007-02-09 15:33:45 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2007-02-02 17:17:13 +00:00
|
|
|
private void makeAssignmentMap() {
|
|
|
|
this.assignmentMap = new Set[getMaxValueNumber() + 1];
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (ISSABasicBlock issaBasicBlock : CFG) {
|
|
|
|
SSACFG.BasicBlock BB = (SSACFG.BasicBlock) issaBasicBlock;
|
2007-02-02 17:17:13 +00:00
|
|
|
if (BB.getFirstInstructionIndex() >= 0) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (SSAInstruction inst : BB) {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (inst != null) {
|
|
|
|
for (int j = 0; j < getNumberOfDefs(inst); j++) {
|
2007-02-02 17:17:13 +00:00
|
|
|
addDefiningBlock(assignmentMap, BB, getDef(inst, j));
|
2007-02-08 20:45:07 +00:00
|
|
|
}
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-08 20:45:07 +00:00
|
|
|
private void addDefiningBlock(Set<SSACFG.BasicBlock>[] A, SSACFG.BasicBlock BB, int i) {
|
|
|
|
if (!skip(i)) {
|
2007-02-02 17:17:13 +00:00
|
|
|
if (A[i] == null) {
|
2017-03-12 03:20:51 +00:00
|
|
|
A[i] = new LinkedHashSet<>(2);
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
A[i].add(BB);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// place phi nodes phase of traditional algorithm
|
|
|
|
//
|
|
|
|
protected void placePhiNodes() {
|
|
|
|
int IterCount = 0;
|
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (ISSABasicBlock issaBasicBlock : CFG) {
|
|
|
|
SSACFG.BasicBlock X = (SSACFG.BasicBlock) issaBasicBlock;
|
2007-02-02 17:17:13 +00:00
|
|
|
setHasAlready(X, 0);
|
|
|
|
setWork(X, 0);
|
|
|
|
}
|
|
|
|
|
2017-03-12 03:20:51 +00:00
|
|
|
Set<BasicBlock> W = new LinkedHashSet<>();
|
2007-02-02 17:17:13 +00:00
|
|
|
for (int V = 0; V < assignmentMap.length; V++) {
|
|
|
|
|
|
|
|
// some things (e.g. constants) have no defs at all
|
|
|
|
if (assignmentMap[V] == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// ignore values as requested
|
|
|
|
if (skip(V))
|
2007-02-08 20:45:07 +00:00
|
|
|
continue;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
IterCount++;
|
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (BasicBlock X : assignmentMap[V]) {
|
2007-02-02 17:17:13 +00:00
|
|
|
setWork(X, IterCount);
|
|
|
|
W.add(X);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!W.isEmpty()) {
|
2007-02-08 20:45:07 +00:00
|
|
|
SSACFG.BasicBlock X = W.iterator().next();
|
2007-02-02 17:17:13 +00:00
|
|
|
W.remove(X);
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<ISSABasicBlock> YS = DF.getDominanceFrontier(X); YS.hasNext();) {
|
2007-02-02 17:17:13 +00:00
|
|
|
SSACFG.BasicBlock Y = (SSACFG.BasicBlock) YS.next();
|
|
|
|
if (getHasAlready(Y) < IterCount) {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (isLive(Y, V)) {
|
2007-02-02 17:17:13 +00:00
|
|
|
placeNewPhiAt(V, Y);
|
2007-02-08 20:45:07 +00:00
|
|
|
phiCounts[Y.getGraphNodeId()]++;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
setHasAlready(Y, IterCount);
|
|
|
|
if (getWork(Y) < IterCount) {
|
|
|
|
setWork(Y, IterCount);
|
|
|
|
W.add(Y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private int getWork(SSACFG.BasicBlock BB) {
|
|
|
|
return flags[BB.getGraphNodeId() * 2 + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setWork(SSACFG.BasicBlock BB, int v) {
|
|
|
|
flags[BB.getGraphNodeId() * 2 + 1] = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int getHasAlready(SSACFG.BasicBlock BB) {
|
|
|
|
return flags[BB.getGraphNodeId() * 2];
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setHasAlready(SSACFG.BasicBlock BB, int v) {
|
|
|
|
flags[BB.getGraphNodeId() * 2] = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// rename variables phase of traditional algorithm
|
|
|
|
//
|
|
|
|
private void renameVariables() {
|
|
|
|
for (int V = 1; V <= getMaxValueNumber(); V++) {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (!skip(V)) {
|
|
|
|
C[V] = 0;
|
|
|
|
S[V] = new IntStack();
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
initializeVariables();
|
|
|
|
|
2013-10-16 21:37:53 +00:00
|
|
|
SEARCH(CFG.entry());
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2010-10-02 20:53:31 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Stack frames for the SEARCH recursion.
|
|
|
|
* Used for converting the recursion to an iteration and avoiding stack overflow.
|
|
|
|
* @author yinnonh
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
private static class Frame{
|
|
|
|
public final SSACFG.BasicBlock X;
|
|
|
|
public final Iterator<ISSABasicBlock> i; // iterator o
|
|
|
|
public Frame(SSACFG.BasicBlock X, Iterator<ISSABasicBlock> i) {
|
|
|
|
this.X = X;
|
|
|
|
this.i = i;
|
|
|
|
}
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
private void SEARCH(SSACFG.BasicBlock X) {
|
2010-10-02 20:53:31 +00:00
|
|
|
// original method was recursive:
|
|
|
|
// SearchPreRec(X)
|
|
|
|
// for (BasicBlock Y: childs(X))
|
|
|
|
// SEARCH(Y)
|
|
|
|
// SearchPostRec(X)
|
|
|
|
|
2017-03-12 03:20:51 +00:00
|
|
|
ArrayList<Frame> stack = new ArrayList<>();
|
2010-10-02 20:53:31 +00:00
|
|
|
|
|
|
|
SearchPreRec(X);
|
2017-01-12 17:25:37 +00:00
|
|
|
push(stack, new Frame(X, dominatorTree.getSuccNodes(X)));
|
2010-10-02 20:53:31 +00:00
|
|
|
|
|
|
|
// invariant: pre-rec phase was performed for elements in the queue.
|
|
|
|
while (!stack.isEmpty()){
|
2017-01-12 17:25:37 +00:00
|
|
|
Frame f = peek(stack);
|
2010-10-02 20:53:31 +00:00
|
|
|
if (f.i.hasNext()){
|
|
|
|
// iterate next child
|
|
|
|
BasicBlock next = (BasicBlock) f.i.next();
|
|
|
|
SearchPreRec(next);
|
2017-01-12 17:25:37 +00:00
|
|
|
push(stack, new Frame(next, dominatorTree.getSuccNodes(next)));
|
2010-10-02 20:53:31 +00:00
|
|
|
} else {
|
|
|
|
// finished iterating children, time to "return"
|
|
|
|
SearchPostRec(f.X);
|
2017-01-12 17:25:37 +00:00
|
|
|
pop(stack);
|
2010-10-02 20:53:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-11 15:47:19 +00:00
|
|
|
private static <T> void push(ArrayList<T> stack, T elt) {
|
2017-01-12 17:25:37 +00:00
|
|
|
stack.add(elt);
|
|
|
|
}
|
|
|
|
|
2017-05-11 15:47:19 +00:00
|
|
|
private static <T> T peek(ArrayList<T> stack) {
|
2017-01-12 17:25:37 +00:00
|
|
|
return stack.get(stack.size()-1);
|
|
|
|
}
|
|
|
|
|
2017-05-11 15:47:19 +00:00
|
|
|
private static <T> T pop(ArrayList<T> stack) {
|
2017-01-12 17:25:37 +00:00
|
|
|
T e = stack.get(stack.size()-1);
|
|
|
|
stack.remove(stack.size()-1);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2010-10-02 20:53:31 +00:00
|
|
|
private void SearchPreRec(SSACFG.BasicBlock X) {
|
2007-02-02 17:17:13 +00:00
|
|
|
int id = X.getGraphNodeId();
|
|
|
|
int Xf = X.getFirstInstructionIndex();
|
|
|
|
|
|
|
|
// first loop
|
|
|
|
for (int i = 0; i < phiCounts[id]; i++) {
|
|
|
|
SSAPhiInstruction phi = getPhi(X, i);
|
2007-02-08 20:45:07 +00:00
|
|
|
if (!skipRepair(phi, -1)) {
|
|
|
|
setPhi(X, i, repairPhiDefs(phi, makeNewDefs(phi)));
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
|
|
|
|
SSAInstruction inst = instructions[i];
|
|
|
|
if (isAssignInstruction(inst)) {
|
2007-02-08 20:45:07 +00:00
|
|
|
int lhs = getDef(inst, 0);
|
|
|
|
int rhs = getUse(inst, 0);
|
|
|
|
int newRhs = skip(rhs) ? rhs : top(rhs);
|
|
|
|
S[lhs].push(newRhs);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-02-08 20:45:07 +00:00
|
|
|
pushAssignment(inst, i, newRhs);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
} else {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (!skipRepair(inst, i)) {
|
|
|
|
int[] newUses = makeNewUses(inst);
|
|
|
|
repairInstructionUses(inst, i, newUses);
|
|
|
|
int[] newDefs = makeNewDefs(inst);
|
|
|
|
repairInstructionDefs(inst, i, newDefs, newUses);
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (X.isExitBlock()) {
|
|
|
|
repairExit();
|
|
|
|
}
|
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<ISSABasicBlock> YS = CFG.getSuccNodes(X); YS.hasNext();) {
|
2007-02-02 17:17:13 +00:00
|
|
|
SSACFG.BasicBlock Y = (SSACFG.BasicBlock) YS.next();
|
|
|
|
int Y_id = Y.getGraphNodeId();
|
|
|
|
int j = com.ibm.wala.cast.ir.cfg.Util.whichPred(CFG, Y, X);
|
|
|
|
for (int i = 0; i < phiCounts[Y_id]; i++) {
|
2007-02-08 20:45:07 +00:00
|
|
|
SSAPhiInstruction phi = getPhi(Y, i);
|
|
|
|
int oldUse = getUse(phi, j);
|
|
|
|
int newUse = skip(oldUse) ? oldUse : top(oldUse);
|
|
|
|
repairPhiUse(Y, i, j, newUse);
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
2010-10-02 20:53:31 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2010-10-02 20:53:31 +00:00
|
|
|
private void SearchPostRec(SSACFG.BasicBlock X) {
|
|
|
|
int id = X.getGraphNodeId();
|
|
|
|
int Xf = X.getFirstInstructionIndex();
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < phiCounts[id]; i++) {
|
|
|
|
SSAInstruction A = getPhi(X, i);
|
|
|
|
for (int j = 0; j < getNumberOfDefs(A); j++) {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (!skip(getDef(A, j))) {
|
|
|
|
S[valueMap[getDef(A, j)]].pop();
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
|
|
|
|
SSAInstruction A = instructions[i];
|
|
|
|
if (isAssignInstruction(A)) {
|
2007-02-08 20:45:07 +00:00
|
|
|
S[getDef(A, 0)].pop();
|
|
|
|
popAssignment(A, i);
|
2007-02-02 17:17:13 +00:00
|
|
|
} else if (A != null) {
|
2007-02-08 20:45:07 +00:00
|
|
|
for (int j = 0; j < getNumberOfDefs(A); j++) {
|
|
|
|
if (!skip(getDef(A, j))) {
|
|
|
|
S[valueMap[getDef(A, j)]].pop();
|
|
|
|
}
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-02-08 20:45:07 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
private int[] makeNewUses(SSAInstruction inst) {
|
|
|
|
int[] newUses = new int[getNumberOfUses(inst)];
|
|
|
|
for (int j = 0; j < getNumberOfUses(inst); j++) {
|
2007-02-08 20:45:07 +00:00
|
|
|
newUses[j] = skip(getUse(inst, j)) ? getUse(inst, j) : top(getUse(inst, j));
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return newUses;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int[] makeNewDefs(SSAInstruction inst) {
|
|
|
|
int[] newDefs = new int[getNumberOfDefs(inst)];
|
|
|
|
|
|
|
|
for (int j = 0; j < getNumberOfDefs(inst); j++) {
|
|
|
|
if (skip(getDef(inst, j))) {
|
2007-02-08 20:45:07 +00:00
|
|
|
newDefs[j] = getDef(inst, j);
|
2007-02-02 17:17:13 +00:00
|
|
|
} else {
|
2007-02-08 20:45:07 +00:00
|
|
|
int ii = getNextNewValueNumber();
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-02-08 20:45:07 +00:00
|
|
|
if (valueMap.length <= ii) {
|
|
|
|
int[] nvm = new int[valueMap.length * 2 + ii + 1];
|
|
|
|
System.arraycopy(valueMap, 0, nvm, 0, valueMap.length);
|
|
|
|
valueMap = nvm;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-02-08 20:45:07 +00:00
|
|
|
valueMap[ii] = getDef(inst, j);
|
|
|
|
S[getDef(inst, j)].push(ii);
|
|
|
|
newDefs[j] = ii;
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return newDefs;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean skipRepair(SSAInstruction inst, int index) {
|
|
|
|
if (inst == null)
|
|
|
|
return true;
|
2007-02-08 20:45:07 +00:00
|
|
|
for (int i = 0; i < getNumberOfDefs(inst); i++)
|
|
|
|
if (!skip(getDef(inst, i)))
|
|
|
|
return false;
|
|
|
|
for (int i = 0; i < getNumberOfUses(inst); i++)
|
|
|
|
if (!skip(getUse(inst, i)))
|
|
|
|
return false;
|
2007-02-02 17:17:13 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void fail(int v) {
|
2009-04-30 13:16:52 +00:00
|
|
|
assert isConstant(v) || !S[v].isEmpty() : "bad stack for " + v + " while SSA converting";
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean hasDefaultValue(int valueNumber) {
|
2007-02-08 20:45:07 +00:00
|
|
|
return (defaultValues != null) && (defaultValues.getDefaultValue(symbolTable, valueNumber) != -1);
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected int getDefaultValue(int valueNumber) {
|
|
|
|
return defaultValues.getDefaultValue(symbolTable, valueNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected int top(int v) {
|
2007-02-08 20:45:07 +00:00
|
|
|
if (!(isConstant(v) || !S[v].isEmpty())) {
|
2007-02-02 17:17:13 +00:00
|
|
|
if (hasDefaultValue(v)) {
|
2007-02-08 20:45:07 +00:00
|
|
|
return getDefaultValue(v);
|
2007-02-02 17:17:13 +00:00
|
|
|
} else {
|
2007-02-08 20:45:07 +00:00
|
|
|
fail(v);
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-12 17:25:37 +00:00
|
|
|
|
|
|
|
return (isConstant(v)) ? v : S[v].peek();
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|