[llvm-commits] [llvm] r154374 - in /llvm/trunk/utils/TableGen: CodeGenRegisters.cpp CodeGenRegisters.h RegisterInfoEmitter.cpp RegisterInfoEmitter.h

Francois Pichet pichet2000 at gmail.com
Tue Apr 10 16:40:36 PDT 2012


On Mon, Apr 9, 2012 at 10:25 PM, Andrew Trick <atrick at apple.com> wrote:
> Author: atrick
> Date: Mon Apr  9 21:25:24 2012
> New Revision: 154374
>
> URL: http://llvm.org/viewvc/llvm-project?rev=154374&view=rev
> Log:
> Added register unit sets to the target description.
>
> This is a new algorithm that finds sets of register units that can be
> used to model registers pressure. This handles arbitrary, overlapping
> register classes. Each register class is associated with a (small)
> list of pressure sets. These are the dimensions of pressure affected
> by the register class's liveness.
>
> Modified:
>    llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
>    llvm/trunk/utils/TableGen/CodeGenRegisters.h
>    llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
>    llvm/trunk/utils/TableGen/RegisterInfoEmitter.h
>
> Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=154374&r1=154373&r2=154374&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original)
> +++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Mon Apr  9 21:25:24 2012
> @@ -1118,6 +1118,169 @@
>   }
>  }
>
> +// Find a set in UniqueSets with the same elements as Set.
> +// Return an iterator into UniqueSets.
> +static std::vector<RegUnitSet>::const_iterator
> +findRegUnitSet(const std::vector<RegUnitSet> &UniqueSets,
> +               const RegUnitSet &Set) {
> +  std::vector<RegUnitSet>::const_iterator
> +    I = UniqueSets.begin(), E = UniqueSets.end();
> +  for(;I != E; ++I) {
> +    if (I->Units == Set.Units)
> +      break;
> +  }
> +  return I;
> +}
> +
> +// Return true if the RUSubSet is a subset of RUSuperSet.
> +static bool isRegUnitSubSet(const std::vector<unsigned> &RUSubSet,
> +                            const std::vector<unsigned> &RUSuperSet) {
> +  for (RegUnitSet::iterator SubIdx = RUSubSet.begin(), EndIdx = RUSubSet.end(),
> +         SearchIdx = RUSuperSet.begin(), SearchEnd = RUSuperSet.end();
> +       SubIdx != EndIdx; ++SubIdx) {
> +    SearchIdx = find(SearchIdx, SearchEnd, *SubIdx);
> +    if (SearchIdx == SearchEnd)
> +      return false;
> +    ++SearchIdx;
> +  }
> +  return true;
> +}
> +
> +// Iteratively prune unit sets.
> +void CodeGenRegBank::pruneUnitSets() {
> +  assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets");
> +
> +  // Form an equivalence class of UnitSets with no significant difference.
> +  IntEqClasses RepUnitSetIDs(RegUnitSets.size());
> +  for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size();
> +       SubIdx != EndIdx; ++SubIdx) {
> +    const RegUnitSet &SubSet = RegUnitSets[SubIdx];
> +    for (unsigned SuperIdx = 0; SuperIdx != EndIdx; ++SuperIdx) {
> +      if (SuperIdx == SubIdx)
> +        continue;
> +
> +      const RegUnitSet &SuperSet = RegUnitSets[SuperIdx];
> +      if (isRegUnitSubSet(SubSet.Units, SuperSet.Units)
> +          && (SubSet.Units.size() + 3 > SuperSet.Units.size())) {
> +        RepUnitSetIDs.join(SubIdx, SuperIdx);
> +      }
> +    }
> +  }
> +  RepUnitSetIDs.compress();
> +
> +  // Populate PrunedUnitSets with each equivalence class's superset.
> +  std::vector<RegUnitSet> PrunedUnitSets(RepUnitSetIDs.getNumClasses());
> +  for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) {
> +    RegUnitSet &SuperSet = PrunedUnitSets[RepUnitSetIDs[i]];
> +    if (SuperSet.Units.size() < RegUnitSets[i].Units.size())
> +      SuperSet = RegUnitSets[i];
> +  }
> +  RegUnitSets.swap(PrunedUnitSets);
> +}
> +
> +// Create a RegUnitSet for each RegClass that contains all units in the class
> +// including adopted units that are necessary to model register pressure. Then
> +// iteratively compute RegUnitSets such that the union of any two overlapping
> +// RegUnitSets is repreresented.
> +//
> +// RegisterInfoEmitter will map each RegClass to its RegUnitClass and any
> +// RegUnitSet that is a superset of that RegUnitClass.
> +void CodeGenRegBank::computeRegUnitSets() {
> +
> +  // Compute a unique RegUnitSet for each RegClass.
> +  const ArrayRef<CodeGenRegisterClass*> &RegClasses = getRegClasses();
> +  unsigned NumRegClasses = RegClasses.size();
> +  for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
> +
> +    // Compute a sorted list of units in this class.
> +    std::vector<unsigned> RegUnits;
> +    const CodeGenRegister::Set &Regs = RegClasses[RCIdx]->getMembers();
> +    for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI)
> +      RegUnits.push_back(*UnitI);
> +    std::sort(RegUnits.begin(), RegUnits.end());
> +
> +    // Speculatively grow the RegUnitSets to hold the new set.
> +    RegUnitSets.resize(RegUnitSets.size() + 1);
> +    RegUnitSets.back().Name = RegClasses[RCIdx]->getName();
> +    std::unique_copy(RegUnits.begin(), RegUnits.end(),
> +                     std::back_inserter(RegUnitSets.back().Units));
> +
> +    // Find an existing RegUnitSet.
> +    std::vector<RegUnitSet>::const_iterator SetI =
> +      findRegUnitSet(RegUnitSets, RegUnitSets.back());
> +    if (SetI != llvm::prior(RegUnitSets.end()))
> +      RegUnitSets.pop_back();
> +  }
> +
> +  // Iteratively prune unit sets.
> +  pruneUnitSets();
> +
> +  // Iterate over all unit sets, including new ones added by this loop.
> +  unsigned NumRegUnitSubSets = RegUnitSets.size();
> +  for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
> +    // In theory, this is combinatorial. In practice, it needs to be bounded
> +    // by a small number of sets for regpressure to be efficient.
> +    // If the assert is hit, we need to implement pruning.
> +    assert(Idx < (2*NumRegUnitSubSets) && "runaway unit set inference");
> +
> +    // Compare new sets with all original classes.
> +    for (unsigned SearchIdx = (SearchIdx >= NumRegUnitSubSets) ? 0 : Idx+1;
> +         SearchIdx != EndIdx; ++SearchIdx) {

This doesn't look right; MSVC warning:

4>c:\dev\llvm\llvm_trunk2\utils\tablegen\codegenregisters.cpp(1225):
warning C4700: uninitialized local variable 'SearchIdx' used




More information about the llvm-commits mailing list