- Revision
- 214836
- Author
- fpi...@apple.com
- Date
- 2017-04-03 13:50:33 -0700 (Mon, 03 Apr 2017)
Log Message
WTF::Liveness should have an API that focuses on actions at instruction boundaries
https://bugs.webkit.org/show_bug.cgi?id=170407
Reviewed by Keith Miller.
Source/_javascript_Core:
Adopt changes to the WTF::Liveness<> API. Instead of having separate functions for the
early/late versions of uses and defs, we now have just a use/def API. Those
automatically take care of eary/late issues as needed.
This reduces the API surface between WTF::Liveness<> and its clients, which makes it
easier to implement some other optimizations I'm thinking about.
* b3/B3VariableLiveness.h:
(JSC::B3::VariableLivenessAdapter::forEachUse):
(JSC::B3::VariableLivenessAdapter::forEachDef):
(JSC::B3::VariableLivenessAdapter::forEachEarlyUse): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachLateUse): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachEarlyDef): Deleted.
(JSC::B3::VariableLivenessAdapter::forEachLateDef): Deleted.
* b3/air/AirLiveness.h:
(JSC::B3::Air::LivenessAdapter::blockSize):
(JSC::B3::Air::LivenessAdapter::forEachUse):
(JSC::B3::Air::LivenessAdapter::forEachDef):
(JSC::B3::Air::LivenessAdapter::forEachEarlyUse): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachLateUse): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachEarlyDef): Deleted.
(JSC::B3::Air::LivenessAdapter::forEachLateDef): Deleted.
Source/WTF:
Change the Liveness<> API to handle early and late things in one lump inside forEachUse
and forEachDef functions. This reduces the amount of different functions that Liveness<>
expects from its adaptor. This makes it easier to implement optimizations that cache the
use/def behavior of each instruction boundary.
* wtf/Liveness.h:
(WTF::Liveness::Liveness):
(WTF::Liveness::LocalCalc::execute):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (214835 => 214836)
--- trunk/Source/_javascript_Core/ChangeLog 2017-04-03 20:44:54 UTC (rev 214835)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-04-03 20:50:33 UTC (rev 214836)
@@ -1,5 +1,35 @@
2017-04-03 Filip Pizlo <fpi...@apple.com>
+ WTF::Liveness should have an API that focuses on actions at instruction boundaries
+ https://bugs.webkit.org/show_bug.cgi?id=170407
+
+ Reviewed by Keith Miller.
+
+ Adopt changes to the WTF::Liveness<> API. Instead of having separate functions for the
+ early/late versions of uses and defs, we now have just a use/def API. Those
+ automatically take care of eary/late issues as needed.
+
+ This reduces the API surface between WTF::Liveness<> and its clients, which makes it
+ easier to implement some other optimizations I'm thinking about.
+
+ * b3/B3VariableLiveness.h:
+ (JSC::B3::VariableLivenessAdapter::forEachUse):
+ (JSC::B3::VariableLivenessAdapter::forEachDef):
+ (JSC::B3::VariableLivenessAdapter::forEachEarlyUse): Deleted.
+ (JSC::B3::VariableLivenessAdapter::forEachLateUse): Deleted.
+ (JSC::B3::VariableLivenessAdapter::forEachEarlyDef): Deleted.
+ (JSC::B3::VariableLivenessAdapter::forEachLateDef): Deleted.
+ * b3/air/AirLiveness.h:
+ (JSC::B3::Air::LivenessAdapter::blockSize):
+ (JSC::B3::Air::LivenessAdapter::forEachUse):
+ (JSC::B3::Air::LivenessAdapter::forEachDef):
+ (JSC::B3::Air::LivenessAdapter::forEachEarlyUse): Deleted.
+ (JSC::B3::Air::LivenessAdapter::forEachLateUse): Deleted.
+ (JSC::B3::Air::LivenessAdapter::forEachEarlyDef): Deleted.
+ (JSC::B3::Air::LivenessAdapter::forEachLateDef): Deleted.
+
+2017-04-03 Filip Pizlo <fpi...@apple.com>
+
Inst::forEachArg could compile to more compact code
https://bugs.webkit.org/show_bug.cgi?id=170406
Modified: trunk/Source/_javascript_Core/b3/B3VariableLiveness.h (214835 => 214836)
--- trunk/Source/_javascript_Core/b3/B3VariableLiveness.h 2017-04-03 20:44:54 UTC (rev 214835)
+++ trunk/Source/_javascript_Core/b3/B3VariableLiveness.h 2017-04-03 20:50:33 UTC (rev 214836)
@@ -61,9 +61,12 @@
}
template<typename Func>
- void forEachEarlyUse(BasicBlock* block, unsigned valueIndex, const Func& func)
+ void forEachUse(BasicBlock* block, unsigned valueBoundaryIndex, const Func& func)
{
- Value* value = block->get(valueIndex);
+ // We want all of the uses that happen between valueBoundaryIndex-1 and
+ // valueBoundaryIndex. Since the Get opcode is the only value that has a use and since
+ // this is an early use, we only care about block[valueBoundaryIndex].
+ Value* value = block->get(valueBoundaryIndex);
if (!value)
return;
if (value->opcode() != Get)
@@ -72,19 +75,12 @@
}
template<typename Func>
- void forEachLateUse(BasicBlock*, unsigned, const Func&)
+ void forEachDef(BasicBlock* block, unsigned valueBoundaryIndex, const Func& func)
{
- }
-
- template<typename Func>
- void forEachEarlyDef(BasicBlock*, unsigned, const Func&)
- {
- }
-
- template<typename Func>
- void forEachLateDef(BasicBlock* block, unsigned valueIndex, const Func& func)
- {
- Value* value = block->get(valueIndex);
+ // We want all of the defs that happen between valueBoundaryIndex-1 and
+ // valueBoundaryIndex. Since the Set opcode is the only value that has a def and since
+ // this is an late def, we only care about block[valueBoundaryIndex - 1].
+ Value* value = block->get(valueBoundaryIndex - 1);
if (!value)
return;
if (value->opcode() != Set)
Modified: trunk/Source/_javascript_Core/b3/air/AirLiveness.h (214835 => 214836)
--- trunk/Source/_javascript_Core/b3/air/AirLiveness.h 2017-04-03 20:44:54 UTC (rev 214835)
+++ trunk/Source/_javascript_Core/b3/air/AirLiveness.h 2017-04-03 20:50:33 UTC (rev 214836)
@@ -50,67 +50,55 @@
{
return block->size();
}
-
- template<typename Func>
- void forEachEarlyUse(BasicBlock* block, unsigned instIndex, const Func& func)
- {
- Inst* inst = block->get(instIndex);
- if (!inst)
- return;
- inst->forEach<typename Adapter::Thing>(
- [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
- if (Arg::isEarlyUse(role)
- && Adapter::acceptsBank(bank)
- && Adapter::acceptsRole(role))
- func(Adapter::valueToIndex(thing));
- });
- }
template<typename Func>
- void forEachLateUse(BasicBlock* block, unsigned instIndex, const Func& func)
+ void forEachUse(BasicBlock* block, size_t instBoundaryIndex, const Func& func)
{
- Inst* inst = block->get(instIndex);
- if (!inst)
- return;
- inst->forEach<typename Adapter::Thing>(
- [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
- if (Arg::isLateUse(role)
- && Adapter::acceptsBank(bank)
- && Adapter::acceptsRole(role))
- func(Adapter::valueToIndex(thing));
- });
+ if (Inst* prevInst = block->get(instBoundaryIndex - 1)) {
+ prevInst->forEach<typename Adapter::Thing>(
+ [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
+ if (Arg::isLateUse(role)
+ && Adapter::acceptsBank(bank)
+ && Adapter::acceptsRole(role))
+ func(Adapter::valueToIndex(thing));
+ });
+ }
+
+ if (Inst* nextInst = block->get(instBoundaryIndex)) {
+ nextInst->forEach<typename Adapter::Thing>(
+ [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
+ if (Arg::isEarlyUse(role)
+ && Adapter::acceptsBank(bank)
+ && Adapter::acceptsRole(role))
+ func(Adapter::valueToIndex(thing));
+ });
+ }
}
template<typename Func>
- void forEachEarlyDef(BasicBlock* block, unsigned instIndex, const Func& func)
+ void forEachDef(BasicBlock* block, size_t instBoundaryIndex, const Func& func)
{
- Inst* inst = block->get(instIndex);
- if (!inst)
- return;
- inst->forEach<typename Adapter::Thing>(
- [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
- if (Arg::isEarlyDef(role)
- && Adapter::acceptsBank(bank)
- && Adapter::acceptsRole(role))
- func(Adapter::valueToIndex(thing));
- });
+ if (Inst* prevInst = block->get(instBoundaryIndex - 1)) {
+ prevInst->forEach<typename Adapter::Thing>(
+ [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
+ if (Arg::isLateDef(role)
+ && Adapter::acceptsBank(bank)
+ && Adapter::acceptsRole(role))
+ func(Adapter::valueToIndex(thing));
+ });
+ }
+
+ if (Inst* nextInst = block->get(instBoundaryIndex)) {
+ nextInst->forEach<typename Adapter::Thing>(
+ [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
+ if (Arg::isEarlyDef(role)
+ && Adapter::acceptsBank(bank)
+ && Adapter::acceptsRole(role))
+ func(Adapter::valueToIndex(thing));
+ });
+ }
}
-
- template<typename Func>
- void forEachLateDef(BasicBlock* block, unsigned instIndex, const Func& func)
- {
- Inst* inst = block->get(instIndex);
- if (!inst)
- return;
- inst->forEach<typename Adapter::Thing>(
- [&] (typename Adapter::Thing& thing, Arg::Role role, Bank bank, Width) {
- if (Arg::isLateDef(role)
- && Adapter::acceptsBank(bank)
- && Adapter::acceptsRole(role))
- func(Adapter::valueToIndex(thing));
- });
- }
-
+
Code& code;
};
Modified: trunk/Source/WTF/ChangeLog (214835 => 214836)
--- trunk/Source/WTF/ChangeLog 2017-04-03 20:44:54 UTC (rev 214835)
+++ trunk/Source/WTF/ChangeLog 2017-04-03 20:50:33 UTC (rev 214836)
@@ -1,3 +1,19 @@
+2017-04-03 Filip Pizlo <fpi...@apple.com>
+
+ WTF::Liveness should have an API that focuses on actions at instruction boundaries
+ https://bugs.webkit.org/show_bug.cgi?id=170407
+
+ Reviewed by Keith Miller.
+
+ Change the Liveness<> API to handle early and late things in one lump inside forEachUse
+ and forEachDef functions. This reduces the amount of different functions that Liveness<>
+ expects from its adaptor. This makes it easier to implement optimizations that cache the
+ use/def behavior of each instruction boundary.
+
+ * wtf/Liveness.h:
+ (WTF::Liveness::Liveness):
+ (WTF::Liveness::LocalCalc::execute):
+
2017-04-01 Csaba Osztrogonác <o...@webkit.org>
Mac cmake buildfix after 214586.
Modified: trunk/Source/WTF/wtf/Liveness.h (214835 => 214836)
--- trunk/Source/WTF/wtf/Liveness.h 2017-04-03 20:44:54 UTC (rev 214835)
+++ trunk/Source/WTF/wtf/Liveness.h 2017-04-03 20:50:33 UTC (rev 214836)
@@ -57,8 +57,8 @@
IndexVector& liveAtTail = m_liveAtTail[block];
- Adapter::forEachLateUse(
- block, Adapter::blockSize(block) - 1,
+ Adapter::forEachUse(
+ block, Adapter::blockSize(block),
[&] (unsigned index) {
liveAtTail.append(index);
});
@@ -91,7 +91,7 @@
localCalc.execute(instIndex);
// Handle the early def's of the first instruction.
- Adapter::forEachEarlyDef(
+ Adapter::forEachDef(
block, 0,
[&] (unsigned index) {
m_workset.remove(index);
@@ -220,33 +220,23 @@
{
auto& workset = m_liveness.m_workset;
- // First handle the early def's of the next instruction.
- m_liveness.forEachEarlyDef(
+ // Want an easy example to help you visualize how this works?
+ // Check out B3VariableLiveness.h.
+ //
+ // Want a hard example to help you understand the hard cases?
+ // Check out AirLiveness.h.
+
+ m_liveness.forEachDef(
m_block, instIndex + 1,
[&] (unsigned index) {
workset.remove(index);
});
- // Then handle def's.
- m_liveness.forEachLateDef(
+ m_liveness.forEachUse(
m_block, instIndex,
[&] (unsigned index) {
- workset.remove(index);
- });
-
- // Then handle use's.
- m_liveness.forEachEarlyUse(
- m_block, instIndex,
- [&] (unsigned index) {
workset.add(index);
});
-
- // And finally, handle the late use's of the previous instruction.
- m_liveness.forEachLateUse(
- m_block, instIndex - 1,
- [&] (unsigned index) {
- workset.add(index);
- });
}
private: