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 <llvm/ADT/ArrayRef.h>
     21 #include <llvm/IR/BasicBlock.h>
     22 #include <llvm/IR/IRBuilder.h>
     23 #include <llvm/IR/LLVMContext.h>
     24 #include <llvm/IR/Module.h>
     25 
     26 #include "invoke_type.h"
     27 #include "compiled_method.h"
     28 #include "dex/compiler_enums.h"
     29 #include "dex/compiler_ir.h"
     30 #include "dex/backend.h"
     31 #include "llvm/intrinsic_helper.h"
     32 #include "llvm/llvm_compilation_unit.h"
     33 #include "safe_map.h"
     34 
     35 namespace art {
     36 
     37 struct BasicBlock;
     38 struct CallInfo;
     39 struct CompilationUnit;
     40 struct MIR;
     41 struct RegLocation;
     42 struct RegisterInfo;
     43 class MIRGraph;
     44 
     45 // Target-specific initialization.
     46 Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
     47                                ArenaAllocator* const arena,
     48                                llvm::LlvmCompilationUnit* const llvm_compilation_unit);
     49 
     50 class MirConverter : public Backend {
     51   public:
     52     // TODO: flesh out and integrate into new world order.
     53     MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena,
     54                  llvm::LlvmCompilationUnit* llvm_compilation_unit)
     55       : Backend(arena),
     56         cu_(cu),
     57         mir_graph_(mir_graph),
     58         llvm_compilation_unit_(llvm_compilation_unit),
     59         llvm_info_(llvm_compilation_unit->GetQuickContext()),
     60         symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()),
     61         context_(NULL),
     62         module_(NULL),
     63         func_(NULL),
     64         intrinsic_helper_(NULL),
     65         irb_(NULL),
     66         placeholder_bb_(NULL),
     67         entry_bb_(NULL),
     68         entry_target_bb_(NULL),
     69         llvm_values_(arena, mir_graph->GetNumSSARegs()),
     70         temp_name_(0),
     71         current_dalvik_offset_(0) {
     72       if (kIsDebugBuild) {
     73         cu->enable_debug |= (1 << kDebugVerifyBitcode);
     74       }
     75     }
     76 
     77     void Materialize() {
     78       MethodMIR2Bitcode();
     79     }
     80 
     81     CompiledMethod* GetCompiledMethod() {
     82       return NULL;
     83     }
     84 
     85   private:
     86     ::llvm::BasicBlock* GetLLVMBlock(int id);
     87     ::llvm::Value* GetLLVMValue(int s_reg);
     88     void SetVregOnValue(::llvm::Value* val, int s_reg);
     89     void DefineValueOnly(::llvm::Value* val, int s_reg);
     90     void DefineValue(::llvm::Value* val, int s_reg);
     91     ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc);
     92     void InitIR();
     93     ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr);
     94     void ConvertPackedSwitch(BasicBlock* bb, int32_t table_offset,
     95                              RegLocation rl_src);
     96     void ConvertSparseSwitch(BasicBlock* bb, int32_t table_offset,
     97                              RegLocation rl_src);
     98     void ConvertSget(int32_t field_index,
     99                      art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
    100     void ConvertSput(int32_t field_index,
    101                      art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
    102     void ConvertFillArrayData(int32_t offset, RegLocation rl_array);
    103     ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
    104                              RegLocation loc);
    105     void EmitPopShadowFrame();
    106     ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
    107                             RegLocation loc);
    108     void ConvertMoveException(RegLocation rl_dest);
    109     void ConvertThrow(RegLocation rl_src);
    110     void ConvertMonitorEnterExit(int opt_flags,
    111                                  art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
    112     void ConvertArrayLength(int opt_flags, RegLocation rl_dest,
    113                             RegLocation rl_src);
    114     void EmitSuspendCheck();
    115     ::llvm::Value* ConvertCompare(ConditionCode cc,
    116                                   ::llvm::Value* src1, ::llvm::Value* src2);
    117     void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
    118                                  RegLocation rl_src1, RegLocation rl_src2);
    119     void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
    120                                      RegLocation rl_src1);
    121     ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1,
    122                                ::llvm::Value* src2);
    123     ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1,
    124                               ::llvm::Value* src2);
    125     void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
    126                           RegLocation rl_src2);
    127     void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
    128                       RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
    129     void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
    130                          RegLocation rl_dest, RegLocation rl_src, int shift_amount);
    131     void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
    132                         RegLocation rl_src2);
    133     void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
    134                            int32_t imm);
    135     void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type,
    136                        bool is_range, bool is_filled_new_array);
    137     void ConvertConstObject(uint32_t idx,
    138                             art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
    139     void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src);
    140     void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest);
    141     void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest,
    142                          RegLocation rl_src);
    143     void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
    144                      RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index);
    145     void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
    146                      RegLocation rl_src, RegLocation rl_array, RegLocation rl_index);
    147     void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
    148                      RegLocation rl_dest, RegLocation rl_obj, int field_index);
    149     void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
    150                      RegLocation rl_src, RegLocation rl_obj, int field_index);
    151     void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest,
    152                            RegLocation rl_src);
    153     void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src);
    154     void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src);
    155     void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src);
    156     void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src);
    157     void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
    158                                RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
    159     void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
    160                              art::llvm::IntrinsicHelper::IntrinsicId id);
    161     void ConvertNeg(RegLocation rl_dest, RegLocation rl_src);
    162     void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src);
    163     void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
    164                         RegLocation rl_dest, RegLocation rl_src);
    165     void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src);
    166     void ConvertNot(RegLocation rl_dest, RegLocation rl_src);
    167     void EmitConstructorBarrier();
    168     bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
    169     void SetDexOffset(int32_t offset);
    170     void SetMethodInfo();
    171     void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
    172     void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb);
    173     bool BlockBitcodeConversion(BasicBlock* bb);
    174     ::llvm::FunctionType* GetFunctionType();
    175     bool CreateFunction();
    176     bool CreateLLVMBasicBlock(BasicBlock* bb);
    177     void MethodMIR2Bitcode();
    178 
    179     CompilationUnit* cu_;
    180     MIRGraph* mir_graph_;
    181     llvm::LlvmCompilationUnit* const llvm_compilation_unit_;
    182     LLVMInfo* llvm_info_;
    183     std::string symbol_;
    184     ::llvm::LLVMContext* context_;
    185     ::llvm::Module* module_;
    186     ::llvm::Function* func_;
    187     art::llvm::IntrinsicHelper* intrinsic_helper_;
    188     art::llvm::IRBuilder* irb_;
    189     ::llvm::BasicBlock* placeholder_bb_;
    190     ::llvm::BasicBlock* entry_bb_;
    191     ::llvm::BasicBlock* entry_target_bb_;
    192     std::string bitcode_filename_;
    193     GrowableArray< ::llvm::Value*> llvm_values_;
    194     int32_t temp_name_;
    195     SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_;  // block id -> llvm bb.
    196     int current_dalvik_offset_;
    197 };  // Class MirConverter
    198 
    199 }  // namespace art
    200 
    201 #endif  // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
    202