Author: whessev8
Date: Mon Dec 15 05:21:45 2008
New Revision: 979
Modified:
branches/experimental/toiger/src/codegen-ia32.cc
branches/experimental/toiger/src/virtual-frame-ia32.cc
branches/experimental/toiger/src/virtual-frame-ia32.h
Log:
Allow non-spilled frames into VisitCompareOperation, and allow them
to be passed from there to SmiComparison and SmiComparisonDeferred.
Profit from constants and registers in SmiComparison.
Review URL: http://codereview.chromium.org/13665
Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc Mon Dec 15 05:21:45
2008
@@ -403,6 +403,7 @@
if (has_cc()) {
ASSERT(frame_ != NULL);
+ frame_->SpillAll();
// Convert cc_reg_ into a boolean value.
JumpTarget loaded(this);
JumpTarget materialize_true(this);
@@ -426,6 +427,7 @@
// Load "true" if necessary.
if (true_target.is_linked()) {
true_target.Bind();
+ frame_->SpillAll();
frame_->EmitPush(Immediate(Factory::true_value()));
}
// If both "true" and "false" need to be reincarnated jump across the
@@ -436,6 +438,7 @@
// Load "false" if necessary.
if (false_target.is_linked()) {
false_target.Bind();
+ frame_->SpillAll();
frame_->EmitPush(Immediate(Factory::false_value()));
}
// A value is loaded on all paths reaching this point.
@@ -1185,8 +1188,13 @@
SmiComparisonDeferred(CodeGenerator* generator,
Condition cc,
bool strict,
- int value)
- : DeferredCode(generator), cc_(cc), strict_(strict), value_(value) {
+ Register left_side,
+ int right_side) :
+ DeferredCode(generator),
+ cc_(cc),
+ strict_(strict),
+ left_side_(left_side),
+ right_side_(right_side) {
set_comment("[ ComparisonDeferred");
}
virtual void Generate();
@@ -1194,18 +1202,21 @@
private:
Condition cc_;
bool strict_;
- int value_;
+ Register left_side_;
+ int right_side_;
};
void SmiComparisonDeferred::Generate() {
CompareStub stub(cc_, strict_);
// Setup parameters and call stub.
- __ mov(edx, Operand(eax));
- __ Set(eax, Immediate(Smi::FromInt(value_)));
+ if (!left_side_.is(edx)) {
+ __ mov(edx, Operand(left_side_));
+ }
+ __ Set(eax, Immediate(Smi::FromInt(right_side_)));
__ CallStub(&stub);
__ cmp(eax, 0);
- // "result" is returned in the flags
+ // "result" is returned in the flags.
}
@@ -1218,13 +1229,16 @@
int int_value = Smi::cast(*value)->value();
ASSERT(is_intn(int_value, kMaxSmiInlinedBits));
+ Result comparee = frame_->Pop();
+ comparee.ToRegister();
+ Register reg = comparee.reg();
+ __ test(reg, Immediate(kSmiTagMask));
SmiComparisonDeferred* deferred =
- new SmiComparisonDeferred(this, cc, strict, int_value);
- frame_->EmitPop(eax);
- __ test(eax, Immediate(kSmiTagMask));
+ new SmiComparisonDeferred(this, cc, strict, reg, int_value);
deferred->enter()->Branch(not_zero, not_taken);
- // Test smi equality by pointer comparison.
- __ cmp(Operand(eax), Immediate(value));
+ // Test smi equality and comparison by signed int comparison.
+ __ cmp(Operand(reg), Immediate(value));
+ comparee.Unuse();
deferred->exit()->Bind();
cc_reg_ = cc;
}
@@ -3986,6 +4000,7 @@
right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
// The 'null' value can only be equal to 'null' or 'undefined'.
if (left_is_null || right_is_null) {
+ frame_->SpillAll();
Load(left_is_null ? right : left);
frame_->SpillAll();
frame_->EmitPop(eax);
@@ -4024,6 +4039,7 @@
right->AsLiteral()->handle()->IsString())) {
Handle<String> check(String::cast(*right->AsLiteral()->handle()));
+ frame_->SpillAll();
// Load the operand and move it to register edx.
LoadTypeofExpression(operation->expression());
frame_->SpillAll();
@@ -4133,6 +4149,7 @@
cc = greater_equal;
break;
case Token::IN: {
+ frame_->SpillAll();
Load(left);
frame_->SpillAll();
Load(right);
@@ -4142,6 +4159,7 @@
return;
}
case Token::INSTANCEOF: {
+ frame_->SpillAll();
Load(left);
frame_->SpillAll();
Load(right);
@@ -4159,6 +4177,7 @@
// Optimize for the case where (at least) one of the expressions
// is a literal small integer.
if (IsInlineSmi(left->AsLiteral())) {
+ frame_->SpillAll();
Load(right);
frame_->SpillAll();
SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(),
strict);
@@ -4166,11 +4185,11 @@
}
if (IsInlineSmi(right->AsLiteral())) {
Load(left);
- frame_->SpillAll();
SmiComparison(cc, right->AsLiteral()->handle(), strict);
return;
}
+ frame_->SpillAll();
Load(left);
frame_->SpillAll();
Load(right);
Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc Mon Dec 15
05:21:45 2008
@@ -50,9 +50,23 @@
void Result::Unuse() {
- ASSERT(!reg().is(no_reg));
- cgen_->allocator()->Unuse(reg());
- data_.reg_ = no_reg;
+ if (is_register()) {
+ cgen_->allocator()->Unuse(reg());
+ }
+ type_ = INVALID;
+}
+
+
+void Result::ToRegister() {
+ ASSERT(is_valid());
+ if (is_constant()) {
+ Register reg = cgen_->allocator()->Allocate();
+ ASSERT(!reg.is(no_reg));
+ cgen_->masm()->Set(reg, Immediate(handle()));
+ data_.reg_ = reg;
+ type_ = REGISTER;
+ }
+ ASSERT(is_register());
}
@@ -514,34 +528,40 @@
for (int i = start; i <= end; i++) {
FrameElement source = elements_[i];
FrameElement target = expected->elements_[i];
- if (source.is_register() && target.is_register() &&
- !target.reg().is(source.reg())) {
- // We need to move source to target.
- if (frame_registers_.is_used(target.reg().code())) {
- // The move is blocked because the target contains valid data.
- // If we are stuck with only cycles remaining, then we spill
source.
- // Otherwise, we just need more iterations.
- if (should_break_cycles) {
- SpillElementAt(i);
- should_break_cycles = false;
- } else { // Record a blocked move.
- if (!any_moves_blocked) {
- first_move_blocked = i;
- }
- last_move_blocked = i;
- any_moves_blocked = true;
- }
- } else {
- // The move is not blocked. This frame element can be moved from
- // its source register to its target register.
- Use(target.reg());
- Unuse(source.reg());
+ if (source.is_register() && target.is_register()) {
+ if (target.reg().is(source.reg())) {
if (target.is_synced() && !source.is_synced()) {
SyncElementAt(i);
}
elements_[i] = target;
- __ mov(target.reg(), source.reg());
- any_moves_made = true;
+ } else {
+ // We need to move source to target.
+ if (frame_registers_.is_used(target.reg().code())) {
+ // The move is blocked because the target contains valid data.
+ // If we are stuck with only cycles remaining, then we spill
source.
+ // Otherwise, we just need more iterations.
+ if (should_break_cycles) {
+ SpillElementAt(i);
+ should_break_cycles = false;
+ } else { // Record a blocked move.
+ if (!any_moves_blocked) {
+ first_move_blocked = i;
+ }
+ last_move_blocked = i;
+ any_moves_blocked = true;
+ }
+ } else {
+ // The move is not blocked. This frame element can be moved
from
+ // its source register to its target register.
+ if (target.is_synced() && !source.is_synced()) {
+ SyncElementAt(i);
+ }
+ Use(target.reg());
+ Unuse(source.reg());
+ elements_[i] = target;
+ __ mov(target.reg(), source.reg());
+ any_moves_made = true;
+ }
}
}
}
Modified: branches/experimental/toiger/src/virtual-frame-ia32.h
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.h (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.h Mon Dec 15
05:21:45 2008
@@ -40,7 +40,7 @@
class Result BASE_EMBEDDED {
public:
// Construct a register Result.
- explicit Result(Register reg, CodeGenerator* cgen);
+ Result(Register reg, CodeGenerator* cgen);
// Construct a Result whose value is a compile-time constant.
Result(Handle<Object> value, CodeGenerator * cgen) :
@@ -50,14 +50,16 @@
}
~Result() {
- // We have called Unuse() before Result goes out of scope.
- ASSERT(!is_register() || reg().is(no_reg));
+ if (is_register()) {
+ Unuse();
+ }
}
void Unuse();
bool is_register() const { return type() == REGISTER; }
bool is_constant() const { return type() == CONSTANT; }
+ bool is_valid() const { return type() != INVALID; }
Register reg() const {
ASSERT(type() == REGISTER);
@@ -69,8 +71,16 @@
return Handle<Object>(data_.handle_);
}
+ // Change a result to a register result. If the result is not already
+ // in a register, allocate a register from the code generator, and emit
+ // code to move the value into that register.
+ void ToRegister();
private:
- enum Type { REGISTER, CONSTANT };
+ enum Type {
+ REGISTER,
+ CONSTANT,
+ INVALID
+ };
Type type_;
@@ -83,9 +93,6 @@
CodeGenerator* cgen_;
};
-
-
-// A result in a register just means that the value can be read from the
register
//
-------------------------------------------------------------------------
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---