Ignore:
Timestamp:
Jan 19, 2017, 12:40:05 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[B3] B3 strength reduction could encounter Value without owner in PureCSE
https://bugs.webkit.org/show_bug.cgi?id=167161

Reviewed by Filip Pizlo.

PureCSE relies on the fact that all the stored Values have owner member.
This assumption is broken when you execute specializeSelect in B3ReduceStrength phase.
It clears owner of Values which are in between Select and Check to clone them to then/else
blocks. If these cleared Values are already stored in PureCSE map, this map poses a Value
with nullptr owner in PureCSE.

This patch changes PureCSE to ignore stored Values tha have nullptr owner. This even means
that a client of PureCSE could deliberately null the owner if they wanted to signal the
Value should be ignored.

While PureCSE ignores chance for optimization if Value's owner is nullptr, in the current
strength reduction algorithm, this does not hurt optimization because CSE will be eventually
applied since the strength reduction phase want to reach fixed point. But even without
this iterations, our result itself is valid since PureCSE is allowed to be conservative.

  • b3/B3PureCSE.cpp:

(JSC::B3::PureCSE::findMatch):
(JSC::B3::PureCSE::process):

  • b3/testb3.cpp:

(JSC::B3::testCheckSelectAndCSE):
(JSC::B3::run):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r210124 r210919  
    1183011830    CHECK(invoke<int>(*code, false, true) == 666);
    1183111831    CHECK(invoke<int>(*code, true, false) == 667);
     11832}
     11833
     11834void testCheckSelectAndCSE()
     11835{
     11836    Procedure proc;
     11837    BasicBlock* root = proc.addBlock();
     11838
     11839    auto* selectValue = root->appendNew<Value>(
     11840        proc, Select, Origin(),
     11841        root->appendNew<Value>(
     11842            proc, BitAnd, Origin(),
     11843            root->appendNew<Value>(
     11844                proc, Trunc, Origin(),
     11845                root->appendNew<ArgumentRegValue>(
     11846                    proc, Origin(), GPRInfo::argumentGPR0)),
     11847            root->appendNew<Const32Value>(proc, Origin(), 0xff)),
     11848        root->appendNew<ConstPtrValue>(proc, Origin(), -42),
     11849        root->appendNew<ConstPtrValue>(proc, Origin(), 35));
     11850
     11851    auto* constant = root->appendNew<ConstPtrValue>(proc, Origin(), 42);
     11852    auto* addValue = root->appendNew<Value>(proc, Add, Origin(), selectValue, constant);
     11853
     11854    CheckValue* check = root->appendNew<CheckValue>(proc, Check, Origin(), addValue);
     11855    unsigned generationCount = 0;
     11856    check->setGenerator(
     11857        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
     11858            AllowMacroScratchRegisterUsage allowScratch(jit);
     11859
     11860            generationCount++;
     11861            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
     11862            jit.emitFunctionEpilogue();
     11863            jit.ret();
     11864        });
     11865
     11866    auto* addValue2 = root->appendNew<Value>(proc, Add, Origin(), selectValue, constant);
     11867
     11868    root->appendNewControlValue(
     11869        proc, Return, Origin(),
     11870        root->appendNew<Value>(proc, Add, Origin(), addValue, addValue2));
     11871
     11872    auto code = compile(proc);
     11873    CHECK(generationCount == 1);
     11874    CHECK(invoke<int>(*code, true) == 0);
     11875    CHECK(invoke<int>(*code, false) == 666);
    1183211876}
    1183311877
     
    1543415478    RUN(testCheckSelect());
    1543515479    RUN(testCheckSelectCheckSelect());
     15480    RUN(testCheckSelectAndCSE());
    1543615481    RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
    1543715482
Note: See TracChangeset for help on using the changeset viewer.