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:
parent
af5eed104c
commit
8ef28eb5ee
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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() {
|
||||
|
@ -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()),
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user