mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:09:48 +00:00
[vm, compiler] Allocate only one SSA index to definitions, even those with pair representation.
Change the mapping between SSA indices and virtual registers from 1:1 to 1:2. This shrinks the size of bit vectors used during optimizations, and leaves the size of bit vectors used during register allocation the same. TEST=ci Change-Id: I0c82ca7972f7efb30559f7e4869396f1eed757c5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250982 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
05e5664ad6
commit
c2058b0f40
|
@ -126,10 +126,7 @@ bool AotCallSpecializer::TryCreateICDataForUniqueTarget(
|
|||
const intptr_t receiver_index = call->FirstArgIndex();
|
||||
RedefinitionInstr* redefinition = new (Z)
|
||||
RedefinitionInstr(new (Z) Value(call->ArgumentAt(receiver_index)));
|
||||
redefinition->set_ssa_temp_index(flow_graph()->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
|
||||
flow_graph()->alloc_ssa_temp_index();
|
||||
}
|
||||
flow_graph()->AllocateSSAIndex(redefinition);
|
||||
redefinition->InsertAfter(call);
|
||||
// Replace all uses of the receiver dominated by this call.
|
||||
FlowGraph::RenameDominatedUses(call->ArgumentAt(receiver_index),
|
||||
|
|
|
@ -31,10 +31,7 @@ class BlockBuilder : public ValueObject {
|
|||
}
|
||||
|
||||
Definition* AddToInitialDefinitions(Definition* def) {
|
||||
def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(def->representation())) {
|
||||
flow_graph_->alloc_ssa_temp_index();
|
||||
}
|
||||
flow_graph_->AllocateSSAIndex(def);
|
||||
auto normal_entry = flow_graph_->graph_entry()->normal_entry();
|
||||
flow_graph_->AddToInitialDefinitions(normal_entry, def);
|
||||
return def;
|
||||
|
@ -42,7 +39,7 @@ class BlockBuilder : public ValueObject {
|
|||
|
||||
template <typename T>
|
||||
T* AddDefinition(T* def) {
|
||||
flow_graph_->AllocateSSAIndexes(def);
|
||||
flow_graph_->AllocateSSAIndex(def);
|
||||
AddInstruction(def);
|
||||
return def;
|
||||
}
|
||||
|
@ -134,10 +131,7 @@ class BlockBuilder : public ValueObject {
|
|||
}
|
||||
|
||||
void AddPhi(PhiInstr* phi) {
|
||||
phi->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(phi->representation())) {
|
||||
flow_graph_->alloc_ssa_temp_index();
|
||||
}
|
||||
flow_graph_->AllocateSSAIndex(phi);
|
||||
phi->mark_alive();
|
||||
entry_->AsJoinEntry()->InsertPhi(phi);
|
||||
}
|
||||
|
|
|
@ -35,9 +35,8 @@ ConstantPropagator::ConstantPropagator(
|
|||
unknown_(Object::unknown_constant()),
|
||||
non_constant_(Object::non_constant()),
|
||||
constant_value_(Object::Handle(Z)),
|
||||
reachable_(new (Z) BitVector(Z, graph->preorder().length())),
|
||||
unwrapped_phis_(new (Z)
|
||||
BitVector(Z, graph->max_virtual_register_number())),
|
||||
reachable_(new(Z) BitVector(Z, graph->preorder().length())),
|
||||
unwrapped_phis_(new(Z) BitVector(Z, graph->current_ssa_temp_index())),
|
||||
block_worklist_(),
|
||||
definition_worklist_(graph, 10) {}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ FlowGraph::FlowGraph(const ParsedFunction& parsed_function,
|
|||
|
||||
void FlowGraph::EnsureSSATempIndex(Definition* defn, Definition* replacement) {
|
||||
if ((replacement->ssa_temp_index() == -1) && (defn->ssa_temp_index() != -1)) {
|
||||
AllocateSSAIndexes(replacement);
|
||||
AllocateSSAIndex(replacement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,10 +191,7 @@ ConstantInstr* FlowGraph::GetConstant(const Object& object,
|
|||
} else {
|
||||
constant = new (zone()) UnboxedConstantInstr(zone_object, representation);
|
||||
}
|
||||
constant->set_ssa_temp_index(alloc_ssa_temp_index());
|
||||
if (NeedsPairLocation(constant->representation())) {
|
||||
alloc_ssa_temp_index();
|
||||
}
|
||||
AllocateSSAIndex(constant);
|
||||
AddToGraphInitialDefinitions(constant);
|
||||
constant_instr_pool_.Insert(constant);
|
||||
}
|
||||
|
@ -271,7 +268,7 @@ void FlowGraph::InsertAfter(Instruction* prev,
|
|||
UseKind use_kind) {
|
||||
if (use_kind == kValue) {
|
||||
ASSERT(instr->IsDefinition());
|
||||
AllocateSSAIndexes(instr->AsDefinition());
|
||||
AllocateSSAIndex(instr->AsDefinition());
|
||||
}
|
||||
instr->InsertAfter(prev);
|
||||
ASSERT(instr->env() == NULL);
|
||||
|
@ -296,7 +293,7 @@ Instruction* FlowGraph::AppendTo(Instruction* prev,
|
|||
UseKind use_kind) {
|
||||
if (use_kind == kValue) {
|
||||
ASSERT(instr->IsDefinition());
|
||||
AllocateSSAIndexes(instr->AsDefinition());
|
||||
AllocateSSAIndex(instr->AsDefinition());
|
||||
}
|
||||
ASSERT(instr->env() == NULL);
|
||||
if (env != NULL) {
|
||||
|
@ -1215,8 +1212,7 @@ void FlowGraph::PopulateEnvironmentFromFunctionEntry(
|
|||
new (zone()) ParameterInstr(i, param_offset, function_entry, kTagged);
|
||||
param_offset++;
|
||||
}
|
||||
param->set_ssa_temp_index(alloc_ssa_temp_index());
|
||||
if (NeedsPairLocation(param->representation())) alloc_ssa_temp_index();
|
||||
AllocateSSAIndex(param);
|
||||
AddToInitialDefinitions(function_entry, param);
|
||||
(*env)[i] = param;
|
||||
}
|
||||
|
@ -1228,7 +1224,7 @@ void FlowGraph::PopulateEnvironmentFromFunctionEntry(
|
|||
if (inlining_parameters != NULL) {
|
||||
for (intptr_t i = 0; i < function().NumParameters(); ++i) {
|
||||
Definition* defn = (*inlining_parameters)[inlined_type_args_param + i];
|
||||
AllocateSSAIndexes(defn);
|
||||
AllocateSSAIndex(defn);
|
||||
AddToInitialDefinitions(function_entry, defn);
|
||||
|
||||
intptr_t index = EnvIndex(parsed_function_.RawParameterVariable(i));
|
||||
|
@ -1250,7 +1246,7 @@ void FlowGraph::PopulateEnvironmentFromFunctionEntry(
|
|||
} else {
|
||||
defn = (*inlining_parameters)[0];
|
||||
}
|
||||
AllocateSSAIndexes(defn);
|
||||
AllocateSSAIndex(defn);
|
||||
AddToInitialDefinitions(function_entry, defn);
|
||||
(*env)[RawTypeArgumentEnvIndex()] = defn;
|
||||
}
|
||||
|
@ -1260,7 +1256,7 @@ void FlowGraph::PopulateEnvironmentFromFunctionEntry(
|
|||
Definition* defn =
|
||||
new (Z) SpecialParameterInstr(SpecialParameterInstr::kArgDescriptor,
|
||||
DeoptId::kNone, function_entry);
|
||||
AllocateSSAIndexes(defn);
|
||||
AllocateSSAIndex(defn);
|
||||
AddToInitialDefinitions(function_entry, defn);
|
||||
(*env)[ArgumentDescriptorEnvIndex()] = defn;
|
||||
}
|
||||
|
@ -1279,7 +1275,7 @@ void FlowGraph::PopulateEnvironmentFromOsrEntry(
|
|||
for (intptr_t i = 0; i < parameter_count; i++) {
|
||||
ParameterInstr* param =
|
||||
new (zone()) ParameterInstr(i, i, osr_entry, kTagged);
|
||||
param->set_ssa_temp_index(alloc_ssa_temp_index());
|
||||
AllocateSSAIndex(param);
|
||||
AddToInitialDefinitions(osr_entry, param);
|
||||
(*env)[i] = param;
|
||||
}
|
||||
|
@ -1313,7 +1309,7 @@ void FlowGraph::PopulateEnvironmentFromCatchEntry(
|
|||
param = new (Z) ParameterInstr(i, i, catch_entry, kTagged);
|
||||
}
|
||||
|
||||
param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
|
||||
AllocateSSAIndex(param); // New SSA temp.
|
||||
(*env)[i] = param;
|
||||
AddToInitialDefinitions(catch_entry, param);
|
||||
}
|
||||
|
@ -1346,7 +1342,7 @@ void FlowGraph::RenameRecursive(
|
|||
PhiInstr* phi = (*join->phis())[i];
|
||||
if (phi != nullptr) {
|
||||
(*env)[i] = phi;
|
||||
AllocateSSAIndexes(phi); // New SSA temp.
|
||||
AllocateSSAIndex(phi); // New SSA temp.
|
||||
if (block_entry->InsideTryBlock() && !phi->is_alive()) {
|
||||
// This is a safe approximation. Inside try{} all locals are
|
||||
// used at every call implicitly, so we mark all phis as live
|
||||
|
@ -1549,7 +1545,7 @@ void FlowGraph::RenameRecursive(
|
|||
if (Definition* definition = current->AsDefinition()) {
|
||||
if (definition->HasTemp()) {
|
||||
// Assign fresh SSA temporary and update expression stack.
|
||||
AllocateSSAIndexes(definition);
|
||||
AllocateSSAIndex(definition);
|
||||
env->Add(definition);
|
||||
}
|
||||
}
|
||||
|
@ -2573,7 +2569,7 @@ void FlowGraph::RenameUsesDominatedByRedefinitions() {
|
|||
Value* redefined = definition->RedefinedValue();
|
||||
if (redefined != nullptr) {
|
||||
if (!definition->HasSSATemp()) {
|
||||
AllocateSSAIndexes(definition);
|
||||
AllocateSSAIndex(definition);
|
||||
}
|
||||
Definition* original = redefined->definition();
|
||||
RenameDominatedUses(original, definition, definition);
|
||||
|
@ -2821,7 +2817,7 @@ JoinEntryInstr* FlowGraph::NewDiamond(Instruction* instruction,
|
|||
|
||||
// Short-circuit second comparison and connect through phi.
|
||||
condition.oper2->InsertAfter(bt);
|
||||
AllocateSSAIndexes(condition.oper2);
|
||||
AllocateSSAIndex(condition.oper2);
|
||||
condition.oper2->InheritDeoptTarget(zone(), inherit); // must inherit
|
||||
PhiInstr* phi =
|
||||
AddPhi(mid_point, condition.oper2, GetConstant(Bool::False()));
|
||||
|
@ -2841,7 +2837,7 @@ PhiInstr* FlowGraph::AddPhi(JoinEntryInstr* join,
|
|||
Value* v1 = new (zone()) Value(d1);
|
||||
Value* v2 = new (zone()) Value(d2);
|
||||
|
||||
AllocateSSAIndexes(phi);
|
||||
AllocateSSAIndex(phi);
|
||||
|
||||
phi->mark_alive();
|
||||
phi->SetInputAt(0, v1);
|
||||
|
|
|
@ -200,11 +200,6 @@ class FlowGraph : public ZoneAllocated {
|
|||
env_index == SuspendStateEnvIndex());
|
||||
}
|
||||
|
||||
static bool NeedsPairLocation(Representation representation) {
|
||||
return representation == kUnboxedInt64 &&
|
||||
compiler::target::kIntSpillFactor == 2;
|
||||
}
|
||||
|
||||
// Flow graph orders.
|
||||
const GrowableArray<BlockEntryInstr*>& preorder() const { return preorder_; }
|
||||
const GrowableArray<BlockEntryInstr*>& postorder() const {
|
||||
|
@ -246,8 +241,8 @@ class FlowGraph : public ZoneAllocated {
|
|||
current_ssa_temp_index_ = index;
|
||||
}
|
||||
|
||||
intptr_t max_virtual_register_number() const {
|
||||
return current_ssa_temp_index();
|
||||
intptr_t max_vreg() const {
|
||||
return current_ssa_temp_index() * kMaxLocationCount;
|
||||
}
|
||||
|
||||
enum class ToCheck { kNoCheck, kCheckNull, kCheckCid };
|
||||
|
@ -272,14 +267,9 @@ class FlowGraph : public ZoneAllocated {
|
|||
|
||||
ConstantInstr* constant_dead() const { return constant_dead_; }
|
||||
|
||||
intptr_t alloc_ssa_temp_index() { return current_ssa_temp_index_++; }
|
||||
|
||||
void AllocateSSAIndexes(Definition* def) {
|
||||
ASSERT(def);
|
||||
def->set_ssa_temp_index(alloc_ssa_temp_index());
|
||||
// Always allocate a second index. This index is unused except
|
||||
// for Definitions with register pair outputs.
|
||||
alloc_ssa_temp_index();
|
||||
void AllocateSSAIndex(Definition* def) {
|
||||
def->set_ssa_temp_index(current_ssa_temp_index_);
|
||||
current_ssa_temp_index_++;
|
||||
}
|
||||
|
||||
intptr_t InstructionCount() const;
|
||||
|
|
|
@ -2321,14 +2321,14 @@ class Definition : public Instruction {
|
|||
}
|
||||
bool HasSSATemp() const { return ssa_temp_index_ >= 0; }
|
||||
void ClearSSATempIndex() { ssa_temp_index_ = -1; }
|
||||
bool HasPairRepresentation() const {
|
||||
if (compiler::target::kWordSize == 8) {
|
||||
return representation() == kPairOfTagged;
|
||||
} else {
|
||||
return (representation() == kPairOfTagged) ||
|
||||
(representation() == kUnboxedInt64);
|
||||
}
|
||||
|
||||
intptr_t vreg(intptr_t index) const {
|
||||
ASSERT((index >= 0) && (index < location_count()));
|
||||
if (ssa_temp_index_ == -1) return -1;
|
||||
return ssa_temp_index_ * kMaxLocationCount + index;
|
||||
}
|
||||
intptr_t location_count() const { return LocationCount(representation()); }
|
||||
bool HasPairRepresentation() const { return location_count() == 2; }
|
||||
|
||||
// Compile time type of the definition, which may be requested before type
|
||||
// propagation during graph building.
|
||||
|
|
|
@ -439,12 +439,7 @@ void FlowGraphPrinter::PrintCidRangeData(const CallTargets& targets,
|
|||
|
||||
static void PrintUse(BaseTextBuffer* f, const Definition& definition) {
|
||||
if (definition.HasSSATemp()) {
|
||||
if (definition.HasPairRepresentation()) {
|
||||
f->Printf("(v%" Pd ", v%" Pd ")", definition.ssa_temp_index(),
|
||||
definition.ssa_temp_index() + 1);
|
||||
} else {
|
||||
f->Printf("v%" Pd "", definition.ssa_temp_index());
|
||||
}
|
||||
f->Printf("v%" Pd "", definition.ssa_temp_index());
|
||||
} else if (definition.HasTemp()) {
|
||||
f->Printf("t%" Pd "", definition.temp_index());
|
||||
}
|
||||
|
@ -1142,12 +1137,7 @@ const char* RepresentationToCString(Representation rep) {
|
|||
}
|
||||
|
||||
void PhiInstr::PrintTo(BaseTextBuffer* f) const {
|
||||
if (HasPairRepresentation()) {
|
||||
f->Printf("(v%" Pd ", v%" Pd ") <- phi(", ssa_temp_index(),
|
||||
ssa_temp_index() + 1);
|
||||
} else {
|
||||
f->Printf("v%" Pd " <- phi(", ssa_temp_index());
|
||||
}
|
||||
f->Printf("v%" Pd " <- phi(", ssa_temp_index());
|
||||
for (intptr_t i = 0; i < inputs_.length(); ++i) {
|
||||
if (inputs_[i] != NULL) inputs_[i]->PrintTo(f);
|
||||
if (i < inputs_.length() - 1) f->AddString(", ");
|
||||
|
|
|
@ -782,10 +782,7 @@ static void ReplaceParameterStubs(Zone* zone,
|
|||
callee_signature, first_arg_index, i)) {
|
||||
RedefinitionInstr* redefinition =
|
||||
new (zone) RedefinitionInstr(actual->Copy(zone));
|
||||
redefinition->set_ssa_temp_index(caller_graph->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
|
||||
caller_graph->alloc_ssa_temp_index();
|
||||
}
|
||||
caller_graph->AllocateSSAIndex(redefinition);
|
||||
if (is_polymorphic_receiver && target_info->IsSingleCid()) {
|
||||
redefinition->UpdateType(CompileType::FromCid(target_info->cid_start));
|
||||
}
|
||||
|
@ -831,11 +828,7 @@ static void ReplaceParameterStubs(Zone* zone,
|
|||
LoadFieldInstr* context_load = new (zone) LoadFieldInstr(
|
||||
new Value((*arguments)[first_arg_index]->definition()),
|
||||
Slot::Closure_context(), call_data->call->source());
|
||||
context_load->set_ssa_temp_index(
|
||||
caller_graph->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(context_load->representation())) {
|
||||
caller_graph->alloc_ssa_temp_index();
|
||||
}
|
||||
caller_graph->AllocateSSAIndex(context_load);
|
||||
context_load->InsertBefore(callee_entry->next());
|
||||
param->ReplaceUsesWith(context_load);
|
||||
break;
|
||||
|
@ -1290,7 +1283,7 @@ class CallSiteInliner : public ValueObject {
|
|||
{
|
||||
// Compute SSA on the callee graph, catching bailouts.
|
||||
COMPILER_TIMINGS_TIMER_SCOPE(thread(), ComputeSSA);
|
||||
callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
|
||||
callee_graph->ComputeSSA(caller_graph_->current_ssa_temp_index(),
|
||||
param_stubs);
|
||||
#if defined(DEBUG)
|
||||
// The inlining IDs of instructions in the callee graph are unset
|
||||
|
@ -1977,11 +1970,7 @@ bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid,
|
|||
Definition* receiver = call_->Receiver()->definition();
|
||||
RedefinitionInstr* redefinition =
|
||||
new (Z) RedefinitionInstr(new (Z) Value(receiver));
|
||||
redefinition->set_ssa_temp_index(
|
||||
owner_->caller_graph()->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(redefinition->representation())) {
|
||||
owner_->caller_graph()->alloc_ssa_temp_index();
|
||||
}
|
||||
owner_->caller_graph()->AllocateSSAIndex(redefinition);
|
||||
if (FlowGraphInliner::TryInlineRecognizedMethod(
|
||||
owner_->caller_graph(), receiver_cid, target, call_, redefinition,
|
||||
call_->source(), call_->ic_data(), graph_entry, &entry, &last,
|
||||
|
@ -2038,7 +2027,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
|||
// at least one branch on the class id.
|
||||
LoadClassIdInstr* load_cid =
|
||||
new (Z) LoadClassIdInstr(new (Z) Value(receiver));
|
||||
load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index());
|
||||
owner_->caller_graph()->AllocateSSAIndex(load_cid);
|
||||
cursor = AppendInstruction(cursor, load_cid);
|
||||
for (intptr_t i = 0; i < inlined_variants_.length(); ++i) {
|
||||
const CidRange& variant = inlined_variants_[i];
|
||||
|
@ -2054,8 +2043,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
|||
if (!call_->complete()) {
|
||||
RedefinitionInstr* cid_redefinition =
|
||||
new RedefinitionInstr(new (Z) Value(load_cid));
|
||||
cid_redefinition->set_ssa_temp_index(
|
||||
owner_->caller_graph()->alloc_ssa_temp_index());
|
||||
owner_->caller_graph()->AllocateSSAIndex(cid_redefinition);
|
||||
cursor = AppendInstruction(cursor, cid_redefinition);
|
||||
CheckClassIdInstr* check_class_id = new (Z) CheckClassIdInstr(
|
||||
new (Z) Value(cid_redefinition), variant, call_->deopt_id());
|
||||
|
@ -2242,11 +2230,7 @@ TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
|
|||
PolymorphicInstanceCallInstr* fallback_call =
|
||||
PolymorphicInstanceCallInstr::FromCall(Z, call_, *non_inlined_variants_,
|
||||
call_->complete());
|
||||
fallback_call->set_ssa_temp_index(
|
||||
owner_->caller_graph()->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(fallback_call->representation())) {
|
||||
owner_->caller_graph()->alloc_ssa_temp_index();
|
||||
}
|
||||
owner_->caller_graph()->AllocateSSAIndex(fallback_call);
|
||||
fallback_call->InheritDeoptTarget(zone(), call_);
|
||||
fallback_call->set_total_call_count(call_->CallCount());
|
||||
ReturnInstr* fallback_return = new ReturnInstr(
|
||||
|
|
|
@ -33,19 +33,6 @@ static const intptr_t kNoVirtualRegister = -1;
|
|||
static const intptr_t kTempVirtualRegister = -2;
|
||||
static const intptr_t kIllegalPosition = -1;
|
||||
static const intptr_t kMaxPosition = 0x7FFFFFFF;
|
||||
static const intptr_t kPairVirtualRegisterOffset = 1;
|
||||
|
||||
// Definitions which have pair representations
|
||||
// (kPairOfTagged) use two virtual register names.
|
||||
// At SSA index allocation time each definition reserves two SSA indexes,
|
||||
// the second index is only used for pairs. This function maps from the first
|
||||
// SSA index to the second.
|
||||
static intptr_t ToSecondPairVreg(intptr_t vreg) {
|
||||
// Map vreg to its pair vreg.
|
||||
ASSERT((vreg == kNoVirtualRegister) || vreg >= 0);
|
||||
return (vreg == kNoVirtualRegister) ? kNoVirtualRegister
|
||||
: (vreg + kPairVirtualRegisterOffset);
|
||||
}
|
||||
|
||||
static intptr_t MinPosition(intptr_t a, intptr_t b) {
|
||||
return (a < b) ? a : b;
|
||||
|
@ -93,15 +80,15 @@ FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph,
|
|||
bool intrinsic_mode)
|
||||
: flow_graph_(flow_graph),
|
||||
reaching_defs_(flow_graph),
|
||||
value_representations_(flow_graph.max_virtual_register_number()),
|
||||
value_representations_(flow_graph.max_vreg()),
|
||||
block_order_(flow_graph.reverse_postorder()),
|
||||
postorder_(flow_graph.postorder()),
|
||||
instructions_(),
|
||||
block_entries_(),
|
||||
extra_loop_info_(),
|
||||
liveness_(flow_graph),
|
||||
vreg_count_(flow_graph.max_virtual_register_number()),
|
||||
live_ranges_(flow_graph.max_virtual_register_number()),
|
||||
vreg_count_(flow_graph.max_vreg()),
|
||||
live_ranges_(flow_graph.max_vreg()),
|
||||
unallocated_cpu_(),
|
||||
unallocated_fpu_(),
|
||||
cpu_regs_(),
|
||||
|
@ -165,7 +152,7 @@ static void DeepLiveness(MaterializeObjectInstr* mat, BitVector* live_in) {
|
|||
if (inner_mat != NULL) {
|
||||
DeepLiveness(inner_mat, live_in);
|
||||
} else {
|
||||
intptr_t idx = defn->ssa_temp_index();
|
||||
intptr_t idx = defn->vreg(0);
|
||||
live_in->Add(idx);
|
||||
}
|
||||
}
|
||||
|
@ -195,11 +182,11 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
// Handle definitions.
|
||||
Definition* current_def = current->AsDefinition();
|
||||
if ((current_def != NULL) && current_def->HasSSATemp()) {
|
||||
kill->Add(current_def->ssa_temp_index());
|
||||
live_in->Remove(current_def->ssa_temp_index());
|
||||
kill->Add(current_def->vreg(0));
|
||||
live_in->Remove(current_def->vreg(0));
|
||||
if (current_def->HasPairRepresentation()) {
|
||||
kill->Add(ToSecondPairVreg(current_def->ssa_temp_index()));
|
||||
live_in->Remove(ToSecondPairVreg(current_def->ssa_temp_index()));
|
||||
kill->Add(current_def->vreg(1));
|
||||
live_in->Remove(current_def->vreg(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,9 +198,9 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
ASSERT(!locs->in(j).IsConstant() || input->BindsToConstant());
|
||||
if (locs->in(j).IsConstant()) continue;
|
||||
|
||||
live_in->Add(input->definition()->ssa_temp_index());
|
||||
live_in->Add(input->definition()->vreg(0));
|
||||
if (input->definition()->HasPairRepresentation()) {
|
||||
live_in->Add(ToSecondPairVreg(input->definition()->ssa_temp_index()));
|
||||
live_in->Add(input->definition()->vreg(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,9 +215,9 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
// Treat its inputs as part of the environment.
|
||||
DeepLiveness(defn->AsMaterializeObject(), live_in);
|
||||
} else if (!defn->IsPushArgument() && !defn->IsConstant()) {
|
||||
live_in->Add(defn->ssa_temp_index());
|
||||
live_in->Add(defn->vreg(0));
|
||||
if (defn->HasPairRepresentation()) {
|
||||
live_in->Add(ToSecondPairVreg(defn->ssa_temp_index()));
|
||||
live_in->Add(defn->vreg(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,11 +230,11 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
for (PhiIterator it(join); !it.Done(); it.Advance()) {
|
||||
PhiInstr* phi = it.Current();
|
||||
ASSERT(phi != NULL);
|
||||
kill->Add(phi->ssa_temp_index());
|
||||
live_in->Remove(phi->ssa_temp_index());
|
||||
kill->Add(phi->vreg(0));
|
||||
live_in->Remove(phi->vreg(0));
|
||||
if (phi->HasPairRepresentation()) {
|
||||
kill->Add(ToSecondPairVreg(phi->ssa_temp_index()));
|
||||
live_in->Remove(ToSecondPairVreg(phi->ssa_temp_index()));
|
||||
kill->Add(phi->vreg(1));
|
||||
live_in->Remove(phi->vreg(1));
|
||||
}
|
||||
|
||||
// If a phi input is not defined by the corresponding predecessor it
|
||||
|
@ -257,12 +244,12 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
if (val->BindsToConstant()) continue;
|
||||
|
||||
BlockEntryInstr* pred = block->PredecessorAt(k);
|
||||
const intptr_t use = val->definition()->ssa_temp_index();
|
||||
const intptr_t use = val->definition()->vreg(0);
|
||||
if (!kill_[pred->postorder_number()]->Contains(use)) {
|
||||
live_in_[pred->postorder_number()]->Add(use);
|
||||
}
|
||||
if (phi->HasPairRepresentation()) {
|
||||
const intptr_t second_use = ToSecondPairVreg(use);
|
||||
const intptr_t second_use = val->definition()->vreg(1);
|
||||
if (!kill_[pred->postorder_number()]->Contains(second_use)) {
|
||||
live_in_[pred->postorder_number()]->Add(second_use);
|
||||
}
|
||||
|
@ -273,12 +260,12 @@ void SSALivenessAnalysis::ComputeInitialSets() {
|
|||
// Process initial definitions, i.e. parameters and special parameters.
|
||||
for (intptr_t i = 0; i < entry->initial_definitions()->length(); i++) {
|
||||
Definition* def = (*entry->initial_definitions())[i];
|
||||
const intptr_t vreg = def->ssa_temp_index();
|
||||
const intptr_t vreg = def->vreg(0);
|
||||
kill_[entry->postorder_number()]->Add(vreg);
|
||||
live_in_[entry->postorder_number()]->Remove(vreg);
|
||||
if (def->HasPairRepresentation()) {
|
||||
kill_[entry->postorder_number()]->Add(ToSecondPairVreg((vreg)));
|
||||
live_in_[entry->postorder_number()]->Remove(ToSecondPairVreg(vreg));
|
||||
kill_[entry->postorder_number()]->Add(def->vreg(1));
|
||||
live_in_[entry->postorder_number()]->Remove(def->vreg(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -598,8 +585,8 @@ void FlowGraphAllocator::BuildLiveRanges() {
|
|||
} else {
|
||||
// All values flowing into the loop header are live at the
|
||||
// back edge and can interfere with phi moves.
|
||||
current_interference_set = new (zone)
|
||||
BitVector(zone, flow_graph_.max_virtual_register_number());
|
||||
current_interference_set =
|
||||
new (zone) BitVector(zone, flow_graph_.max_vreg());
|
||||
current_interference_set->AddAll(
|
||||
liveness_.GetLiveInSet(loop_info->header()));
|
||||
extra_loop_info_[loop_info->id()]->backedge_interference =
|
||||
|
@ -643,7 +630,7 @@ void FlowGraphAllocator::BuildLiveRanges() {
|
|||
for (intptr_t i = 0; i < catch_entry->initial_definitions()->length();
|
||||
i++) {
|
||||
Definition* defn = (*catch_entry->initial_definitions())[i];
|
||||
LiveRange* range = GetLiveRange(defn->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(defn->vreg(0));
|
||||
range->DefineAt(catch_entry->start_pos()); // Defined at block entry.
|
||||
ProcessInitialDefinition(defn, range, catch_entry, i);
|
||||
}
|
||||
|
@ -654,14 +641,13 @@ void FlowGraphAllocator::BuildLiveRanges() {
|
|||
Definition* defn = initial_definitions[i];
|
||||
if (defn->HasPairRepresentation()) {
|
||||
// The lower bits are pushed after the higher bits
|
||||
LiveRange* range =
|
||||
GetLiveRange(ToSecondPairVreg(defn->ssa_temp_index()));
|
||||
LiveRange* range = GetLiveRange(defn->vreg(1));
|
||||
range->AddUseInterval(entry->start_pos(), entry->start_pos() + 2);
|
||||
range->DefineAt(entry->start_pos());
|
||||
ProcessInitialDefinition(defn, range, entry, i,
|
||||
/*second_location_for_definition=*/true);
|
||||
}
|
||||
LiveRange* range = GetLiveRange(defn->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(defn->vreg(0));
|
||||
range->AddUseInterval(entry->start_pos(), entry->start_pos() + 2);
|
||||
range->DefineAt(entry->start_pos());
|
||||
ProcessInitialDefinition(defn, range, entry, i);
|
||||
|
@ -676,13 +662,13 @@ void FlowGraphAllocator::BuildLiveRanges() {
|
|||
Definition* defn = (*graph_entry->initial_definitions())[i];
|
||||
if (defn->HasPairRepresentation()) {
|
||||
// The lower bits are pushed after the higher bits
|
||||
LiveRange* range = GetLiveRange(ToSecondPairVreg(defn->ssa_temp_index()));
|
||||
LiveRange* range = GetLiveRange(defn->vreg(1));
|
||||
range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
|
||||
range->DefineAt(graph_entry->start_pos());
|
||||
ProcessInitialDefinition(defn, range, graph_entry, i,
|
||||
/*second_location_for_definition=*/true);
|
||||
}
|
||||
LiveRange* range = GetLiveRange(defn->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(defn->vreg(0));
|
||||
range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
|
||||
range->DefineAt(graph_entry->start_pos());
|
||||
ProcessInitialDefinition(defn, range, graph_entry, i);
|
||||
|
@ -920,27 +906,25 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
|
|||
// g g'
|
||||
// value --*
|
||||
//
|
||||
intptr_t vreg = val->definition()->ssa_temp_index();
|
||||
intptr_t vreg = val->definition()->vreg(0);
|
||||
LiveRange* range = GetLiveRange(vreg);
|
||||
if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg);
|
||||
|
||||
range->AddUseInterval(block->start_pos(), pos);
|
||||
range->AddHintedUse(
|
||||
pos, move->src_slot(),
|
||||
GetLiveRange(phi->ssa_temp_index())->assigned_location_slot());
|
||||
range->AddHintedUse(pos, move->src_slot(),
|
||||
GetLiveRange(phi->vreg(0))->assigned_location_slot());
|
||||
move->set_src(Location::PrefersRegister());
|
||||
|
||||
if (val->definition()->HasPairRepresentation()) {
|
||||
move = parallel_move->MoveOperandsAt(move_index++);
|
||||
vreg = ToSecondPairVreg(vreg);
|
||||
vreg = val->definition()->vreg(1);
|
||||
range = GetLiveRange(vreg);
|
||||
if (interfere_at_backedge != NULL) {
|
||||
interfere_at_backedge->Add(vreg);
|
||||
}
|
||||
range->AddUseInterval(block->start_pos(), pos);
|
||||
range->AddHintedUse(pos, move->src_slot(),
|
||||
GetLiveRange(ToSecondPairVreg(phi->ssa_temp_index()))
|
||||
->assigned_location_slot());
|
||||
GetLiveRange(phi->vreg(1))->assigned_location_slot());
|
||||
move->set_src(Location::PrefersRegister());
|
||||
}
|
||||
}
|
||||
|
@ -962,7 +946,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
|
|||
for (PhiIterator it(join); !it.Done(); it.Advance()) {
|
||||
PhiInstr* phi = it.Current();
|
||||
ASSERT(phi != NULL);
|
||||
const intptr_t vreg = phi->ssa_temp_index();
|
||||
const intptr_t vreg = phi->vreg(0);
|
||||
ASSERT(vreg >= 0);
|
||||
const bool is_pair_phi = phi->HasPairRepresentation();
|
||||
|
||||
|
@ -976,7 +960,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
|
|||
if (is_loop_header) range->mark_loop_phi();
|
||||
|
||||
if (is_pair_phi) {
|
||||
LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
|
||||
LiveRange* second_range = GetLiveRange(phi->vreg(1));
|
||||
second_range->DefineAt(pos); // Shorten live range.
|
||||
if (is_loop_header) second_range->mark_loop_phi();
|
||||
}
|
||||
|
@ -990,7 +974,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
|
|||
move->set_dest(Location::PrefersRegister());
|
||||
range->AddUse(pos, move->dest_slot());
|
||||
if (is_pair_phi) {
|
||||
LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
|
||||
LiveRange* second_range = GetLiveRange(phi->vreg(1));
|
||||
MoveOperands* second_move =
|
||||
goto_instr->parallel_move()->MoveOperandsAt(move_idx + 1);
|
||||
second_move->set_dest(Location::PrefersRegister());
|
||||
|
@ -1003,7 +987,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
|
|||
AssignSafepoints(phi, range);
|
||||
CompleteRange(range, phi->RegisterKindForResult());
|
||||
if (is_pair_phi) {
|
||||
LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
|
||||
LiveRange* second_range = GetLiveRange(phi->vreg(1));
|
||||
AssignSafepoints(phi, second_range);
|
||||
CompleteRange(second_range, phi->RegisterKindForResult());
|
||||
}
|
||||
|
@ -1059,7 +1043,7 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block,
|
|||
// they are still used when resolving control flow.
|
||||
ASSERT(def->IsParameter() || def->IsPhi());
|
||||
ASSERT(!def->HasPairRepresentation());
|
||||
LiveRange* range = GetLiveRange(def->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(def->vreg(0));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
}
|
||||
continue;
|
||||
|
@ -1089,19 +1073,18 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block,
|
|||
PairLocation* location_pair = locations[i].AsPairLocation();
|
||||
{
|
||||
// First live range.
|
||||
LiveRange* range = GetLiveRange(def->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(def->vreg(0));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, location_pair->SlotAt(0));
|
||||
}
|
||||
{
|
||||
// Second live range.
|
||||
LiveRange* range =
|
||||
GetLiveRange(ToSecondPairVreg(def->ssa_temp_index()));
|
||||
LiveRange* range = GetLiveRange(def->vreg(1));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, location_pair->SlotAt(1));
|
||||
}
|
||||
} else {
|
||||
LiveRange* range = GetLiveRange(def->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(def->vreg(0));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, &locations[i]);
|
||||
}
|
||||
|
@ -1141,14 +1124,13 @@ void FlowGraphAllocator::ProcessMaterializationUses(
|
|||
PairLocation* location_pair = locations[i].AsPairLocation();
|
||||
{
|
||||
// First live range.
|
||||
LiveRange* range = GetLiveRange(def->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(def->vreg(0));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, location_pair->SlotAt(0));
|
||||
}
|
||||
{
|
||||
// Second live range.
|
||||
LiveRange* range =
|
||||
GetLiveRange(ToSecondPairVreg(def->ssa_temp_index()));
|
||||
LiveRange* range = GetLiveRange(def->vreg(1));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, location_pair->SlotAt(1));
|
||||
}
|
||||
|
@ -1158,7 +1140,7 @@ void FlowGraphAllocator::ProcessMaterializationUses(
|
|||
def->AsMaterializeObject());
|
||||
} else {
|
||||
locations[i] = Location::Any();
|
||||
LiveRange* range = GetLiveRange(def->ssa_temp_index());
|
||||
LiveRange* range = GetLiveRange(def->vreg(0));
|
||||
range->AddUseInterval(block_start_pos, use_pos);
|
||||
range->AddUse(use_pos, &locations[i]);
|
||||
}
|
||||
|
@ -1323,7 +1305,7 @@ void FlowGraphAllocator::ProcessOneOutput(BlockEntryInstr* block,
|
|||
|
||||
if ((interference_set != NULL) && (range->vreg() >= 0) &&
|
||||
interference_set->Contains(range->vreg())) {
|
||||
interference_set->Add(input->ssa_temp_index());
|
||||
interference_set->Add(input->vreg(0));
|
||||
}
|
||||
} else {
|
||||
// Normal unallocated location that requires a register. Expected shape of
|
||||
|
@ -1355,9 +1337,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
|
|||
Definition* def = current->AsDefinition();
|
||||
if ((def != NULL) && (def->AsConstant() != NULL)) {
|
||||
ASSERT(!def->HasPairRepresentation());
|
||||
LiveRange* range = (def->ssa_temp_index() != -1)
|
||||
? GetLiveRange(def->ssa_temp_index())
|
||||
: NULL;
|
||||
LiveRange* range = (def->vreg(0) != -1) ? GetLiveRange(def->vreg(0)) : NULL;
|
||||
|
||||
// Drop definitions of constants that have no uses.
|
||||
if ((range == NULL) || (range->first_use() == NULL)) {
|
||||
|
@ -1435,16 +1415,15 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
|
|||
if (in_ref->IsPairLocation()) {
|
||||
ASSERT(input->definition()->HasPairRepresentation());
|
||||
PairLocation* pair = in_ref->AsPairLocation();
|
||||
const intptr_t vreg = input->definition()->ssa_temp_index();
|
||||
// Each element of the pair is assigned it's own virtual register number
|
||||
// and is allocated its own LiveRange.
|
||||
ProcessOneInput(block, pos, pair->SlotAt(0), input, vreg,
|
||||
live_registers);
|
||||
ProcessOneInput(block, pos, pair->SlotAt(0), input,
|
||||
input->definition()->vreg(0), live_registers);
|
||||
ProcessOneInput(block, pos, pair->SlotAt(1), input,
|
||||
ToSecondPairVreg(vreg), live_registers);
|
||||
input->definition()->vreg(1), live_registers);
|
||||
} else {
|
||||
ProcessOneInput(block, pos, in_ref, input,
|
||||
input->definition()->ssa_temp_index(), live_registers);
|
||||
ProcessOneInput(block, pos, in_ref, input, input->definition()->vreg(0),
|
||||
live_registers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1543,7 +1522,7 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
|
|||
}
|
||||
|
||||
if (locs->out(0).IsInvalid()) {
|
||||
ASSERT(def->ssa_temp_index() < 0);
|
||||
ASSERT(def->vreg(0) < 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1559,42 +1538,40 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
|
|||
ASSERT(input->HasPairRepresentation());
|
||||
// Each element of the pair is assigned it's own virtual register number
|
||||
// and is allocated its own LiveRange.
|
||||
ProcessOneOutput(block, pos, // BlockEntry, seq.
|
||||
pair->SlotAt(0), def, // (output) Location, Definition.
|
||||
def->ssa_temp_index(), // (output) virtual register.
|
||||
true, // output mapped to first input.
|
||||
ProcessOneOutput(block, pos, // BlockEntry, seq.
|
||||
pair->SlotAt(0), def, // (output) Location, Definition.
|
||||
def->vreg(0), // (output) virtual register.
|
||||
true, // output mapped to first input.
|
||||
in_pair->SlotAt(0), input, // (input) Location, Def.
|
||||
input->ssa_temp_index(), // (input) virtual register.
|
||||
input->vreg(0), // (input) virtual register.
|
||||
interference_set);
|
||||
ProcessOneOutput(block, pos, pair->SlotAt(1), def, def->vreg(1), true,
|
||||
in_pair->SlotAt(1), input, input->vreg(1),
|
||||
interference_set);
|
||||
ProcessOneOutput(
|
||||
block, pos, pair->SlotAt(1), def,
|
||||
ToSecondPairVreg(def->ssa_temp_index()), true, in_pair->SlotAt(1),
|
||||
input, ToSecondPairVreg(input->ssa_temp_index()), interference_set);
|
||||
} else {
|
||||
// Each element of the pair is assigned it's own virtual register number
|
||||
// and is allocated its own LiveRange.
|
||||
ProcessOneOutput(block, pos, pair->SlotAt(0), def, def->ssa_temp_index(),
|
||||
ProcessOneOutput(block, pos, pair->SlotAt(0), def, def->vreg(0),
|
||||
false, // output is not mapped to first input.
|
||||
NULL, NULL, -1, // First input not needed.
|
||||
interference_set);
|
||||
ProcessOneOutput(block, pos, pair->SlotAt(1), def,
|
||||
ToSecondPairVreg(def->ssa_temp_index()), false, NULL,
|
||||
NULL, -1, interference_set);
|
||||
ProcessOneOutput(block, pos, pair->SlotAt(1), def, def->vreg(1), false,
|
||||
NULL, NULL, -1, interference_set);
|
||||
}
|
||||
} else {
|
||||
if (output_same_as_first_input) {
|
||||
Location* in_ref = locs->in_slot(0);
|
||||
Definition* input = current->InputAt(0)->definition();
|
||||
ASSERT(!in_ref->IsPairLocation());
|
||||
ProcessOneOutput(block, pos, // BlockEntry, Instruction, seq.
|
||||
out, def, // (output) Location, Definition.
|
||||
def->ssa_temp_index(), // (output) virtual register.
|
||||
true, // output mapped to first input.
|
||||
in_ref, input, // (input) Location, Def.
|
||||
input->ssa_temp_index(), // (input) virtual register.
|
||||
ProcessOneOutput(block, pos, // BlockEntry, Instruction, seq.
|
||||
out, def, // (output) Location, Definition.
|
||||
def->vreg(0), // (output) virtual register.
|
||||
true, // output mapped to first input.
|
||||
in_ref, input, // (input) Location, Def.
|
||||
input->vreg(0), // (input) virtual register.
|
||||
interference_set);
|
||||
} else {
|
||||
ProcessOneOutput(block, pos, out, def, def->ssa_temp_index(),
|
||||
ProcessOneOutput(block, pos, out, def, def->vreg(0),
|
||||
false, // output is not mapped to first input.
|
||||
NULL, NULL, -1, // First input not needed.
|
||||
interference_set);
|
||||
|
@ -2202,8 +2179,7 @@ intptr_t FlowGraphAllocator::FirstIntersectionWithAllocated(
|
|||
void ReachingDefs::AddPhi(PhiInstr* phi) {
|
||||
if (phi->reaching_defs() == NULL) {
|
||||
Zone* zone = flow_graph_.zone();
|
||||
phi->set_reaching_defs(
|
||||
new (zone) BitVector(zone, flow_graph_.max_virtual_register_number()));
|
||||
phi->set_reaching_defs(new (zone) BitVector(zone, flow_graph_.max_vreg()));
|
||||
|
||||
// Compute initial set reaching defs set.
|
||||
bool depends_on_phi = false;
|
||||
|
@ -2212,9 +2188,9 @@ void ReachingDefs::AddPhi(PhiInstr* phi) {
|
|||
if (input->IsPhi()) {
|
||||
depends_on_phi = true;
|
||||
}
|
||||
phi->reaching_defs()->Add(input->ssa_temp_index());
|
||||
phi->reaching_defs()->Add(input->vreg(0));
|
||||
if (phi->HasPairRepresentation()) {
|
||||
phi->reaching_defs()->Add(ToSecondPairVreg(input->ssa_temp_index()));
|
||||
phi->reaching_defs()->Add(input->vreg(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2329,7 +2305,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
|
|||
it.Advance()) {
|
||||
PhiInstr* phi = it.Current();
|
||||
ASSERT(phi->is_alive());
|
||||
const intptr_t phi_vreg = phi->ssa_temp_index();
|
||||
const intptr_t phi_vreg = phi->vreg(0);
|
||||
LiveRange* range = GetLiveRange(phi_vreg);
|
||||
if (range->assigned_location().kind() == register_kind_) {
|
||||
const intptr_t reg = range->assigned_location().register_code();
|
||||
|
@ -2338,7 +2314,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
|
|||
}
|
||||
}
|
||||
if (phi->HasPairRepresentation()) {
|
||||
const intptr_t second_phi_vreg = ToSecondPairVreg(phi_vreg);
|
||||
const intptr_t second_phi_vreg = phi->vreg(1);
|
||||
LiveRange* second_range = GetLiveRange(second_phi_vreg);
|
||||
if (second_range->assigned_location().kind() == register_kind_) {
|
||||
const intptr_t reg =
|
||||
|
@ -3091,10 +3067,10 @@ void FlowGraphAllocator::CollectRepresentations() {
|
|||
auto initial_definitions = graph_entry->initial_definitions();
|
||||
for (intptr_t i = 0; i < initial_definitions->length(); ++i) {
|
||||
Definition* def = (*initial_definitions)[i];
|
||||
value_representations_[def->ssa_temp_index()] =
|
||||
value_representations_[def->vreg(0)] =
|
||||
RepresentationForRange(def->representation());
|
||||
if (def->HasPairRepresentation()) {
|
||||
value_representations_[ToSecondPairVreg(def->ssa_temp_index())] =
|
||||
value_representations_[def->vreg(1)] =
|
||||
RepresentationForRange(def->representation());
|
||||
}
|
||||
}
|
||||
|
@ -3107,21 +3083,21 @@ void FlowGraphAllocator::CollectRepresentations() {
|
|||
initial_definitions = entry->initial_definitions();
|
||||
for (intptr_t i = 0; i < initial_definitions->length(); ++i) {
|
||||
Definition* def = (*initial_definitions)[i];
|
||||
value_representations_[def->ssa_temp_index()] =
|
||||
value_representations_[def->vreg(0)] =
|
||||
RepresentationForRange(def->representation());
|
||||
if (def->HasPairRepresentation()) {
|
||||
value_representations_[ToSecondPairVreg(def->ssa_temp_index())] =
|
||||
value_representations_[def->vreg(1)] =
|
||||
RepresentationForRange(def->representation());
|
||||
}
|
||||
}
|
||||
} else if (auto join = block->AsJoinEntry()) {
|
||||
for (PhiIterator it(join); !it.Done(); it.Advance()) {
|
||||
PhiInstr* phi = it.Current();
|
||||
ASSERT(phi != NULL && phi->ssa_temp_index() >= 0);
|
||||
value_representations_[phi->ssa_temp_index()] =
|
||||
ASSERT(phi != NULL && phi->vreg(0) >= 0);
|
||||
value_representations_[phi->vreg(0)] =
|
||||
RepresentationForRange(phi->representation());
|
||||
if (phi->HasPairRepresentation()) {
|
||||
value_representations_[ToSecondPairVreg(phi->ssa_temp_index())] =
|
||||
value_representations_[phi->vreg(1)] =
|
||||
RepresentationForRange(phi->representation());
|
||||
}
|
||||
}
|
||||
|
@ -3131,12 +3107,12 @@ void FlowGraphAllocator::CollectRepresentations() {
|
|||
for (ForwardInstructionIterator instr_it(block); !instr_it.Done();
|
||||
instr_it.Advance()) {
|
||||
Definition* def = instr_it.Current()->AsDefinition();
|
||||
if ((def != NULL) && (def->ssa_temp_index() >= 0)) {
|
||||
const intptr_t vreg = def->ssa_temp_index();
|
||||
if ((def != NULL) && (def->vreg(0) >= 0)) {
|
||||
const intptr_t vreg = def->vreg(0);
|
||||
value_representations_[vreg] =
|
||||
RepresentationForRange(def->representation());
|
||||
if (def->HasPairRepresentation()) {
|
||||
value_representations_[ToSecondPairVreg(vreg)] =
|
||||
value_representations_[def->vreg(1)] =
|
||||
RepresentationForRange(def->representation());
|
||||
}
|
||||
}
|
||||
|
@ -3290,10 +3266,10 @@ void FlowGraphAllocator::RemoveFrameIfNotNeeded() {
|
|||
if (FunctionEntryInstr* entry = block->AsFunctionEntry()) {
|
||||
for (auto defn : *entry->initial_definitions()) {
|
||||
if (auto param = defn->AsParameter()) {
|
||||
const auto vreg = param->ssa_temp_index();
|
||||
const auto vreg = param->vreg(0);
|
||||
fix_location_for(block, param, vreg, 0);
|
||||
if (param->HasPairRepresentation()) {
|
||||
fix_location_for(block, param, ToSecondPairVreg(vreg),
|
||||
fix_location_for(block, param, param->vreg(1),
|
||||
/*pair_index=*/1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@ class ReachingDefs : public ValueObject {
|
|||
class SSALivenessAnalysis : public LivenessAnalysis {
|
||||
public:
|
||||
explicit SSALivenessAnalysis(const FlowGraph& flow_graph)
|
||||
: LivenessAnalysis(flow_graph.max_virtual_register_number(),
|
||||
flow_graph.postorder()),
|
||||
: LivenessAnalysis(flow_graph.max_vreg(), flow_graph.postorder()),
|
||||
graph_entry_(flow_graph.graph_entry()) {}
|
||||
|
||||
private:
|
||||
|
|
|
@ -66,6 +66,19 @@ enum Representation {
|
|||
kNumRepresentations
|
||||
};
|
||||
|
||||
static const intptr_t kMaxLocationCount = 2;
|
||||
|
||||
inline intptr_t LocationCount(Representation rep) {
|
||||
switch (rep) {
|
||||
case kPairOfTagged:
|
||||
return 2;
|
||||
case kUnboxedInt64:
|
||||
return compiler::target::kWordSize == 8 ? 1 : 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct RepresentationUtils : AllStatic {
|
||||
// Whether the representation is for a type of unboxed integer.
|
||||
static bool IsUnboxedInteger(Representation rep);
|
||||
|
|
|
@ -2611,7 +2611,7 @@ class LoadOptimizer : public ValueObject {
|
|||
replacement->AddInputUse(input);
|
||||
}
|
||||
|
||||
graph_->AllocateSSAIndexes(phi);
|
||||
graph_->AllocateSSAIndex(phi);
|
||||
phis_.Add(phi); // Postpone phi insertion until after load forwarding.
|
||||
|
||||
if (FLAG_support_il_printer && FLAG_trace_load_optimization) {
|
||||
|
@ -4259,10 +4259,7 @@ void TryCatchAnalyzer::Optimize() {
|
|||
ConstantInstr* orig = cdefs[j]->AsConstant();
|
||||
ConstantInstr* copy =
|
||||
new (flow_graph_->zone()) ConstantInstr(orig->value());
|
||||
copy->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
|
||||
if (FlowGraph::NeedsPairLocation(copy->representation())) {
|
||||
flow_graph_->alloc_ssa_temp_index();
|
||||
}
|
||||
flow_graph_->AllocateSSAIndex(copy);
|
||||
old->ReplaceUsesWith(copy);
|
||||
copy->set_previous(old->previous()); // partial link
|
||||
(*idefs)[j] = copy;
|
||||
|
|
|
@ -286,7 +286,7 @@ void FlowGraphTypePropagator::VisitCheckNull(CheckNullInstr* check) {
|
|||
// motion of the check may still enable valid code motion
|
||||
// of the checked code.
|
||||
if (check->ssa_temp_index() == -1) {
|
||||
flow_graph_->AllocateSSAIndexes(check);
|
||||
flow_graph_->AllocateSSAIndex(check);
|
||||
GrowTypes(check->ssa_temp_index() + 1);
|
||||
}
|
||||
FlowGraph::RenameDominatedUses(receiver, check, check);
|
||||
|
@ -370,7 +370,7 @@ void FlowGraphTypePropagator::VisitAssertAssignable(
|
|||
auto defn = check->value()->definition();
|
||||
SetTypeOf(defn, new (zone()) CompileType(check->ComputeType()));
|
||||
if (check->ssa_temp_index() == -1) {
|
||||
flow_graph_->AllocateSSAIndexes(check);
|
||||
flow_graph_->AllocateSSAIndex(check);
|
||||
GrowTypes(check->ssa_temp_index() + 1);
|
||||
}
|
||||
FlowGraph::RenameDominatedUses(defn, check, check);
|
||||
|
|
|
@ -41,13 +41,13 @@ void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
|
|||
COMPILER_TIMINGS_TIMER_SCOPE(callee_graph->thread(), PrepareGraphs);
|
||||
ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
|
||||
ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
|
||||
ASSERT(callee_graph->max_virtual_register_number() >
|
||||
caller_graph_->max_virtual_register_number());
|
||||
ASSERT(callee_graph->current_ssa_temp_index() >
|
||||
caller_graph_->current_ssa_temp_index());
|
||||
|
||||
// Adjust the caller's maximum block id and current SSA temp index.
|
||||
caller_graph_->set_max_block_id(callee_graph->max_block_id());
|
||||
caller_graph_->set_current_ssa_temp_index(
|
||||
callee_graph->max_virtual_register_number());
|
||||
callee_graph->current_ssa_temp_index());
|
||||
|
||||
// Attach the outer environment on each instruction in the callee graph.
|
||||
ASSERT(call_->env() != NULL);
|
||||
|
@ -218,7 +218,7 @@ Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block,
|
|||
if (call_->HasUses()) {
|
||||
// Add a phi of the return values.
|
||||
PhiInstr* phi = new (Z) PhiInstr(join, num_exits);
|
||||
caller_graph_->AllocateSSAIndexes(phi);
|
||||
caller_graph_->AllocateSSAIndex(phi);
|
||||
phi->mark_alive();
|
||||
for (intptr_t i = 0; i < num_exits; ++i) {
|
||||
ReturnAt(i)->RemoveEnvironment();
|
||||
|
|
Loading…
Reference in a new issue