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. 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 70 void Materialize() { 71 MethodMIR2Bitcode(); 72 } 73 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