• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 package com.android.tools.r8.ir.code;
5 
6 import com.android.tools.r8.code.ReturnObject;
7 import com.android.tools.r8.code.ReturnVoid;
8 import com.android.tools.r8.code.ReturnWide;
9 import com.android.tools.r8.dex.Constants;
10 import com.android.tools.r8.errors.Unreachable;
11 import com.android.tools.r8.graph.AppInfo;
12 import com.android.tools.r8.graph.DexType;
13 import com.android.tools.r8.ir.conversion.DexBuilder;
14 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
15 
16 public class Return extends JumpInstruction {
17 
18   // Need to keep track of the original return type, as a null value will have MoveType.SINGLE.
19   final private MoveType returnType;
20 
Return()21   public Return() {
22     super(null);
23     returnType = null;
24   }
25 
Return(Value value, MoveType returnType)26   public Return(Value value, MoveType returnType) {
27     super(null, value);
28     this.returnType = returnType;
29   }
30 
isReturnVoid()31   public boolean isReturnVoid() {
32     return inValues.size() == 0;
33   }
34 
getReturnType()35   public MoveType getReturnType() {
36     return returnType;
37   }
38 
returnValue()39   public Value returnValue() {
40     assert !isReturnVoid();
41     return inValues.get(0);
42   }
43 
createDexInstruction(DexBuilder builder)44   public com.android.tools.r8.code.Instruction createDexInstruction(DexBuilder builder) {
45     if (isReturnVoid()) {
46       return new ReturnVoid();
47     } else {
48       switch (returnValue().type) {
49         case OBJECT:
50           assert returnType == MoveType.OBJECT;
51           return new ReturnObject(builder.allocatedRegister(returnValue(), getNumber()));
52         case SINGLE:
53           if (returnType == MoveType.OBJECT) {
54             return new ReturnObject(builder.allocatedRegister(returnValue(), getNumber()));
55           } else {
56             assert returnType == MoveType.SINGLE;
57             return new com.android.tools.r8.code.Return(builder.allocatedRegister(returnValue(), getNumber()));
58           }
59         case WIDE:
60           assert returnType == MoveType.WIDE;
61           return new ReturnWide(builder.allocatedRegister(returnValue(), getNumber()));
62         default:
63           throw new Unreachable();
64       }
65     }
66   }
67 
68   @Override
buildDex(DexBuilder builder)69   public void buildDex(DexBuilder builder) {
70     builder.add(this, createDexInstruction(builder));
71   }
72 
73   @Override
identicalNonValueParts(Instruction other)74   public boolean identicalNonValueParts(Instruction other) {
75     if (isReturnVoid()) {
76       return other.asReturn().isReturnVoid();
77     } else {
78       return other.asReturn().returnValue().type == returnValue().type;
79     }
80   }
81 
82   @Override
compareNonValueParts(Instruction other)83   public int compareNonValueParts(Instruction other) {
84     if (isReturnVoid()) {
85       return other.asReturn().isReturnVoid() ? 0 : -1;
86     } else {
87       return returnValue().type.ordinal() - other.asReturn().returnValue().type.ordinal();
88     }
89   }
90 
91   @Override
maxInValueRegister()92   public int maxInValueRegister() {
93     return Constants.U8BIT_MAX;
94   }
95 
96   @Override
maxOutValueRegister()97   public int maxOutValueRegister() {
98     assert false : "Return defines no values.";
99     return 0;
100   }
101 
102   @Override
isReturn()103   public boolean isReturn() {
104     return true;
105   }
106 
107   @Override
asReturn()108   public Return asReturn() {
109     return this;
110   }
111 
112   @Override
inliningConstraint(AppInfo info, DexType holder)113   public Constraint inliningConstraint(AppInfo info, DexType holder) {
114     return Constraint.ALWAYS;
115   }
116 }
117