Revision: 15624
Author: [email protected]
Date: Thu Jul 11 04:41:33 2013
Log: Allocation folding integrated into the GVN phase.
BUG=
[email protected], [email protected]
Review URL: https://codereview.chromium.org/18596005
http://code.google.com/p/v8/source/detail?r=15624
Modified:
/branches/bleeding_edge/src/flag-definitions.h
/branches/bleeding_edge/src/hydrogen-gvn.cc
/branches/bleeding_edge/src/hydrogen-instructions.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.h
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h Wed Jul 10 08:32:39 2013
+++ /branches/bleeding_edge/src/flag-definitions.h Thu Jul 11 04:41:33 2013
@@ -215,6 +215,7 @@
DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction
canonicalizing")
DEFINE_bool(use_inlining, true, "use function inlining")
DEFINE_bool(use_escape_analysis, false, "use hydrogen escape analysis")
+DEFINE_bool(use_allocation_folding, false, "use allocation folding")
DEFINE_int(max_inlined_source_size, 600,
"maximum source size in bytes considered for a single inlining")
DEFINE_int(max_inlined_nodes, 196,
@@ -236,6 +237,7 @@
DEFINE_bool(trace_gvn, false, "trace global value numbering")
DEFINE_bool(trace_representation, false, "trace representation types")
DEFINE_bool(trace_escape_analysis, false, "trace hydrogen escape analysis")
+DEFINE_bool(trace_allocation_folding, false, "trace allocation folding")
DEFINE_bool(trace_track_allocation_sites, false,
"trace the tracking of allocation sites")
DEFINE_bool(trace_migration, false, "trace object migration")
=======================================
--- /branches/bleeding_edge/src/hydrogen-gvn.cc Fri Jul 5 02:52:11 2013
+++ /branches/bleeding_edge/src/hydrogen-gvn.cc Thu Jul 11 04:41:33 2013
@@ -776,9 +776,28 @@
}
// Go through all instructions of the current block.
- HInstruction* instr = block->first();
- while (instr != NULL) {
- HInstruction* next = instr->next();
+ for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+ HInstruction* instr = it.Current();
+ if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) {
+ for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
+ HValue* other = dominators->at(i);
+ GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
+ GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i);
+ if (instr->DependsOnFlags().Contains(depends_on_flag) &&
+ (other != NULL)) {
+ TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d
(%s)\n",
+ i,
+ instr->id(),
+ instr->Mnemonic(),
+ other->id(),
+ other->Mnemonic());
+ instr->HandleSideEffectDominator(changes_flag, other);
+ }
+ }
+ }
+ // Instruction was unlinked during graph traversal.
+ if (!instr->IsLinked()) continue;
+
GVNFlagSet flags = instr->ChangesFlags();
if (!flags.IsEmpty()) {
// Clear all instructions in the map that are affected by side
effects.
@@ -804,25 +823,6 @@
map->Add(instr, zone());
}
}
- if (instr->IsLinked() &&
- instr->CheckFlag(HValue::kTrackSideEffectDominators)) {
- for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
- HValue* other = dominators->at(i);
- GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
- GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i);
- if (instr->DependsOnFlags().Contains(depends_on_flag) &&
- (other != NULL)) {
- TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d
(%s)\n",
- i,
- instr->id(),
- instr->Mnemonic(),
- other->id(),
- other->Mnemonic());
- instr->SetSideEffectDominator(changes_flag, other);
- }
- }
- }
- instr = next;
}
HBasicBlock* dominator_block;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Jul 10
05:19:37 2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.cc Thu Jul 11
04:41:33 2013
@@ -1654,8 +1654,8 @@
}
-void HCheckMaps::SetSideEffectDominator(GVNFlag side_effect,
- HValue* dominator) {
+void HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator) {
ASSERT(side_effect == kChangesMaps);
// TODO(mstarzinger): For now we specialize on HStoreNamedField, but once
// type information is rich enough we should generalize this to any HType
@@ -3181,6 +3181,84 @@
HType HAllocate::CalculateInferredType() {
return type_;
}
+
+
+void HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator) {
+ ASSERT(side_effect == kChangesNewSpacePromotion);
+ // Try to fold allocations together with their dominating allocations.
+ if (!FLAG_use_allocation_folding || !dominator->IsAllocate()) {
+ return;
+ }
+ HAllocate* dominator_allocate_instr = HAllocate::cast(dominator);
+ HValue* dominator_size = dominator_allocate_instr->size();
+ HValue* current_size = size();
+ // We can just fold allocations that are guaranteed in new space.
+ // TODO(hpayer): Support double aligned allocations.
+ // TODO(hpayer): Add support for non-constant allocation in dominator.
+ if (!GuaranteedInNewSpace() || MustAllocateDoubleAligned() ||
+ !current_size->IsInteger32Constant() ||
+ !dominator_allocate_instr->GuaranteedInNewSpace() ||
+ dominator_allocate_instr->MustAllocateDoubleAligned() ||
+ !dominator_size->IsInteger32Constant()) {
+ return;
+ }
+
+ // First update the size of the dominator allocate instruction.
+ int32_t dominator_size_constant =
+ HConstant::cast(dominator_size)->GetInteger32Constant();
+ int32_t current_size_constant =
+ HConstant::cast(current_size)->GetInteger32Constant();
+ HBasicBlock* block = dominator->block();
+ Zone* zone = block->zone();
+ HInstruction* new_dominator_size = new(zone) HConstant(
+ dominator_size_constant + current_size_constant);
+ new_dominator_size->InsertBefore(dominator_allocate_instr);
+ dominator_allocate_instr->UpdateSize(new_dominator_size);
+
+ // TODO(hpayer): Remove filler map but make sure new space is valid.
+ HInstruction* free_space_instr =
+ new(zone) HInnerAllocatedObject(dominator_allocate_instr,
+ dominator_size_constant,
+ type());
+ free_space_instr->InsertAfter(dominator_allocate_instr);
+ HConstant* filler_map = new(zone) HConstant(
+ isolate()->factory()->free_space_map(),
+ UniqueValueId(isolate()->heap()->free_space_map()),
+ Representation::Tagged(),
+ HType::Tagged(),
+ false,
+ true,
+ false,
+ false);
+ filler_map->InsertAfter(free_space_instr);
+
+ HInstruction* store_map = new(zone) HStoreNamedField(
+ free_space_instr, HObjectAccess::ForMap(), filler_map);
+ store_map->SetFlag(HValue::kHasNoObservableSideEffects);
+ store_map->InsertAfter(filler_map);
+
+ HInstruction* free_space_size = new(zone)
HConstant(current_size_constant);
+ free_space_size->InsertAfter(store_map);
+ HObjectAccess access =
+ HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
+ HInstruction* store_size = new(zone) HStoreNamedField(
+ free_space_instr, access, free_space_size);
+ store_size->SetFlag(HValue::kHasNoObservableSideEffects);
+ store_size->InsertAfter(free_space_size);
+
+ // After that replace the dominated allocate instruction.
+ HInstruction* dominated_allocate_instr =
+ new(zone) HInnerAllocatedObject(dominator_allocate_instr,
+ dominator_size_constant,
+ type());
+ dominated_allocate_instr->InsertBefore(this);
+ DeleteAndReplaceWith(dominated_allocate_instr);
+ if (FLAG_trace_allocation_folding) {
+ PrintF("#%d (%s) folded into #%d (%s)\n",
+ id(), Mnemonic(), dominator->id(), dominator->Mnemonic());
+ }
+}
void HAllocate::PrintDataTo(StringStream* stream) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Jul 10 05:19:37
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Thu Jul 11 04:41:33
2013
@@ -790,7 +790,7 @@
// occurrences of the instruction are indeed the same.
kUseGVN,
// Track instructions that are dominating side effects. If an
instruction
- // sets this flag, it must implement SetSideEffectDominator() and
should
+ // sets this flag, it must implement HandleSideEffectDominator() and
should
// indicate which side effects to track by setting GVN flags.
kTrackSideEffectDominators,
kCanOverflow,
@@ -1109,7 +1109,8 @@
// This function must be overridden for instructions which have the
// kTrackSideEffectDominators flag set, to track instructions that are
// dominating side effects.
- virtual void SetSideEffectDominator(GVNFlag side_effect, HValue*
dominator) {
+ virtual void HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator) {
UNREACHABLE();
}
@@ -2774,7 +2775,8 @@
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
- virtual void SetSideEffectDominator(GVNFlag side_effect, HValue*
dominator);
+ virtual void HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator);
virtual void PrintDataTo(StringStream* stream);
virtual HType CalculateInferredType();
@@ -4975,10 +4977,12 @@
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
+
virtual Handle<Map> GetMonomorphicJSObjectMap() {
ASSERT(!constructor_initial_map_.is_null());
return constructor_initial_map_;
}
+
virtual HType CalculateInferredType();
DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
@@ -5007,7 +5011,9 @@
SetOperandAt(0, context);
SetOperandAt(1, size);
set_representation(Representation::Tagged());
+ SetFlag(kTrackSideEffectDominators);
SetGVNFlag(kChangesNewSpacePromotion);
+ SetGVNFlag(kDependsOnNewSpacePromotion);
}
static Flags DefaultFlags() {
@@ -5025,6 +5031,7 @@
HValue* context() { return OperandAt(0); }
HValue* size() { return OperandAt(1); }
+ HType type() { return type_; }
virtual Representation RequiredInputRepresentation(int index) {
if (index == 0) {
@@ -5061,6 +5068,13 @@
return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
}
+ void UpdateSize(HValue* size) {
+ SetOperandAt(1, size);
+ }
+
+ virtual void HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator);
+
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(Allocate)
@@ -5073,8 +5087,9 @@
class HInnerAllocatedObject: public HTemplateInstruction<1> {
public:
- HInnerAllocatedObject(HValue* value, int offset)
- : offset_(offset) {
+ HInnerAllocatedObject(HValue* value, int offset, HType type =
HType::Tagged())
+ : offset_(offset),
+ type_(type) {
ASSERT(value->IsAllocate());
SetOperandAt(0, value);
set_representation(Representation::Tagged());
@@ -5086,6 +5101,8 @@
virtual Representation RequiredInputRepresentation(int index) {
return Representation::Tagged();
}
+
+ virtual HType CalculateInferredType() { return type_; }
virtual void PrintDataTo(StringStream* stream);
@@ -5093,6 +5110,7 @@
private:
int offset_;
+ HType type_;
};
@@ -5815,7 +5833,8 @@
}
return Representation::Tagged();
}
- virtual void SetSideEffectDominator(GVNFlag side_effect, HValue*
dominator) {
+ virtual void HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator) {
ASSERT(side_effect == kChangesNewSpacePromotion);
new_space_dominator_ = dominator;
}
@@ -6017,7 +6036,8 @@
return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
}
- virtual void SetSideEffectDominator(GVNFlag side_effect, HValue*
dominator) {
+ virtual void HandleSideEffectDominator(GVNFlag side_effect,
+ HValue* dominator) {
ASSERT(side_effect == kChangesNewSpacePromotion);
new_space_dominator_ = dominator;
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Thu Jul 11 01:21:50 2013
+++ /branches/bleeding_edge/src/hydrogen.h Thu Jul 11 04:41:33 2013
@@ -233,14 +233,21 @@
class HInstructionIterator BASE_EMBEDDED {
public:
- explicit HInstructionIterator(HBasicBlock* block) :
instr_(block->first()) { }
+ explicit HInstructionIterator(HBasicBlock* block)
+ : instr_(block->first()) {
+ next_ = Done() ? NULL : instr_->next();
+ }
- bool Done() { return instr_ == NULL; }
- HInstruction* Current() { return instr_; }
- void Advance() { instr_ = instr_->next(); }
+ inline bool Done() const { return instr_ == NULL; }
+ inline HInstruction* Current() { return instr_; }
+ inline void Advance() {
+ instr_ = next_;
+ next_ = Done() ? NULL : instr_->next();
+ }
private:
HInstruction* instr_;
+ HInstruction* next_;
};
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.