Skip to content

Commit

Permalink
hir: better input def after phi handling
Browse files Browse the repository at this point in the history
* lir: handling value to multiple inputs case
  • Loading branch information
indutny committed Apr 12, 2012
1 parent 6082cba commit 3c859d8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/hir.cc
Expand Up @@ -142,8 +142,6 @@ void HIRBasicBlock::LiftValues(HIRBasicBlock* block,
} }
} }


// If loop detected and there're phis those inputs are defined in this block
// (i.e. in loop header) - use them as values
if (instructions()->length() != 0) { if (instructions()->length() != 0) {
// Add non-local variable uses to the end of loop // Add non-local variable uses to the end of loop
// to ensure that they will be live after the first loop's pass // to ensure that they will be live after the first loop's pass
Expand All @@ -160,6 +158,8 @@ void HIRBasicBlock::LiftValues(HIRBasicBlock* block,
} }
} }


// If loop detected and there're phis those inputs are defined in this block
// (i.e. in loop header) - use them as values
HIRPhiList::Item* item = phis()->head(); HIRPhiList::Item* item = phis()->head();
for (; item != NULL; item = item->next()) { for (; item != NULL; item = item->next()) {
HIRPhi* phi = item->value(); HIRPhi* phi = item->value();
Expand Down Expand Up @@ -377,6 +377,7 @@ void HIRPhi::AddInput(HIRValue* input) {
// Replace all input's uses if Phi appeared in loop // Replace all input's uses if Phi appeared in loop
HIRValueList::Item* item = inputs()->head(); HIRValueList::Item* item = inputs()->head();
for (; item != NULL; item = item->next()) { for (; item != NULL; item = item->next()) {
if (item->value()->block() == block()) continue;
block()->ReplaceVarUse(item->value(), this); block()->ReplaceVarUse(item->value(), this);
} }


Expand Down
19 changes: 18 additions & 1 deletion src/lir.cc
Expand Up @@ -394,13 +394,30 @@ void LIR::GenerateInstruction(Masm* masm, HIRInstruction* hinstr) {
HIRValue* value = item->value(); HIRValue* value = item->value();


// Allocate immediate values // Allocate immediate values
if (value->slot()->is_immediate()) { if (value->slot()->is_immediate() && value->operand() == NULL) {
value->operand(new LIROperand(LIROperand::kImmediate, value->operand(new LIROperand(LIROperand::kImmediate,
value->slot()->value())); value->slot()->value()));
} }


if (i < linstr->input_count()) { if (i < linstr->input_count()) {
if (linstr->inputs[i] != NULL) { if (linstr->inputs[i] != NULL) {
// there may be a situation where the same value is used in multiple
// inputs with predefined registers - just insert movement in non-first
// inputs then.
if (value->operand() != NULL) {
int j;
for (j = 0; j < i; j++) {
if (linstr->inputs[j] != NULL &&
linstr->inputs[j]->is_equal(value->operand())) {
HIRParallelMove::GetBefore(hinstr)->
AddMove(linstr->inputs[j], linstr->inputs[i]);
HIRParallelMove::GetBefore(hinstr)->Reorder(this);
break;
}
}
if (j != i) continue;
}

// Instruction requires it's input to reside in some specific register // Instruction requires it's input to reside in some specific register
GetRegister(hinstr, value, linstr->inputs[i]); GetRegister(hinstr, value, linstr->inputs[i]);
} else if (value->operand() != NULL && value->operand()->is_immediate()) { } else if (value->operand() != NULL && value->operand()->is_immediate()) {
Expand Down
9 changes: 5 additions & 4 deletions src/x64/lir-instructions-x64.cc
Expand Up @@ -142,12 +142,13 @@ void LIRStoreContext::Generate() {
LIRStoreProperty::LIRStoreProperty() { LIRStoreProperty::LIRStoreProperty() {
inputs[0] = ToLIROperand(rax); inputs[0] = ToLIROperand(rax);
inputs[1] = ToLIROperand(rbx); inputs[1] = ToLIROperand(rbx);
inputs[2] = ToLIROperand(rcx);
} }




void LIRStoreProperty::Generate() { void LIRStoreProperty::Generate() {
__ Push(inputs[2]); __ push(rcx);
__ Push(inputs[0]); __ push(rax);


// rax <- object // rax <- object
// rbx <- property // rbx <- property
Expand All @@ -164,8 +165,8 @@ void LIRStoreProperty::Generate() {
// Result may be rax // Result may be rax
__ Mov(scratches[0], rax); __ Mov(scratches[0], rax);


__ pop(rbx); __ Pop(rbx);
__ Pop(inputs[2]); __ Pop(rcx);


__ IsNil(ToRegister(scratches[0]), NULL, &done); __ IsNil(ToRegister(scratches[0]), NULL, &done);
Operand qmap(rbx, HObject::kMapOffset); Operand qmap(rbx, HObject::kMapOffset);
Expand Down

0 comments on commit 3c859d8

Please sign in to comment.