Fixed numeric relations on HPhi instances.

Review URL: https://codereview.chromium.org/12301027

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13703 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mmassi@chromium.org 2013-02-21 10:22:31 +00:00
parent af5eed104c
commit 8ef28eb5ee
6 changed files with 125 additions and 9 deletions

View File

@ -1690,6 +1690,12 @@ LInstruction* LChunkBuilder::DoNumericConstraint(HNumericConstraint* instr) {
}
LInstruction* LChunkBuilder::DoInductionVariableAnnotation(
HInductionVariableAnnotation* instr) {
return NULL;
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = UseRegister(instr->length());

View File

@ -843,6 +843,27 @@ void HNumericConstraint::PrintDataTo(StringStream* stream) {
}
HInductionVariableAnnotation* HInductionVariableAnnotation::AddToGraph(
HPhi* phi,
NumericRelation relation,
int operand_index) {
HInductionVariableAnnotation* result =
new(phi->block()->zone()) HInductionVariableAnnotation(phi, relation,
operand_index);
result->InsertAfter(phi->block()->first());
return result;
}
void HInductionVariableAnnotation::PrintDataTo(StringStream* stream) {
stream->Add("(");
RedefinedOperand()->PrintNameTo(stream);
stream->Add(" %s ", relation().Mnemonic());
induction_base()->PrintNameTo(stream);
stream->Add(")");
}
void HDummyUse::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
}
@ -1554,15 +1575,14 @@ Range* HMod::InferRange(Zone* zone) {
void HPhi::AddInformativeDefinitions() {
if (OperandCount() == 2) {
// If one of the operands is an OSR block give up (this cannot be an
// induction variable).
if (OperandAt(0)->block()->is_osr_entry() ||
OperandAt(1)->block()->is_osr_entry()) return;
for (int operand_index = 0; operand_index < 2; operand_index++) {
int other_operand_index = (operand_index + 1) % 2;
// Add an idef that "discards" the OSR entry block branch.
if (OperandAt(operand_index)->block()->is_osr_entry()) {
HNumericConstraint::AddToGraph(
this, NumericRelation::Eq(), OperandAt(other_operand_index));
}
static NumericRelation relations[] = {
NumericRelation::Ge(),
NumericRelation::Le()
@ -1574,9 +1594,9 @@ void HPhi::AddInformativeDefinitions() {
for (int relation_index = 0; relation_index < 2; relation_index++) {
if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index],
this)) {
HNumericConstraint::AddToGraph(this,
relations[relation_index],
OperandAt(other_operand_index));
HInductionVariableAnnotation::AddToGraph(this,
relations[relation_index],
other_operand_index);
}
}
}
@ -1584,6 +1604,26 @@ void HPhi::AddInformativeDefinitions() {
}
bool HPhi::IsRelationTrueInternal(NumericRelation relation, HValue* other) {
if (CheckFlag(kNumericConstraintEvaluationInProgress)) return false;
SetFlag(kNumericConstraintEvaluationInProgress);
bool result = true;
for (int i = 0; i < OperandCount(); i++) {
// Skip OSR entry blocks
if (OperandAt(i)->block()->is_osr_entry()) continue;
if (!OperandAt(i)->IsRelationTrue(relation, other)) {
result = false;
break;
}
}
ClearFlag(kNumericConstraintEvaluationInProgress);
return result;
}
Range* HMathMinMax::InferRange(Zone* zone) {
if (representation().IsInteger32()) {
Range* a = left()->range();

View File

@ -119,6 +119,7 @@ class LChunkBuilder;
V(Goto) \
V(HasCachedArrayIndexAndBranch) \
V(HasInstanceTypeAndBranch) \
V(InductionVariableAnnotation) \
V(In) \
V(InstanceOf) \
V(InstanceOfKnownGlobal) \
@ -704,6 +705,9 @@ class HValue: public ZoneObject {
// HGraph::ComputeSafeUint32Operations is responsible for setting this
// flag.
kUint32,
// If a phi is involved in the evaluation of a numeric constraint the
// recursion can cause an endless cycle: we use this flag to exit the loop.
kNumericConstraintEvaluationInProgress,
// This flag is set to true after the SetupInformativeDefinitions() pass
// has processed this instruction.
kIDefsProcessingDone,
@ -2955,6 +2959,8 @@ class HPhi: public HValue {
inputs_[index] = value;
}
virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other);
private:
ZoneList<HValue*> inputs_;
int merged_index_;
@ -2967,6 +2973,52 @@ class HPhi: public HValue {
};
class HInductionVariableAnnotation : public HUnaryOperation {
public:
static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
NumericRelation relation,
int operand_index);
NumericRelation relation() { return relation_; }
HValue* induction_base() { return phi_->OperandAt(operand_index_); }
virtual int RedefinedOperandIndex() { return 0; }
virtual bool IsPurelyInformativeDefinition() { return true; }
virtual Representation RequiredInputRepresentation(int index) {
return representation();
}
virtual void PrintDataTo(StringStream* stream);
virtual bool IsRelationTrueInternal(NumericRelation other_relation,
HValue* other_related_value) {
if (induction_base() == other_related_value) {
return relation().Implies(other_relation);
} else {
return false;
}
}
DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
private:
HInductionVariableAnnotation(HPhi* phi,
NumericRelation relation,
int operand_index)
: HUnaryOperation(phi),
phi_(phi), relation_(relation), operand_index_(operand_index) {
set_representation(phi->representation());
}
// We need to store the phi both here and in the instruction operand because
// the operand can change if a new idef of the phi is added between the phi
// and this instruction (inserting an idef updates every use).
HPhi* phi_;
NumericRelation relation_;
int operand_index_;
};
class HArgumentsObject: public HTemplateInstruction<0> {
public:
HArgumentsObject() {

View File

@ -1717,6 +1717,12 @@ LInstruction* LChunkBuilder::DoNumericConstraint(HNumericConstraint* instr) {
}
LInstruction* LChunkBuilder::DoInductionVariableAnnotation(
HInductionVariableAnnotation* instr) {
return NULL;
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
return AssignEnvironment(new(zone()) LBoundsCheck(
UseRegisterOrConstantAtStart(instr->index()),

View File

@ -1595,6 +1595,12 @@ LInstruction* LChunkBuilder::DoNumericConstraint(HNumericConstraint* instr) {
}
LInstruction* LChunkBuilder::DoInductionVariableAnnotation(
HInductionVariableAnnotation* instr) {
return NULL;
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = UseRegister(instr->length());

View File

@ -1641,6 +1641,12 @@ LInstruction* LChunkBuilder::DoNumericConstraint(HNumericConstraint* instr) {
}
LInstruction* LChunkBuilder::DoInductionVariableAnnotation(
HInductionVariableAnnotation* instr) {
return NULL;
}
LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
LOperand* value = UseRegisterOrConstantAtStart(instr->index());
LOperand* length = Use(instr->length());