• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
18 #define ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
19 
20 #include "invoke_type.h"
21 #include "compiled_method.h"
22 #include "dex/compiler_enums.h"
23 #include "dex/compiler_ir.h"
24 #include "dex/backend.h"
25 #include "llvm/llvm_compilation_unit.h"
26 #include "safe_map.h"
27 
28 namespace art {
29 
30 struct BasicBlock;
31 struct CallInfo;
32 struct CompilationUnit;
33 struct MIR;
34 struct RegLocation;
35 struct RegisterInfo;
36 class MIRGraph;
37 
38 // Target-specific initialization.
39 Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
40                                ArenaAllocator* const arena,
41                                llvm::LlvmCompilationUnit* const llvm_compilation_unit);
42 
43 class MirConverter : public Backend {
44   public:
45     // TODO: flesh out and integrate into new world order.
MirConverter(CompilationUnit * cu,MIRGraph * mir_graph,ArenaAllocator * arena,llvm::LlvmCompilationUnit * llvm_compilation_unit)46     MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena,
47                  llvm::LlvmCompilationUnit* llvm_compilation_unit)
48       : Backend(arena),
49         cu_(cu),
50         mir_graph_(mir_graph),
51         llvm_compilation_unit_(llvm_compilation_unit),
52         llvm_info_(llvm_compilation_unit->GetQuickContext()),
53         symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()),
54         context_(NULL),
55         module_(NULL),
56         func_(NULL),
57         intrinsic_helper_(NULL),
58         irb_(NULL),
59         placeholder_bb_(NULL),
60         entry_bb_(NULL),
61         entry_target_bb_(NULL),
62         llvm_values_(arena, mir_graph->GetNumSSARegs()),
63         temp_name_(0),
64         current_dalvik_offset_(0) {
65       if (kIsDebugBuild) {
66         cu->enable_debug |= (1 << kDebugVerifyBitcode);
67       }
68     }
69 
Materialize()70     void Materialize() {
71       MethodMIR2Bitcode();
72     }
73 
GetCompiledMethod()74     CompiledMethod* GetCompiledMethod() {
75       return NULL;
76     }
77 
78   private:
79     ::llvm::BasicBlock* GetLLVMBlock(int id);
80     ::llvm::Value* GetLLVMValue(int s_reg);
81     void SetVregOnValue(::llvm::Value* val, int s_reg);
82     void DefineValueOnly(::llvm::Value* val, int s_reg);
83     void DefineValue(::llvm::Value* val, int s_reg);
84     ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc);
85     void InitIR();
86     ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr);
87     void ConvertPackedSwitch(BasicBlock* bb, int32_t table_offset,
88                              RegLocation rl_src);
89     void ConvertSparseSwitch(BasicBlock* bb, int32_t table_offset,
90                              RegLocation rl_src);
91     void ConvertSget(int32_t field_index,
92                      art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
93     void ConvertSput(int32_t field_index,
94                      art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
95     void ConvertFillArrayData(int32_t offset, RegLocation rl_array);
96     ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
97                              RegLocation loc);
98     void EmitPopShadowFrame();
99     ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
100                             RegLocation loc);
101     void ConvertMoveException(RegLocation rl_dest);
102     void ConvertThrow(RegLocation rl_src);
103     void ConvertMonitorEnterExit(int opt_flags,
104                                  art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
105     void ConvertArrayLength(int opt_flags, RegLocation rl_dest,
106                             RegLocation rl_src);
107     void EmitSuspendCheck();
108     ::llvm::Value* ConvertCompare(ConditionCode cc,
109                                   ::llvm::Value* src1, ::llvm::Value* src2);
110     void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
111                                  RegLocation rl_src1, RegLocation rl_src2);
112     void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
113                                      RegLocation rl_src1);
114     ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1,
115                                ::llvm::Value* src2);
116     ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1,
117                               ::llvm::Value* src2);
118     void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
119                           RegLocation rl_src2);
120     void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
121                       RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
122     void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
123                          RegLocation rl_dest, RegLocation rl_src, int shift_amount);
124     void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
125                         RegLocation rl_src2);
126     void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
127                            int32_t imm);
128     void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type,
129                        bool is_range, bool is_filled_new_array);
130     void ConvertConstObject(uint32_t idx,
131                             art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
132     void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src);
133     void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest);
134     void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest,
135                          RegLocation rl_src);
136     void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
137                      RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index);
138     void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
139                      RegLocation rl_src, RegLocation rl_array, RegLocation rl_index);
140     void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
141                      RegLocation rl_dest, RegLocation rl_obj, int field_index);
142     void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
143                      RegLocation rl_src, RegLocation rl_obj, int field_index);
144     void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest,
145                            RegLocation rl_src);
146     void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src);
147     void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src);
148     void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src);
149     void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src);
150     void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
151                                RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
152     void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
153                              art::llvm::IntrinsicHelper::IntrinsicId id);
154     void ConvertNeg(RegLocation rl_dest, RegLocation rl_src);
155     void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src);
156     void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
157                         RegLocation rl_dest, RegLocation rl_src);
158     void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src);
159     void ConvertNot(RegLocation rl_dest, RegLocation rl_src);
160     void EmitConstructorBarrier();
161     bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
162     void SetDexOffset(int32_t offset);
163     void SetMethodInfo();
164     void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
165     void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb);
166     bool BlockBitcodeConversion(BasicBlock* bb);
167     ::llvm::FunctionType* GetFunctionType();
168     bool CreateFunction();
169     bool CreateLLVMBasicBlock(BasicBlock* bb);
170     void MethodMIR2Bitcode();
171 
172     CompilationUnit* cu_;
173     MIRGraph* mir_graph_;
174     llvm::LlvmCompilationUnit* const llvm_compilation_unit_;
175     LLVMInfo* llvm_info_;
176     std::string symbol_;
177     ::llvm::LLVMContext* context_;
178     ::llvm::Module* module_;
179     ::llvm::Function* func_;
180     art::llvm::IntrinsicHelper* intrinsic_helper_;
181     art::llvm::IRBuilder* irb_;
182     ::llvm::BasicBlock* placeholder_bb_;
183     ::llvm::BasicBlock* entry_bb_;
184     ::llvm::BasicBlock* entry_target_bb_;
185     std::string bitcode_filename_;
186     GrowableArray< ::llvm::Value*> llvm_values_;
187     int32_t temp_name_;
188     SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_;  // block id -> llvm bb.
189     int current_dalvik_offset_;
190 };  // Class MirConverter
191 
192 }  // namespace art
193 
194 #endif  // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
195