use of org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class LiveAnalysis method collectOsrInfo.
/* collect osr info according to live information */
private void collectOsrInfo(Instruction inst, LiveSet lives) {
// create an entry to the OSRIRMap, order: callee => caller
LinkedList<MethodVariables> mvarList = new LinkedList<MethodVariables>();
// get the type info for locals and stacks
InlinedOsrTypeInfoOperand typeInfo = OsrPoint.getInlinedTypeInfo(inst);
/* iterator over type info and create LocalRegTuple
* for each variable.
* NOTE: we do not process LONG type register operand here,
* which was splitted in BURS.
*/
byte[][] ltypes = typeInfo.localTypeCodes;
byte[][] stypes = typeInfo.stackTypeCodes;
int nummeth = typeInfo.methodids.length;
int elm_idx = 0;
int snd_long_idx = typeInfo.validOps;
for (int midx = 0; midx < nummeth; midx++) {
LinkedList<LocalRegPair> tupleList = new LinkedList<LocalRegPair>();
byte[] ls = ltypes[midx];
byte[] ss = stypes[midx];
/* record maps for local variables, skip dead ones */
for (int i = 0, n = ls.length; i < n; i++) {
if (ls[i] != VoidTypeCode) {
// check liveness
Operand op = OsrPoint.getElement(inst, elm_idx++);
LocalRegPair tuple = new LocalRegPair(LOCAL, i, ls[i], op);
// put it in the list
tupleList.add(tuple);
// get another half of a long type operand
if (VM.BuildFor32Addr && (ls[i] == LongTypeCode)) {
Operand other_op = OsrPoint.getElement(inst, snd_long_idx++);
tuple._otherHalf = new LocalRegPair(LOCAL, i, ls[i], other_op);
}
}
}
/* record maps for stack slots */
for (int i = 0, n = ss.length; i < n; i++) {
if (ss[i] != VoidTypeCode) {
LocalRegPair tuple = new LocalRegPair(STACK, i, ss[i], OsrPoint.getElement(inst, elm_idx++));
tupleList.add(tuple);
if (VM.BuildFor32Addr && (ss[i] == LongTypeCode)) {
tuple._otherHalf = new LocalRegPair(STACK, i, ss[i], OsrPoint.getElement(inst, snd_long_idx++));
}
}
}
// create MethodVariables
MethodVariables mvar = new MethodVariables(typeInfo.methodids[midx], typeInfo.bcindexes[midx], tupleList);
mvarList.add(mvar);
}
// put the method variables for this OSR in the osrMap, encoding later.
osrMap.insertFirst(inst, mvarList);
}
use of org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class MinimalBURS method buildTree.
// //////////////////////////////
// Implementation
// //////////////////////////////
/**
* Build a BURS Tree for each Instruction.
* Complete BURS trees by adding leaf nodes as needed, and
* creating tree edges by calling insertChild1() or insertChild2()
* This step is also where we introduce intermediate tree nodes for
* any LIR instruction that has > 2 "real" operands e.g., a CALL.
*
* @param s The instruction for which a tree must be built
* @return the root of the newly constructed tree
*/
private AbstractBURS_TreeNode buildTree(Instruction s) {
AbstractBURS_TreeNode root = AbstractBURS_TreeNode.create(new DepGraphNode(s));
AbstractBURS_TreeNode cur = root;
for (Enumeration<Operand> uses = s.getUses(); uses.hasMoreElements(); ) {
Operand op = uses.nextElement();
if (op == null)
continue;
// Set child = AbstractBURS_TreeNode for operand op
AbstractBURS_TreeNode child;
if (op instanceof RegisterOperand) {
if (op.asRegister().getRegister().isValidation())
continue;
child = Register;
} else if (op instanceof IntConstantOperand) {
child = new BURS_IntConstantTreeNode(((IntConstantOperand) op).value);
} else if (op instanceof LongConstantOperand) {
child = LongConstant;
} else if (op instanceof AddressConstantOperand) {
child = AddressConstant;
} else if (op instanceof BranchOperand && s.isCall()) {
child = BranchTarget;
} else if (op instanceof InlinedOsrTypeInfoOperand && s.isYieldPoint()) {
child = NullTreeNode;
} else {
continue;
}
// Attach child as child of cur_parent in correct position
if (cur.child1 == null) {
cur.child1 = child;
} else if (cur.child2 == null) {
cur.child2 = child;
} else {
// Create auxiliary node so as to represent
// a instruction with arity > 2 in a binary tree.
AbstractBURS_TreeNode child1 = cur.child2;
AbstractBURS_TreeNode aux = AbstractBURS_TreeNode.create(OTHER_OPERAND_opcode);
cur.child2 = aux;
cur = aux;
cur.child1 = child1;
cur.child2 = child;
}
}
// patch for calls & return
switch(s.getOpcode()) {
case CALL_opcode:
case SYSCALL_opcode:
case YIELDPOINT_OSR_opcode:
if (cur.child2 == null) {
cur.child2 = NullTreeNode;
}
// fall through
case RETURN_opcode:
if (cur.child1 == null) {
cur.child1 = NullTreeNode;
}
}
return root;
}
use of org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class OsrPointConstructor method renovateOsrPoints.
/**
* For each OsrPoint instruction, traces its OsrBarriers created by
* inlining. rebuild OsrPoint instruction to hold all necessary
* information to recover from inlined activation.
* @param ir the IR
*/
private void renovateOsrPoints(IR ir) {
for (int osrIdx = 0, osrSize = osrPoints.size(); osrIdx < osrSize; osrIdx++) {
Instruction osr = osrPoints.get(osrIdx);
LinkedList<Instruction> barriers = new LinkedList<Instruction>();
// Step 1: collect barriers put before inlined method
// in the order of from inner to outer
{
GenerationContext gc = ir.getGc();
Instruction bar = gc.getOSRBarrierFromInst(osr);
if (osr.position() == null)
osr.setPosition(bar.position());
adjustBCIndex(osr);
while (bar != null) {
barriers.add(bar);
// verify each barrier is clean
if (VM.VerifyAssertions) {
if (!isBarrierClean(bar)) {
VM.sysWriteln("Barrier " + bar + " is not clean!");
}
VM._assert(isBarrierClean(bar));
}
Instruction callsite = bar.position().getCallSite();
if (callsite != null) {
bar = gc.getOSRBarrierFromInst(callsite);
if (bar == null) {
VM.sysWrite("call site :" + callsite);
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
adjustBCIndex(bar);
} else {
bar = null;
}
}
}
int inlineDepth = barriers.size();
if (VM.VerifyAssertions) {
if (inlineDepth == 0) {
VM.sysWriteln("Inlining depth for " + osr + " is 0!");
}
VM._assert(inlineDepth != 0);
}
// Step 2: make a new InlinedOsrTypeOperand from barriers
int[] methodids = new int[inlineDepth];
int[] bcindexes = new int[inlineDepth];
byte[][] localTypeCodes = new byte[inlineDepth][];
byte[][] stackTypeCodes = new byte[inlineDepth][];
int totalOperands = 0;
// first iteration, count the size of total locals and stack sizes
for (int barIdx = 0, barSize = barriers.size(); barIdx < barSize; barIdx++) {
Instruction bar = barriers.get(barIdx);
methodids[barIdx] = bar.position().method.getId();
bcindexes[barIdx] = bar.getBytecodeIndex();
OsrTypeInfoOperand typeInfo = OsrBarrier.getTypeInfo(bar);
localTypeCodes[barIdx] = typeInfo.localTypeCodes;
stackTypeCodes[barIdx] = typeInfo.stackTypeCodes;
// count the number of operand, but ignore VoidTypeCode
totalOperands += OsrBarrier.getNumberOfElements(bar);
/*
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("OsrBarrier : "+bar.bcIndex
+"@"+bar.position.method
+" "+typeInfo);
}
*/
}
// new make InlinedOsrTypeInfoOperand
InlinedOsrTypeInfoOperand typeInfo = new InlinedOsrTypeInfoOperand(methodids, bcindexes, localTypeCodes, stackTypeCodes);
OsrPoint.mutate(osr, osr.operator(), typeInfo, totalOperands);
// Step 3: second iteration, copy operands
int opIndex = 0;
for (int barIdx = 0, barSize = barriers.size(); barIdx < barSize; barIdx++) {
Instruction bar = barriers.get(barIdx);
for (int elmIdx = 0, elmSize = OsrBarrier.getNumberOfElements(bar); elmIdx < elmSize; elmIdx++) {
Operand op = OsrBarrier.getElement(bar, elmIdx);
if (VM.VerifyAssertions) {
if (op == null) {
VM.sysWriteln(elmIdx + "th Operand of " + bar + " is null!");
}
VM._assert(op != null);
}
if (op.isRegister()) {
op = op.asRegister().copyU2U();
} else {
op = op.copy();
}
OsrPoint.setElement(osr, opIndex, op);
opIndex++;
}
}
// the last OsrBarrier should in the current method
if (VM.VerifyAssertions) {
Instruction lastBar = barriers.getLast();
if (ir.method != lastBar.position().method) {
VM.sysWriteln("The last barrier is not in the same method as osr:");
VM.sysWriteln(lastBar + "@" + lastBar.position().method);
VM.sysWriteln("current method @" + ir.method);
}
VM._assert(ir.method == lastBar.position().method);
if (opIndex != totalOperands) {
VM.sysWriteln("opIndex and totalOperands do not match:");
VM.sysWriteln("opIndex = " + opIndex);
VM.sysWriteln("totalOperands = " + totalOperands);
}
VM._assert(opIndex == totalOperands);
}
// end of assertion
}
// end of for loop
}
use of org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method OSR.
/* special case handling OSR instructions */
protected void OSR(BURS burs, Instruction s) {
if (VM.VerifyAssertions)
VM._assert(OsrPoint.conforms(s));
// 1. how many params
int numparam = OsrPoint.getNumberOfElements(s);
int numlong = 0;
if (VM.BuildFor32Addr) {
for (int i = 0; i < numparam; i++) {
if (OsrPoint.getElement(s, i).getType().isLongType()) {
numlong++;
}
}
}
// 2. collect params
Operand[] params = new Operand[numparam];
for (int i = 0; i < numparam; i++) {
params[i] = OsrPoint.getClearElement(s, i);
}
InlinedOsrTypeInfoOperand typeInfo = OsrPoint.getClearInlinedTypeInfo(s);
if (VM.VerifyAssertions)
VM._assert(typeInfo != null);
// 3: only makes second half register of long being used
// creates room for long types.
burs.append(OsrPoint.mutate(s, YIELDPOINT_OSR, typeInfo, numparam + numlong));
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
int pidx = numparam;
for (int i = 0; i < numparam; i++) {
Operand param = params[i];
OsrPoint.setElement(s, i, param);
if (VM.BuildFor32Addr) {
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
// LinearScan will update the map.
if (rparam.getType().isLongType()) {
OsrPoint.setElement(s, pidx++, L(burs.ir.regpool.getSecondReg(rparam.getRegister())));
}
}
}
}
if (VM.VerifyAssertions)
VM._assert(pidx == (numparam + numlong));
}
use of org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method OSR.
/**
* special case handling OSR instructions expand long type variables to two
* integers
* @param burs the burs instance
* @param s an OSRPoint instruction
*/
protected void OSR(BURS burs, Instruction s) {
if (VM.VerifyAssertions) {
opt_assert(OsrPoint.conforms(s));
}
// Check type info first because this needs to be done
// for both 32-bit and 64-bit cases.
InlinedOsrTypeInfoOperand typeInfo;
if (VM.BuildFor32Addr) {
// Clearing type info is ok, because instruction will be mutated and the
// info will be reinserted
typeInfo = OsrPoint.getClearInlinedTypeInfo(s);
} else {
// Instruction won't be changed so info needs to be left in
typeInfo = OsrPoint.getInlinedTypeInfo(s);
}
if (VM.VerifyAssertions) {
if (typeInfo == null) {
VM.sysWriteln("OsrPoint " + s + " has a <null> type info:");
VM.sysWriteln(" position :" + s.getBytecodeIndex() + "@" + s.position().method);
}
opt_assert(typeInfo != null);
}
int numparam = OsrPoint.getNumberOfElements(s);
if (VM.BuildFor32Addr) {
// 1. how many params
int numlong = 0;
for (int i = 0; i < numparam; i++) {
Operand param = OsrPoint.getElement(s, i);
if (param.getType().isLongType()) {
numlong++;
}
}
// 2. collect params
Operand[] params = new Operand[numparam];
for (int i = 0; i < numparam; i++) {
params[i] = OsrPoint.getClearElement(s, i);
}
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
// 3: only makes second half register of long being used
// creates room for long types.
burs.append(OsrPoint.mutate(s, s.operator(), typeInfo, numparam + numlong));
int pidx = numparam;
for (int i = 0; i < numparam; i++) {
Operand param = params[i];
OsrPoint.setElement(s, i, param);
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
// LinearScan will update the map.
if (rparam.getType().isLongType()) {
OsrPoint.setElement(s, pidx++, L(burs.ir.regpool.getSecondReg(rparam.getRegister())));
}
} else if (param instanceof LongConstantOperand) {
LongConstantOperand val = (LongConstantOperand) param;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("caught a long const " + val);
}
OsrPoint.setElement(s, i, IC(val.upper32()));
OsrPoint.setElement(s, pidx++, IC(val.lower32()));
} else if (param instanceof IntConstantOperand) {
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected parameter type" + param);
}
}
if (pidx != (numparam + numlong)) {
VM.sysWriteln("pidx = " + pidx);
VM.sysWriteln("numparam = " + numparam);
VM.sysWriteln("numlong = " + numlong);
}
if (VM.VerifyAssertions) {
opt_assert(pidx == (numparam + numlong));
}
} else {
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
burs.append(s);
}
}
Aggregations