summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.libart-compiler-llvm.mk4
-rw-r--r--build/Android.libart.mk2
-rw-r--r--src/compiler/codegen/mir_to_gbc.cc207
-rw-r--r--src/compiler/frontend.h1
-rw-r--r--src/compiler_llvm/compilation_unit.h2
-rw-r--r--src/compiler_llvm/compiler_llvm.cc19
-rw-r--r--src/compiler_llvm/gbc_expander.cc8
7 files changed, 145 insertions, 98 deletions
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk
index daef06e37a..4909f8103d 100644
--- a/build/Android.libart-compiler-llvm.mk
+++ b/build/Android.libart-compiler-llvm.mk
@@ -15,9 +15,9 @@
#
-LIBART_COMPILER_LLVM_CFLAGS := -DART_USE_LLVM_COMPILER
+LIBART_COMPILER_LLVM_CFLAGS := -DART_USE_LLVM_COMPILER=1
ifeq ($(ART_USE_PORTABLE_COMPILER),true)
- ART_TEST_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
+ LIBART_COMPILER_LLVM_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
endif
LIBART_COMPILER_LLVM_SRC_FILES += \
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 435056a1b0..5226db7a10 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -19,7 +19,7 @@ ifeq ($(ART_USE_LLVM_COMPILER),true)
LIBART_CFLAGS += -DART_USE_LLVM_COMPILER=1
endif
ifeq ($(ART_USE_PORTABLE_COMPILER),true)
- ART_TEST_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
+ LIBART_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
endif
# $(1): target or host
diff --git a/src/compiler/codegen/mir_to_gbc.cc b/src/compiler/codegen/mir_to_gbc.cc
index e1e1fb16a5..766a630a0c 100644
--- a/src/compiler/codegen/mir_to_gbc.cc
+++ b/src/compiler/codegen/mir_to_gbc.cc
@@ -50,8 +50,22 @@ static llvm::Value* GetLLVMValue(CompilationUnit* cu, int s_reg)
return reinterpret_cast<llvm::Value*>(GrowableListGetElement(&cu->llvm_values, s_reg));
}
+static void SetVregOnValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
+{
+ // Set vreg for debugging
+ if (cu->compiler->IsDebuggingSupported()) {
+ greenland::IntrinsicHelper::IntrinsicId id =
+ greenland::IntrinsicHelper::SetVReg;
+ llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
+ int v_reg = SRegToVReg(cu, s_reg);
+ llvm::Value* table_slot = cu->irb->getInt32(v_reg);
+ llvm::Value* args[] = { table_slot, val };
+ cu->irb->CreateCall(func, args);
+ }
+}
+
// Replace the placeholder value with the real definition
-static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
+static void DefineValueOnly(CompilationUnit* cu, llvm::Value* val, int s_reg)
{
llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
if (placeholder == NULL) {
@@ -66,16 +80,12 @@ static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
DCHECK(inst != NULL);
inst->eraseFromParent();
- // Set vreg for debugging
- if (!cu->compiler->IsDebuggingSupported()) {
- greenland::IntrinsicHelper::IntrinsicId id =
- greenland::IntrinsicHelper::SetVReg;
- llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
- int v_reg = SRegToVReg(cu, s_reg);
- llvm::Value* table_slot = cu->irb->getInt32(v_reg);
- llvm::Value* args[] = { table_slot, val };
- cu->irb->CreateCall(func, args);
- }
+}
+
+static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
+{
+ DefineValueOnly(cu, val, s_reg);
+ SetVregOnValue(cu, val, s_reg);
}
static llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
@@ -1625,6 +1635,97 @@ static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
return res;
}
+static void SetDexOffset(CompilationUnit* cu, int32_t offset)
+{
+ cu->current_dalvik_offset = offset;
+ llvm::SmallVector<llvm::Value*, 1> array_ref;
+ array_ref.push_back(cu->irb->getInt32(offset));
+ llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
+ cu->irb->SetDexOffset(node);
+}
+
+// Attach method info as metadata to special intrinsic
+static void SetMethodInfo(CompilationUnit* cu)
+{
+ // We don't want dex offset on this
+ cu->irb->SetDexOffset(NULL);
+ greenland::IntrinsicHelper::IntrinsicId id;
+ id = greenland::IntrinsicHelper::MethodInfo;
+ llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
+ llvm::Instruction* inst = cu->irb->CreateCall(intr);
+ llvm::SmallVector<llvm::Value*, 2> reg_info;
+ reg_info.push_back(cu->irb->getInt32(cu->num_ins));
+ reg_info.push_back(cu->irb->getInt32(cu->num_regs));
+ reg_info.push_back(cu->irb->getInt32(cu->num_outs));
+ reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
+ reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
+ llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
+ inst->setMetadata("RegInfo", reg_info_node);
+ int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
+ llvm::SmallVector<llvm::Value*, 50> pmap;
+ for (int i = 0; i < promo_size; i++) {
+ PromotionMap* p = &cu->promotion_map[i];
+ int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
+ ((p->FpReg & 0xff) << 16) |
+ ((p->core_reg & 0xff) << 8) |
+ ((p->fp_location & 0xf) << 4) |
+ (p->core_location & 0xf);
+ pmap.push_back(cu->irb->getInt32(map_data));
+ }
+ llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
+ inst->setMetadata("PromotionMap", map_node);
+ SetDexOffset(cu, cu->current_dalvik_offset);
+}
+
+static void HandlePhiNodes(CompilationUnit* cu, BasicBlock* bb, llvm::BasicBlock* llvm_bb)
+{
+ SetDexOffset(cu, bb->start_offset);
+ for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
+ int opcode = mir->dalvikInsn.opcode;
+ if (opcode < kMirOpFirst) {
+ // Stop after first non-pseudo MIR op.
+ continue;
+ }
+ if (opcode != kMirOpPhi) {
+ // Skip other mir Pseudos.
+ continue;
+ }
+ RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
+ /*
+ * The Art compiler's Phi nodes only handle 32-bit operands,
+ * representing wide values using a matched set of Phi nodes
+ * for the lower and upper halves. In the llvm world, we only
+ * want a single Phi for wides. Here we will simply discard
+ * the Phi node representing the high word.
+ */
+ if (rl_dest.high_word) {
+ continue; // No Phi node - handled via low word
+ }
+ int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
+ llvm::Type* phi_type =
+ LlvmTypeFromLocRec(cu, rl_dest);
+ llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
+ for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
+ RegLocation loc;
+ // Don't check width here.
+ loc = GetRawSrc(cu, mir, i);
+ DCHECK_EQ(rl_dest.wide, loc.wide);
+ DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
+ DCHECK_EQ(rl_dest.fp, loc.fp);
+ DCHECK_EQ(rl_dest.core, loc.core);
+ DCHECK_EQ(rl_dest.ref, loc.ref);
+ SafeMap<unsigned int, unsigned int>::iterator it;
+ it = cu->block_id_map.find(incoming[i]);
+ DCHECK(it != cu->block_id_map.end());
+ DCHECK(GetLLVMValue(cu, loc.orig_sreg) != NULL);
+ DCHECK(GetLLVMBlock(cu, it->second) != NULL);
+ phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
+ GetLLVMBlock(cu, it->second));
+ }
+ DefineValueOnly(cu, phi, rl_dest.orig_sreg);
+ }
+}
+
/* Extended MIR instructions like PHI */
static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
llvm::BasicBlock* llvm_bb)
@@ -1632,42 +1733,14 @@ static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
case kMirOpPhi: {
+ // The llvm Phi node already emitted - just DefineValue() here.
RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
- /*
- * The Art compiler's Phi nodes only handle 32-bit operands,
- * representing wide values using a matched set of Phi nodes
- * for the lower and upper halves. In the llvm world, we only
- * want a single Phi for wides. Here we will simply discard
- * the Phi node representing the high word.
- */
- if (rl_dest.high_word) {
- return; // No Phi node - handled via low word
+ if (!rl_dest.high_word) {
+ // Only consider low word of pairs.
+ DCHECK(GetLLVMValue(cu, rl_dest.orig_sreg) != NULL);
+ llvm::Value* phi = GetLLVMValue(cu, rl_dest.orig_sreg);
+ if (1) SetVregOnValue(cu, phi, rl_dest.orig_sreg);
}
- // LLVM requires that all Phi nodes are at the beginning of the block
- llvm::IRBuilderBase::InsertPoint ip = cu->irb->saveAndClearIP();
- cu->irb->SetInsertPoint(llvm_bb);
- int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
- llvm::Type* phi_type =
- LlvmTypeFromLocRec(cu, rl_dest);
- llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
- for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
- RegLocation loc;
- // Don't check width here.
- loc = GetRawSrc(cu, mir, i);
- DCHECK_EQ(rl_dest.wide, loc.wide);
- DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
- DCHECK_EQ(rl_dest.fp, loc.fp);
- DCHECK_EQ(rl_dest.core, loc.core);
- DCHECK_EQ(rl_dest.ref, loc.ref);
- SafeMap<unsigned int, unsigned int>::iterator it;
- it = cu->block_id_map.find(incoming[i]);
- DCHECK(it != cu->block_id_map.end());
- phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
- GetLLVMBlock(cu, it->second));
- }
- // Now that Phi node is emitted, add definition at old insert point
- cu->irb->restoreIP(ip);
- DefineValue(cu, phi, rl_dest.orig_sreg);
break;
}
case kMirOpCopy: {
@@ -1702,48 +1775,6 @@ static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
}
}
-static void SetDexOffset(CompilationUnit* cu, int32_t offset)
-{
- cu->current_dalvik_offset = offset;
- llvm::SmallVector<llvm::Value*, 1> array_ref;
- array_ref.push_back(cu->irb->getInt32(offset));
- llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
- cu->irb->SetDexOffset(node);
-}
-
-// Attach method info as metadata to special intrinsic
-static void SetMethodInfo(CompilationUnit* cu)
-{
- // We don't want dex offset on this
- cu->irb->SetDexOffset(NULL);
- greenland::IntrinsicHelper::IntrinsicId id;
- id = greenland::IntrinsicHelper::MethodInfo;
- llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
- llvm::Instruction* inst = cu->irb->CreateCall(intr);
- llvm::SmallVector<llvm::Value*, 2> reg_info;
- reg_info.push_back(cu->irb->getInt32(cu->num_ins));
- reg_info.push_back(cu->irb->getInt32(cu->num_regs));
- reg_info.push_back(cu->irb->getInt32(cu->num_outs));
- reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
- reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
- llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
- inst->setMetadata("RegInfo", reg_info_node);
- int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
- llvm::SmallVector<llvm::Value*, 50> pmap;
- for (int i = 0; i < promo_size; i++) {
- PromotionMap* p = &cu->promotion_map[i];
- int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
- ((p->FpReg & 0xff) << 16) |
- ((p->core_reg & 0xff) << 8) |
- ((p->fp_location & 0xf) << 4) |
- (p->core_location & 0xf);
- pmap.push_back(cu->irb->getInt32(map_data));
- }
- llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
- inst->setMetadata("PromotionMap", map_node);
- SetDexOffset(cu, cu->current_dalvik_offset);
-}
-
/* Handle the content in each basic block */
static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
{
@@ -1811,6 +1842,8 @@ static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
return false;
}
+ HandlePhiNodes(cu, bb, llvm_bb);
+
for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
SetDexOffset(cu, mir->offset);
diff --git a/src/compiler/frontend.h b/src/compiler/frontend.h
index fb32cdd31a..9cf3080ef0 100644
--- a/src/compiler/frontend.h
+++ b/src/compiler/frontend.h
@@ -145,6 +145,7 @@ extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
const art::DexFile::CodeItem* code_item,
uint32_t access_flags,
art::InvokeType invoke_type,
+ uint32_t class_dex_idx,
uint32_t method_idx,
jobject class_loader,
const art::DexFile& dex_file);
diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h
index 591d4f0a31..6ebac9aa68 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -29,7 +29,7 @@
#include "safe_map.h"
#if defined(ART_USE_PORTABLE_COMPILER)
-# include "compiler/Dalvik.h"
+# include "compiler/compiler_internals.h"
# include "compiler.h"
# include "oat_compilation_unit.h"
#endif
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 6de10e6940..29c381d143 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -164,6 +164,18 @@ CompileDexMethod(OatCompilationUnit* oat_compilation_unit, InvokeType invoke_typ
return method_compiler->Compile();
} else {
+
+#if 1
+ /*
+ * FIXME: temporary workaround
+ * Until Portable/llvm is fixed, use Iceland.
+ */
+ UniquePtr<MethodCompiler> method_compiler(
+ new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
+
+ return method_compiler->Compile();
+#endif
+
// TODO: consolidate ArtCompileMethods
CompileOneMethod(*compiler_,
kPortable,
@@ -181,9 +193,10 @@ CompileDexMethod(OatCompilationUnit* oat_compilation_unit, InvokeType invoke_typ
cunit->Materialize();
- Compiler::MethodReference mref(dex_file_, method_idx_);
- return new CompiledMethod(cunit_->GetInstructionSet(),
- cunit_->GetCompiledCode(),
+ Compiler::MethodReference mref(oat_compilation_unit->GetDexFile(),
+ oat_compilation_unit->GetDexMethodIndex());
+ return new CompiledMethod(compiler_->GetInstructionSet(),
+ cunit->GetCompiledCode(),
*verifier::MethodVerifier::GetDexGcMap(mref));
}
#else
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index 93d7d48ab3..0f71512e5d 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -45,7 +45,7 @@ using namespace art::compiler_llvm;
using art::greenland::IntrinsicHelper;
namespace art {
-extern char remapShorty(char shortyType);
+extern char RemapShorty(char shortyType);
};
namespace {
@@ -2485,7 +2485,7 @@ llvm::FunctionType* GBCExpanderPass::GetFunctionType(uint32_t method_idx,
char ret_shorty = shorty[0];
#if defined(ART_USE_PORTABLE_COMPILER)
- ret_shorty = art::remapShorty(ret_shorty);
+ ret_shorty = art::RemapShorty(ret_shorty);
#endif
llvm::Type* ret_type = irb_.getJType(ret_shorty, kAccurate);
@@ -2500,7 +2500,7 @@ llvm::FunctionType* GBCExpanderPass::GetFunctionType(uint32_t method_idx,
for (uint32_t i = 1; i < shorty_size; ++i) {
#if defined(ART_USE_PORTABLE_COMPILER)
- char shorty_type = art::remapShorty(shorty[i]);
+ char shorty_type = art::RemapShorty(shorty[i]);
args_type.push_back(irb_.getJType(shorty_type, kAccurate));
#else
args_type.push_back(irb_.getJType(shorty[i], kAccurate));
@@ -2635,7 +2635,7 @@ llvm::BasicBlock* GBCExpanderPass::GetUnwindBasicBlock() {
// 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_PORTABLE_COMPILER)
- ret_shorty = art::remapShorty(ret_shorty);
+ ret_shorty = art::RemapShorty(ret_shorty);
#endif
if (ret_shorty == 'V') {
irb_.CreateRetVoid();