Title: [207164] trunk/Source/_javascript_Core
- Revision
- 207164
- Author
- [email protected]
- Date
- 2016-10-11 13:51:53 -0700 (Tue, 11 Oct 2016)
Log Message
Air should be able to replace constant materializations with adds
https://bugs.webkit.org/show_bug.cgi?id=162749
Reviewed by Yusuke Suzuki.
We have a lot of defenses against emitting code that materializes huge contants. But if we do
end up with such code in the backend, it's better to convert those materializations into add
instructions by checking if other registers are known to contain nearby constants. That's
what this patch does.
* b3/air/AirFixObviousSpills.cpp:
* b3/testb3.cpp:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (207163 => 207164)
--- trunk/Source/_javascript_Core/ChangeLog 2016-10-11 20:37:51 UTC (rev 207163)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-10-11 20:51:53 UTC (rev 207164)
@@ -1,3 +1,18 @@
+2016-10-10 Filip Pizlo <[email protected]>
+
+ Air should be able to replace constant materializations with adds
+ https://bugs.webkit.org/show_bug.cgi?id=162749
+
+ Reviewed by Yusuke Suzuki.
+
+ We have a lot of defenses against emitting code that materializes huge contants. But if we do
+ end up with such code in the backend, it's better to convert those materializations into add
+ instructions by checking if other registers are known to contain nearby constants. That's
+ what this patch does.
+
+ * b3/air/AirFixObviousSpills.cpp:
+ * b3/testb3.cpp:
+
2016-10-11 Filip Pizlo <[email protected]>
B3->Air lowering needs the same defenses in effectiveAddr() that it has in tryAppendLea()
Modified: trunk/Source/_javascript_Core/b3/air/AirFixObviousSpills.cpp (207163 => 207164)
--- trunk/Source/_javascript_Core/b3/air/AirFixObviousSpills.cpp 2016-10-11 20:37:51 UTC (rev 207163)
+++ trunk/Source/_javascript_Core/b3/air/AirFixObviousSpills.cpp 2016-10-11 20:51:53 UTC (rev 207164)
@@ -191,6 +191,42 @@
if (verbose)
dataLog("Fixing inst ", inst, ": ", m_state, "\n");
+
+ // First handle some special instructions.
+ switch (inst.kind.opcode) {
+ case Move: {
+ if (inst.args[0].isBigImm() && inst.args[1].isReg()
+ && isValidForm(Add64, Arg::Imm, Arg::Tmp, Arg::Tmp)) {
+ // BigImm materializations are super expensive on both x86 and ARM. Let's try to
+ // materialize this bad boy using math instead. Note that we use unsigned math here
+ // since it's more deterministic.
+ uint64_t myValue = inst.args[0].value();
+ Reg myDest = inst.args[1].reg();
+ for (const RegConst& regConst : m_state.regConst) {
+ uint64_t otherValue = regConst.constant;
+
+ // Let's try add. That's the only thing that works on all platforms, since it's
+ // the only cheap arithmetic op that x86 does in three operands. Long term, we
+ // should add fancier materializations here for ARM if the BigImm is yuge.
+ uint64_t delta = myValue - otherValue;
+
+ if (Arg::isValidImmForm(delta)) {
+ inst.kind = Add64;
+ inst.args.resize(3);
+ inst.args[0] = Arg::imm(delta);
+ inst.args[1] = Tmp(regConst.reg);
+ inst.args[2] = Tmp(myDest);
+ return;
+ }
+ }
+ return;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
// Create a copy in case we invalidate the instruction. That doesn't happen often.
Inst instCopy = inst;
Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (207163 => 207164)
--- trunk/Source/_javascript_Core/b3/testb3.cpp 2016-10-11 20:37:51 UTC (rev 207163)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp 2016-10-11 20:51:53 UTC (rev 207164)
@@ -13705,6 +13705,30 @@
CHECK_EQ(invoke<int32_t>(*code, ptr - (static_cast<intptr_t>(1) << static_cast<intptr_t>(32)) * i, i), 12341234);
}
+void testOptimizeMaterialization()
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNew<CCallValue>(
+ proc, Void, Origin(),
+ root->appendNew<ConstPtrValue>(proc, Origin(), 0x123423453456llu),
+ root->appendNew<ConstPtrValue>(proc, Origin(), 0x123423453456llu + 35));
+ root->appendNew<Value>(proc, Return, Origin());
+
+ auto code = compile(proc);
+ bool found = false;
+ for (Air::BasicBlock* block : proc.code()) {
+ for (Air::Inst& inst : *block) {
+ if (inst.kind.opcode != Air::Add64)
+ continue;
+ if (inst.args[0] != Air::Arg::imm(35))
+ continue;
+ found = true;
+ }
+ }
+ CHECK(found);
+}
+
// Make sure the compiler does not try to optimize anything out.
NEVER_INLINE double zero()
{
@@ -15143,6 +15167,7 @@
RUN(testAddShl65());
RUN(testLoadBaseIndexShift2());
RUN(testLoadBaseIndexShift32());
+ RUN(testOptimizeMaterialization());
if (isX86()) {
RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes