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(polymorphic_inlining, true, "polymorphic inlining")
|
||||
DEFINE_bool(use_osr, true, "use on-stack replacement")
|
||||
DEFINE_bool(idefs, false, "use informative definitions")
|
||||
DEFINE_bool(array_bounds_checks_elimination, true,
|
||||
"perform array bounds checks elimination")
|
||||
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 {
|
||||
return block()->block_id() > other->block_id();
|
||||
}
|
||||
|
@ -579,7 +579,10 @@ class HValue: public ZoneObject {
|
||||
// HGraph::ComputeSafeUint32Operations is responsible for setting this
|
||||
// flag.
|
||||
kUint32,
|
||||
kLastFlag = kUint32
|
||||
// This flag is set to true after the SetupInformativeDefinitions() pass
|
||||
// has processed this instruction.
|
||||
kIDefsProcessingDone,
|
||||
kLastFlag = kIDefsProcessingDone
|
||||
};
|
||||
|
||||
STATIC_ASSERT(kLastFlag < kBitsPerInt);
|
||||
@ -687,8 +690,8 @@ class HValue: public ZoneObject {
|
||||
return RedefinedOperandIndex() != kNoRedefinedOperand;
|
||||
}
|
||||
HValue* RedefinedOperand() {
|
||||
ASSERT(IsInformativeDefinition());
|
||||
return OperandAt(RedefinedOperandIndex());
|
||||
return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex())
|
||||
: NULL;
|
||||
}
|
||||
|
||||
// This method must always return the original HValue SSA definition
|
||||
@ -698,6 +701,15 @@ class HValue: public ZoneObject {
|
||||
: this;
|
||||
}
|
||||
|
||||
virtual void AddInformativeDefinitions() {}
|
||||
|
||||
void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
|
||||
UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
|
||||
}
|
||||
void UpdateRedefinedUses() {
|
||||
UpdateRedefinedUsesInner<Dominates>();
|
||||
}
|
||||
|
||||
bool IsDefinedAfter(HBasicBlock* other) const;
|
||||
|
||||
// Operands.
|
||||
@ -856,6 +868,36 @@ class HValue: public ZoneObject {
|
||||
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() {
|
||||
GVNFlagSet result;
|
||||
// Create changes mask.
|
||||
|
@ -3587,7 +3587,10 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
||||
HStackCheckEliminator sce(this);
|
||||
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_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
|
||||
// dominator tree.
|
||||
// For now we handle checks where the index is like "exp + int32value".
|
||||
|
@ -269,7 +269,7 @@ class HGraph: public ZoneObject {
|
||||
void Canonicalize();
|
||||
void OrderBlocks();
|
||||
void AssignDominators();
|
||||
void ReplaceCheckedValues();
|
||||
void SetupInformativeDefinitions();
|
||||
void EliminateRedundantBoundsChecks();
|
||||
void DehoistSimpleArrayIndexComputations();
|
||||
void DeadCodeElimination();
|
||||
@ -398,6 +398,8 @@ class HGraph: public ZoneObject {
|
||||
void InferTypes(ZoneList<HValue*>* worklist);
|
||||
void InitializeInferredTypes(int from_inclusive, int to_inclusive);
|
||||
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
|
||||
void SetupInformativeDefinitionsInBlock(HBasicBlock* block);
|
||||
void SetupInformativeDefinitionsRecursively(HBasicBlock* block);
|
||||
void EliminateRedundantBoundsChecks(HBasicBlock* bb, BoundsCheckTable* table);
|
||||
|
||||
Isolate* isolate_;
|
||||
|
Loading…
Reference in New Issue
Block a user