Home | History | Annotate | Download | only in portable
      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