当前位置: 首页>>代码示例>>C++>>正文


C++ LaneBitmask类代码示例

本文整理汇总了C++中LaneBitmask的典型用法代码示例。如果您正苦于以下问题:C++ LaneBitmask类的具体用法?C++ LaneBitmask怎么用?C++ LaneBitmask使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了LaneBitmask类的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: setRegUsed

void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
  for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
    LaneBitmask UnitMask = (*RUI).second;
    if (UnitMask.none() || (LaneMask & UnitMask).any())
      RegUnitsAvailable.reset((*RUI).first);
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:7,代码来源:RegisterScavenging.cpp

示例2: refineSubRanges

void LiveInterval::refineSubRanges(BumpPtrAllocator &Allocator,
    LaneBitmask LaneMask, std::function<void(LiveInterval::SubRange&)> Apply) {
  LaneBitmask ToApply = LaneMask;
  for (SubRange &SR : subranges()) {
    LaneBitmask SRMask = SR.LaneMask;
    LaneBitmask Matching = SRMask & LaneMask;
    if (Matching.none())
      continue;

    SubRange *MatchingRange;
    if (SRMask == Matching) {
      // The subrange fits (it does not cover bits outside \p LaneMask).
      MatchingRange = &SR;
    } else {
      // We have to split the subrange into a matching and non-matching part.
      // Reduce lanemask of existing lane to non-matching part.
      SR.LaneMask = SRMask & ~Matching;
      // Create a new subrange for the matching part
      MatchingRange = createSubRangeFrom(Allocator, Matching, SR);
    }
    Apply(*MatchingRange);
    ToApply &= ~Matching;
  }
  // Create a new subrange if there are uncovered bits left.
  if (ToApply.any()) {
    SubRange *NewRange = createSubRange(Allocator, ToApply);
    Apply(*NewRange);
  }
}
开发者ID:bkaradzic,项目名称:SwiftShader,代码行数:29,代码来源:LiveInterval.cpp

示例3: increaseSetPressure

/// Increase pressure for each pressure set provided by TargetRegisterInfo.
static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
                                const MachineRegisterInfo &MRI, unsigned Reg,
                                LaneBitmask PrevMask, LaneBitmask NewMask) {
  assert((PrevMask & ~NewMask).none() && "Must not remove bits");
  if (PrevMask.any() || NewMask.none())
    return;

  PSetIterator PSetI = MRI.getPressureSets(Reg);
  unsigned Weight = PSetI.getWeight();
  for (; PSetI.isValid(); ++PSetI)
    CurrSetPressure[*PSetI] += Weight;
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:13,代码来源:RegisterPressure.cpp

示例4: assert

/// Advance across the current instruction.
void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
  assert(!TrackUntiedDefs && "unsupported mode");
  assert(CurrPos != MBB->end());
  if (!isTopClosed())
    closeTop();

  SlotIndex SlotIdx;
  if (RequireIntervals)
    SlotIdx = getCurrSlot();

  // Open the bottom of the region using slot indexes.
  if (isBottomClosed()) {
    if (RequireIntervals)
      static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
    else
      static_cast<RegionPressure&>(P).openBottom(CurrPos);
  }

  for (const RegisterMaskPair &Use : RegOpers.Uses) {
    unsigned Reg = Use.RegUnit;
    LaneBitmask LiveMask = LiveRegs.contains(Reg);
    LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
    if (LiveIn.any()) {
      discoverLiveIn(RegisterMaskPair(Reg, LiveIn));
      increaseRegPressure(Reg, LiveMask, LiveMask | LiveIn);
      LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
    }
    // Kill liveness at last uses.
    if (RequireIntervals) {
      LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
      if (LastUseMask.any()) {
        LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
        decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
      }
    }
  }

  // Generate liveness for defs.
  for (const RegisterMaskPair &Def : RegOpers.Defs) {
    LaneBitmask PreviousMask = LiveRegs.insert(Def);
    LaneBitmask NewMask = PreviousMask | Def.LaneMask;
    increaseRegPressure(Def.RegUnit, PreviousMask, NewMask);
  }

  // Boost pressure for all dead defs together.
  bumpDeadDefs(RegOpers.DeadDefs);

  // Find the next instruction.
  CurrPos = skipDebugInstructionsForward(std::next(CurrPos), MBB->end());
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:51,代码来源:RegisterPressure.cpp

示例5: decreaseSetPressure

/// Decrease pressure for each pressure set provided by TargetRegisterInfo.
static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
                                const MachineRegisterInfo &MRI, unsigned Reg,
                                LaneBitmask PrevMask, LaneBitmask NewMask) {
  //assert((NewMask & !PrevMask) == 0 && "Must not add bits");
  if (NewMask.any() || PrevMask.none())
    return;

  PSetIterator PSetI = MRI.getPressureSets(Reg);
  unsigned Weight = PSetI.getWeight();
  for (; PSetI.isValid(); ++PSetI) {
    assert(CurrSetPressure[*PSetI] >= Weight && "register pressure underflow");
    CurrSetPressure[*PSetI] -= Weight;
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:15,代码来源:RegisterPressure.cpp

示例6: increaseRegPressure

void RegPressureTracker::increaseRegPressure(unsigned RegUnit,
                                             LaneBitmask PreviousMask,
                                             LaneBitmask NewMask) {
  if (PreviousMask.any() || NewMask.none())
    return;

  PSetIterator PSetI = MRI->getPressureSets(RegUnit);
  unsigned Weight = PSetI.getWeight();
  for (; PSetI.isValid(); ++PSetI) {
    CurrSetPressure[*PSetI] += Weight;
    P.MaxSetPressure[*PSetI] =
        std::max(P.MaxSetPressure[*PSetI], CurrSetPressure[*PSetI]);
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:14,代码来源:RegisterPressure.cpp

示例7: extendToUses

void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask,
                                 LiveInterval *LI) {
  SmallVector<SlotIndex, 4> Undefs;
  if (LI != nullptr)
    LI->computeSubRangeUndefs(Undefs, Mask, *MRI, *Indexes);

  // Visit all operands that read Reg. This may include partial defs.
  bool IsSubRange = !Mask.all();
  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
  for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    // Clear all kill flags. They will be reinserted after register allocation
    // by LiveIntervals::addKillFlags().
    if (MO.isUse())
      MO.setIsKill(false);
    // MO::readsReg returns "true" for subregister defs. This is for keeping
    // liveness of the entire register (i.e. for the main range of the live
    // interval). For subranges, definitions of non-overlapping subregisters
    // do not count as uses.
    if (!MO.readsReg() || (IsSubRange && MO.isDef()))
      continue;

    unsigned SubReg = MO.getSubReg();
    if (SubReg != 0) {
      LaneBitmask SLM = TRI.getSubRegIndexLaneMask(SubReg);
      if (MO.isDef())
        SLM = ~SLM;
      // Ignore uses not reading the current (sub)range.
      if ((SLM & Mask).none())
        continue;
    }

    // Determine the actual place of the use.
    const MachineInstr *MI = MO.getParent();
    unsigned OpNo = (&MO - &MI->getOperand(0));
    SlotIndex UseIdx;
    if (MI->isPHI()) {
      assert(!MO.isDef() && "Cannot handle PHI def of partial register.");
      // The actual place where a phi operand is used is the end of the pred
      // MBB. PHI operands are paired: (Reg, PredMBB).
      UseIdx = Indexes->getMBBEndIdx(MI->getOperand(OpNo+1).getMBB());
    } else {
      // Check for early-clobber redefs.
      bool isEarlyClobber = false;
      unsigned DefIdx;
      if (MO.isDef())
        isEarlyClobber = MO.isEarlyClobber();
      else if (MI->isRegTiedToDefOperand(OpNo, &DefIdx)) {
        // FIXME: This would be a lot easier if tied early-clobber uses also
        // had an early-clobber flag.
        isEarlyClobber = MI->getOperand(DefIdx).isEarlyClobber();
      }
      UseIdx = Indexes->getInstructionIndex(*MI).getRegSlot(isEarlyClobber);
    }

    // MI is reading Reg. We may have visited MI before if it happens to be
    // reading Reg multiple times. That is OK, extend() is idempotent.
    extend(LR, UseIdx, Reg, Undefs);
  }
}
开发者ID:BNieuwenhuizen,项目名称:llvm,代码行数:59,代码来源:LiveRangeCalc.cpp

示例8: assert

void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
                                             unsigned PhysReg) const {
  assert(!LI.empty());
  assert(LI.hasSubRanges());

  using SubRangeIteratorPair =
      std::pair<const LiveInterval::SubRange *, LiveInterval::const_iterator>;

  SmallVector<SubRangeIteratorPair, 4> SubRanges;
  SlotIndex First;
  SlotIndex Last;
  for (const LiveInterval::SubRange &SR : LI.subranges()) {
    SubRanges.push_back(std::make_pair(&SR, SR.begin()));
    if (!First.isValid() || SR.segments.front().start < First)
      First = SR.segments.front().start;
    if (!Last.isValid() || SR.segments.back().end > Last)
      Last = SR.segments.back().end;
  }

  // Check all mbb start positions between First and Last while
  // simulatenously advancing an iterator for each subrange.
  for (SlotIndexes::MBBIndexIterator MBBI = Indexes->findMBBIndex(First);
       MBBI != Indexes->MBBIndexEnd() && MBBI->first <= Last; ++MBBI) {
    SlotIndex MBBBegin = MBBI->first;
    // Advance all subrange iterators so that their end position is just
    // behind MBBBegin (or the iterator is at the end).
    LaneBitmask LaneMask;
    for (auto &RangeIterPair : SubRanges) {
      const LiveInterval::SubRange *SR = RangeIterPair.first;
      LiveInterval::const_iterator &SRI = RangeIterPair.second;
      while (SRI != SR->end() && SRI->end <= MBBBegin)
        ++SRI;
      if (SRI == SR->end())
        continue;
      if (SRI->start <= MBBBegin)
        LaneMask |= SR->LaneMask;
    }
    if (LaneMask.none())
      continue;
    MachineBasicBlock *MBB = MBBI->second;
    MBB->addLiveIn(PhysReg, LaneMask);
  }
}
开发者ID:bkaradzic,项目名称:SwiftShader,代码行数:43,代码来源:VirtRegMap.cpp

示例9: inc

void GCNRegPressure::inc(unsigned Reg,
                         LaneBitmask PrevMask,
                         LaneBitmask NewMask,
                         const MachineRegisterInfo &MRI) {
  if (NewMask == PrevMask)
    return;

  int Sign = 1;
  if (NewMask < PrevMask) {
    std::swap(NewMask, PrevMask);
    Sign = -1;
  }
#ifndef NDEBUG
  const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
#endif
  switch (auto Kind = getRegKind(Reg, MRI)) {
  case SGPR32:
  case VGPR32:
    assert(PrevMask.none() && NewMask == MaxMask);
    Value[Kind] += Sign;
    break;

  case SGPR_TUPLE:
  case VGPR_TUPLE:
    assert(NewMask < MaxMask || NewMask == MaxMask);
    assert(PrevMask < NewMask);

    Value[Kind == SGPR_TUPLE ? SGPR32 : VGPR32] +=
      Sign * (~PrevMask & NewMask).getNumLanes();

    if (PrevMask.none()) {
      assert(NewMask.any());
      Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
    }
    break;

  default: llvm_unreachable("Unknown register kind");
  }
}
开发者ID:dongjinxian,项目名称:llvm,代码行数:39,代码来源:GCNRegPressure.cpp

示例10: findUseBetween

/// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
/// The query starts with a lane bitmask which gets lanes/bits removed for every
/// use we find.
static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
                                  SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
                                  const MachineRegisterInfo &MRI,
                                  const LiveIntervals *LIS) {
  const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
  for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
    if (MO.isUndef())
      continue;
    const MachineInstr *MI = MO.getParent();
    SlotIndex InstSlot = LIS->getInstructionIndex(*MI).getRegSlot();
    if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx) {
      unsigned SubRegIdx = MO.getSubReg();
      LaneBitmask UseMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
      LastUseMask &= ~UseMask;
      if (LastUseMask.none())
        return LaneBitmask::getNone();
    }
  }
  return LastUseMask;
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:23,代码来源:RegisterPressure.cpp

示例11: getLiveLanesAt

void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
                                          const MachineRegisterInfo &MRI,
                                          SlotIndex Pos,
                                          MachineInstr *AddFlagsMI) {
  for (auto I = Defs.begin(); I != Defs.end(); ) {
    LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
                                           Pos.getDeadSlot());
    // If the the def is all that is live after the instruction, then in case
    // of a subregister def we need a read-undef flag.
    unsigned RegUnit = I->RegUnit;
    if (TargetRegisterInfo::isVirtualRegister(RegUnit) &&
        AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask).none())
      AddFlagsMI->setRegisterDefReadUndef(RegUnit);

    LaneBitmask ActualDef = I->LaneMask & LiveAfter;
    if (ActualDef.none()) {
      I = Defs.erase(I);
    } else {
      I->LaneMask = ActualDef;
      ++I;
    }
  }
  for (auto I = Uses.begin(); I != Uses.end(); ) {
    LaneBitmask LiveBefore = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
                                            Pos.getBaseIndex());
    LaneBitmask LaneMask = I->LaneMask & LiveBefore;
    if (LaneMask.none()) {
      I = Uses.erase(I);
    } else {
      I->LaneMask = LaneMask;
      ++I;
    }
  }
  if (AddFlagsMI != nullptr) {
    for (const RegisterMaskPair &P : DeadDefs) {
      unsigned RegUnit = P.RegUnit;
      if (!TargetRegisterInfo::isVirtualRegister(RegUnit))
        continue;
      LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
                                             Pos.getDeadSlot());
      if (LiveAfter.none())
        AddFlagsMI->setRegisterDefReadUndef(RegUnit);
    }
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:45,代码来源:RegisterPressure.cpp

示例12: assert

void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM,
      LiveRange &Range) {
  assert(TargetRegisterInfo::isVirtualRegister(Reg));
  if (Range.empty())
    return;

  // Return two booleans: { def-modifes-reg, def-covers-reg }.
  auto IsRegDef = [this,Reg,LM] (MachineOperand &Op) -> std::pair<bool,bool> {
    if (!Op.isReg() || !Op.isDef())
      return { false, false };
    unsigned DR = Op.getReg(), DSR = Op.getSubReg();
    if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg)
      return { false, false };
    LaneBitmask SLM = getLaneMask(DR, DSR);
    LaneBitmask A = SLM & LM;
    return { A.any(), A == SLM };
  };

  // The splitting step will create pairs of predicated definitions without
  // any implicit uses (since implicit uses would interfere with predication).
  // This can cause the reaching defs to become dead after live range
  // recomputation, even though they are not really dead.
  // We need to identify predicated defs that need implicit uses, and
  // dead defs that are not really dead, and correct both problems.

  auto Dominate = [this] (SetVector<MachineBasicBlock*> &Defs,
                          MachineBasicBlock *Dest) -> bool {
    for (MachineBasicBlock *D : Defs)
      if (D != Dest && MDT->dominates(D, Dest))
        return true;

    MachineBasicBlock *Entry = &Dest->getParent()->front();
    SetVector<MachineBasicBlock*> Work(Dest->pred_begin(), Dest->pred_end());
    for (unsigned i = 0; i < Work.size(); ++i) {
      MachineBasicBlock *B = Work[i];
      if (Defs.count(B))
        continue;
      if (B == Entry)
        return false;
      for (auto *P : B->predecessors())
        Work.insert(P);
    }
    return true;
  };

  // First, try to extend live range within individual basic blocks. This
  // will leave us only with dead defs that do not reach any predicated
  // defs in the same block.
  SetVector<MachineBasicBlock*> Defs;
  SmallVector<SlotIndex,4> PredDefs;
  for (auto &Seg : Range) {
    if (!Seg.start.isRegister())
      continue;
    MachineInstr *DefI = LIS->getInstructionFromIndex(Seg.start);
    Defs.insert(DefI->getParent());
    if (HII->isPredicated(*DefI))
      PredDefs.push_back(Seg.start);
  }

  SmallVector<SlotIndex,8> Undefs;
  LiveInterval &LI = LIS->getInterval(Reg);
  LI.computeSubRangeUndefs(Undefs, LM, *MRI, *LIS->getSlotIndexes());

  for (auto &SI : PredDefs) {
    MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
    auto P = Range.extendInBlock(Undefs, LIS->getMBBStartIdx(BB), SI);
    if (P.first != nullptr || P.second)
      SI = SlotIndex();
  }

  // Calculate reachability for those predicated defs that were not handled
  // by the in-block extension.
  SmallVector<SlotIndex,4> ExtTo;
  for (auto &SI : PredDefs) {
    if (!SI.isValid())
      continue;
    MachineBasicBlock *BB = LIS->getMBBFromIndex(SI);
    if (BB->pred_empty())
      continue;
    // If the defs from this range reach SI via all predecessors, it is live.
    // It can happen that SI is reached by the defs through some paths, but
    // not all. In the IR coming into this optimization, SI would not be
    // considered live, since the defs would then not jointly dominate SI.
    // That means that SI is an overwriting def, and no implicit use is
    // needed at this point. Do not add SI to the extension points, since
    // extendToIndices will abort if there is no joint dominance.
    // If the abort was avoided by adding extra undefs added to Undefs,
    // extendToIndices could actually indicate that SI is live, contrary
    // to the original IR.
    if (Dominate(Defs, BB))
      ExtTo.push_back(SI);
  }

  if (!ExtTo.empty())
    LIS->extendToIndices(Range, ExtTo, Undefs);

  // Remove <dead> flags from all defs that are not dead after live range
  // extension, and collect all def operands. They will be used to generate
  // the necessary implicit uses.
  // At the same time, add <dead> flag to all defs that are actually dead.
//.........这里部分代码省略.........
开发者ID:Leedehai,项目名称:llvm,代码行数:101,代码来源:HexagonExpandCondsets.cpp

示例13: assert

void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
  assert(MRI && Indexes && "call reset() first");

  // Step 1: Create minimal live segments for every definition of Reg.
  // Visit all def operands. If the same instruction has multiple defs of Reg,
  // createDeadDef() will deduplicate.
  const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
  unsigned Reg = LI.reg;
  for (const MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
    if (!MO.isDef() && !MO.readsReg())
      continue;

    unsigned SubReg = MO.getSubReg();
    if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) {
      LaneBitmask SubMask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg)
                                        : MRI->getMaxLaneMaskForVReg(Reg);
      // If this is the first time we see a subregister def, initialize
      // subranges by creating a copy of the main range.
      if (!LI.hasSubRanges() && !LI.empty()) {
        LaneBitmask ClassMask = MRI->getMaxLaneMaskForVReg(Reg);
        LI.createSubRangeFrom(*Alloc, ClassMask, LI);
      }

      LaneBitmask Mask = SubMask;
      for (LiveInterval::SubRange &S : LI.subranges()) {
        // A Mask for subregs common to the existing subrange and current def.
        LaneBitmask Common = S.LaneMask & Mask;
        if (Common.none())
          continue;
        LiveInterval::SubRange *CommonRange;
        // A Mask for subregs covered by the subrange but not the current def.
        LaneBitmask RM = S.LaneMask & ~Mask;
        if (RM.any()) {
          // Split the subrange S into two parts: one covered by the current
          // def (CommonRange), and the one not affected by it (updated S).
          S.LaneMask = RM;
          CommonRange = LI.createSubRangeFrom(*Alloc, Common, S);
        } else {
          assert(Common == S.LaneMask);
          CommonRange = &S;
        }
        if (MO.isDef())
          createDeadDef(*Indexes, *Alloc, *CommonRange, MO);
        Mask &= ~Common;
      }
      // Create a new SubRange for subregs we did not cover yet.
      if (Mask.any()) {
        LiveInterval::SubRange *NewRange = LI.createSubRange(*Alloc, Mask);
        if (MO.isDef())
          createDeadDef(*Indexes, *Alloc, *NewRange, MO);
      }
    }

    // Create the def in the main liverange. We do not have to do this if
    // subranges are tracked as we recreate the main range later in this case.
    if (MO.isDef() && !LI.hasSubRanges())
      createDeadDef(*Indexes, *Alloc, LI, MO);
  }

  // We may have created empty live ranges for partially undefined uses, we
  // can't keep them because we won't find defs in them later.
  LI.removeEmptySubRanges();

  // Step 2: Extend live segments to all uses, constructing SSA form as
  // necessary.
  if (LI.hasSubRanges()) {
    for (LiveInterval::SubRange &S : LI.subranges()) {
      LiveRangeCalc SubLRC;
      SubLRC.reset(MF, Indexes, DomTree, Alloc);
      SubLRC.extendToUses(S, Reg, S.LaneMask, &LI);
    }
    LI.clear();
    constructMainRangeFromSubranges(LI);
  } else {
    resetLiveOutMap();
    extendToUses(LI, Reg, LaneBitmask::getAll());
  }
}
开发者ID:AstroVPK,项目名称:LLVM-4.0.0,代码行数:78,代码来源:LiveRangeCalc.cpp

示例14: DRs

void Liveness::computePhiInfo() {
  RealUseMap.clear();

  NodeList Phis;
  NodeAddr<FuncNode*> FA = DFG.getFunc();
  NodeList Blocks = FA.Addr->members(DFG);
  for (NodeAddr<BlockNode*> BA : Blocks) {
    auto Ps = BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG);
    Phis.insert(Phis.end(), Ps.begin(), Ps.end());
  }

  // phi use -> (map: reaching phi -> set of registers defined in between)
  std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
  std::vector<NodeId> PhiUQ;  // Work list of phis for upward propagation.
  std::map<NodeId,RegisterAggr> PhiDRs;  // Phi -> registers defined by it.

  // Go over all phis.
  for (NodeAddr<PhiNode*> PhiA : Phis) {
    // Go over all defs and collect the reached uses that are non-phi uses
    // (i.e. the "real uses").
    RefMap &RealUses = RealUseMap[PhiA.Id];
    NodeList PhiRefs = PhiA.Addr->members(DFG);

    // Have a work queue of defs whose reached uses need to be found.
    // For each def, add to the queue all reached (non-phi) defs.
    SetVector<NodeId> DefQ;
    NodeSet PhiDefs;
    RegisterAggr DRs(PRI);
    for (NodeAddr<RefNode*> R : PhiRefs) {
      if (!DFG.IsRef<NodeAttrs::Def>(R))
        continue;
      DRs.insert(R.Addr->getRegRef(DFG));
      DefQ.insert(R.Id);
      PhiDefs.insert(R.Id);
    }
    PhiDRs.insert(std::make_pair(PhiA.Id, DRs));

    // Collect the super-set of all possible reached uses. This set will
    // contain all uses reached from this phi, either directly from the
    // phi defs, or (recursively) via non-phi defs reached by the phi defs.
    // This set of uses will later be trimmed to only contain these uses that
    // are actually reached by the phi defs.
    for (unsigned i = 0; i < DefQ.size(); ++i) {
      NodeAddr<DefNode*> DA = DFG.addr<DefNode*>(DefQ[i]);
      // Visit all reached uses. Phi defs should not really have the "dead"
      // flag set, but check it anyway for consistency.
      bool IsDead = DA.Addr->getFlags() & NodeAttrs::Dead;
      NodeId UN = !IsDead ? DA.Addr->getReachedUse() : 0;
      while (UN != 0) {
        NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
        uint16_t F = A.Addr->getFlags();
        if ((F & (NodeAttrs::Undef | NodeAttrs::PhiRef)) == 0) {
          RegisterRef R = PRI.normalize(A.Addr->getRegRef(DFG));
          RealUses[R.Reg].insert({A.Id,R.Mask});
        }
        UN = A.Addr->getSibling();
      }
      // Visit all reached defs, and add them to the queue. These defs may
      // override some of the uses collected here, but that will be handled
      // later.
      NodeId DN = DA.Addr->getReachedDef();
      while (DN != 0) {
        NodeAddr<DefNode*> A = DFG.addr<DefNode*>(DN);
        for (auto T : DFG.getRelatedRefs(A.Addr->getOwner(DFG), A)) {
          uint16_t Flags = NodeAddr<DefNode*>(T).Addr->getFlags();
          // Must traverse the reached-def chain. Consider:
          //   def(D0) -> def(R0) -> def(R0) -> use(D0)
          // The reachable use of D0 passes through a def of R0.
          if (!(Flags & NodeAttrs::PhiRef))
            DefQ.insert(T.Id);
        }
        DN = A.Addr->getSibling();
      }
    }
    // Filter out these uses that appear to be reachable, but really
    // are not. For example:
    //
    // R1:0 =          d1
    //      = R1:0     u2     Reached by d1.
    //   R0 =          d3
    //      = R1:0     u4     Still reached by d1: indirectly through
    //                        the def d3.
    //   R1 =          d5
    //      = R1:0     u6     Not reached by d1 (covered collectively
    //                        by d3 and d5), but following reached
    //                        defs and uses from d1 will lead here.
    for (auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
      // For each reached register UI->first, there is a set UI->second, of
      // uses of it. For each such use, check if it is reached by this phi,
      // i.e. check if the set of its reaching uses intersects the set of
      // this phi's defs.
      NodeRefSet Uses = UI->second;
      UI->second.clear();
      for (std::pair<NodeId,LaneBitmask> I : Uses) {
        auto UA = DFG.addr<UseNode*>(I.first);
        // Undef flag is checked above.
        assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0);
        RegisterRef R(UI->first, I.second);
        // Calculate the exposed part of the reached use.
        RegisterAggr Covered(PRI);
//.........这里部分代码省略.........
开发者ID:BNieuwenhuizen,项目名称:llvm,代码行数:101,代码来源:RDFLiveness.cpp


注:本文中的LaneBitmask类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。