예제 #1
0
//
// Synthesize missing register class intersections.
//
// Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X)
// returns a maximal register class for all X.
//
void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
  for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
    CodeGenRegisterClass *RC1 = RC;
    CodeGenRegisterClass *RC2 = RegClasses[rci];
    if (RC1 == RC2)
      continue;

    // Compute the set intersection of RC1 and RC2.
    const CodeGenRegister::Set &Memb1 = RC1->getMembers();
    const CodeGenRegister::Set &Memb2 = RC2->getMembers();
    CodeGenRegister::Set Intersection;
    std::set_intersection(Memb1.begin(), Memb1.end(),
                          Memb2.begin(), Memb2.end(),
                          std::inserter(Intersection, Intersection.begin()),
                          CodeGenRegister::Less());

    // Skip disjoint class pairs.
    if (Intersection.empty())
      continue;

    // If RC1 and RC2 have different spill sizes or alignments, use the
    // larger size for sub-classing.  If they are equal, prefer RC1.
    if (RC2->SpillSize > RC1->SpillSize ||
        (RC2->SpillSize == RC1->SpillSize &&
         RC2->SpillAlignment > RC1->SpillAlignment))
      std::swap(RC1, RC2);

    getOrCreateSubClass(RC1, &Intersection,
                        RC1->getName() + "_and_" + RC2->getName());
  }
}
예제 #2
0
void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
                                                unsigned FirstSubRegRC) {
  SmallVector<std::pair<const CodeGenRegister*,
                        const CodeGenRegister*>, 16> SSPairs;

  // Iterate in SubRegIndex numerical order to visit synthetic indices last.
  for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
    Record *SubIdx = SubRegIndices[sri];
    // Skip indexes that aren't fully supported by RC's registers. This was
    // computed by inferSubClassWithSubReg() above which should have been
    // called first.
    if (RC->getSubClassWithSubReg(SubIdx) != RC)
      continue;

    // Build list of (Super, Sub) pairs for this SubIdx.
    SSPairs.clear();
    for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
         RE = RC->getMembers().end(); RI != RE; ++RI) {
      const CodeGenRegister *Super = *RI;
      const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
      assert(Sub && "Missing sub-register");
      SSPairs.push_back(std::make_pair(Super, Sub));
    }

    // Iterate over sub-register class candidates.  Ignore classes created by
    // this loop. They will never be useful.
    for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
         ++rci) {
      CodeGenRegisterClass *SubRC = RegClasses[rci];
      // Compute the subset of RC that maps into SubRC.
      CodeGenRegister::Set SubSet;
      for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
        if (SubRC->contains(SSPairs[i].second))
          SubSet.insert(SSPairs[i].first);
      if (SubSet.empty())
        continue;
      // RC injects completely into SubRC.
      if (SubSet.size() == SSPairs.size()) {
        SubRC->addSuperRegClass(SubIdx, RC);
        continue;
      }
      // Only a subset of RC maps into SubRC. Make sure it is represented by a
      // class.
      getOrCreateSubClass(RC, &SubSet, RC->getName() +
                          "_with_" + SubIdx->getName() +
                          "_in_" + SubRC->getName());
    }
  }
}