1 //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines structures to encapsulate information gleaned from the 11 // target register and register class definitions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef CODEGEN_REGISTERS_H 16 #define CODEGEN_REGISTERS_H 17 18 #include "SetTheory.h" 19 #include "llvm/TableGen/Record.h" 20 #include "llvm/CodeGen/ValueTypes.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/BitVector.h" 23 #include "llvm/ADT/DenseMap.h" 24 #include "llvm/ADT/SetVector.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include <cstdlib> 27 #include <map> 28 #include <string> 29 #include <set> 30 #include <vector> 31 32 namespace llvm { 33 class CodeGenRegBank; 34 35 /// CodeGenSubRegIndex - Represents a sub-register index. 36 class CodeGenSubRegIndex { 37 Record *const TheDef; 38 39 public: 40 const unsigned EnumValue; 41 42 CodeGenSubRegIndex(Record *R, unsigned Enum); 43 44 const std::string &getName() const; 45 std::string getNamespace() const; 46 std::string getQualifiedName() const; 47 48 // Order CodeGenSubRegIndex pointers by EnumValue. 49 struct Less { 50 bool operator()(const CodeGenSubRegIndex *A, 51 const CodeGenSubRegIndex *B) const { 52 assert(A && B); 53 return A->EnumValue < B->EnumValue; 54 } 55 }; 56 57 // Map of composite subreg indices. 58 typedef std::map<CodeGenSubRegIndex*, CodeGenSubRegIndex*, Less> CompMap; 59 60 // Returns the subreg index that results from composing this with Idx. 61 // Returns NULL if this and Idx don't compose. 62 CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const { 63 CompMap::const_iterator I = Composed.find(Idx); 64 return I == Composed.end() ? 0 : I->second; 65 } 66 67 // Add a composite subreg index: this+A = B. 68 // Return a conflicting composite, or NULL 69 CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, 70 CodeGenSubRegIndex *B) { 71 assert(A && B); 72 std::pair<CompMap::iterator, bool> Ins = 73 Composed.insert(std::make_pair(A, B)); 74 return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second; 75 } 76 77 // Update the composite maps of components specified in 'ComposedOf'. 78 void updateComponents(CodeGenRegBank&); 79 80 // Clean out redundant composite mappings. 81 void cleanComposites(); 82 83 // Return the map of composites. 84 const CompMap &getComposites() const { return Composed; } 85 86 private: 87 CompMap Composed; 88 }; 89 90 /// CodeGenRegister - Represents a register definition. 91 struct CodeGenRegister { 92 Record *TheDef; 93 unsigned EnumValue; 94 unsigned CostPerUse; 95 bool CoveredBySubRegs; 96 97 // Map SubRegIndex -> Register. 98 typedef std::map<CodeGenSubRegIndex*, CodeGenRegister*, 99 CodeGenSubRegIndex::Less> SubRegMap; 100 101 CodeGenRegister(Record *R, unsigned Enum); 102 103 const std::string &getName() const; 104 105 // Extract more information from TheDef. This is used to build an object 106 // graph after all CodeGenRegister objects have been created. 107 void buildObjectGraph(CodeGenRegBank&); 108 109 // Lazily compute a map of all sub-registers. 110 // This includes unique entries for all sub-sub-registers. 111 const SubRegMap &computeSubRegs(CodeGenRegBank&); 112 113 // Compute extra sub-registers by combining the existing sub-registers. 114 void computeSecondarySubRegs(CodeGenRegBank&); 115 116 // Add this as a super-register to all sub-registers after the sub-register 117 // graph has been built. 118 void computeSuperRegs(CodeGenRegBank&); 119 120 const SubRegMap &getSubRegs() const { 121 assert(SubRegsComplete && "Must precompute sub-registers"); 122 return SubRegs; 123 } 124 125 // Add sub-registers to OSet following a pre-order defined by the .td file. 126 void addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet, 127 CodeGenRegBank&) const; 128 129 // Return the sub-register index naming Reg as a sub-register of this 130 // register. Returns NULL if Reg is not a sub-register. 131 CodeGenSubRegIndex *getSubRegIndex(const CodeGenRegister *Reg) const { 132 return SubReg2Idx.lookup(Reg); 133 } 134 135 typedef std::vector<const CodeGenRegister*> SuperRegList; 136 137 // Get the list of super-registers in topological order, small to large. 138 // This is valid after computeSubRegs visits all registers during RegBank 139 // construction. 140 const SuperRegList &getSuperRegs() const { 141 assert(SubRegsComplete && "Must precompute sub-registers"); 142 return SuperRegs; 143 } 144 145 // Get the list of ad hoc aliases. The graph is symmetric, so the list 146 // contains all registers in 'Aliases', and all registers that mention this 147 // register in 'Aliases'. 148 ArrayRef<CodeGenRegister*> getExplicitAliases() const { 149 return ExplicitAliases; 150 } 151 152 // Get the topological signature of this register. This is a small integer 153 // less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have 154 // identical sub-register structure. That is, they support the same set of 155 // sub-register indices mapping to the same kind of sub-registers 156 // (TopoSig-wise). 157 unsigned getTopoSig() const { 158 assert(SuperRegsComplete && "TopoSigs haven't been computed yet."); 159 return TopoSig; 160 } 161 162 // List of register units in ascending order. 163 typedef SmallVector<unsigned, 16> RegUnitList; 164 165 // How many entries in RegUnitList are native? 166 unsigned NumNativeRegUnits; 167 168 // Get the list of register units. 169 // This is only valid after computeSubRegs() completes. 170 const RegUnitList &getRegUnits() const { return RegUnits; } 171 172 // Get the native register units. This is a prefix of getRegUnits(). 173 ArrayRef<unsigned> getNativeRegUnits() const { 174 return makeArrayRef(RegUnits).slice(0, NumNativeRegUnits); 175 } 176 177 // Inherit register units from subregisters. 178 // Return true if the RegUnits changed. 179 bool inheritRegUnits(CodeGenRegBank &RegBank); 180 181 // Adopt a register unit for pressure tracking. 182 // A unit is adopted iff its unit number is >= NumNativeRegUnits. 183 void adoptRegUnit(unsigned RUID) { RegUnits.push_back(RUID); } 184 185 // Get the sum of this register's register unit weights. 186 unsigned getWeight(const CodeGenRegBank &RegBank) const; 187 188 // Order CodeGenRegister pointers by EnumValue. 189 struct Less { 190 bool operator()(const CodeGenRegister *A, 191 const CodeGenRegister *B) const { 192 assert(A && B); 193 return A->EnumValue < B->EnumValue; 194 } 195 }; 196 197 // Canonically ordered set. 198 typedef std::set<const CodeGenRegister*, Less> Set; 199 200 // Compute the set of registers overlapping this. 201 void computeOverlaps(Set &Overlaps, const CodeGenRegBank&) const; 202 203 private: 204 bool SubRegsComplete; 205 bool SuperRegsComplete; 206 unsigned TopoSig; 207 208 // The sub-registers explicit in the .td file form a tree. 209 SmallVector<CodeGenSubRegIndex*, 8> ExplicitSubRegIndices; 210 SmallVector<CodeGenRegister*, 8> ExplicitSubRegs; 211 212 // Explicit ad hoc aliases, symmetrized to form an undirected graph. 213 SmallVector<CodeGenRegister*, 8> ExplicitAliases; 214 215 // Super-registers where this is the first explicit sub-register. 216 SuperRegList LeadingSuperRegs; 217 218 SubRegMap SubRegs; 219 SuperRegList SuperRegs; 220 DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*> SubReg2Idx; 221 RegUnitList RegUnits; 222 }; 223 224 225 class CodeGenRegisterClass { 226 CodeGenRegister::Set Members; 227 // Allocation orders. Order[0] always contains all registers in Members. 228 std::vector<SmallVector<Record*, 16> > Orders; 229 // Bit mask of sub-classes including this, indexed by their EnumValue. 230 BitVector SubClasses; 231 // List of super-classes, topologocally ordered to have the larger classes 232 // first. This is the same as sorting by EnumValue. 233 SmallVector<CodeGenRegisterClass*, 4> SuperClasses; 234 Record *TheDef; 235 std::string Name; 236 237 // For a synthesized class, inherit missing properties from the nearest 238 // super-class. 239 void inheritProperties(CodeGenRegBank&); 240 241 // Map SubRegIndex -> sub-class. This is the largest sub-class where all 242 // registers have a SubRegIndex sub-register. 243 DenseMap<CodeGenSubRegIndex*, CodeGenRegisterClass*> SubClassWithSubReg; 244 245 // Map SubRegIndex -> set of super-reg classes. This is all register 246 // classes SuperRC such that: 247 // 248 // R:SubRegIndex in this RC for all R in SuperRC. 249 // 250 DenseMap<CodeGenSubRegIndex*, 251 SmallPtrSet<CodeGenRegisterClass*, 8> > SuperRegClasses; 252 253 // Bit vector of TopoSigs for the registers in this class. This will be 254 // very sparse on regular architectures. 255 BitVector TopoSigs; 256 257 public: 258 unsigned EnumValue; 259 std::string Namespace; 260 std::vector<MVT::SimpleValueType> VTs; 261 unsigned SpillSize; 262 unsigned SpillAlignment; 263 int CopyCost; 264 bool Allocatable; 265 std::string AltOrderSelect; 266 267 // Return the Record that defined this class, or NULL if the class was 268 // created by TableGen. 269 Record *getDef() const { return TheDef; } 270 271 const std::string &getName() const { return Name; } 272 std::string getQualifiedName() const; 273 const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;} 274 unsigned getNumValueTypes() const { return VTs.size(); } 275 276 MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const { 277 if (VTNum < VTs.size()) 278 return VTs[VTNum]; 279 llvm_unreachable("VTNum greater than number of ValueTypes in RegClass!"); 280 } 281 282 // Return true if this this class contains the register. 283 bool contains(const CodeGenRegister*) const; 284 285 // Returns true if RC is a subclass. 286 // RC is a sub-class of this class if it is a valid replacement for any 287 // instruction operand where a register of this classis required. It must 288 // satisfy these conditions: 289 // 290 // 1. All RC registers are also in this. 291 // 2. The RC spill size must not be smaller than our spill size. 292 // 3. RC spill alignment must be compatible with ours. 293 // 294 bool hasSubClass(const CodeGenRegisterClass *RC) const { 295 return SubClasses.test(RC->EnumValue); 296 } 297 298 // getSubClassWithSubReg - Returns the largest sub-class where all 299 // registers have a SubIdx sub-register. 300 CodeGenRegisterClass* 301 getSubClassWithSubReg(CodeGenSubRegIndex *SubIdx) const { 302 return SubClassWithSubReg.lookup(SubIdx); 303 } 304 305 void setSubClassWithSubReg(CodeGenSubRegIndex *SubIdx, 306 CodeGenRegisterClass *SubRC) { 307 SubClassWithSubReg[SubIdx] = SubRC; 308 } 309 310 // getSuperRegClasses - Returns a bit vector of all register classes 311 // containing only SubIdx super-registers of this class. 312 void getSuperRegClasses(CodeGenSubRegIndex *SubIdx, BitVector &Out) const; 313 314 // addSuperRegClass - Add a class containing only SudIdx super-registers. 315 void addSuperRegClass(CodeGenSubRegIndex *SubIdx, 316 CodeGenRegisterClass *SuperRC) { 317 SuperRegClasses[SubIdx].insert(SuperRC); 318 } 319 320 // getSubClasses - Returns a constant BitVector of subclasses indexed by 321 // EnumValue. 322 // The SubClasses vector includs an entry for this class. 323 const BitVector &getSubClasses() const { return SubClasses; } 324 325 // getSuperClasses - Returns a list of super classes ordered by EnumValue. 326 // The array does not include an entry for this class. 327 ArrayRef<CodeGenRegisterClass*> getSuperClasses() const { 328 return SuperClasses; 329 } 330 331 // Returns an ordered list of class members. 332 // The order of registers is the same as in the .td file. 333 // No = 0 is the default allocation order, No = 1 is the first alternative. 334 ArrayRef<Record*> getOrder(unsigned No = 0) const { 335 return Orders[No]; 336 } 337 338 // Return the total number of allocation orders available. 339 unsigned getNumOrders() const { return Orders.size(); } 340 341 // Get the set of registers. This set contains the same registers as 342 // getOrder(0). 343 const CodeGenRegister::Set &getMembers() const { return Members; } 344 345 // Get a bit vector of TopoSigs present in this register class. 346 const BitVector &getTopoSigs() const { return TopoSigs; } 347 348 // Populate a unique sorted list of units from a register set. 349 void buildRegUnitSet(std::vector<unsigned> &RegUnits) const; 350 351 CodeGenRegisterClass(CodeGenRegBank&, Record *R); 352 353 // A key representing the parts of a register class used for forming 354 // sub-classes. Note the ordering provided by this key is not the same as 355 // the topological order used for the EnumValues. 356 struct Key { 357 const CodeGenRegister::Set *Members; 358 unsigned SpillSize; 359 unsigned SpillAlignment; 360 361 Key(const Key &O) 362 : Members(O.Members), 363 SpillSize(O.SpillSize), 364 SpillAlignment(O.SpillAlignment) {} 365 366 Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0) 367 : Members(M), SpillSize(S), SpillAlignment(A) {} 368 369 Key(const CodeGenRegisterClass &RC) 370 : Members(&RC.getMembers()), 371 SpillSize(RC.SpillSize), 372 SpillAlignment(RC.SpillAlignment) {} 373 374 // Lexicographical order of (Members, SpillSize, SpillAlignment). 375 bool operator<(const Key&) const; 376 }; 377 378 // Create a non-user defined register class. 379 CodeGenRegisterClass(CodeGenRegBank&, StringRef Name, Key Props); 380 381 // Called by CodeGenRegBank::CodeGenRegBank(). 382 static void computeSubClasses(CodeGenRegBank&); 383 }; 384 385 // Register units are used to model interference and register pressure. 386 // Every register is assigned one or more register units such that two 387 // registers overlap if and only if they have a register unit in common. 388 // 389 // Normally, one register unit is created per leaf register. Non-leaf 390 // registers inherit the units of their sub-registers. 391 struct RegUnit { 392 // Weight assigned to this RegUnit for estimating register pressure. 393 // This is useful when equalizing weights in register classes with mixed 394 // register topologies. 395 unsigned Weight; 396 397 // Each native RegUnit corresponds to one or two root registers. The full 398 // set of registers containing this unit can be computed as the union of 399 // these two registers and their super-registers. 400 const CodeGenRegister *Roots[2]; 401 402 RegUnit() : Weight(0) { Roots[0] = Roots[1] = 0; } 403 404 ArrayRef<const CodeGenRegister*> getRoots() const { 405 assert(!(Roots[1] && !Roots[0]) && "Invalid roots array"); 406 return makeArrayRef(Roots, !!Roots[0] + !!Roots[1]); 407 } 408 }; 409 410 // Each RegUnitSet is a sorted vector with a name. 411 struct RegUnitSet { 412 typedef std::vector<unsigned>::const_iterator iterator; 413 414 std::string Name; 415 std::vector<unsigned> Units; 416 }; 417 418 // Base vector for identifying TopoSigs. The contents uniquely identify a 419 // TopoSig, only computeSuperRegs needs to know how. 420 typedef SmallVector<unsigned, 16> TopoSigId; 421 422 // CodeGenRegBank - Represent a target's registers and the relations between 423 // them. 424 class CodeGenRegBank { 425 RecordKeeper &Records; 426 SetTheory Sets; 427 428 // SubRegIndices. 429 std::vector<CodeGenSubRegIndex*> SubRegIndices; 430 DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx; 431 unsigned NumNamedIndices; 432 433 typedef std::map<SmallVector<CodeGenSubRegIndex*, 8>, 434 CodeGenSubRegIndex*> ConcatIdxMap; 435 ConcatIdxMap ConcatIdx; 436 437 // Registers. 438 std::vector<CodeGenRegister*> Registers; 439 DenseMap<Record*, CodeGenRegister*> Def2Reg; 440 unsigned NumNativeRegUnits; 441 442 std::map<TopoSigId, unsigned> TopoSigs; 443 444 // Includes native (0..NumNativeRegUnits-1) and adopted register units. 445 SmallVector<RegUnit, 8> RegUnits; 446 447 // Register classes. 448 std::vector<CodeGenRegisterClass*> RegClasses; 449 DenseMap<Record*, CodeGenRegisterClass*> Def2RC; 450 typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap; 451 RCKeyMap Key2RC; 452 453 // Remember each unique set of register units. Initially, this contains a 454 // unique set for each register class. Simliar sets are coalesced with 455 // pruneUnitSets and new supersets are inferred during computeRegUnitSets. 456 std::vector<RegUnitSet> RegUnitSets; 457 458 // Map RegisterClass index to the index of the RegUnitSet that contains the 459 // class's units and any inferred RegUnit supersets. 460 std::vector<std::vector<unsigned> > RegClassUnitSets; 461 462 // Add RC to *2RC maps. 463 void addToMaps(CodeGenRegisterClass*); 464 465 // Create a synthetic sub-class if it is missing. 466 CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC, 467 const CodeGenRegister::Set *Membs, 468 StringRef Name); 469 470 // Infer missing register classes. 471 void computeInferredRegisterClasses(); 472 void inferCommonSubClass(CodeGenRegisterClass *RC); 473 void inferSubClassWithSubReg(CodeGenRegisterClass *RC); 474 void inferMatchingSuperRegClass(CodeGenRegisterClass *RC, 475 unsigned FirstSubRegRC = 0); 476 477 // Iteratively prune unit sets. 478 void pruneUnitSets(); 479 480 // Compute a weight for each register unit created during getSubRegs. 481 void computeRegUnitWeights(); 482 483 // Create a RegUnitSet for each RegClass and infer superclasses. 484 void computeRegUnitSets(); 485 486 // Populate the Composite map from sub-register relationships. 487 void computeComposites(); 488 489 public: 490 CodeGenRegBank(RecordKeeper&); 491 492 SetTheory &getSets() { return Sets; } 493 494 // Sub-register indices. The first NumNamedIndices are defined by the user 495 // in the .td files. The rest are synthesized such that all sub-registers 496 // have a unique name. 497 ArrayRef<CodeGenSubRegIndex*> getSubRegIndices() { return SubRegIndices; } 498 unsigned getNumNamedIndices() { return NumNamedIndices; } 499 500 // Find a SubRegIndex form its Record def. 501 CodeGenSubRegIndex *getSubRegIdx(Record*); 502 503 // Find or create a sub-register index representing the A+B composition. 504 CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A, 505 CodeGenSubRegIndex *B); 506 507 // Find or create a sub-register index representing the concatenation of 508 // non-overlapping sibling indices. 509 CodeGenSubRegIndex * 510 getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8>&); 511 512 void 513 addConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8> &Parts, 514 CodeGenSubRegIndex *Idx) { 515 ConcatIdx.insert(std::make_pair(Parts, Idx)); 516 } 517 518 const std::vector<CodeGenRegister*> &getRegisters() { return Registers; } 519 520 // Find a register from its Record def. 521 CodeGenRegister *getReg(Record*); 522 523 // Get a Register's index into the Registers array. 524 unsigned getRegIndex(const CodeGenRegister *Reg) const { 525 return Reg->EnumValue - 1; 526 } 527 528 // Return the number of allocated TopoSigs. The first TopoSig representing 529 // leaf registers is allocated number 0. 530 unsigned getNumTopoSigs() const { 531 return TopoSigs.size(); 532 } 533 534 // Find or create a TopoSig for the given TopoSigId. 535 // This function is only for use by CodeGenRegister::computeSuperRegs(). 536 // Others should simply use Reg->getTopoSig(). 537 unsigned getTopoSig(const TopoSigId &Id) { 538 return TopoSigs.insert(std::make_pair(Id, TopoSigs.size())).first->second; 539 } 540 541 // Create a native register unit that is associated with one or two root 542 // registers. 543 unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = 0) { 544 RegUnits.resize(RegUnits.size() + 1); 545 RegUnits.back().Roots[0] = R0; 546 RegUnits.back().Roots[1] = R1; 547 return RegUnits.size() - 1; 548 } 549 550 // Create a new non-native register unit that can be adopted by a register 551 // to increase its pressure. Note that NumNativeRegUnits is not increased. 552 unsigned newRegUnit(unsigned Weight) { 553 RegUnits.resize(RegUnits.size() + 1); 554 RegUnits.back().Weight = Weight; 555 return RegUnits.size() - 1; 556 } 557 558 // Native units are the singular unit of a leaf register. Register aliasing 559 // is completely characterized by native units. Adopted units exist to give 560 // register additional weight but don't affect aliasing. 561 bool isNativeUnit(unsigned RUID) { 562 return RUID < NumNativeRegUnits; 563 } 564 565 unsigned getNumNativeRegUnits() const { 566 return NumNativeRegUnits; 567 } 568 569 RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; } 570 const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; } 571 572 ArrayRef<CodeGenRegisterClass*> getRegClasses() const { 573 return RegClasses; 574 } 575 576 // Find a register class from its def. 577 CodeGenRegisterClass *getRegClass(Record*); 578 579 /// getRegisterClassForRegister - Find the register class that contains the 580 /// specified physical register. If the register is not in a register 581 /// class, return null. If the register is in multiple classes, and the 582 /// classes have a superset-subset relationship and the same set of types, 583 /// return the superclass. Otherwise return null. 584 const CodeGenRegisterClass* getRegClassForRegister(Record *R); 585 586 // Get the sum of unit weights. 587 unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const { 588 unsigned Weight = 0; 589 for (std::vector<unsigned>::const_iterator 590 I = Units.begin(), E = Units.end(); I != E; ++I) 591 Weight += getRegUnit(*I).Weight; 592 return Weight; 593 } 594 595 // Increase a RegUnitWeight. 596 void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { 597 getRegUnit(RUID).Weight += Inc; 598 } 599 600 // Get the number of register pressure dimensions. 601 unsigned getNumRegPressureSets() const { return RegUnitSets.size(); } 602 603 // Get a set of register unit IDs for a given dimension of pressure. 604 RegUnitSet getRegPressureSet(unsigned Idx) const { 605 return RegUnitSets[Idx]; 606 } 607 608 // Get a list of pressure set IDs for a register class. Liveness of a 609 // register in this class impacts each pressure set in this list by the 610 // weight of the register. An exact solution requires all registers in a 611 // class to have the same class, but it is not strictly guaranteed. 612 ArrayRef<unsigned> getRCPressureSetIDs(unsigned RCIdx) const { 613 return RegClassUnitSets[RCIdx]; 614 } 615 616 // Computed derived records such as missing sub-register indices. 617 void computeDerivedInfo(); 618 619 // Compute the set of registers completely covered by the registers in Regs. 620 // The returned BitVector will have a bit set for each register in Regs, 621 // all sub-registers, and all super-registers that are covered by the 622 // registers in Regs. 623 // 624 // This is used to compute the mask of call-preserved registers from a list 625 // of callee-saves. 626 BitVector computeCoveredRegisters(ArrayRef<Record*> Regs); 627 }; 628 } 629 630 #endif 631