@@ -57,8 +57,8 @@ private static void process(MethodNode mth) {
5757 renameVariables (mth );
5858 fixLastAssignInTry (mth );
5959 removeBlockerInsns (mth );
60- markThisArgs (mth .getThisArg ());
6160 tryToFixUselessPhi (mth );
61+ markThisArgs (mth .getThisArg ());
6262 hidePhiInsns (mth );
6363 removeUnusedInvokeResults (mth );
6464 }
@@ -312,6 +312,20 @@ private static boolean fixPhiWithSameArgs(MethodNode mth, BlockNode block, PhiIn
312312 if (allSame ) {
313313 return replacePhiWithMove (mth , block , phi , phi .getArg (0 ));
314314 }
315+ SSAVar sameVar = isSameMove (phi );
316+ if (sameVar != null ) {
317+ RegisterArg sameArg = sameVar .getAssign ().duplicate ();
318+ if (inlinePhiInsn (mth , block , phi , sameArg )) {
319+ for (InsnArg arg : phi .getArguments ()) {
320+ InsnNode moveInsn = ((RegisterArg ) arg ).getAssignInsn ();
321+ if (moveInsn != null ) {
322+ moveInsn .add (AFlag .REMOVE );
323+ InsnRemover .remove (mth , moveInsn );
324+ }
325+ }
326+ return true ;
327+ }
328+ }
315329 return false ;
316330 }
317331
@@ -330,6 +344,32 @@ private static boolean isSameArgs(PhiInsn phi) {
330344 return allSame ;
331345 }
332346
347+ private static SSAVar isSameMove (PhiInsn phi ) {
348+ SSAVar var = null ;
349+ int argsCount = phi .getArgsCount ();
350+ for (int i = 0 ; i < argsCount ; i ++) {
351+ RegisterArg arg = phi .getArg (i );
352+ if (arg .getSVar ().getUseCount () != 1 ) {
353+ return null ;
354+ }
355+ InsnNode assignInsn = arg .getAssignInsn ();
356+ if (assignInsn == null || assignInsn .getType () != InsnType .MOVE ) {
357+ return null ;
358+ }
359+ InsnArg moveArg = assignInsn .getArg (0 );
360+ if (!moveArg .isRegister ()) {
361+ return null ;
362+ }
363+ SSAVar moveVar = ((RegisterArg ) moveArg ).getSVar ();
364+ if (var == null ) {
365+ var = moveVar ;
366+ } else if (var != moveVar ) {
367+ return null ;
368+ }
369+ }
370+ return var ;
371+ }
372+
333373 private static boolean removePhiList (MethodNode mth , List <PhiInsn > insnToRemove ) {
334374 for (BlockNode block : mth .getBasicBlocks ()) {
335375 PhiListAttr phiList = block .get (AType .PHI_LIST );
@@ -372,7 +412,7 @@ private static boolean replacePhiWithMove(MethodNode mth, BlockNode block, PhiIn
372412 argVar .removeUsedInPhi (phi );
373413 }
374414 // try inline
375- if (inlinePhiInsn (mth , block , phi )) {
415+ if (inlinePhiInsn (mth , block , phi , phi . getArg ( 0 ) )) {
376416 insns .remove (phiIndex );
377417 } else {
378418 assign .removeUsedInPhi (phi );
@@ -387,29 +427,34 @@ private static boolean replacePhiWithMove(MethodNode mth, BlockNode block, PhiIn
387427 return true ;
388428 }
389429
390- private static boolean inlinePhiInsn (MethodNode mth , BlockNode block , PhiInsn phi ) {
430+ private static boolean inlinePhiInsn (MethodNode mth , BlockNode block , PhiInsn phi , RegisterArg inlineArg ) {
391431 SSAVar resVar = phi .getResult ().getSVar ();
392432 if (resVar == null ) {
393433 return false ;
394434 }
395- RegisterArg arg = phi .getArg (0 );
396- if (arg .getSVar () == null ) {
435+ if (inlineArg .getSVar () == null ) {
397436 return false ;
398437 }
399438 List <RegisterArg > useList = resVar .getUseList ();
400439 for (RegisterArg useArg : new ArrayList <>(useList )) {
401440 InsnNode useInsn = useArg .getParentInsn ();
402- if (useInsn == null || useInsn == phi || useArg . getRegNum () != arg . getRegNum () ) {
441+ if (useInsn == null || useInsn == phi ) {
403442 return false ;
404443 }
405- // replace SSAVar in 'useArg' to SSAVar from 'arg'
406- // no need to replace whole RegisterArg
407- useArg .getSVar ().removeUse (useArg );
408- arg .getSVar ().use (useArg );
444+ if (useArg .getRegNum () == inlineArg .getRegNum ()) {
445+ // replace SSAVar in 'useArg' to SSAVar from 'arg'
446+ // no need to replace whole RegisterArg
447+ useArg .getSVar ().removeUse (useArg );
448+ inlineArg .getSVar ().use (useArg );
449+ } else {
450+ if (!useInsn .replaceArg (useArg , inlineArg )) {
451+ return false ;
452+ }
453+ }
409454 }
410455 if (block .contains (AType .EXC_HANDLER )) {
411456 // don't inline into exception handler
412- InsnNode assignInsn = arg .getAssignInsn ();
457+ InsnNode assignInsn = inlineArg .getAssignInsn ();
413458 if (assignInsn != null && !assignInsn .isConstInsn ()) {
414459 assignInsn .add (AFlag .DONT_INLINE );
415460 }
0 commit comments