Esempio n. 1
0
void
LinearScanMD::LegalizeConstantUse(IR::Instr * instr, IR::Opnd * opnd)
{
    Assert(opnd->IsAddrOpnd() || opnd->IsIntConstOpnd());
    intptr_t value = opnd->IsAddrOpnd() ? (intptr_t)opnd->AsAddrOpnd()->m_address : opnd->AsIntConstOpnd()->GetValue();
    if (value == 0
        && instr->m_opcode == Js::OpCode::MOV
        && !instr->GetDst()->IsRegOpnd()
        && TySize[opnd->GetType()] >= 4)
    {
        Assert(this->linearScan->instrUseRegs.IsEmpty());

        // MOV doesn't have an imm8 encoding for 32-bit/64-bit assignment, so if we have a register available,
        // we should hoist it and generate xor reg, reg and MOV dst, reg
        BitVector regsBv;
        regsBv.Copy(this->linearScan->activeRegs);
        regsBv.Or(this->linearScan->callSetupRegs);

        regsBv.ComplimentAll();
        regsBv.And(this->linearScan->int32Regs);
        regsBv.Minus(this->linearScan->tempRegs);       // Avoid tempRegs
        BVIndex regIndex = regsBv.GetNextBit();
        if (regIndex != BVInvalidIndex)
        {
            instr->HoistSrc1(Js::OpCode::MOV, (RegNum)regIndex);
            this->linearScan->instrUseRegs.Set(regIndex);
            this->func->m_regsUsed.Set(regIndex);

            // If we are in a loop, we need to mark the register being used by the loop so that
            // reload to that register will not be hoisted out of the loop
            this->linearScan->RecordLoopUse(nullptr, (RegNum)regIndex);
        }
    }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AggregateCopyPropagation::IterateToFixedpoint() {
    // We use an iterative data-flow algorithm to propagate the copies
    // that are available on entry of each block. Add the blocks
    // in reverse-postorder, this minimizes the number of iterations.
    StaticList<Block*, 64> worklist;
    SparseBitVector inWorklist;

    CFGInfo<Block, Function> cfgInfo(funct_->FirstBlock(), false);
    auto& postorderList = cfgInfo.PostorderList();
    int copyCount = infoList_.Count();

    // Add all blocks to the worklist.
    for(int i = 0; i < postorderList.Count(); i++) {
        auto block = const_cast<Block*>(postorderList[i]);
        worklist.Add(block);
        inWorklist.SetBit(block->Id());
    }

    while(worklist.IsNotEmpty()) {
        // Extract a block from the worklist.
        auto block = worklist.RemoveLast();
        inWorklist.ResetBit(block->Id());

        // Compute the 'in' set, which is the intersection
        // out the 'out' sets of the predecessors.
        BitVector inSet(copyCount, false);
        auto predecessorEnum = block->GetPredecessorEnum();
        bool first = true;

        while(predecessorEnum.IsValid()) {
            auto predecessorBlock = predecessorEnum.Next();

            if(first) {
                inSet = outSets_[predecessorBlock];
                first = false;
            }
            else inSet.And(outSets_[predecessorBlock]);
        }

        // Save the 'in' set, it's needed later
        // when we want to eliminate the copies.
        inSets_.Add(block, inSet);

        // Now compute the new 'out' set, which is the union of the 'copy' set
        // with the 'in' set, from which the 'kill' set has been subtracted.
        // Out(B) = Copy(B) U (In(B) - Kill(B))
        BitVector outSet = copySets_[block];
        inSet.Difference(killSets_[block]);
        outSet.Or(inSet);

        if(outSets_[block] != outSet) {
            // The 'out' set must be updated, and all successors
            // must be added to the worklist and reprocessed.
            outSets_[block] = outSet;

            auto successorEnum = block->GetSuccessorEnum();

            while(successorEnum.IsValid()) {
                auto successorBlock = successorEnum.Next();

                if(inWorklist.IsSet(successorBlock->Id()) == false) {
                    worklist.Add(successorBlock);
                    inWorklist.IsSet(successorBlock->Id());
                }
            }
        }
    }
}