Base iDef update code.
Review URL: https://codereview.chromium.org/12079042 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13575 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
bc16616911
commit
3b8a61dcf3
@ -205,6 +205,7 @@ DEFINE_bool(trap_on_deopt, false, "put a break point before deoptimizing")
|
|||||||
DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases")
|
DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases")
|
||||||
DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining")
|
DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining")
|
||||||
DEFINE_bool(use_osr, true, "use on-stack replacement")
|
DEFINE_bool(use_osr, true, "use on-stack replacement")
|
||||||
|
DEFINE_bool(idefs, false, "use informative definitions")
|
||||||
DEFINE_bool(array_bounds_checks_elimination, true,
|
DEFINE_bool(array_bounds_checks_elimination, true,
|
||||||
"perform array bounds checks elimination")
|
"perform array bounds checks elimination")
|
||||||
DEFINE_bool(array_index_dehoisting, true,
|
DEFINE_bool(array_index_dehoisting, true,
|
||||||
|
@ -364,6 +364,54 @@ HType HType::TypeFromValue(Handle<Object> value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool HValue::Dominates(HValue* dominator, HValue* dominated) {
|
||||||
|
if (dominator->block() != dominated->block()) {
|
||||||
|
// If they are in different blocks we can use the dominance relation
|
||||||
|
// between the blocks.
|
||||||
|
return dominator->block()->Dominates(dominated->block());
|
||||||
|
} else {
|
||||||
|
// Otherwise we must see which instruction comes first, considering
|
||||||
|
// that phis always precede regular instructions.
|
||||||
|
if (dominator->IsInstruction()) {
|
||||||
|
if (dominated->IsInstruction()) {
|
||||||
|
for (HInstruction* next = HInstruction::cast(dominator)->next();
|
||||||
|
next != NULL;
|
||||||
|
next = next->next()) {
|
||||||
|
if (next == dominated) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else if (dominated->IsPhi()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
} else if (dominator->IsPhi()) {
|
||||||
|
if (dominated->IsInstruction()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// We cannot compare which phi comes first.
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool HValue::TestDominanceUsingProcessedFlag(HValue* dominator,
|
||||||
|
HValue* dominated) {
|
||||||
|
if (dominator->block() != dominated->block()) {
|
||||||
|
return dominator->block()->Dominates(dominated->block());
|
||||||
|
} else {
|
||||||
|
// If both arguments are in the same block we check if "dominator" has
|
||||||
|
// already been processed or if it is a phi: if yes it dominates the other.
|
||||||
|
return dominator->CheckFlag(kIDefsProcessingDone) || dominator->IsPhi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool HValue::IsDefinedAfter(HBasicBlock* other) const {
|
bool HValue::IsDefinedAfter(HBasicBlock* other) const {
|
||||||
return block()->block_id() > other->block_id();
|
return block()->block_id() > other->block_id();
|
||||||
}
|
}
|
||||||
|
@ -579,7 +579,10 @@ class HValue: public ZoneObject {
|
|||||||
// HGraph::ComputeSafeUint32Operations is responsible for setting this
|
// HGraph::ComputeSafeUint32Operations is responsible for setting this
|
||||||
// flag.
|
// flag.
|
||||||
kUint32,
|
kUint32,
|
||||||
kLastFlag = kUint32
|
// This flag is set to true after the SetupInformativeDefinitions() pass
|
||||||
|
// has processed this instruction.
|
||||||
|
kIDefsProcessingDone,
|
||||||
|
kLastFlag = kIDefsProcessingDone
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC_ASSERT(kLastFlag < kBitsPerInt);
|
STATIC_ASSERT(kLastFlag < kBitsPerInt);
|
||||||
@ -687,8 +690,8 @@ class HValue: public ZoneObject {
|
|||||||
return RedefinedOperandIndex() != kNoRedefinedOperand;
|
return RedefinedOperandIndex() != kNoRedefinedOperand;
|
||||||
}
|
}
|
||||||
HValue* RedefinedOperand() {
|
HValue* RedefinedOperand() {
|
||||||
ASSERT(IsInformativeDefinition());
|
return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex())
|
||||||
return OperandAt(RedefinedOperandIndex());
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method must always return the original HValue SSA definition
|
// This method must always return the original HValue SSA definition
|
||||||
@ -698,6 +701,15 @@ class HValue: public ZoneObject {
|
|||||||
: this;
|
: this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void AddInformativeDefinitions() {}
|
||||||
|
|
||||||
|
void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
|
||||||
|
UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
|
||||||
|
}
|
||||||
|
void UpdateRedefinedUses() {
|
||||||
|
UpdateRedefinedUsesInner<Dominates>();
|
||||||
|
}
|
||||||
|
|
||||||
bool IsDefinedAfter(HBasicBlock* other) const;
|
bool IsDefinedAfter(HBasicBlock* other) const;
|
||||||
|
|
||||||
// Operands.
|
// Operands.
|
||||||
@ -856,6 +868,36 @@ class HValue: public ZoneObject {
|
|||||||
representation_ = r;
|
representation_ = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signature of a function testing if a HValue properly dominates another.
|
||||||
|
typedef bool (*DominanceTest)(HValue*, HValue*);
|
||||||
|
|
||||||
|
// Simple implementation of DominanceTest implemented walking the chain
|
||||||
|
// of Hinstructions (used in UpdateRedefinedUsesInner).
|
||||||
|
static bool Dominates(HValue* dominator, HValue* dominated);
|
||||||
|
|
||||||
|
// A fast implementation of DominanceTest that works only for the
|
||||||
|
// "current" instruction in the SetupInformativeDefinitions() phase.
|
||||||
|
// During that phase we use a flag to mark processed instructions, and by
|
||||||
|
// checking the flag we can quickly test if an instruction comes before or
|
||||||
|
// after the "current" one.
|
||||||
|
static bool TestDominanceUsingProcessedFlag(HValue* dominator,
|
||||||
|
HValue* dominated);
|
||||||
|
|
||||||
|
// If we are redefining an operand, update all its dominated uses (the
|
||||||
|
// function that checks if a use is dominated is the template argument).
|
||||||
|
template<DominanceTest TestDominance>
|
||||||
|
void UpdateRedefinedUsesInner() {
|
||||||
|
HValue* input = RedefinedOperand();
|
||||||
|
if (input != NULL) {
|
||||||
|
for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
|
||||||
|
HValue* use = uses.value();
|
||||||
|
if (TestDominance(this, use)) {
|
||||||
|
use->SetOperandAt(uses.index(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GVNFlagSet AllDependsOnFlagSet() {
|
static GVNFlagSet AllDependsOnFlagSet() {
|
||||||
GVNFlagSet result;
|
GVNFlagSet result;
|
||||||
// Create changes mask.
|
// Create changes mask.
|
||||||
|
@ -3587,7 +3587,10 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
|||||||
HStackCheckEliminator sce(this);
|
HStackCheckEliminator sce(this);
|
||||||
sce.Process();
|
sce.Process();
|
||||||
|
|
||||||
if (FLAG_array_bounds_checks_elimination) EliminateRedundantBoundsChecks();
|
if (FLAG_idefs) SetupInformativeDefinitions();
|
||||||
|
if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
|
||||||
|
EliminateRedundantBoundsChecks();
|
||||||
|
}
|
||||||
if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations();
|
if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations();
|
||||||
if (FLAG_dead_code_elimination) DeadCodeElimination();
|
if (FLAG_dead_code_elimination) DeadCodeElimination();
|
||||||
|
|
||||||
@ -3597,6 +3600,39 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) {
|
||||||
|
for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) {
|
||||||
|
HPhi* phi = block->phis()->at(phi_index);
|
||||||
|
phi->AddInformativeDefinitions();
|
||||||
|
// We do not support phis that "redefine just one operand".
|
||||||
|
ASSERT(!phi->IsInformativeDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HInstruction* i = block->first(); i != NULL; i = i->next()) {
|
||||||
|
i->AddInformativeDefinitions();
|
||||||
|
i->UpdateRedefinedUsesWhileSettingUpInformativeDefinitions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method is recursive, so if its stack frame is large it could
|
||||||
|
// cause a stack overflow.
|
||||||
|
// To keep the individual stack frames small we do the actual work inside
|
||||||
|
// SetupInformativeDefinitionsInBlock();
|
||||||
|
void HGraph::SetupInformativeDefinitionsRecursively(HBasicBlock* block) {
|
||||||
|
SetupInformativeDefinitionsInBlock(block);
|
||||||
|
for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
|
||||||
|
SetupInformativeDefinitionsRecursively(block->dominated_blocks()->at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HGraph::SetupInformativeDefinitions() {
|
||||||
|
HPhase phase("H_Setup informative definitions", this);
|
||||||
|
SetupInformativeDefinitionsRecursively(entry_block());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We try to "factor up" HBoundsCheck instructions towards the root of the
|
// We try to "factor up" HBoundsCheck instructions towards the root of the
|
||||||
// dominator tree.
|
// dominator tree.
|
||||||
// For now we handle checks where the index is like "exp + int32value".
|
// For now we handle checks where the index is like "exp + int32value".
|
||||||
|
@ -269,7 +269,7 @@ class HGraph: public ZoneObject {
|
|||||||
void Canonicalize();
|
void Canonicalize();
|
||||||
void OrderBlocks();
|
void OrderBlocks();
|
||||||
void AssignDominators();
|
void AssignDominators();
|
||||||
void ReplaceCheckedValues();
|
void SetupInformativeDefinitions();
|
||||||
void EliminateRedundantBoundsChecks();
|
void EliminateRedundantBoundsChecks();
|
||||||
void DehoistSimpleArrayIndexComputations();
|
void DehoistSimpleArrayIndexComputations();
|
||||||
void DeadCodeElimination();
|
void DeadCodeElimination();
|
||||||
@ -398,6 +398,8 @@ class HGraph: public ZoneObject {
|
|||||||
void InferTypes(ZoneList<HValue*>* worklist);
|
void InferTypes(ZoneList<HValue*>* worklist);
|
||||||
void InitializeInferredTypes(int from_inclusive, int to_inclusive);
|
void InitializeInferredTypes(int from_inclusive, int to_inclusive);
|
||||||
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
|
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
|
||||||
|
void SetupInformativeDefinitionsInBlock(HBasicBlock* block);
|
||||||
|
void SetupInformativeDefinitionsRecursively(HBasicBlock* block);
|
||||||
void EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table);
|
void EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table);
|
||||||
|
|
||||||
Isolate* isolate_;
|
Isolate* isolate_;
|
||||||
|
Loading…
Reference in New Issue
Block a user