Integrating portable path with the Frontend.

(1) Connect the new interface oatCompileMethodToGBC and gbc_expander.
(2) Need to fix Android.common.mk for fly2iceland: Portable path has
    frontend: USE_QUICK_COMPILER and backend: USE_LLVM_COMPILER.
(3) Fix Android.libart-compiler-llvm.mk so we can call the new interface.

Change-Id: I7216f378bdb5e42a35fd6fa10c1d5d161a912401
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index 9d7f1ae..3dcd793 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -59,7 +59,6 @@
   Compiler* compiler_;
 
   const DexFile* dex_file_;
-  DexCache* dex_cache_;
   const DexFile::CodeItem* code_item_;
 
   OatCompilationUnit* oat_compilation_unit_;
@@ -326,14 +325,25 @@
   GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb)
       : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
         context_(irb.getContext()), rtb_(irb.Runtime()),
-
-        // TODO: Initialize these fields correctly.
         shadow_frame_(NULL), old_shadow_frame_(NULL), shadow_frame_size_(0),
-        compiler_(NULL), dex_file_(NULL), dex_cache_(NULL), code_item_(NULL),
+        compiler_(NULL), dex_file_(NULL), code_item_(NULL),
         oat_compilation_unit_(NULL), method_idx_(-1u), func_(NULL),
         changed_(false)
   { }
 
+  GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
+                  Compiler* compiler, OatCompilationUnit* oat_compilation_unit)
+      : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
+        context_(irb.getContext()), rtb_(irb.Runtime()),
+        shadow_frame_(NULL), old_shadow_frame_(NULL), shadow_frame_size_(0),
+        compiler_(compiler),
+        dex_file_(oat_compilation_unit->GetDexFile()),
+        code_item_(oat_compilation_unit->GetCodeItem()),
+        oat_compilation_unit_(oat_compilation_unit),
+        method_idx_(oat_compilation_unit->GetDexMethodIndex()),
+        func_(NULL), changed_(false)
+  { }
+
   bool runOnFunction(llvm::Function& func);
 
  private:
@@ -359,6 +369,21 @@
   func_ = &func;
   changed_ = false; // Assume unchanged
 
+#if defined(ART_USE_QUICK_COMPILER)
+  basic_blocks_.resize(code_item_->insns_size_in_code_units_);
+  basic_block_landing_pads_.resize(code_item_->tries_size_, NULL);
+  basic_block_unwind_ = NULL;
+  for (llvm::Function::iterator bb_iter = func_->begin(), bb_end = func_->end();
+       bb_iter != bb_end;
+       ++bb_iter) {
+    if (bb_iter->begin()->getMetadata("DexOff") == NULL) {
+      continue;
+    }
+    uint32_t dex_pc = LV2UInt(bb_iter->begin()->getMetadata("DexOff")->getOperand(0));
+    basic_blocks_[dex_pc] = bb_iter;
+  }
+#endif
+
   // Insert stack overflow check
   InsertStackOverflowCheck(func); // TODO: Use intrinsic.
 
@@ -1138,6 +1163,11 @@
 }
 
 void GBCExpanderPass::Expand_PopShadowFrame() {
+#if defined(ART_USE_QUICK_COMPILER)
+  if (old_shadow_frame_ == NULL) {
+    return;
+  }
+#endif
   rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
   return;
 }
@@ -1317,6 +1347,8 @@
 
   case kBoolean:
   case kChar:
+  case kByte:
+  case kShort:
     new_value = irb_.CreateTrunc(new_value, irb_.getJType(elem_jty, kArray));
     break;
 
@@ -1412,8 +1444,8 @@
 void GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst,
                                     JType field_jty) {
   uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(1);
-  llvm::Value* new_value = call_inst.getArgOperand(2);
+  llvm::Value* new_value = call_inst.getArgOperand(1);
+  llvm::Value* object_addr = call_inst.getArgOperand(2);
   uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3));
 
   if (field_jty == kFloat || field_jty == kDouble) {
@@ -1475,8 +1507,7 @@
 
 llvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc,
                                                     uint32_t type_idx) {
-  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, dex_cache_,
-                                             *dex_file_, type_idx)) {
+  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
     llvm::Value* type_idx_value = irb_.getInt32(type_idx);
 
     llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
@@ -1502,7 +1533,7 @@
 
     llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAAJRuntime);
 
-    if (compiler_->CanAssumeTypeIsPresentInDexCache(dex_cache_, type_idx)) {
+    if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
       return type_object_addr;
     }
 
@@ -1774,7 +1805,7 @@
 
   llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAAJRuntime);
 
-  if (!compiler_->CanAssumeStringIsPresentInDexCache(dex_cache_, string_idx)) {
+  if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
     llvm::BasicBlock* block_str_exist =
       CreateBasicBlockWithDexPC(dex_pc, "str_exist");
 
@@ -1809,6 +1840,9 @@
 
     EmitGuard_ExceptionLandingPad(dex_pc);
 
+    irb_.CreateBr(block_cont);
+
+
     llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock();
 
     irb_.SetInsertPoint(block_cont);
@@ -1995,8 +2029,7 @@
   uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
 
   llvm::Function* runtime_func;
-  if (compiler_->CanAccessInstantiableTypeWithoutChecks(
-        method_idx_, dex_cache_, *dex_file_, type_idx)) {
+  if (compiler_->CanAccessInstantiableTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
     runtime_func = irb_.GetRuntime(runtime_support::AllocObject);
   } else {
     runtime_func = irb_.GetRuntime(runtime_support::AllocObjectWithAccessCheck);
@@ -2245,8 +2278,7 @@
   llvm::Function* runtime_func;
 
   bool skip_access_check =
-    compiler_->CanAccessTypeWithoutChecks(method_idx_, dex_cache_,
-                                          *dex_file_, type_idx);
+    compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx);
 
 
   if (is_filled_new_array) {
@@ -2342,6 +2374,11 @@
 }
 
 void GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) {
+#if defined(ART_USE_QUICK_COMPILER)
+  if (shadow_frame_ == NULL) {
+    return;
+  }
+#endif
   irb_.StoreToObjectOffset(shadow_frame_,
                            ShadowFrame::DexPCOffset(),
                            irb_.getInt32(dex_pc),
@@ -2434,7 +2471,18 @@
   CHECK_GE(shorty_size, 1u);
 
   // Get return type
-  llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
+
+  char ret_shorty = shorty[0];
+#if defined(ART_USE_QUICK_COMPILER)
+  switch(ret_shorty) {
+    case 'Z' : ret_shorty = 'I'; break;
+    case 'B' : ret_shorty = 'I'; break;
+    case 'S' : ret_shorty = 'I'; break;
+    case 'C' : ret_shorty = 'I'; break;
+    default: break;
+  }
+#endif
+  llvm::Type* ret_type = irb_.getJType(ret_shorty, kAccurate);
 
   // Get argument type
   std::vector<llvm::Type*> args_type;
@@ -2478,7 +2526,7 @@
 
 llvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) {
   DCHECK(dex_pc < code_item_->insns_size_in_code_units_);
-
+  CHECK(basic_blocks_[dex_pc] != NULL);
   return basic_blocks_[dex_pc];
 }
 
@@ -2588,6 +2636,15 @@
 
   // Emit the code to return default value (zero) for the given return type.
   char ret_shorty = oat_compilation_unit_->GetShorty()[0];
+#if defined(ART_USE_QUICK_COMPILER)
+  switch(ret_shorty) {
+    case 'Z' : ret_shorty = 'I'; break;
+    case 'B' : ret_shorty = 'I'; break;
+    case 'S' : ret_shorty = 'I'; break;
+    case 'C' : ret_shorty = 'I'; break;
+    default: break;
+  }
+#endif
   if (ret_shorty == 'V') {
     irb_.CreateRetVoid();
   } else {
@@ -3472,8 +3529,8 @@
                                 irb_.getJDoubleTy());
     }
     case greenland::IntrinsicHelper::ConstObj: {
-      LOG(FATAL) << "ConstObj should not occur at all";
-      return NULL;
+      CHECK(LV2UInt(call_inst.getArgOperand(0)) == 0);
+      return irb_.getJNull();
     }
 
     //==- Method Info ------------------------------------------------------==//
@@ -3560,5 +3617,16 @@
   return new GBCExpanderPass(intrinsic_helper, irb);
 }
 
+llvm::FunctionPass*
+CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
+                      Compiler* compiler, OatCompilationUnit* oat_compilation_unit) {
+  if (compiler != NULL) {
+    return new GBCExpanderPass(intrinsic_helper, irb,
+                               compiler, oat_compilation_unit);
+  } else {
+    return new GBCExpanderPass(intrinsic_helper, irb);
+  }
+}
+
 } // namespace compiler_llvm
 } // namespace art