Class MethodModel
- java.lang.Object
-
- com.aparapi.internal.model.MethodModel
-
public class MethodModel extends java.lang.Object
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
MethodModel.FakeLocalVariableTableEntry
-
Field Summary
Fields Modifier and Type Field Description private ClassModel.ConstantPool.FieldEntry
accessorVariableFieldEntry
private java.util.Set<MethodModel>
calledMethods
(package private) Entrypoint
entrypoint
private ExpressionList
expressionList
private static java.util.logging.Logger
logger
private ClassModel.ClassModelMethod
method
private boolean
methodIsGetter
private boolean
methodIsPrivateMemoryGetter
private boolean
methodIsSetter
private boolean
noCL
private Instruction
pcHead
private Instruction
pcTail
After we have folded the top level instructions this root list will contain a list of all of the 'root' instructions (stores/loops/conditionals) We are going to build a linked list.(package private) InstructionTransformer[]
transformers
private boolean
usesByteWrites
True is an indication to use the byte addressable store pragmaprivate boolean
usesDoubles
True is an indication to use the fp64 pragmaprivate boolean
usesPutfield
-
Constructor Summary
Constructors Constructor Description MethodModel(ClassModel.ClassModelMethod _method)
MethodModel(ClassModel.ClassModelMethod _method, Entrypoint _entrypoint)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) void
applyTransformations(ExpressionList _expressionList, Instruction _instruction, Instruction _operandStart)
void
buildBranchGraphs(java.util.Map<java.lang.Integer,Instruction> pcMap)
Here we connect the branch nodes to the instruction that they branch to.(package private) void
checkForGetter(java.util.Map<java.lang.Integer,Instruction> pcMap)
Determine if this method is a getter and record the accessed field if sovoid
checkForRecursion(java.util.Set<MethodModel> transitiveCalledMethods)
(package private) void
checkForSetter(java.util.Map<java.lang.Integer,Instruction> pcMap)
Determine if this method is a setter and record the accessed field if sojava.util.Map<java.lang.Integer,Instruction>
createListOfInstructions()
Create a linked list of instructions (from pcHead to pcTail).void
deoptimizeReverseBranches()
Javac optimizes some branches to avoid goto->goto, branch->goto etc.(package private) void
foldExpressions()
Try to fold the instructions into higher level structures.ClassModel.ConstantPool.FieldEntry
getAccessorVariableFieldEntry()
java.util.Set<MethodModel>
getCalledMethods()
ClassModel.ConstantPool
getConstantPool()
Instruction
getExprHead()
ClassModel.LocalVariableInfo
getLocalVariable(int _pc, int _index)
ClassModel.LocalVariableTableEntry<ClassModel.LocalVariableInfo>
getLocalVariableTableEntry()
ClassModel.ClassModelMethod
getMethod()
java.util.List<InstructionSet.MethodCall>
getMethodCalls()
java.lang.String
getName()
Instruction
getPCHead()
java.lang.String
getReturnType()
java.lang.String
getSimpleName()
private void
init(ClassModel.ClassModelMethod _method)
boolean
isGetter()
boolean
isNoCL()
boolean
isPrivateMemoryGetter()
boolean
isSetter()
boolean
methodUsesPutfield()
boolean
requiresByteAddressableStorePragma()
boolean
requiresDoublePragma()
private void
setAccessorVariableFieldEntry(ClassModel.ConstantPool.FieldEntry field)
void
setRequiredPragmas(Instruction instruction)
Look at each instruction for use of long/double or byte writes which require pragmas to be used in the OpenCL sourcejava.lang.String
toString()
void
txFormDups(ExpressionList _expressionList, Instruction _instruction)
DUP family of instructions break our stack unwind model (whereby we treat instructions like the oeprands they create/consume).
-
-
-
Field Detail
-
logger
private static java.util.logging.Logger logger
-
expressionList
private ExpressionList expressionList
-
method
private ClassModel.ClassModelMethod method
-
usesDoubles
private boolean usesDoubles
True is an indication to use the fp64 pragma
-
usesByteWrites
private boolean usesByteWrites
True is an indication to use the byte addressable store pragma
-
methodIsGetter
private boolean methodIsGetter
-
methodIsSetter
private boolean methodIsSetter
-
methodIsPrivateMemoryGetter
private boolean methodIsPrivateMemoryGetter
-
usesPutfield
private boolean usesPutfield
-
accessorVariableFieldEntry
private ClassModel.ConstantPool.FieldEntry accessorVariableFieldEntry
-
noCL
private boolean noCL
-
calledMethods
private final java.util.Set<MethodModel> calledMethods
-
pcTail
private Instruction pcTail
After we have folded the top level instructions this root list will contain a list of all of the 'root' instructions (stores/loops/conditionals) We are going to build a linked list. Here we track the head and tail
-
pcHead
private Instruction pcHead
-
transformers
InstructionTransformer[] transformers
-
entrypoint
Entrypoint entrypoint
-
-
Constructor Detail
-
MethodModel
MethodModel(ClassModel.ClassModelMethod _method, Entrypoint _entrypoint) throws AparapiException
- Throws:
AparapiException
-
MethodModel
MethodModel(ClassModel.ClassModelMethod _method) throws AparapiException
- Throws:
AparapiException
-
-
Method Detail
-
isGetter
public boolean isGetter()
-
isSetter
public boolean isSetter()
-
methodUsesPutfield
public boolean methodUsesPutfield()
-
isNoCL
public boolean isNoCL()
-
isPrivateMemoryGetter
public boolean isPrivateMemoryGetter()
-
getMethod
public ClassModel.ClassModelMethod getMethod()
-
getAccessorVariableFieldEntry
public ClassModel.ConstantPool.FieldEntry getAccessorVariableFieldEntry()
-
getCalledMethods
public java.util.Set<MethodModel> getCalledMethods()
-
checkForRecursion
public void checkForRecursion(java.util.Set<MethodModel> transitiveCalledMethods) throws AparapiException
- Throws:
AparapiException
-
setRequiredPragmas
public void setRequiredPragmas(Instruction instruction)
Look at each instruction for use of long/double or byte writes which require pragmas to be used in the OpenCL source
-
requiresDoublePragma
public boolean requiresDoublePragma()
-
requiresByteAddressableStorePragma
public boolean requiresByteAddressableStorePragma()
-
createListOfInstructions
public java.util.Map<java.lang.Integer,Instruction> createListOfInstructions() throws ClassParseException
Create a linked list of instructions (from pcHead to pcTail). Returns a map of int (pc) to Instruction which to allow us to quickly get from a bytecode offset to the appropriate instruction. Note that not all int values from 0 to code.length values will map to a valid instruction, if pcMap.get(n) == null then this implies that 'n' is not the start of an instruction So either pcMap.get(i)== null or pcMap.get(i).getThisPC()==i- Returns:
- Map
the returned pc to Instruction map - Throws:
ClassParseException
-
buildBranchGraphs
public void buildBranchGraphs(java.util.Map<java.lang.Integer,Instruction> pcMap)
Here we connect the branch nodes to the instruction that they branch to.Each branch node contains a 'target' field indended to reference the node that the branch targets. Each instruction also contain four seperate lists of branch nodes that reference it. These lists hold forwardConditional, forwardUnconditional, reverseConditional and revereseUnconditional branches that reference it.
So assuming that we had a branch node at pc offset 100 which represented 'goto 200'.
Following this call the branch node at pc offset 100 will have a 'target' field which actually references the instruction at pc offset 200, and the instruction at pc offset 200 will have the branch node (at 100) added to it's forwardUnconditional list.
- See Also:
InstructionSet.Branch.getTarget()
-
deoptimizeReverseBranches
public void deoptimizeReverseBranches()
Javac optimizes some branches to avoid goto->goto, branch->goto etc. This method specifically deals with reverse branches which are the result of such optimisations.
-
txFormDups
public void txFormDups(ExpressionList _expressionList, Instruction _instruction) throws ClassParseException
DUP family of instructions break our stack unwind model (whereby we treat instructions like the oeprands they create/consume).Here we replace DUP style instructions with a 'mock' instruction which 'clones' the effect of the instruction. This would be invalid to execute but is useful to replace the DUP with a 'pattern' which it simulates. This allows us to later apply transforms to represent the original code.
An example might be the bytecode for the following sequence.
Which results in the following bytecoderesults[10]++; return
First we need to know what the stack will look like before the dup2 is encountered. Using our folding technique we represent the first two instructions inside ()0: aload_0 // reference through 'this' to get 1: getfield // field 'results' which is an array of int 4: bipush 10 // push the array index 6: dup2 // dreaded dup2 we'll come back here 7: iaload // ignore for the moment. 8: iconst_1 9: iadd 10: iastore 11: return
Thegetfield (aload_0 // result in the array field reference on stack bipush 10 // the array index dup2 // dreaded dup2 we'll come back here
dup2
essentially copies the top two elements on the stack. So we emulate this by replacing the dup2 with clones of the instructions which would reinstate the same stack state.So after the
dup2
transform we end up with:-
So carrying on lets look at thegetfield (aload_0) // result in the array field reference on stack bipush 10 // the array index {getfield (aload_0)} // result in the array field reference on stack {bipush 10} // the array index
iaload
which consumes two operands (the index and the array field reference) and creates one (the result of an array access)
So we now havegetfield (aload_0) // result in the array field reference on stack bipush 10 // the array index {getfield (aload_0)} // result in the array field reference on stack {bipush 10} // the array index iaload
And if you are following along thegetfield (aload_0) // result in the array field reference on stack bipush 10 // the array index iaload ({getfield(aload_0), {bipush 10}) // results in the array element on the stack iconst iadd
iadd
will fold the previous two stack entries essentially pushing the result ofresults[10]+1
on the stack.
Then the finalgetfield (aload_0) // result in the array field reference on stack bipush 10 // the array index iadd (iaload ({getfield(aload_0), {bipush 10}, iconst_1) // push of results[10]+1
istore
instruction which consumes 3 stack operands (the field array reference, the index and the value to assign).Which results in
Whereistore (getfield (aload_0), bipush 10, iadd (iaload ({getfield(aload_0), {bipush 10}, iconst_1)) // results[10] = results[10+1]
results[10] = results[10+1]
is the long-hand form of the
results[10]++
and will be transformed by one of the 'inc' transforms to the more familiar form a little later.- Parameters:
_expressionList
-_instruction
-- Throws:
ClassParseException
-
foldExpressions
void foldExpressions() throws ClassParseException
Try to fold the instructions into higher level structures. At the end we have a folded instruction tree with 'roots' containing the top level branches (stores mostly)- Throws:
ClassParseException
-
applyTransformations
void applyTransformations(ExpressionList _expressionList, Instruction _instruction, Instruction _operandStart) throws ClassParseException
- Throws:
ClassParseException
-
checkForGetter
void checkForGetter(java.util.Map<java.lang.Integer,Instruction> pcMap) throws ClassParseException
Determine if this method is a getter and record the accessed field if so- Throws:
ClassParseException
-
setAccessorVariableFieldEntry
private void setAccessorVariableFieldEntry(ClassModel.ConstantPool.FieldEntry field)
-
checkForSetter
void checkForSetter(java.util.Map<java.lang.Integer,Instruction> pcMap) throws ClassParseException
Determine if this method is a setter and record the accessed field if so- Throws:
ClassParseException
-
init
private void init(ClassModel.ClassModelMethod _method) throws AparapiException
- Throws:
AparapiException
-
getLocalVariableTableEntry
public ClassModel.LocalVariableTableEntry<ClassModel.LocalVariableInfo> getLocalVariableTableEntry()
-
getConstantPool
public ClassModel.ConstantPool getConstantPool()
-
getLocalVariable
public ClassModel.LocalVariableInfo getLocalVariable(int _pc, int _index)
-
getSimpleName
public java.lang.String getSimpleName()
-
getName
public java.lang.String getName()
-
getReturnType
public java.lang.String getReturnType()
-
getMethodCalls
public java.util.List<InstructionSet.MethodCall> getMethodCalls()
-
getPCHead
public Instruction getPCHead()
-
getExprHead
public Instruction getExprHead()
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
-