Skip to content

Commit

Permalink
Remove Meth{Add,odHandle,odLookupInstr}. Saves a couple of MB on Rail…
Browse files Browse the repository at this point in the history
…s console
  • Loading branch information
enebo committed Dec 18, 2014
1 parent bf0ebab commit d56d246
Show file tree
Hide file tree
Showing 24 changed files with 165 additions and 474 deletions.
38 changes: 19 additions & 19 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ private Operand buildAttrAssign(final AttrAssignNode attrAssignNode, IRScope s)
List<Operand> args = new ArrayList<>();
Node argsNode = attrAssignNode.getArgsNode();
Operand lastArg = (argsNode == null) ? manager.getNil() : buildCallArgs(args, argsNode, s);
addInstr(s, new AttrAssignInstr(obj, new MethAddr(attrAssignNode.getName()), args.toArray(new Operand[args.size()])));
addInstr(s, new AttrAssignInstr(obj, attrAssignNode.getName(), args.toArray(new Operand[args.size()])));
return lastArg;
}

Expand All @@ -839,7 +839,7 @@ public Operand buildAttrAssignAssignment(Node node, IRScope s, Operand value) {
Operand obj = build(attrAssignNode.getReceiverNode(), s);
List<Operand> args = setupCallArgs(attrAssignNode.getArgsNode(), s);
args.add(value);
addInstr(s, new AttrAssignInstr(obj, new MethAddr(attrAssignNode.getName()), args.toArray(new Operand[args.size()])));
addInstr(s, new AttrAssignInstr(obj, attrAssignNode.getName(), args.toArray(new Operand[args.size()])));
return value;
}

Expand Down Expand Up @@ -987,7 +987,7 @@ public Operand buildCall(CallNode callNode, IRScope s) {
List<Operand> args = setupCallArgs(callArgsNode, s);
Operand block = setupCallClosure(callNode.getIterNode(), s);
Variable callResult = s.createTemporaryVariable();
CallInstr callInstr = CallInstr.create(callResult, new MethAddr(callNode.getName()), receiver, args.toArray(new Operand[args.size()]), block);
CallInstr callInstr = CallInstr.create(callResult, callNode.getName(), receiver, args.toArray(new Operand[args.size()]), block);

// This is to support the ugly Proc.new with no block, which must see caller's frame
if (
Expand Down Expand Up @@ -2204,7 +2204,7 @@ public Operand buildFCall(FCallNode fcallNode, IRScope s) {
List<Operand> args = setupCallArgs(callArgsNode, s);
Operand block = setupCallClosure(fcallNode.getIterNode(), s);
Variable callResult = s.createTemporaryVariable();
CallInstr callInstr = CallInstr.create(CallType.FUNCTIONAL, callResult, new MethAddr(fcallNode.getName()), s.getSelf(), args.toArray(new Operand[args.size()]), block);
CallInstr callInstr = CallInstr.create(CallType.FUNCTIONAL, callResult, fcallNode.getName(), s.getSelf(), args.toArray(new Operand[args.size()]), block);
receiveBreakException(s, block, callInstr);
return callResult;
}
Expand Down Expand Up @@ -2321,7 +2321,7 @@ public Operand buildFor(ForNode forNode, IRScope s) {
Variable result = s.createTemporaryVariable();
Operand receiver = build(forNode.getIterNode(), s);
Operand forBlock = buildForIter(forNode, s);
CallInstr callInstr = new CallInstr(CallType.NORMAL, result, new MethAddr("each"), receiver, NO_ARGS, forBlock);
CallInstr callInstr = new CallInstr(CallType.NORMAL, result, "each", receiver, NO_ARGS, forBlock);
receiveBreakException(s, forBlock, callInstr);

return result;
Expand Down Expand Up @@ -2711,7 +2711,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {

// get attr
Operand v1 = build(opAsgnNode.getReceiverNode(), s);
addInstr(s, CallInstr.create(readerValue, new MethAddr(opAsgnNode.getVariableName()), v1, NO_ARGS, null));
addInstr(s, CallInstr.create(readerValue, opAsgnNode.getVariableName(), v1, NO_ARGS, null));

// Ex: e.val ||= n
// e.val &&= n
Expand All @@ -2722,7 +2722,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {

// compute value and set it
Operand v2 = build(opAsgnNode.getValueNode(), s);
addInstr(s, CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {v2}, null));
addInstr(s, CallInstr.create(writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {v2}, null));
// It is readerValue = v2.
// readerValue = writerValue is incorrect because the assignment method
// might return something else other than the value being set!
Expand All @@ -2736,10 +2736,10 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode, IRScope s) {
// call operator
Operand v2 = build(opAsgnNode.getValueNode(), s);
Variable setValue = s.createTemporaryVariable();
addInstr(s, CallInstr.create(setValue, new MethAddr(opAsgnNode.getOperatorName()), readerValue, new Operand[]{v2}, null));
addInstr(s, CallInstr.create(setValue, opAsgnNode.getOperatorName(), readerValue, new Operand[]{v2}, null));

// set attr
addInstr(s, CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {setValue}, null));
addInstr(s, CallInstr.create(writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {setValue}, null));
// Returning writerValue is incorrect becuase the assignment method
// might return something else other than the value being set!
return setValue;
Expand Down Expand Up @@ -2823,11 +2823,11 @@ public Operand buildOpElementAsgnWithOr(OpElementAsgnNode opElementAsgnNode, IRS
Label l = s.getNewLabel();
Variable elt = s.createTemporaryVariable();
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, BEQInstr.create(elt, manager.getTrue(), l));
Operand value = build(opElementAsgnNode.getValueNode(), s);
argList.add(value);
addInstr(s, CallInstr.create(elt, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]=", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, new CopyInstr(elt, value));
addInstr(s, new LabelInstr(l));
return elt;
Expand All @@ -2839,11 +2839,11 @@ public Operand buildOpElementAsgnWithAnd(OpElementAsgnNode opElementAsgnNode, IR
Label l = s.getNewLabel();
Variable elt = s.createTemporaryVariable();
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, BEQInstr.create(elt, manager.getFalse(), l));
Operand value = build(opElementAsgnNode.getValueNode(), s);
argList.add(value);
addInstr(s, CallInstr.create(elt, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, CallInstr.create(elt, "[]=", array, argList.toArray(new Operand[argList.size()]), null));
addInstr(s, new CopyInstr(elt, value));
addInstr(s, new LabelInstr(l));
return elt;
Expand All @@ -2860,15 +2860,15 @@ public Operand buildOpElementAsgnWithMethod(OpElementAsgnNode opElementAsgnNode,
Operand array = build(opElementAsgnNode.getReceiverNode(), s);
List<Operand> argList = setupCallArgs(opElementAsgnNode.getArgsNode(), s);
Variable elt = s.createTemporaryVariable();
addInstr(s, CallInstr.create(elt, new MethAddr("[]"), array, argList.toArray(new Operand[argList.size()]), null)); // elt = a[args]
addInstr(s, CallInstr.create(elt, "[]", array, argList.toArray(new Operand[argList.size()]), null)); // elt = a[args]
Operand value = build(opElementAsgnNode.getValueNode(), s); // Load 'value'
String operation = opElementAsgnNode.getOperatorName();
addInstr(s, CallInstr.create(elt, new MethAddr(operation), elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
addInstr(s, CallInstr.create(elt, operation, elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
// SSS: do not load the call result into 'elt' to eliminate the RAW dependency on the call
// We already know what the result is going be .. we are just storing it back into the array
Variable tmp = s.createTemporaryVariable();
argList.add(elt);
addInstr(s, CallInstr.create(tmp, new MethAddr("[]="), array, argList.toArray(new Operand[argList.size()]), null)); // a[args] = elt
addInstr(s, CallInstr.create(tmp, "[]=", array, argList.toArray(new Operand[argList.size()]), null)); // a[args] = elt
return elt;
}

Expand Down Expand Up @@ -3264,9 +3264,9 @@ private Operand buildSuperInstr(IRScope s, Operand block, Operand[] args) {
if ((s instanceof IRMethod) && (s.getLexicalParent() instanceof IRClassBody)) {
IRMethod m = (IRMethod)s;
if (m.isInstanceMethod) {
superInstr = new InstanceSuperInstr(ret, s.getCurrentModuleVariable(), new MethAddr(s.getName()), args, block);
superInstr = new InstanceSuperInstr(ret, s.getCurrentModuleVariable(), s.getName(), args, block);
} else {
superInstr = new ClassSuperInstr(ret, s.getCurrentModuleVariable(), new MethAddr(s.getName()), args, block);
superInstr = new ClassSuperInstr(ret, s.getCurrentModuleVariable(), s.getName(), args, block);
}
} else {
// We dont always know the method name we are going to be invoking if the super occurs in a closure.
Expand Down Expand Up @@ -3378,7 +3378,7 @@ public Operand buildVAlias(VAliasNode valiasNode, IRScope s) {

public Operand buildVCall(VCallNode node, IRScope s) {
Variable callResult = s.createTemporaryVariable();
Instr callInstr = CallInstr.create(CallType.VARIABLE, callResult, new MethAddr(node.getName()), s.getSelf(), NO_ARGS, null);
Instr callInstr = CallInstr.create(CallType.VARIABLE, callResult, node.getName(), s.getSelf(), NO_ARGS, null);
addInstr(s, callInstr);
return callResult;
}
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/java/org/jruby/ir/IRVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ private void error(Object object) {
public void Match2Instr(Match2Instr match2instr) { error(match2instr); }
public void Match3Instr(Match3Instr match3instr) { error(match3instr); }
public void MatchInstr(MatchInstr matchinstr) { error(matchinstr); }
public void MethodLookupInstr(MethodLookupInstr methodlookupinstr) { error(methodlookupinstr); }
public void ModuleVersionGuardInstr(ModuleVersionGuardInstr moduleversionguardinstr) { error(moduleversionguardinstr); }
public void NonlocalReturnInstr(NonlocalReturnInstr nonlocalreturninstr) { error(nonlocalreturninstr); }
public void NopInstr(NopInstr nopinstr) { error(nopinstr); }
Expand Down Expand Up @@ -153,8 +152,6 @@ private void error(Object object) {
public void IRException(IRException irexception) { error(irexception); }
public void Label(Label label) { error(label); }
public void LocalVariable(LocalVariable localvariable) { error(localvariable); }
public void MethAddr(MethAddr methaddr) { error(methaddr); }
public void MethodHandle(MethodHandle methodhandle) { error(methodhandle); }
public void Nil(Nil nil) { error(nil); }
public void NthRef(NthRef nthref) { error(nthref); }
public void ObjectClass(ObjectClass objectclass) { error(objectclass); }
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/ir/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ public enum Operation {
PUSH_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
PUSH_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_FRAME(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect),
METHOD_LOOKUP(0); /* for splitting calls into method-lookup and call -- unused **/
POP_BINDING(OpFlags.f_is_book_keeping_op | OpFlags.f_has_side_effect);

public final OpClass opClass;
private int flags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,10 @@ public void applyTransferFunction(Instr i) {
// Process calls specially -- these are what we want to optimize!
if (i instanceof CallBase && o == null) {
CallBase c = (CallBase)i;
MethAddr m = c.getMethodAddr();
String m = c.getName();
Operand r = c.getReceiver();
Operand[] args = c.getCallArgs();
if (dst != null && args.length == 1 && m.resemblesALUOp()) {
if (dst != null && args.length == 1 && resemblesALUOp(m)) {
Operand a = args[0];
Class receiverType = getOperandType(tmpState, r);
Class argType = getOperandType(tmpState, a);
Expand All @@ -255,7 +255,7 @@ public void applyTransferFunction(Instr i) {
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Float.class);
Class dstType = getUnboxedResultType(Float.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

Expand All @@ -272,7 +272,7 @@ public void applyTransferFunction(Instr i) {
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Fixnum.class);
Class dstType = getUnboxedResultType(Fixnum.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

Expand Down Expand Up @@ -641,21 +641,21 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
Operand o = ((ClosureAcceptingInstr)i).getClosureArg();
if (i instanceof CallBase && o == null) {
CallBase c = (CallBase)i;
MethAddr m = c.getMethodAddr();
String m = c.getName();
Operand r = c.getReceiver();
Operand[] args = c.getCallArgs();
if (dst != null && args.length == 1 && m.resemblesALUOp()) {
if (dst != null && args.length == 1 && resemblesALUOp(m)) {
Operand a = args[0];
Class receiverType = getOperandType(tmpState, r);
Class argType = getOperandType(tmpState, a);
// Optimistically assume that call is an ALU op
Operation unboxedOp;
if ((receiverType == Float.class || (receiverType == Fixnum.class && argType == Float.class)) &&
(unboxedOp = m.getUnboxedOp(Float.class)) != null)
(unboxedOp = getUnboxedOp(Float.class, m)) != null)
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Float.class);
Class dstType = getUnboxedResultType(Float.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

Expand All @@ -664,11 +664,11 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
a = unboxOperand(tmpState, Float.class, unboxMap, a, newInstrs);
newInstrs.add(new AluInstr(unboxedOp, unboxedDst, r, a));
} else if ((receiverType == Float.class || (receiverType == Fixnum.class && argType == Fixnum.class)) &&
(unboxedOp = m.getUnboxedOp(Fixnum.class)) != null)
(unboxedOp = getUnboxedOp(Fixnum.class, m)) != null)
{
dirtied = true;

Class dstType = m.getUnboxedResultType(Fixnum.class);
Class dstType = getUnboxedResultType(Fixnum.class, m);
setOperandType(tmpState, dst, dstType);
tmpState.unboxedVars.put(dst, dstType);

Expand Down Expand Up @@ -755,6 +755,66 @@ public void unbox(Map<Variable, TemporaryLocalVariable> unboxMap) {
basicBlock.replaceInstrs(newInstrs);
}

private boolean resemblesALUOp(String name) {
return name.equals("+") || name.equals("-") || name.equals("*") || name.equals("/") ||
name.equals("|") || name.equals("&") || name.equals(">>") || name.equals("<<") ||
name.equals(">") || name.equals("<") || name.equals("==") || name.equals("!=");
}

private Class getUnboxedResultType(Class operandType, String name) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' :
case '-' :
case '*' :
case '/' : return operandType == Float.class ? Float.class : operandType == Fixnum.class ? Fixnum.class : null;
case '>' :
case '<' : return operandType == Float.class || operandType == Fixnum.class ? UnboxedBoolean.class : null;
}
}
return null;
}

public Operation getUnboxedOp(Class unboxedType, String name) {
if (unboxedType == Float.class) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' : return Operation.FADD;
case '-' : return Operation.FSUB;
case '*' : return Operation.FMUL;
case '/' : return Operation.FDIV;
case '>' : return Operation.FGT;
case '<' : return Operation.FLT;
}
} else if (name.length() == 2) {
if (name.equals("==")) return Operation.FEQ;
} else if (name.equals("===")) {
return Operation.FEQ;
}
} else if (unboxedType == Fixnum.class) {
if (name.length() == 1) {
switch (name.charAt(0)) {
case '+' : return Operation.IADD;
case '-' : return Operation.ISUB;
case '*' : return Operation.IMUL;
case '/' : return Operation.IDIV;
case '>' : return Operation.IGT;
case '<' : return Operation.ILT;
case '|' : return Operation.IOR;
case '&' : return Operation.IAND;
case '^' : return Operation.IXOR;
}
} else if (name.length() == 2) {
if (name.equals(">>")) return Operation.ISHR;
if (name.equals("<<")) return Operation.ISHL;
if (name.equals("==")) return Operation.IEQ;
} else if (name.equals("===")) {
return Operation.IEQ;
}
}
return null;
}

@Override
public String toString() {
return "";
Expand Down
Loading

0 comments on commit d56d246

Please sign in to comment.