Compiler: LIR restructuring
Continuing restructuring of the compiler. In this installment,
all LIR reverences are moved from compiler_ir down to quick. Further,
all Portable data is moved to from compiler_ir down to portable.
In short, the great dumping ground of CompilationUnit has been
split into three smaller dumping grounds of MIRGraph, Codegen
and MIRConverter. From here, subsequent CLs will repartition
those smaller dumping grounds into (hopefully) more coherent classes.
As a result, most function signatures have been altered to remove
the passing around of a CompilationUnit* pointer.
Change-Id: I7195f7baecd81e87786a952e18bbce0b6ceeaac4
diff --git a/src/compiler/dex/quick/ralloc_util.cc b/src/compiler/dex/quick/ralloc_util.cc
index 18c7714..a89cfa8 100644
--- a/src/compiler/dex/quick/ralloc_util.cc
+++ b/src/compiler/dex/quick/ralloc_util.cc
@@ -19,31 +19,24 @@
#include "compiler/dex/compiler_ir.h"
#include "compiler/dex/compiler_internals.h"
#include "compiler/dex/compiler_utility.h"
-//#include "compiler/dex/dataflow.h"
-#include "compiler/dex/quick/codegen_util.h"
-#include "ralloc_util.h"
namespace art {
-static const RegLocation bad_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
- INVALID_REG, INVALID_REG, INVALID_SREG,
- INVALID_SREG};
-
/*
* Free all allocated temps in the temp pools. Note that this does
* not affect the "liveness" of a temp register, which will stay
* live until it is either explicitly killed or reallocated.
*/
-void ResetRegPool(CompilationUnit* cu)
+void Mir2Lir::ResetRegPool()
{
int i;
- for (i=0; i < cu->reg_pool->num_core_regs; i++) {
- if (cu->reg_pool->core_regs[i].is_temp)
- cu->reg_pool->core_regs[i].in_use = false;
+ for (i=0; i < reg_pool_->num_core_regs; i++) {
+ if (reg_pool_->core_regs[i].is_temp)
+ reg_pool_->core_regs[i].in_use = false;
}
- for (i=0; i < cu->reg_pool->num_fp_regs; i++) {
- if (cu->reg_pool->FPRegs[i].is_temp)
- cu->reg_pool->FPRegs[i].in_use = false;
+ for (i=0; i < reg_pool_->num_fp_regs; i++) {
+ if (reg_pool_->FPRegs[i].is_temp)
+ reg_pool_->FPRegs[i].in_use = false;
}
}
@@ -51,7 +44,7 @@
* Set up temp & preserved register pools specialized by target.
* Note: num_regs may be zero.
*/
-void CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num)
+void Mir2Lir::CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num)
{
int i;
for (i=0; i < num; i++) {
@@ -65,7 +58,7 @@
}
}
-void DumpRegPool(RegisterInfo* p, int num_regs)
+void Mir2Lir::DumpRegPool(RegisterInfo* p, int num_regs)
{
LOG(INFO) << "================================================";
for (int i = 0; i < num_regs; i++) {
@@ -78,18 +71,18 @@
LOG(INFO) << "================================================";
}
-void DumpCoreRegPool(CompilationUnit* cu)
+void Mir2Lir::DumpCoreRegPool()
{
- DumpRegPool(cu->reg_pool->core_regs, cu->reg_pool->num_core_regs);
+ DumpRegPool(reg_pool_->core_regs, reg_pool_->num_core_regs);
}
-void DumpFpRegPool(CompilationUnit* cu)
+void Mir2Lir::DumpFpRegPool()
{
- DumpRegPool(cu->reg_pool->FPRegs, cu->reg_pool->num_fp_regs);
+ DumpRegPool(reg_pool_->FPRegs, reg_pool_->num_fp_regs);
}
/* Mark a temp register as dead. Does not affect allocation state. */
-static void ClobberBody(CompilationUnit *cu, RegisterInfo* p)
+void Mir2Lir::ClobberBody(RegisterInfo* p)
{
if (p->is_temp) {
DCHECK(!(p->live && p->dirty)) << "Live & dirty temp in clobber";
@@ -99,19 +92,18 @@
p->def_end = NULL;
if (p->pair) {
p->pair = false;
- Clobber(cu, p->partner);
+ Clobber(p->partner);
}
}
}
/* Mark a temp register as dead. Does not affect allocation state. */
-void Clobber(CompilationUnit* cu, int reg)
+void Mir2Lir::Clobber(int reg)
{
- Codegen* cg = cu->cg.get();
- ClobberBody(cu, cg->GetRegInfo(cu, reg));
+ ClobberBody(GetRegInfo(reg));
}
-static void ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg)
+void Mir2Lir::ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg)
{
int i;
for (i=0; i< num_regs; i++) {
@@ -136,16 +128,16 @@
* changes (for example: INT_TO_FLOAT v1, v1). Revisit when improved register allocation is
* addressed.
*/
-void ClobberSReg(CompilationUnit* cu, int s_reg)
+void Mir2Lir::ClobberSReg(int s_reg)
{
/* Reset live temp tracking sanity checker */
if (kIsDebugBuild) {
- if (s_reg == cu->live_sreg) {
- cu->live_sreg = INVALID_SREG;
+ if (s_reg == live_sreg_) {
+ live_sreg_ = INVALID_SREG;
}
}
- ClobberSRegBody(cu->reg_pool->core_regs, cu->reg_pool->num_core_regs, s_reg);
- ClobberSRegBody(cu->reg_pool->FPRegs, cu->reg_pool->num_fp_regs, s_reg);
+ ClobberSRegBody(reg_pool_->core_regs, reg_pool_->num_core_regs, s_reg);
+ ClobberSRegBody(reg_pool_->FPRegs, reg_pool_->num_fp_regs, s_reg);
}
/*
@@ -157,60 +149,57 @@
* ssa name (above the last original Dalvik register). This function
* maps SSA names to positions in the promotion_map array.
*/
-int SRegToPMap(CompilationUnit* cu, int s_reg)
+int Mir2Lir::SRegToPMap(int s_reg)
{
- DCHECK_LT(s_reg, cu->mir_graph->GetNumSSARegs());
+ DCHECK_LT(s_reg, mir_graph_->GetNumSSARegs());
DCHECK_GE(s_reg, 0);
- int v_reg = cu->mir_graph->SRegToVReg(s_reg);
+ int v_reg = mir_graph_->SRegToVReg(s_reg);
if (v_reg >= 0) {
- DCHECK_LT(v_reg, cu->num_dalvik_registers);
+ DCHECK_LT(v_reg, cu_->num_dalvik_registers);
return v_reg;
} else {
int pos = std::abs(v_reg) - std::abs(SSA_METHOD_BASEREG);
- DCHECK_LE(pos, cu->num_compiler_temps);
- return cu->num_dalvik_registers + pos;
+ DCHECK_LE(pos, cu_->num_compiler_temps);
+ return cu_->num_dalvik_registers + pos;
}
}
-void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg)
+void Mir2Lir::RecordCorePromotion(int reg, int s_reg)
{
- Codegen* cg = cu->cg.get();
- int p_map_idx = SRegToPMap(cu, s_reg);
- int v_reg = cu->mir_graph->SRegToVReg(s_reg);
- cg->GetRegInfo(cu, reg)->in_use = true;
- cu->core_spill_mask |= (1 << reg);
+ int p_map_idx = SRegToPMap(s_reg);
+ int v_reg = mir_graph_->SRegToVReg(s_reg);
+ GetRegInfo(reg)->in_use = true;
+ core_spill_mask_ |= (1 << reg);
// Include reg for later sort
- cu->core_vmap_table.push_back(reg << VREG_NUM_WIDTH |
- (v_reg & ((1 << VREG_NUM_WIDTH) - 1)));
- cu->num_core_spills++;
- cu->promotion_map[p_map_idx].core_location = kLocPhysReg;
- cu->promotion_map[p_map_idx].core_reg = reg;
+ core_vmap_table_.push_back(reg << VREG_NUM_WIDTH | (v_reg & ((1 << VREG_NUM_WIDTH) - 1)));
+ num_core_spills_++;
+ promotion_map_[p_map_idx].core_location = kLocPhysReg;
+ promotion_map_[p_map_idx].core_reg = reg;
}
/* Reserve a callee-save register. Return -1 if none available */
-static int AllocPreservedCoreReg(CompilationUnit* cu, int s_reg)
+int Mir2Lir::AllocPreservedCoreReg(int s_reg)
{
int res = -1;
- RegisterInfo* core_regs = cu->reg_pool->core_regs;
- for (int i = 0; i < cu->reg_pool->num_core_regs; i++) {
+ RegisterInfo* core_regs = reg_pool_->core_regs;
+ for (int i = 0; i < reg_pool_->num_core_regs; i++) {
if (!core_regs[i].is_temp && !core_regs[i].in_use) {
res = core_regs[i].reg;
- RecordCorePromotion(cu, res, s_reg);
+ RecordCorePromotion(res, s_reg);
break;
}
}
return res;
}
-void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg)
+void Mir2Lir::RecordFpPromotion(int reg, int s_reg)
{
- Codegen* cg = cu->cg.get();
- int p_map_idx = SRegToPMap(cu, s_reg);
- int v_reg = cu->mir_graph->SRegToVReg(s_reg);
- cg->GetRegInfo(cu, reg)->in_use = true;
- cg->MarkPreservedSingle(cu, v_reg, reg);
- cu->promotion_map[p_map_idx].fp_location = kLocPhysReg;
- cu->promotion_map[p_map_idx].FpReg = reg;
+ int p_map_idx = SRegToPMap(s_reg);
+ int v_reg = mir_graph_->SRegToVReg(s_reg);
+ GetRegInfo(reg)->in_use = true;
+ MarkPreservedSingle(v_reg, reg);
+ promotion_map_[p_map_idx].fp_location = kLocPhysReg;
+ promotion_map_[p_map_idx].FpReg = reg;
}
/*
@@ -218,15 +207,15 @@
* even/odd allocation, but go ahead and allocate anything if not
* available. If nothing's available, return -1.
*/
-static int AllocPreservedSingle(CompilationUnit* cu, int s_reg, bool even)
+int Mir2Lir::AllocPreservedSingle(int s_reg, bool even)
{
int res = -1;
- RegisterInfo* FPRegs = cu->reg_pool->FPRegs;
- for (int i = 0; i < cu->reg_pool->num_fp_regs; i++) {
+ RegisterInfo* FPRegs = reg_pool_->FPRegs;
+ for (int i = 0; i < reg_pool_->num_fp_regs; i++) {
if (!FPRegs[i].is_temp && !FPRegs[i].in_use &&
((FPRegs[i].reg & 0x1) == 0) == even) {
res = FPRegs[i].reg;
- RecordFpPromotion(cu, res, s_reg);
+ RecordFpPromotion(res, s_reg);
break;
}
}
@@ -241,21 +230,20 @@
* allocate if we can't meet the requirements for the pair of
* s_reg<=sX[even] & (s_reg+1)<= sX+1.
*/
-static int AllocPreservedDouble(CompilationUnit* cu, int s_reg)
+int Mir2Lir::AllocPreservedDouble(int s_reg)
{
- Codegen* cg = cu->cg.get();
int res = -1; // Assume failure
- int v_reg = cu->mir_graph->SRegToVReg(s_reg);
- int p_map_idx = SRegToPMap(cu, s_reg);
- if (cu->promotion_map[p_map_idx+1].fp_location == kLocPhysReg) {
+ int v_reg = mir_graph_->SRegToVReg(s_reg);
+ int p_map_idx = SRegToPMap(s_reg);
+ if (promotion_map_[p_map_idx+1].fp_location == kLocPhysReg) {
// Upper reg is already allocated. Can we fit?
- int high_reg = cu->promotion_map[p_map_idx+1].FpReg;
+ int high_reg = promotion_map_[p_map_idx+1].FpReg;
if ((high_reg & 1) == 0) {
// High reg is even - fail.
return res;
}
// Is the low reg of the pair free?
- RegisterInfo* p = cg->GetRegInfo(cu, high_reg-1);
+ RegisterInfo* p = GetRegInfo(high_reg-1);
if (p->in_use || p->is_temp) {
// Already allocated or not preserved - fail.
return res;
@@ -264,10 +252,10 @@
res = p->reg;
p->in_use = true;
DCHECK_EQ((res & 1), 0);
- cg->MarkPreservedSingle(cu, v_reg, res);
+ MarkPreservedSingle(v_reg, res);
} else {
- RegisterInfo* FPRegs = cu->reg_pool->FPRegs;
- for (int i = 0; i < cu->reg_pool->num_fp_regs; i++) {
+ RegisterInfo* FPRegs = reg_pool_->FPRegs;
+ for (int i = 0; i < reg_pool_->num_fp_regs; i++) {
if (!FPRegs[i].is_temp && !FPRegs[i].in_use &&
((FPRegs[i].reg & 0x1) == 0x0) &&
!FPRegs[i+1].is_temp && !FPRegs[i+1].in_use &&
@@ -275,19 +263,19 @@
(FPRegs[i].reg + 1) == FPRegs[i+1].reg) {
res = FPRegs[i].reg;
FPRegs[i].in_use = true;
- cg->MarkPreservedSingle(cu, v_reg, res);
+ MarkPreservedSingle(v_reg, res);
FPRegs[i+1].in_use = true;
DCHECK_EQ(res + 1, FPRegs[i+1].reg);
- cg->MarkPreservedSingle(cu, v_reg+1, res+1);
+ MarkPreservedSingle(v_reg+1, res+1);
break;
}
}
}
if (res != -1) {
- cu->promotion_map[p_map_idx].fp_location = kLocPhysReg;
- cu->promotion_map[p_map_idx].FpReg = res;
- cu->promotion_map[p_map_idx+1].fp_location = kLocPhysReg;
- cu->promotion_map[p_map_idx+1].FpReg = res + 1;
+ promotion_map_[p_map_idx].fp_location = kLocPhysReg;
+ promotion_map_[p_map_idx].FpReg = res;
+ promotion_map_[p_map_idx+1].fp_location = kLocPhysReg;
+ promotion_map_[p_map_idx+1].FpReg = res + 1;
}
return res;
}
@@ -299,22 +287,22 @@
* single regs (but if can't still attempt to allocate a single, preferring
* first to allocate an odd register.
*/
-static int AllocPreservedFPReg(CompilationUnit* cu, int s_reg, bool double_start)
+int Mir2Lir::AllocPreservedFPReg(int s_reg, bool double_start)
{
int res = -1;
if (double_start) {
- res = AllocPreservedDouble(cu, s_reg);
+ res = AllocPreservedDouble(s_reg);
}
if (res == -1) {
- res = AllocPreservedSingle(cu, s_reg, false /* try odd # */);
+ res = AllocPreservedSingle(s_reg, false /* try odd # */);
}
if (res == -1)
- res = AllocPreservedSingle(cu, s_reg, true /* try even # */);
+ res = AllocPreservedSingle(s_reg, true /* try even # */);
return res;
}
-static int AllocTempBody(CompilationUnit* cu, RegisterInfo* p, int num_regs, int* next_temp,
- bool required)
+int Mir2Lir::AllocTempBody(RegisterInfo* p, int num_regs, int* next_temp,
+ bool required)
{
int i;
int next = *next_temp;
@@ -322,7 +310,7 @@
if (next >= num_regs)
next = 0;
if (p[next].is_temp && !p[next].in_use && !p[next].live) {
- Clobber(cu, p[next].reg);
+ Clobber(p[next].reg);
p[next].in_use = true;
p[next].pair = false;
*next_temp = next + 1;
@@ -335,7 +323,7 @@
if (next >= num_regs)
next = 0;
if (p[next].is_temp && !p[next].in_use) {
- Clobber(cu, p[next].reg);
+ Clobber(p[next].reg);
p[next].in_use = true;
p[next].pair = false;
*next_temp = next + 1;
@@ -344,21 +332,21 @@
next++;
}
if (required) {
- CodegenDump(cu);
- DumpRegPool(cu->reg_pool->core_regs,
- cu->reg_pool->num_core_regs);
+ CodegenDump();
+ DumpRegPool(reg_pool_->core_regs,
+ reg_pool_->num_core_regs);
LOG(FATAL) << "No free temp registers";
}
return -1; // No register available
}
//REDO: too many assumptions.
-int AllocTempDouble(CompilationUnit* cu)
+int Mir2Lir::AllocTempDouble()
{
- RegisterInfo* p = cu->reg_pool->FPRegs;
- int num_regs = cu->reg_pool->num_fp_regs;
+ RegisterInfo* p = reg_pool_->FPRegs;
+ int num_regs = reg_pool_->num_fp_regs;
/* Start looking at an even reg */
- int next = cu->reg_pool->next_fp_reg & ~0x1;
+ int next = reg_pool_->next_fp_reg & ~0x1;
// First try to avoid allocating live registers
for (int i=0; i < num_regs; i+=2) {
@@ -366,21 +354,21 @@
next = 0;
if ((p[next].is_temp && !p[next].in_use && !p[next].live) &&
(p[next+1].is_temp && !p[next+1].in_use && !p[next+1].live)) {
- Clobber(cu, p[next].reg);
- Clobber(cu, p[next+1].reg);
+ Clobber(p[next].reg);
+ Clobber(p[next+1].reg);
p[next].in_use = true;
p[next+1].in_use = true;
DCHECK_EQ((p[next].reg+1), p[next+1].reg);
DCHECK_EQ((p[next].reg & 0x1), 0);
- cu->reg_pool->next_fp_reg = next + 2;
- if (cu->reg_pool->next_fp_reg >= num_regs) {
- cu->reg_pool->next_fp_reg = 0;
+ reg_pool_->next_fp_reg = next + 2;
+ if (reg_pool_->next_fp_reg >= num_regs) {
+ reg_pool_->next_fp_reg = 0;
}
return p[next].reg;
}
next += 2;
}
- next = cu->reg_pool->next_fp_reg & ~0x1;
+ next = reg_pool_->next_fp_reg & ~0x1;
// No choice - find a pair and kill it.
for (int i=0; i < num_regs; i+=2) {
@@ -388,15 +376,15 @@
next = 0;
if (p[next].is_temp && !p[next].in_use && p[next+1].is_temp &&
!p[next+1].in_use) {
- Clobber(cu, p[next].reg);
- Clobber(cu, p[next+1].reg);
+ Clobber(p[next].reg);
+ Clobber(p[next+1].reg);
p[next].in_use = true;
p[next+1].in_use = true;
DCHECK_EQ((p[next].reg+1), p[next+1].reg);
DCHECK_EQ((p[next].reg & 0x1), 0);
- cu->reg_pool->next_fp_reg = next + 2;
- if (cu->reg_pool->next_fp_reg >= num_regs) {
- cu->reg_pool->next_fp_reg = 0;
+ reg_pool_->next_fp_reg = next + 2;
+ if (reg_pool_->next_fp_reg >= num_regs) {
+ reg_pool_->next_fp_reg = 0;
}
return p[next].reg;
}
@@ -407,28 +395,28 @@
}
/* Return a temp if one is available, -1 otherwise */
-int AllocFreeTemp(CompilationUnit* cu)
+int Mir2Lir::AllocFreeTemp()
{
- return AllocTempBody(cu, cu->reg_pool->core_regs,
- cu->reg_pool->num_core_regs,
- &cu->reg_pool->next_core_reg, true);
+ return AllocTempBody(reg_pool_->core_regs,
+ reg_pool_->num_core_regs,
+ ®_pool_->next_core_reg, true);
}
-int AllocTemp(CompilationUnit* cu)
+int Mir2Lir::AllocTemp()
{
- return AllocTempBody(cu, cu->reg_pool->core_regs,
- cu->reg_pool->num_core_regs,
- &cu->reg_pool->next_core_reg, true);
+ return AllocTempBody(reg_pool_->core_regs,
+ reg_pool_->num_core_regs,
+ ®_pool_->next_core_reg, true);
}
-int AllocTempFloat(CompilationUnit* cu)
+int Mir2Lir::AllocTempFloat()
{
- return AllocTempBody(cu, cu->reg_pool->FPRegs,
- cu->reg_pool->num_fp_regs,
- &cu->reg_pool->next_fp_reg, true);
+ return AllocTempBody(reg_pool_->FPRegs,
+ reg_pool_->num_fp_regs,
+ ®_pool_->next_fp_reg, true);
}
-static RegisterInfo* AllocLiveBody(RegisterInfo* p, int num_regs, int s_reg)
+Mir2Lir::RegisterInfo* Mir2Lir::AllocLiveBody(RegisterInfo* p, int num_regs, int s_reg)
{
int i;
if (s_reg == -1)
@@ -443,23 +431,23 @@
return NULL;
}
-RegisterInfo* AllocLive(CompilationUnit* cu, int s_reg, int reg_class)
+Mir2Lir::RegisterInfo* Mir2Lir::AllocLive(int s_reg, int reg_class)
{
RegisterInfo* res = NULL;
switch (reg_class) {
case kAnyReg:
- res = AllocLiveBody(cu->reg_pool->FPRegs,
- cu->reg_pool->num_fp_regs, s_reg);
+ res = AllocLiveBody(reg_pool_->FPRegs,
+ reg_pool_->num_fp_regs, s_reg);
if (res)
break;
/* Intentional fallthrough */
case kCoreReg:
- res = AllocLiveBody(cu->reg_pool->core_regs,
- cu->reg_pool->num_core_regs, s_reg);
+ res = AllocLiveBody(reg_pool_->core_regs,
+ reg_pool_->num_core_regs, s_reg);
break;
case kFPReg:
- res = AllocLiveBody(cu->reg_pool->FPRegs,
- cu->reg_pool->num_fp_regs, s_reg);
+ res = AllocLiveBody(reg_pool_->FPRegs,
+ reg_pool_->num_fp_regs, s_reg);
break;
default:
LOG(FATAL) << "Invalid register type";
@@ -467,10 +455,10 @@
return res;
}
-void FreeTemp(CompilationUnit* cu, int reg)
+void Mir2Lir::FreeTemp(int reg)
{
- RegisterInfo* p = cu->reg_pool->core_regs;
- int num_regs = cu->reg_pool->num_core_regs;
+ RegisterInfo* p = reg_pool_->core_regs;
+ int num_regs = reg_pool_->num_core_regs;
int i;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
@@ -481,8 +469,8 @@
return;
}
}
- p = cu->reg_pool->FPRegs;
- num_regs = cu->reg_pool->num_fp_regs;
+ p = reg_pool_->FPRegs;
+ num_regs = reg_pool_->num_fp_regs;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
if (p[i].is_temp) {
@@ -495,18 +483,18 @@
LOG(FATAL) << "Tried to free a non-existant temp: r" << reg;
}
-RegisterInfo* IsLive(CompilationUnit* cu, int reg)
+Mir2Lir::RegisterInfo* Mir2Lir::IsLive(int reg)
{
- RegisterInfo* p = cu->reg_pool->core_regs;
- int num_regs = cu->reg_pool->num_core_regs;
+ RegisterInfo* p = reg_pool_->core_regs;
+ int num_regs = reg_pool_->num_core_regs;
int i;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
return p[i].live ? &p[i] : NULL;
}
}
- p = cu->reg_pool->FPRegs;
- num_regs = cu->reg_pool->num_fp_regs;
+ p = reg_pool_->FPRegs;
+ num_regs = reg_pool_->num_fp_regs;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
return p[i].live ? &p[i] : NULL;
@@ -515,24 +503,21 @@
return NULL;
}
-RegisterInfo* IsTemp(CompilationUnit* cu, int reg)
+Mir2Lir::RegisterInfo* Mir2Lir::IsTemp(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* p = cg->GetRegInfo(cu, reg);
+ RegisterInfo* p = GetRegInfo(reg);
return (p->is_temp) ? p : NULL;
}
-RegisterInfo* IsPromoted(CompilationUnit* cu, int reg)
+Mir2Lir::RegisterInfo* Mir2Lir::IsPromoted(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* p = cg->GetRegInfo(cu, reg);
+ RegisterInfo* p = GetRegInfo(reg);
return (p->is_temp) ? NULL : p;
}
-bool IsDirty(CompilationUnit* cu, int reg)
+bool Mir2Lir::IsDirty(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* p = cg->GetRegInfo(cu, reg);
+ RegisterInfo* p = GetRegInfo(reg);
return p->dirty;
}
@@ -541,10 +526,10 @@
* register. No check is made to see if the register was previously
* allocated. Use with caution.
*/
-void LockTemp(CompilationUnit* cu, int reg)
+void Mir2Lir::LockTemp(int reg)
{
- RegisterInfo* p = cu->reg_pool->core_regs;
- int num_regs = cu->reg_pool->num_core_regs;
+ RegisterInfo* p = reg_pool_->core_regs;
+ int num_regs = reg_pool_->num_core_regs;
int i;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
@@ -554,8 +539,8 @@
return;
}
}
- p = cu->reg_pool->FPRegs;
- num_regs = cu->reg_pool->num_fp_regs;
+ p = reg_pool_->FPRegs;
+ num_regs = reg_pool_->num_fp_regs;
for (i=0; i< num_regs; i++) {
if (p[i].reg == reg) {
DCHECK(p[i].is_temp);
@@ -567,19 +552,18 @@
LOG(FATAL) << "Tried to lock a non-existant temp: r" << reg;
}
-static void ResetDefBody(RegisterInfo* p)
+void Mir2Lir::ResetDefBody(RegisterInfo* p)
{
p->def_start = NULL;
p->def_end = NULL;
}
-void ResetDef(CompilationUnit* cu, int reg)
+void Mir2Lir::ResetDef(int reg)
{
- Codegen* cg = cu->cg.get();
- ResetDefBody(cg->GetRegInfo(cu, reg));
+ ResetDefBody(GetRegInfo(reg));
}
-static void NullifyRange(CompilationUnit* cu, LIR *start, LIR *finish, int s_reg1, int s_reg2)
+void Mir2Lir::NullifyRange(LIR *start, LIR *finish, int s_reg1, int s_reg2)
{
if (start && finish) {
LIR *p;
@@ -597,14 +581,12 @@
* on entry start points to the LIR prior to the beginning of the
* sequence.
*/
-void MarkDef(CompilationUnit* cu, RegLocation rl,
- LIR *start, LIR *finish)
+void Mir2Lir::MarkDef(RegLocation rl, LIR *start, LIR *finish)
{
DCHECK(!rl.wide);
DCHECK(start && start->next);
DCHECK(finish);
- Codegen* cg = cu->cg.get();
- RegisterInfo* p = cg->GetRegInfo(cu, rl.low_reg);
+ RegisterInfo* p = GetRegInfo(rl.low_reg);
p->def_start = start->next;
p->def_end = finish;
}
@@ -614,26 +596,23 @@
* on entry start points to the LIR prior to the beginning of the
* sequence.
*/
-void MarkDefWide(CompilationUnit* cu, RegLocation rl,
- LIR *start, LIR *finish)
+void Mir2Lir::MarkDefWide(RegLocation rl, LIR *start, LIR *finish)
{
DCHECK(rl.wide);
DCHECK(start && start->next);
DCHECK(finish);
- Codegen* cg = cu->cg.get();
- RegisterInfo* p = cg->GetRegInfo(cu, rl.low_reg);
- ResetDef(cu, rl.high_reg); // Only track low of pair
+ RegisterInfo* p = GetRegInfo(rl.low_reg);
+ ResetDef(rl.high_reg); // Only track low of pair
p->def_start = start->next;
p->def_end = finish;
}
-RegLocation WideToNarrow(CompilationUnit* cu, RegLocation rl)
+RegLocation Mir2Lir::WideToNarrow(RegLocation rl)
{
DCHECK(rl.wide);
- Codegen* cg = cu->cg.get();
if (rl.location == kLocPhysReg) {
- RegisterInfo* info_lo = cg->GetRegInfo(cu, rl.low_reg);
- RegisterInfo* info_hi = cg->GetRegInfo(cu, rl.high_reg);
+ RegisterInfo* info_lo = GetRegInfo(rl.low_reg);
+ RegisterInfo* info_hi = GetRegInfo(rl.high_reg);
if (info_lo->is_temp) {
info_lo->pair = false;
info_lo->def_start = NULL;
@@ -649,102 +628,99 @@
return rl;
}
-void ResetDefLoc(CompilationUnit* cu, RegLocation rl)
+void Mir2Lir::ResetDefLoc(RegLocation rl)
{
DCHECK(!rl.wide);
- RegisterInfo* p = IsTemp(cu, rl.low_reg);
- if (p && !(cu->disable_opt & (1 << kSuppressLoads))) {
+ RegisterInfo* p = IsTemp(rl.low_reg);
+ if (p && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(!p->pair);
- NullifyRange(cu, p->def_start, p->def_end, p->s_reg, rl.s_reg_low);
+ NullifyRange(p->def_start, p->def_end, p->s_reg, rl.s_reg_low);
}
- ResetDef(cu, rl.low_reg);
+ ResetDef(rl.low_reg);
}
-void ResetDefLocWide(CompilationUnit* cu, RegLocation rl)
+void Mir2Lir::ResetDefLocWide(RegLocation rl)
{
DCHECK(rl.wide);
- RegisterInfo* p_low = IsTemp(cu, rl.low_reg);
- RegisterInfo* p_high = IsTemp(cu, rl.high_reg);
- if (p_low && !(cu->disable_opt & (1 << kSuppressLoads))) {
+ RegisterInfo* p_low = IsTemp(rl.low_reg);
+ RegisterInfo* p_high = IsTemp(rl.high_reg);
+ if (p_low && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_low->pair);
- NullifyRange(cu, p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
+ NullifyRange(p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
}
- if (p_high && !(cu->disable_opt & (1 << kSuppressLoads))) {
+ if (p_high && !(cu_->disable_opt & (1 << kSuppressLoads))) {
DCHECK(p_high->pair);
}
- ResetDef(cu, rl.low_reg);
- ResetDef(cu, rl.high_reg);
+ ResetDef(rl.low_reg);
+ ResetDef(rl.high_reg);
}
-void ResetDefTracking(CompilationUnit* cu)
+void Mir2Lir::ResetDefTracking()
{
int i;
- for (i=0; i< cu->reg_pool->num_core_regs; i++) {
- ResetDefBody(&cu->reg_pool->core_regs[i]);
+ for (i=0; i< reg_pool_->num_core_regs; i++) {
+ ResetDefBody(®_pool_->core_regs[i]);
}
- for (i=0; i< cu->reg_pool->num_fp_regs; i++) {
- ResetDefBody(&cu->reg_pool->FPRegs[i]);
+ for (i=0; i< reg_pool_->num_fp_regs; i++) {
+ ResetDefBody(®_pool_->FPRegs[i]);
}
}
-void ClobberAllRegs(CompilationUnit* cu)
+void Mir2Lir::ClobberAllRegs()
{
int i;
- for (i=0; i< cu->reg_pool->num_core_regs; i++) {
- ClobberBody(cu, &cu->reg_pool->core_regs[i]);
+ for (i=0; i< reg_pool_->num_core_regs; i++) {
+ ClobberBody(®_pool_->core_regs[i]);
}
- for (i=0; i< cu->reg_pool->num_fp_regs; i++) {
- ClobberBody(cu, &cu->reg_pool->FPRegs[i]);
+ for (i=0; i< reg_pool_->num_fp_regs; i++) {
+ ClobberBody(®_pool_->FPRegs[i]);
}
}
// Make sure nothing is live and dirty
-static void FlushAllRegsBody(CompilationUnit* cu, RegisterInfo* info, int num_regs)
+void Mir2Lir::FlushAllRegsBody(RegisterInfo* info, int num_regs)
{
- Codegen* cg = cu->cg.get();
int i;
for (i=0; i < num_regs; i++) {
if (info[i].live && info[i].dirty) {
if (info[i].pair) {
- cg->FlushRegWide(cu, info[i].reg, info[i].partner);
+ FlushRegWide(info[i].reg, info[i].partner);
} else {
- cg->FlushReg(cu, info[i].reg);
+ FlushReg(info[i].reg);
}
}
}
}
-void FlushAllRegs(CompilationUnit* cu)
+void Mir2Lir::FlushAllRegs()
{
- FlushAllRegsBody(cu, cu->reg_pool->core_regs,
- cu->reg_pool->num_core_regs);
- FlushAllRegsBody(cu, cu->reg_pool->FPRegs,
- cu->reg_pool->num_fp_regs);
- ClobberAllRegs(cu);
+ FlushAllRegsBody(reg_pool_->core_regs,
+ reg_pool_->num_core_regs);
+ FlushAllRegsBody(reg_pool_->FPRegs,
+ reg_pool_->num_fp_regs);
+ ClobberAllRegs();
}
//TUNING: rewrite all of this reg stuff. Probably use an attribute table
-static bool RegClassMatches(CompilationUnit* cu, int reg_class, int reg)
+bool Mir2Lir::RegClassMatches(int reg_class, int reg)
{
- Codegen* cg = cu->cg.get();
if (reg_class == kAnyReg) {
return true;
} else if (reg_class == kCoreReg) {
- return !cg->IsFpReg(reg);
+ return !IsFpReg(reg);
} else {
- return cg->IsFpReg(reg);
+ return IsFpReg(reg);
}
}
-void MarkLive(CompilationUnit* cu, int reg, int s_reg)
+void Mir2Lir::MarkLive(int reg, int s_reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, reg);
+ RegisterInfo* info = GetRegInfo(reg);
if ((info->reg == reg) && (info->s_reg == s_reg) && info->live) {
return; /* already live */
} else if (s_reg != INVALID_SREG) {
- ClobberSReg(cu, s_reg);
+ ClobberSReg(s_reg);
if (info->is_temp) {
info->live = true;
}
@@ -756,68 +732,61 @@
info->s_reg = s_reg;
}
-void MarkTemp(CompilationUnit* cu, int reg)
+void Mir2Lir::MarkTemp(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, reg);
+ RegisterInfo* info = GetRegInfo(reg);
info->is_temp = true;
}
-void UnmarkTemp(CompilationUnit* cu, int reg)
+void Mir2Lir::UnmarkTemp(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, reg);
+ RegisterInfo* info = GetRegInfo(reg);
info->is_temp = false;
}
-void MarkPair(CompilationUnit* cu, int low_reg, int high_reg)
+void Mir2Lir::MarkPair(int low_reg, int high_reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info_lo = cg->GetRegInfo(cu, low_reg);
- RegisterInfo* info_hi = cg->GetRegInfo(cu, high_reg);
+ RegisterInfo* info_lo = GetRegInfo(low_reg);
+ RegisterInfo* info_hi = GetRegInfo(high_reg);
info_lo->pair = info_hi->pair = true;
info_lo->partner = high_reg;
info_hi->partner = low_reg;
}
-void MarkClean(CompilationUnit* cu, RegLocation loc)
+void Mir2Lir::MarkClean(RegLocation loc)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, loc.low_reg);
+ RegisterInfo* info = GetRegInfo(loc.low_reg);
info->dirty = false;
if (loc.wide) {
- info = cg->GetRegInfo(cu, loc.high_reg);
+ info = GetRegInfo(loc.high_reg);
info->dirty = false;
}
}
-void MarkDirty(CompilationUnit* cu, RegLocation loc)
+void Mir2Lir::MarkDirty(RegLocation loc)
{
if (loc.home) {
// If already home, can't be dirty
return;
}
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, loc.low_reg);
+ RegisterInfo* info = GetRegInfo(loc.low_reg);
info->dirty = true;
if (loc.wide) {
- info = cg->GetRegInfo(cu, loc.high_reg);
+ info = GetRegInfo(loc.high_reg);
info->dirty = true;
}
}
-void MarkInUse(CompilationUnit* cu, int reg)
+void Mir2Lir::MarkInUse(int reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* info = cg->GetRegInfo(cu, reg);
+ RegisterInfo* info = GetRegInfo(reg);
info->in_use = true;
}
-static void CopyRegInfo(CompilationUnit* cu, int new_reg, int old_reg)
+void Mir2Lir::CopyRegInfo(int new_reg, int old_reg)
{
- Codegen* cg = cu->cg.get();
- RegisterInfo* new_info = cg->GetRegInfo(cu, new_reg);
- RegisterInfo* old_info = cg->GetRegInfo(cu, old_reg);
+ RegisterInfo* new_info = GetRegInfo(new_reg);
+ RegisterInfo* old_info = GetRegInfo(old_reg);
// Target temp status must not change
bool is_temp = new_info->is_temp;
*new_info = *old_info;
@@ -826,15 +795,14 @@
new_info->reg = new_reg;
}
-static bool CheckCorePoolSanity(CompilationUnit* cu)
+bool Mir2Lir::CheckCorePoolSanity()
{
- Codegen* cg = cu->cg.get();
- for (static int i = 0; i < cu->reg_pool->num_core_regs; i++) {
- if (cu->reg_pool->core_regs[i].pair) {
- static int my_reg = cu->reg_pool->core_regs[i].reg;
- static int my_sreg = cu->reg_pool->core_regs[i].s_reg;
- static int partner_reg = cu->reg_pool->core_regs[i].partner;
- static RegisterInfo* partner = cg->GetRegInfo(cu, partner_reg);
+ for (static int i = 0; i < reg_pool_->num_core_regs; i++) {
+ if (reg_pool_->core_regs[i].pair) {
+ static int my_reg = reg_pool_->core_regs[i].reg;
+ static int my_sreg = reg_pool_->core_regs[i].s_reg;
+ static int partner_reg = reg_pool_->core_regs[i].partner;
+ static RegisterInfo* partner = GetRegInfo(partner_reg);
DCHECK(partner != NULL);
DCHECK(partner->pair);
DCHECK_EQ(my_reg, partner->partner);
@@ -846,9 +814,9 @@
DCHECK((diff == -1) || (diff == 1));
}
}
- if (!cu->reg_pool->core_regs[i].live) {
- DCHECK(cu->reg_pool->core_regs[i].def_start == NULL);
- DCHECK(cu->reg_pool->core_regs[i].def_end == NULL);
+ if (!reg_pool_->core_regs[i].live) {
+ DCHECK(reg_pool_->core_regs[i].def_start == NULL);
+ DCHECK(reg_pool_->core_regs[i].def_end == NULL);
}
}
return true;
@@ -864,19 +832,19 @@
* if it's worthwhile trying to be more clever here.
*/
-RegLocation UpdateLoc(CompilationUnit* cu, RegLocation loc)
+RegLocation Mir2Lir::UpdateLoc(RegLocation loc)
{
DCHECK(!loc.wide);
- DCHECK(CheckCorePoolSanity(cu));
+ DCHECK(CheckCorePoolSanity());
if (loc.location != kLocPhysReg) {
DCHECK((loc.location == kLocDalvikFrame) ||
(loc.location == kLocCompilerTemp));
- RegisterInfo* info_lo = AllocLive(cu, loc.s_reg_low, kAnyReg);
+ RegisterInfo* info_lo = AllocLive(loc.s_reg_low, kAnyReg);
if (info_lo) {
if (info_lo->pair) {
- Clobber(cu, info_lo->reg);
- Clobber(cu, info_lo->partner);
- FreeTemp(cu, info_lo->reg);
+ Clobber(info_lo->reg);
+ Clobber(info_lo->partner);
+ FreeTemp(info_lo->reg);
} else {
loc.low_reg = info_lo->reg;
loc.location = kLocPhysReg;
@@ -888,25 +856,23 @@
}
/* see comments for update_loc */
-RegLocation UpdateLocWide(CompilationUnit* cu, RegLocation loc)
+RegLocation Mir2Lir::UpdateLocWide(RegLocation loc)
{
DCHECK(loc.wide);
- DCHECK(CheckCorePoolSanity(cu));
- Codegen* cg = cu->cg.get();
+ DCHECK(CheckCorePoolSanity());
if (loc.location != kLocPhysReg) {
DCHECK((loc.location == kLocDalvikFrame) ||
(loc.location == kLocCompilerTemp));
// Are the dalvik regs already live in physical registers?
- RegisterInfo* info_lo = AllocLive(cu, loc.s_reg_low, kAnyReg);
- RegisterInfo* info_hi = AllocLive(cu,
- GetSRegHi(loc.s_reg_low), kAnyReg);
+ RegisterInfo* info_lo = AllocLive(loc.s_reg_low, kAnyReg);
+ RegisterInfo* info_hi = AllocLive(GetSRegHi(loc.s_reg_low), kAnyReg);
bool match = true;
match = match && (info_lo != NULL);
match = match && (info_hi != NULL);
// Are they both core or both FP?
- match = match && (cg->IsFpReg(info_lo->reg) == cg->IsFpReg(info_hi->reg));
+ match = match && (IsFpReg(info_lo->reg) == IsFpReg(info_hi->reg));
// If a pair of floating point singles, are they properly aligned?
- if (match && cg->IsFpReg(info_lo->reg)) {
+ if (match && IsFpReg(info_lo->reg)) {
match &= ((info_lo->reg & 0x1) == 0);
match &= ((info_hi->reg - info_lo->reg) == 1);
}
@@ -921,22 +887,22 @@
loc.low_reg = info_lo->reg;
loc.high_reg = info_hi->reg;
loc.location = kLocPhysReg;
- MarkPair(cu, loc.low_reg, loc.high_reg);
- DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ MarkPair(loc.low_reg, loc.high_reg);
+ DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
return loc;
}
// Can't easily reuse - clobber and free any overlaps
if (info_lo) {
- Clobber(cu, info_lo->reg);
- FreeTemp(cu, info_lo->reg);
+ Clobber(info_lo->reg);
+ FreeTemp(info_lo->reg);
if (info_lo->pair)
- Clobber(cu, info_lo->partner);
+ Clobber(info_lo->partner);
}
if (info_hi) {
- Clobber(cu, info_hi->reg);
- FreeTemp(cu, info_hi->reg);
+ Clobber(info_hi->reg);
+ FreeTemp(info_hi->reg);
if (info_hi->pair)
- Clobber(cu, info_hi->partner);
+ Clobber(info_hi->partner);
}
}
return loc;
@@ -944,42 +910,41 @@
/* For use in cases we don't know (or care) width */
-RegLocation UpdateRawLoc(CompilationUnit* cu, RegLocation loc)
+RegLocation Mir2Lir::UpdateRawLoc(RegLocation loc)
{
if (loc.wide)
- return UpdateLocWide(cu, loc);
+ return UpdateLocWide(loc);
else
- return UpdateLoc(cu, loc);
+ return UpdateLoc(loc);
}
-RegLocation EvalLocWide(CompilationUnit* cu, RegLocation loc, int reg_class, bool update)
+RegLocation Mir2Lir::EvalLocWide(RegLocation loc, int reg_class, bool update)
{
DCHECK(loc.wide);
int new_regs;
int low_reg;
int high_reg;
- Codegen* cg = cu->cg.get();
- loc = UpdateLocWide(cu, loc);
+ loc = UpdateLocWide(loc);
/* If already in registers, we can assume proper form. Right reg class? */
if (loc.location == kLocPhysReg) {
- DCHECK_EQ(cg->IsFpReg(loc.low_reg), cg->IsFpReg(loc.high_reg));
- DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
- if (!RegClassMatches(cu, reg_class, loc.low_reg)) {
+ DCHECK_EQ(IsFpReg(loc.low_reg), IsFpReg(loc.high_reg));
+ DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ if (!RegClassMatches(reg_class, loc.low_reg)) {
/* Wrong register class. Reallocate and copy */
- new_regs = cg->AllocTypedTempPair(cu, loc.fp, reg_class);
+ new_regs = AllocTypedTempPair(loc.fp, reg_class);
low_reg = new_regs & 0xff;
high_reg = (new_regs >> 8) & 0xff;
- cg->OpRegCopyWide(cu, low_reg, high_reg, loc.low_reg, loc.high_reg);
- CopyRegInfo(cu, low_reg, loc.low_reg);
- CopyRegInfo(cu, high_reg, loc.high_reg);
- Clobber(cu, loc.low_reg);
- Clobber(cu, loc.high_reg);
+ OpRegCopyWide(low_reg, high_reg, loc.low_reg, loc.high_reg);
+ CopyRegInfo(low_reg, loc.low_reg);
+ CopyRegInfo(high_reg, loc.high_reg);
+ Clobber(loc.low_reg);
+ Clobber(loc.high_reg);
loc.low_reg = low_reg;
loc.high_reg = high_reg;
- MarkPair(cu, loc.low_reg, loc.high_reg);
- DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ MarkPair(loc.low_reg, loc.high_reg);
+ DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
}
return loc;
}
@@ -987,38 +952,36 @@
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
DCHECK_NE(GetSRegHi(loc.s_reg_low), INVALID_SREG);
- new_regs = cg->AllocTypedTempPair(cu, loc.fp, reg_class);
+ new_regs = AllocTypedTempPair(loc.fp, reg_class);
loc.low_reg = new_regs & 0xff;
loc.high_reg = (new_regs >> 8) & 0xff;
- MarkPair(cu, loc.low_reg, loc.high_reg);
+ MarkPair(loc.low_reg, loc.high_reg);
if (update) {
loc.location = kLocPhysReg;
- MarkLive(cu, loc.low_reg, loc.s_reg_low);
- MarkLive(cu, loc.high_reg, GetSRegHi(loc.s_reg_low));
+ MarkLive(loc.low_reg, loc.s_reg_low);
+ MarkLive(loc.high_reg, GetSRegHi(loc.s_reg_low));
}
- DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
+ DCHECK(!IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
return loc;
}
-RegLocation EvalLoc(CompilationUnit* cu, RegLocation loc,
- int reg_class, bool update)
+RegLocation Mir2Lir::EvalLoc(RegLocation loc, int reg_class, bool update)
{
int new_reg;
if (loc.wide)
- return EvalLocWide(cu, loc, reg_class, update);
+ return EvalLocWide(loc, reg_class, update);
- Codegen* cg = cu->cg.get();
- loc = UpdateLoc(cu, loc);
+ loc = UpdateLoc(loc);
if (loc.location == kLocPhysReg) {
- if (!RegClassMatches(cu, reg_class, loc.low_reg)) {
+ if (!RegClassMatches(reg_class, loc.low_reg)) {
/* Wrong register class. Realloc, copy and transfer ownership */
- new_reg = cg->AllocTypedTemp(cu, loc.fp, reg_class);
- cg->OpRegCopy(cu, new_reg, loc.low_reg);
- CopyRegInfo(cu, new_reg, loc.low_reg);
- Clobber(cu, loc.low_reg);
+ new_reg = AllocTypedTemp(loc.fp, reg_class);
+ OpRegCopy(new_reg, loc.low_reg);
+ CopyRegInfo(new_reg, loc.low_reg);
+ Clobber(loc.low_reg);
loc.low_reg = new_reg;
}
return loc;
@@ -1026,76 +989,33 @@
DCHECK_NE(loc.s_reg_low, INVALID_SREG);
- new_reg = cg->AllocTypedTemp(cu, loc.fp, reg_class);
+ new_reg = AllocTypedTemp(loc.fp, reg_class);
loc.low_reg = new_reg;
if (update) {
loc.location = kLocPhysReg;
- MarkLive(cu, loc.low_reg, loc.s_reg_low);
+ MarkLive(loc.low_reg, loc.s_reg_low);
}
return loc;
}
-RegLocation GetRawSrc(CompilationUnit* cu, MIR* mir, int num)
-{
- DCHECK(num < mir->ssa_rep->num_uses);
- RegLocation res = cu->reg_location[mir->ssa_rep->uses[num]];
- return res;
-}
-
-RegLocation GetRawDest(CompilationUnit* cu, MIR* mir)
-{
- DCHECK_GT(mir->ssa_rep->num_defs, 0);
- RegLocation res = cu->reg_location[mir->ssa_rep->defs[0]];
- return res;
-}
-
-RegLocation GetDest(CompilationUnit* cu, MIR* mir)
-{
- RegLocation res = GetRawDest(cu, mir);
- DCHECK(!res.wide);
- return res;
-}
-
-RegLocation GetSrc(CompilationUnit* cu, MIR* mir, int num)
-{
- RegLocation res = GetRawSrc(cu, mir, num);
- DCHECK(!res.wide);
- return res;
-}
-
-RegLocation GetDestWide(CompilationUnit* cu, MIR* mir)
-{
- RegLocation res = GetRawDest(cu, mir);
- DCHECK(res.wide);
- return res;
-}
-
-RegLocation GetSrcWide(CompilationUnit* cu, MIR* mir,
- int low)
-{
- RegLocation res = GetRawSrc(cu, mir, low);
- DCHECK(res.wide);
- return res;
-}
-
/* USE SSA names to count references of base Dalvik v_regs. */
-static void CountRefs(CompilationUnit *cu, BasicBlock* bb, RefCounts* core_counts,
- RefCounts* fp_counts)
+void Mir2Lir::CountRefs(BasicBlock* bb, RefCounts* core_counts,
+ RefCounts* fp_counts)
{
// TUNING: this routine could use some tweaking.
- if ((cu->disable_opt & (1 << kPromoteRegs)) ||
+ if ((cu_->disable_opt & (1 << kPromoteRegs)) ||
!((bb->block_type == kEntryBlock) || (bb->block_type == kExitBlock) ||
(bb->block_type == kDalvikByteCode))) {
return;
}
- for (int i = 0; i < cu->mir_graph->GetNumSSARegs(); i++) {
- RegLocation loc = cu->reg_location[i];
+ for (int i = 0; i < mir_graph_->GetNumSSARegs(); i++) {
+ RegLocation loc = mir_graph_->reg_location_[i];
RefCounts* counts = loc.fp ? fp_counts : core_counts;
- int p_map_idx = SRegToPMap(cu, loc.s_reg_low);
+ int p_map_idx = SRegToPMap(loc.s_reg_low);
//Don't count easily regenerated immediates
- if (loc.fp || !IsInexpensiveConstant(cu, loc)) {
- counts[p_map_idx].count += cu->mir_graph->GetUseCount(i);
+ if (loc.fp || !IsInexpensiveConstant(loc)) {
+ counts[p_map_idx].count += mir_graph_->GetUseCount(i);
}
if (loc.wide && loc.fp && !loc.high_word) {
counts[p_map_idx].double_start = true;
@@ -1106,12 +1026,12 @@
/* qsort callback function, sort descending */
static int SortCounts(const void *val1, const void *val2)
{
- const RefCounts* op1 = reinterpret_cast<const RefCounts*>(val1);
- const RefCounts* op2 = reinterpret_cast<const RefCounts*>(val2);
+ const Mir2Lir::RefCounts* op1 = reinterpret_cast<const Mir2Lir::RefCounts*>(val1);
+ const Mir2Lir::RefCounts* op2 = reinterpret_cast<const Mir2Lir::RefCounts*>(val2);
return (op1->count == op2->count) ? 0 : (op1->count < op2->count ? 1 : -1);
}
-static void DumpCounts(const RefCounts* arr, int size, const char* msg)
+void Mir2Lir::DumpCounts(const RefCounts* arr, int size, const char* msg)
{
LOG(INFO) << msg;
for (int i = 0; i < size; i++) {
@@ -1123,16 +1043,15 @@
* Note: some portions of this code required even if the kPromoteRegs
* optimization is disabled.
*/
-void DoPromotion(CompilationUnit* cu)
+void Mir2Lir::DoPromotion()
{
- Codegen* cg = cu->cg.get();
- int reg_bias = cu->num_compiler_temps + 1;
- int dalvik_regs = cu->num_dalvik_registers;
+ int reg_bias = cu_->num_compiler_temps + 1;
+ int dalvik_regs = cu_->num_dalvik_registers;
int num_regs = dalvik_regs + reg_bias;
const int promotion_threshold = 2;
// Allow target code to add any special registers
- cg->AdjustSpillMask(cu);
+ AdjustSpillMask();
/*
* Simple register promotion. Just do a static count of the uses
@@ -1145,30 +1064,30 @@
* TUNING: replace with linear scan once we have the ability
* to describe register live ranges for GC.
*/
- RefCounts *core_regs = static_cast<RefCounts*>(NewMem(cu, sizeof(RefCounts) * num_regs,
+ RefCounts *core_regs = static_cast<RefCounts*>(NewMem(cu_, sizeof(RefCounts) * num_regs,
true, kAllocRegAlloc));
- RefCounts *FpRegs = static_cast<RefCounts *>(NewMem(cu, sizeof(RefCounts) * num_regs,
+ RefCounts *FpRegs = static_cast<RefCounts *>(NewMem(cu_, sizeof(RefCounts) * num_regs,
true, kAllocRegAlloc));
// Set ssa names for original Dalvik registers
for (int i = 0; i < dalvik_regs; i++) {
core_regs[i].s_reg = FpRegs[i].s_reg = i;
}
// Set ssa name for Method*
- core_regs[dalvik_regs].s_reg = cu->method_sreg;
- FpRegs[dalvik_regs].s_reg = cu->method_sreg; // For consistecy
+ core_regs[dalvik_regs].s_reg = mir_graph_->GetMethodSReg();
+ FpRegs[dalvik_regs].s_reg = mir_graph_->GetMethodSReg(); // For consistecy
// Set ssa names for compiler_temps
- for (int i = 1; i <= cu->num_compiler_temps; i++) {
- CompilerTemp* ct = reinterpret_cast<CompilerTemp*>(cu->compiler_temps.elem_list[i]);
+ for (int i = 1; i <= cu_->num_compiler_temps; i++) {
+ CompilerTemp* ct = reinterpret_cast<CompilerTemp*>(mir_graph_->compiler_temps_.elem_list[i]);
core_regs[dalvik_regs + i].s_reg = ct->s_reg;
FpRegs[dalvik_regs + i].s_reg = ct->s_reg;
}
- GrowableListIterator iterator = cu->mir_graph->GetBasicBlockIterator();
+ GrowableListIterator iterator = mir_graph_->GetBasicBlockIterator();
while (true) {
BasicBlock* bb;
bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
if (bb == NULL) break;
- CountRefs(cu, bb, core_regs, FpRegs);
+ CountRefs(bb, core_regs, FpRegs);
}
/*
@@ -1186,18 +1105,18 @@
qsort(core_regs, num_regs, sizeof(RefCounts), SortCounts);
qsort(FpRegs, num_regs, sizeof(RefCounts), SortCounts);
- if (cu->verbose) {
+ if (cu_->verbose) {
DumpCounts(core_regs, num_regs, "Core regs after sort");
DumpCounts(FpRegs, num_regs, "Fp regs after sort");
}
- if (!(cu->disable_opt & (1 << kPromoteRegs))) {
+ if (!(cu_->disable_opt & (1 << kPromoteRegs))) {
// Promote FpRegs
for (int i = 0; (i < num_regs) &&
(FpRegs[i].count >= promotion_threshold ); i++) {
- int p_map_idx = SRegToPMap(cu, FpRegs[i].s_reg);
- if (cu->promotion_map[p_map_idx].fp_location != kLocPhysReg) {
- int reg = AllocPreservedFPReg(cu, FpRegs[i].s_reg,
+ int p_map_idx = SRegToPMap(FpRegs[i].s_reg);
+ if (promotion_map_[p_map_idx].fp_location != kLocPhysReg) {
+ int reg = AllocPreservedFPReg(FpRegs[i].s_reg,
FpRegs[i].double_start);
if (reg < 0) {
break; // No more left
@@ -1208,10 +1127,10 @@
// Promote core regs
for (int i = 0; (i < num_regs) &&
(core_regs[i].count > promotion_threshold); i++) {
- int p_map_idx = SRegToPMap(cu, core_regs[i].s_reg);
- if (cu->promotion_map[p_map_idx].core_location !=
+ int p_map_idx = SRegToPMap(core_regs[i].s_reg);
+ if (promotion_map_[p_map_idx].core_location !=
kLocPhysReg) {
- int reg = AllocPreservedCoreReg(cu, core_regs[i].s_reg);
+ int reg = AllocPreservedCoreReg(core_regs[i].s_reg);
if (reg < 0) {
break; // No more left
}
@@ -1220,20 +1139,20 @@
}
// Now, update SSA names to new home locations
- for (int i = 0; i < cu->mir_graph->GetNumSSARegs(); i++) {
- RegLocation *curr = &cu->reg_location[i];
- int p_map_idx = SRegToPMap(cu, curr->s_reg_low);
+ for (int i = 0; i < mir_graph_->GetNumSSARegs(); i++) {
+ RegLocation *curr = &mir_graph_->reg_location_[i];
+ int p_map_idx = SRegToPMap(curr->s_reg_low);
if (!curr->wide) {
if (curr->fp) {
- if (cu->promotion_map[p_map_idx].fp_location == kLocPhysReg) {
+ if (promotion_map_[p_map_idx].fp_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->low_reg = cu->promotion_map[p_map_idx].FpReg;
+ curr->low_reg = promotion_map_[p_map_idx].FpReg;
curr->home = true;
}
} else {
- if (cu->promotion_map[p_map_idx].core_location == kLocPhysReg) {
+ if (promotion_map_[p_map_idx].core_location == kLocPhysReg) {
curr->location = kLocPhysReg;
- curr->low_reg = cu->promotion_map[p_map_idx].core_reg;
+ curr->low_reg = promotion_map_[p_map_idx].core_reg;
curr->home = true;
}
}
@@ -1243,11 +1162,11 @@
continue;
}
if (curr->fp) {
- if ((cu->promotion_map[p_map_idx].fp_location == kLocPhysReg) &&
- (cu->promotion_map[p_map_idx+1].fp_location ==
+ if ((promotion_map_[p_map_idx].fp_location == kLocPhysReg) &&
+ (promotion_map_[p_map_idx+1].fp_location ==
kLocPhysReg)) {
- int low_reg = cu->promotion_map[p_map_idx].FpReg;
- int high_reg = cu->promotion_map[p_map_idx+1].FpReg;
+ int low_reg = promotion_map_[p_map_idx].FpReg;
+ int high_reg = promotion_map_[p_map_idx+1].FpReg;
// Doubles require pair of singles starting at even reg
if (((low_reg & 0x1) == 0) && ((low_reg + 1) == high_reg)) {
curr->location = kLocPhysReg;
@@ -1257,85 +1176,97 @@
}
}
} else {
- if ((cu->promotion_map[p_map_idx].core_location == kLocPhysReg)
- && (cu->promotion_map[p_map_idx+1].core_location ==
+ if ((promotion_map_[p_map_idx].core_location == kLocPhysReg)
+ && (promotion_map_[p_map_idx+1].core_location ==
kLocPhysReg)) {
curr->location = kLocPhysReg;
- curr->low_reg = cu->promotion_map[p_map_idx].core_reg;
- curr->high_reg = cu->promotion_map[p_map_idx+1].core_reg;
+ curr->low_reg = promotion_map_[p_map_idx].core_reg;
+ curr->high_reg = promotion_map_[p_map_idx+1].core_reg;
curr->home = true;
}
}
}
}
- if (cu->verbose) {
- DumpPromotionMap(cu);
+ if (cu_->verbose) {
+ DumpPromotionMap();
}
}
/* Returns sp-relative offset in bytes for a VReg */
-int VRegOffset(CompilationUnit* cu, int v_reg)
+int Mir2Lir::VRegOffset(int v_reg)
{
- return StackVisitor::GetVRegOffset(cu->code_item, cu->core_spill_mask,
- cu->fp_spill_mask, cu->frame_size, v_reg);
+ return StackVisitor::GetVRegOffset(cu_->code_item, core_spill_mask_,
+ fp_spill_mask_, frame_size_, v_reg);
}
/* Returns sp-relative offset in bytes for a SReg */
-int SRegOffset(CompilationUnit* cu, int s_reg)
+int Mir2Lir::SRegOffset(int s_reg)
{
- return VRegOffset(cu, cu->mir_graph->SRegToVReg(s_reg));
-}
-
-RegLocation GetBadLoc()
-{
- RegLocation res = bad_loc;
- return res;
+ return VRegOffset(mir_graph_->SRegToVReg(s_reg));
}
/* Mark register usage state and return long retloc */
-RegLocation GetReturnWide(CompilationUnit* cu, bool is_double)
+RegLocation Mir2Lir::GetReturnWide(bool is_double)
{
- Codegen* cg = cu->cg.get();
- RegLocation gpr_res = cg->LocCReturnWide();
- RegLocation fpr_res = cg->LocCReturnDouble();
+ RegLocation gpr_res = LocCReturnWide();
+ RegLocation fpr_res = LocCReturnDouble();
RegLocation res = is_double ? fpr_res : gpr_res;
- Clobber(cu, res.low_reg);
- Clobber(cu, res.high_reg);
- LockTemp(cu, res.low_reg);
- LockTemp(cu, res.high_reg);
- MarkPair(cu, res.low_reg, res.high_reg);
+ Clobber(res.low_reg);
+ Clobber(res.high_reg);
+ LockTemp(res.low_reg);
+ LockTemp(res.high_reg);
+ MarkPair(res.low_reg, res.high_reg);
return res;
}
-RegLocation GetReturn(CompilationUnit* cu, bool is_float)
+RegLocation Mir2Lir::GetReturn(bool is_float)
{
- Codegen* cg = cu->cg.get();
- RegLocation gpr_res = cg->LocCReturn();
- RegLocation fpr_res = cg->LocCReturnFloat();
+ RegLocation gpr_res = LocCReturn();
+ RegLocation fpr_res = LocCReturnFloat();
RegLocation res = is_float ? fpr_res : gpr_res;
- Clobber(cu, res.low_reg);
- if (cu->instruction_set == kMips) {
- MarkInUse(cu, res.low_reg);
+ Clobber(res.low_reg);
+ if (cu_->instruction_set == kMips) {
+ MarkInUse(res.low_reg);
} else {
- LockTemp(cu, res.low_reg);
+ LockTemp(res.low_reg);
}
return res;
}
-void Codegen::SimpleRegAlloc(CompilationUnit* cu)
+void Mir2Lir::SimpleRegAlloc()
{
- DoPromotion(cu);
+ DoPromotion();
- /* Get easily-accessable post-promotion copy of RegLocation for Method* */
- cu->method_loc = cu->reg_location[cu->method_sreg];
-
- if (cu->verbose && !(cu->disable_opt & (1 << kPromoteRegs))) {
+ if (cu_->verbose && !(cu_->disable_opt & (1 << kPromoteRegs))) {
LOG(INFO) << "After Promotion";
- cu->mir_graph->DumpRegLocTable(cu->reg_location, cu->mir_graph->GetNumSSARegs());
+ mir_graph_->DumpRegLocTable(mir_graph_->reg_location_, mir_graph_->GetNumSSARegs());
}
/* Set the frame size */
- cu->frame_size = cu->mir_graph->ComputeFrameSize();
+ frame_size_ = ComputeFrameSize();
+}
+
+/*
+ * Get the "real" sreg number associated with an s_reg slot. In general,
+ * s_reg values passed through codegen are the SSA names created by
+ * dataflow analysis and refer to slot numbers in the mir_graph_->reg_location
+ * array. However, renaming is accomplished by simply replacing RegLocation
+ * entries in the reglocation[] array. Therefore, when location
+ * records for operands are first created, we need to ask the locRecord
+ * identified by the dataflow pass what it's new name is.
+ */
+int Mir2Lir::GetSRegHi(int lowSreg) {
+ return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
+}
+
+bool Mir2Lir::oat_live_out(int s_reg) {
+ //For now.
+ return true;
+}
+
+int Mir2Lir::oatSSASrc(MIR* mir, int num) {
+ DCHECK_GT(mir->ssa_rep->num_uses, num);
+ return mir->ssa_rep->uses[num];
}
} // namespace art