1293838Sdim//===-- SIMachineScheduler.h - SI Scheduler Interface -*- C++ -*-------===// 2293838Sdim// 3293838Sdim// The LLVM Compiler Infrastructure 4293838Sdim// 5293838Sdim// This file is distributed under the University of Illinois Open Source 6293838Sdim// License. See LICENSE.TXT for details. 7293838Sdim// 8293838Sdim//===----------------------------------------------------------------------===// 9293838Sdim// 10293838Sdim/// \file 11293838Sdim/// \brief SI Machine Scheduler interface 12293838Sdim// 13293838Sdim//===----------------------------------------------------------------------===// 14293838Sdim 15293838Sdim#ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINESCHEDULER_H 16293838Sdim#define LLVM_LIB_TARGET_AMDGPU_SIMACHINESCHEDULER_H 17293838Sdim 18293838Sdim#include "SIInstrInfo.h" 19293838Sdim#include "llvm/CodeGen/MachineScheduler.h" 20293838Sdim#include "llvm/CodeGen/RegisterPressure.h" 21293838Sdim 22293838Sdimusing namespace llvm; 23293838Sdim 24293838Sdimnamespace llvm { 25293838Sdim 26293838Sdimenum SIScheduleCandReason { 27293838Sdim NoCand, 28293838Sdim RegUsage, 29293838Sdim Latency, 30293838Sdim Successor, 31293838Sdim Depth, 32293838Sdim NodeOrder 33293838Sdim}; 34293838Sdim 35293838Sdimstruct SISchedulerCandidate { 36293838Sdim // The reason for this candidate. 37293838Sdim SIScheduleCandReason Reason; 38293838Sdim 39293838Sdim // Set of reasons that apply to multiple candidates. 40293838Sdim uint32_t RepeatReasonSet; 41293838Sdim 42293838Sdim SISchedulerCandidate() 43293838Sdim : Reason(NoCand), RepeatReasonSet(0) {} 44293838Sdim 45293838Sdim bool isRepeat(SIScheduleCandReason R) { return RepeatReasonSet & (1 << R); } 46293838Sdim void setRepeat(SIScheduleCandReason R) { RepeatReasonSet |= (1 << R); } 47293838Sdim}; 48293838Sdim 49293838Sdimclass SIScheduleDAGMI; 50293838Sdimclass SIScheduleBlockCreator; 51293838Sdim 52293838Sdimclass SIScheduleBlock { 53293838Sdim SIScheduleDAGMI *DAG; 54293838Sdim SIScheduleBlockCreator *BC; 55293838Sdim 56293838Sdim std::vector<SUnit*> SUnits; 57293838Sdim std::map<unsigned, unsigned> NodeNum2Index; 58293838Sdim std::vector<SUnit*> TopReadySUs; 59293838Sdim std::vector<SUnit*> ScheduledSUnits; 60293838Sdim 61293838Sdim /// The top of the unscheduled zone. 62293838Sdim IntervalPressure TopPressure; 63293838Sdim RegPressureTracker TopRPTracker; 64293838Sdim 65293838Sdim // Pressure: number of said class of registers needed to 66293838Sdim // store the live virtual and real registers. 67293838Sdim // We do care only of SGPR32 and VGPR32 and do track only virtual registers. 68293838Sdim // Pressure of additional registers required inside the block. 69293838Sdim std::vector<unsigned> InternalAdditionnalPressure; 70293838Sdim // Pressure of input and output registers 71293838Sdim std::vector<unsigned> LiveInPressure; 72293838Sdim std::vector<unsigned> LiveOutPressure; 73293838Sdim // Registers required by the block, and outputs. 74293838Sdim // We do track only virtual registers. 75293838Sdim // Note that some registers are not 32 bits, 76293838Sdim // and thus the pressure is not equal 77293838Sdim // to the number of live registers. 78293838Sdim std::set<unsigned> LiveInRegs; 79293838Sdim std::set<unsigned> LiveOutRegs; 80293838Sdim 81293838Sdim bool Scheduled; 82293838Sdim bool HighLatencyBlock; 83293838Sdim 84293838Sdim std::vector<unsigned> HasLowLatencyNonWaitedParent; 85293838Sdim 86293838Sdim // Unique ID, the index of the Block in the SIScheduleDAGMI Blocks table. 87293838Sdim unsigned ID; 88293838Sdim 89293838Sdim std::vector<SIScheduleBlock*> Preds; // All blocks predecessors. 90293838Sdim std::vector<SIScheduleBlock*> Succs; // All blocks successors. 91293838Sdim unsigned NumHighLatencySuccessors; 92293838Sdim 93293838Sdimpublic: 94293838Sdim SIScheduleBlock(SIScheduleDAGMI *DAG, SIScheduleBlockCreator *BC, 95293838Sdim unsigned ID): 96293838Sdim DAG(DAG), BC(BC), SUnits(), TopReadySUs(), ScheduledSUnits(), 97293838Sdim TopRPTracker(TopPressure), Scheduled(false), 98293838Sdim HighLatencyBlock(false), ID(ID), 99293838Sdim Preds(), Succs(), NumHighLatencySuccessors(0) {}; 100293838Sdim 101293838Sdim ~SIScheduleBlock() {}; 102293838Sdim 103293838Sdim unsigned getID() const { return ID; } 104293838Sdim 105293838Sdim /// Functions for Block construction. 106293838Sdim void addUnit(SUnit *SU); 107293838Sdim 108293838Sdim // When all SUs have been added. 109293838Sdim void finalizeUnits(); 110293838Sdim 111293838Sdim // Add block pred, which has instruction predecessor of SU. 112293838Sdim void addPred(SIScheduleBlock *Pred); 113293838Sdim void addSucc(SIScheduleBlock *Succ); 114293838Sdim 115293838Sdim const std::vector<SIScheduleBlock*>& getPreds() const { return Preds; } 116293838Sdim const std::vector<SIScheduleBlock*>& getSuccs() const { return Succs; } 117293838Sdim 118293838Sdim unsigned Height; // Maximum topdown path length to block without outputs 119293838Sdim unsigned Depth; // Maximum bottomup path length to block without inputs 120293838Sdim 121293838Sdim unsigned getNumHighLatencySuccessors() const { 122293838Sdim return NumHighLatencySuccessors; 123293838Sdim } 124293838Sdim 125293838Sdim bool isHighLatencyBlock() { return HighLatencyBlock; } 126293838Sdim 127293838Sdim // This is approximative. 128293838Sdim // Ideally should take into accounts some instructions (rcp, etc) 129293838Sdim // are 4 times slower. 130293838Sdim int getCost() { return SUnits.size(); } 131293838Sdim 132293838Sdim // The block Predecessors and Successors must be all registered 133293838Sdim // before fastSchedule(). 134293838Sdim // Fast schedule with no particular requirement. 135293838Sdim void fastSchedule(); 136293838Sdim 137293838Sdim std::vector<SUnit*> getScheduledUnits() { return ScheduledSUnits; } 138293838Sdim 139293838Sdim // Complete schedule that will try to minimize reg pressure and 140293838Sdim // low latencies, and will fill liveins and liveouts. 141293838Sdim // Needs all MIs to be grouped between BeginBlock and EndBlock. 142293838Sdim // The MIs can be moved after the scheduling, 143293838Sdim // it is just used to allow correct track of live registers. 144293838Sdim void schedule(MachineBasicBlock::iterator BeginBlock, 145293838Sdim MachineBasicBlock::iterator EndBlock); 146293838Sdim 147293838Sdim bool isScheduled() { return Scheduled; } 148293838Sdim 149293838Sdim 150293838Sdim // Needs the block to be scheduled inside 151293838Sdim // TODO: find a way to compute it. 152293838Sdim std::vector<unsigned> &getInternalAdditionnalRegUsage() { 153293838Sdim return InternalAdditionnalPressure; 154293838Sdim } 155293838Sdim 156293838Sdim std::set<unsigned> &getInRegs() { return LiveInRegs; } 157293838Sdim std::set<unsigned> &getOutRegs() { return LiveOutRegs; } 158293838Sdim 159293838Sdim void printDebug(bool Full); 160293838Sdim 161293838Sdimprivate: 162293838Sdim struct SISchedCandidate : SISchedulerCandidate { 163293838Sdim // The best SUnit candidate. 164293838Sdim SUnit *SU; 165293838Sdim 166293838Sdim unsigned SGPRUsage; 167293838Sdim unsigned VGPRUsage; 168293838Sdim bool IsLowLatency; 169293838Sdim unsigned LowLatencyOffset; 170293838Sdim bool HasLowLatencyNonWaitedParent; 171293838Sdim 172293838Sdim SISchedCandidate() 173293838Sdim : SU(nullptr) {} 174293838Sdim 175293838Sdim bool isValid() const { return SU; } 176293838Sdim 177293838Sdim // Copy the status of another candidate without changing policy. 178293838Sdim void setBest(SISchedCandidate &Best) { 179293838Sdim assert(Best.Reason != NoCand && "uninitialized Sched candidate"); 180293838Sdim SU = Best.SU; 181293838Sdim Reason = Best.Reason; 182293838Sdim SGPRUsage = Best.SGPRUsage; 183293838Sdim VGPRUsage = Best.VGPRUsage; 184293838Sdim IsLowLatency = Best.IsLowLatency; 185293838Sdim LowLatencyOffset = Best.LowLatencyOffset; 186293838Sdim HasLowLatencyNonWaitedParent = Best.HasLowLatencyNonWaitedParent; 187293838Sdim } 188293838Sdim }; 189293838Sdim 190293838Sdim void undoSchedule(); 191293838Sdim 192293838Sdim void undoReleaseSucc(SUnit *SU, SDep *SuccEdge); 193293838Sdim void releaseSucc(SUnit *SU, SDep *SuccEdge); 194293838Sdim // InOrOutBlock: restrict to links pointing inside the block (true), 195293838Sdim // or restrict to links pointing outside the block (false). 196293838Sdim void releaseSuccessors(SUnit *SU, bool InOrOutBlock); 197293838Sdim 198293838Sdim void nodeScheduled(SUnit *SU); 199293838Sdim void tryCandidateTopDown(SISchedCandidate &Cand, SISchedCandidate &TryCand); 200293838Sdim void tryCandidateBottomUp(SISchedCandidate &Cand, SISchedCandidate &TryCand); 201293838Sdim SUnit* pickNode(); 202293838Sdim void traceCandidate(const SISchedCandidate &Cand); 203293838Sdim void initRegPressure(MachineBasicBlock::iterator BeginBlock, 204293838Sdim MachineBasicBlock::iterator EndBlock); 205293838Sdim}; 206293838Sdim 207293838Sdimstruct SIScheduleBlocks { 208293838Sdim std::vector<SIScheduleBlock*> Blocks; 209293838Sdim std::vector<int> TopDownIndex2Block; 210293838Sdim std::vector<int> TopDownBlock2Index; 211293838Sdim}; 212293838Sdim 213293838Sdimenum SISchedulerBlockCreatorVariant { 214293838Sdim LatenciesAlone, 215293838Sdim LatenciesGrouped, 216293838Sdim LatenciesAlonePlusConsecutive 217293838Sdim}; 218293838Sdim 219293838Sdimclass SIScheduleBlockCreator { 220293838Sdim SIScheduleDAGMI *DAG; 221293838Sdim // unique_ptr handles freeing memory for us. 222293838Sdim std::vector<std::unique_ptr<SIScheduleBlock>> BlockPtrs; 223293838Sdim std::map<SISchedulerBlockCreatorVariant, 224293838Sdim SIScheduleBlocks> Blocks; 225293838Sdim std::vector<SIScheduleBlock*> CurrentBlocks; 226293838Sdim std::vector<int> Node2CurrentBlock; 227293838Sdim 228293838Sdim // Topological sort 229293838Sdim // Maps topological index to the node number. 230293838Sdim std::vector<int> TopDownIndex2Block; 231293838Sdim std::vector<int> TopDownBlock2Index; 232293838Sdim std::vector<int> BottomUpIndex2Block; 233293838Sdim 234293838Sdim // 0 -> Color not given. 235293838Sdim // 1 to SUnits.size() -> Reserved group (you should only add elements to them). 236293838Sdim // Above -> Other groups. 237293838Sdim int NextReservedID; 238293838Sdim int NextNonReservedID; 239293838Sdim std::vector<int> CurrentColoring; 240293838Sdim std::vector<int> CurrentTopDownReservedDependencyColoring; 241293838Sdim std::vector<int> CurrentBottomUpReservedDependencyColoring; 242293838Sdim 243293838Sdimpublic: 244293838Sdim SIScheduleBlockCreator(SIScheduleDAGMI *DAG); 245293838Sdim ~SIScheduleBlockCreator(); 246293838Sdim 247293838Sdim SIScheduleBlocks 248293838Sdim getBlocks(SISchedulerBlockCreatorVariant BlockVariant); 249293838Sdim 250293838Sdim bool isSUInBlock(SUnit *SU, unsigned ID); 251293838Sdim 252293838Sdimprivate: 253293838Sdim // Give a Reserved color to every high latency. 254293838Sdim void colorHighLatenciesAlone(); 255293838Sdim 256293838Sdim // Create groups of high latencies with a Reserved color. 257293838Sdim void colorHighLatenciesGroups(); 258293838Sdim 259293838Sdim // Compute coloring for topdown and bottom traversals with 260293838Sdim // different colors depending on dependencies on Reserved colors. 261293838Sdim void colorComputeReservedDependencies(); 262293838Sdim 263293838Sdim // Give color to all non-colored SUs according to Reserved groups dependencies. 264293838Sdim void colorAccordingToReservedDependencies(); 265293838Sdim 266293838Sdim // Divides Blocks having no bottom up or top down dependencies on Reserved groups. 267293838Sdim // The new colors are computed according to the dependencies on the other blocks 268293838Sdim // formed with colorAccordingToReservedDependencies. 269293838Sdim void colorEndsAccordingToDependencies(); 270293838Sdim 271293838Sdim // Cut groups into groups with SUs in consecutive order (except for Reserved groups). 272293838Sdim void colorForceConsecutiveOrderInGroup(); 273293838Sdim 274293838Sdim // Merge Constant loads that have all their users into another group to the group. 275293838Sdim // (TODO: else if all their users depend on the same group, put them there) 276293838Sdim void colorMergeConstantLoadsNextGroup(); 277293838Sdim 278293838Sdim // Merge SUs that have all their users into another group to the group 279293838Sdim void colorMergeIfPossibleNextGroup(); 280293838Sdim 281293838Sdim // Merge SUs that have all their users into another group to the group, 282293838Sdim // but only for Reserved groups. 283293838Sdim void colorMergeIfPossibleNextGroupOnlyForReserved(); 284293838Sdim 285293838Sdim // Merge SUs that have all their users into another group to the group, 286293838Sdim // but only if the group is no more than a few SUs. 287293838Sdim void colorMergeIfPossibleSmallGroupsToNextGroup(); 288293838Sdim 289293838Sdim // Divides Blocks with important size. 290293838Sdim // Idea of implementation: attribute new colors depending on topdown and 291293838Sdim // bottom up links to other blocks. 292293838Sdim void cutHugeBlocks(); 293293838Sdim 294293838Sdim // Put in one group all instructions with no users in this scheduling region 295293838Sdim // (we'd want these groups be at the end). 296293838Sdim void regroupNoUserInstructions(); 297293838Sdim 298293838Sdim void createBlocksForVariant(SISchedulerBlockCreatorVariant BlockVariant); 299293838Sdim 300293838Sdim void topologicalSort(); 301293838Sdim 302293838Sdim void scheduleInsideBlocks(); 303293838Sdim 304293838Sdim void fillStats(); 305293838Sdim}; 306293838Sdim 307293838Sdimenum SISchedulerBlockSchedulerVariant { 308293838Sdim BlockLatencyRegUsage, 309293838Sdim BlockRegUsageLatency, 310293838Sdim BlockRegUsage 311293838Sdim}; 312293838Sdim 313293838Sdimclass SIScheduleBlockScheduler { 314293838Sdim SIScheduleDAGMI *DAG; 315293838Sdim SISchedulerBlockSchedulerVariant Variant; 316293838Sdim std::vector<SIScheduleBlock*> Blocks; 317293838Sdim 318293838Sdim std::vector<std::map<unsigned, unsigned>> LiveOutRegsNumUsages; 319293838Sdim std::set<unsigned> LiveRegs; 320293838Sdim // Num of schedulable unscheduled blocks reading the register. 321293838Sdim std::map<unsigned, unsigned> LiveRegsConsumers; 322293838Sdim 323293838Sdim std::vector<unsigned> LastPosHighLatencyParentScheduled; 324293838Sdim int LastPosWaitedHighLatency; 325293838Sdim 326293838Sdim std::vector<SIScheduleBlock*> BlocksScheduled; 327293838Sdim unsigned NumBlockScheduled; 328293838Sdim std::vector<SIScheduleBlock*> ReadyBlocks; 329293838Sdim 330293838Sdim unsigned VregCurrentUsage; 331293838Sdim unsigned SregCurrentUsage; 332293838Sdim 333293838Sdim // Currently is only approximation. 334293838Sdim unsigned maxVregUsage; 335293838Sdim unsigned maxSregUsage; 336293838Sdim 337293838Sdim std::vector<unsigned> BlockNumPredsLeft; 338293838Sdim std::vector<unsigned> BlockNumSuccsLeft; 339293838Sdim 340293838Sdimpublic: 341293838Sdim SIScheduleBlockScheduler(SIScheduleDAGMI *DAG, 342293838Sdim SISchedulerBlockSchedulerVariant Variant, 343293838Sdim SIScheduleBlocks BlocksStruct); 344293838Sdim ~SIScheduleBlockScheduler() {}; 345293838Sdim 346293838Sdim std::vector<SIScheduleBlock*> getBlocks() { return BlocksScheduled; }; 347293838Sdim 348293838Sdim unsigned getVGPRUsage() { return maxVregUsage; }; 349293838Sdim unsigned getSGPRUsage() { return maxSregUsage; }; 350293838Sdim 351293838Sdimprivate: 352293838Sdim struct SIBlockSchedCandidate : SISchedulerCandidate { 353293838Sdim // The best Block candidate. 354293838Sdim SIScheduleBlock *Block; 355293838Sdim 356293838Sdim bool IsHighLatency; 357293838Sdim int VGPRUsageDiff; 358293838Sdim unsigned NumSuccessors; 359293838Sdim unsigned NumHighLatencySuccessors; 360293838Sdim unsigned LastPosHighLatParentScheduled; 361293838Sdim unsigned Height; 362293838Sdim 363293838Sdim SIBlockSchedCandidate() 364293838Sdim : Block(nullptr) {} 365293838Sdim 366293838Sdim bool isValid() const { return Block; } 367293838Sdim 368293838Sdim // Copy the status of another candidate without changing policy. 369293838Sdim void setBest(SIBlockSchedCandidate &Best) { 370293838Sdim assert(Best.Reason != NoCand && "uninitialized Sched candidate"); 371293838Sdim Block = Best.Block; 372293838Sdim Reason = Best.Reason; 373293838Sdim IsHighLatency = Best.IsHighLatency; 374293838Sdim VGPRUsageDiff = Best.VGPRUsageDiff; 375293838Sdim NumSuccessors = Best.NumSuccessors; 376293838Sdim NumHighLatencySuccessors = Best.NumHighLatencySuccessors; 377293838Sdim LastPosHighLatParentScheduled = Best.LastPosHighLatParentScheduled; 378293838Sdim Height = Best.Height; 379293838Sdim } 380293838Sdim }; 381293838Sdim 382293838Sdim bool tryCandidateLatency(SIBlockSchedCandidate &Cand, 383293838Sdim SIBlockSchedCandidate &TryCand); 384293838Sdim bool tryCandidateRegUsage(SIBlockSchedCandidate &Cand, 385293838Sdim SIBlockSchedCandidate &TryCand); 386293838Sdim SIScheduleBlock *pickBlock(); 387293838Sdim 388293838Sdim void addLiveRegs(std::set<unsigned> &Regs); 389293838Sdim void decreaseLiveRegs(SIScheduleBlock *Block, std::set<unsigned> &Regs); 390293838Sdim void releaseBlockSuccs(SIScheduleBlock *Parent); 391293838Sdim void blockScheduled(SIScheduleBlock *Block); 392293838Sdim 393293838Sdim // Check register pressure change 394293838Sdim // by scheduling a block with these LiveIn and LiveOut. 395293838Sdim std::vector<int> checkRegUsageImpact(std::set<unsigned> &InRegs, 396293838Sdim std::set<unsigned> &OutRegs); 397293838Sdim 398293838Sdim void schedule(); 399293838Sdim}; 400293838Sdim 401293838Sdimstruct SIScheduleBlockResult { 402293838Sdim std::vector<unsigned> SUs; 403293838Sdim unsigned MaxSGPRUsage; 404293838Sdim unsigned MaxVGPRUsage; 405293838Sdim}; 406293838Sdim 407293838Sdimclass SIScheduler { 408293838Sdim SIScheduleDAGMI *DAG; 409293838Sdim SIScheduleBlockCreator BlockCreator; 410293838Sdim 411293838Sdimpublic: 412293838Sdim SIScheduler(SIScheduleDAGMI *DAG) : DAG(DAG), BlockCreator(DAG) {}; 413293838Sdim 414293838Sdim ~SIScheduler() {}; 415293838Sdim 416293838Sdim struct SIScheduleBlockResult 417293838Sdim scheduleVariant(SISchedulerBlockCreatorVariant BlockVariant, 418293838Sdim SISchedulerBlockSchedulerVariant ScheduleVariant); 419293838Sdim}; 420293838Sdim 421293838Sdimclass SIScheduleDAGMI : public ScheduleDAGMILive { 422293838Sdim const SIInstrInfo *SITII; 423293838Sdim const SIRegisterInfo *SITRI; 424293838Sdim 425293838Sdim std::vector<SUnit> SUnitsLinksBackup; 426293838Sdim 427293838Sdim // For moveLowLatencies. After all Scheduling variants are tested. 428293838Sdim std::vector<unsigned> ScheduledSUnits; 429293838Sdim std::vector<unsigned> ScheduledSUnitsInv; 430293838Sdim 431293838Sdim unsigned VGPRSetID; 432293838Sdim unsigned SGPRSetID; 433293838Sdim 434293838Sdimpublic: 435293838Sdim SIScheduleDAGMI(MachineSchedContext *C); 436293838Sdim 437293838Sdim ~SIScheduleDAGMI() override; 438293838Sdim 439293838Sdim // Entry point for the schedule. 440293838Sdim void schedule() override; 441293838Sdim 442293838Sdim // To init Block's RPTracker. 443293838Sdim void initRPTracker(RegPressureTracker &RPTracker) { 444293838Sdim RPTracker.init(&MF, RegClassInfo, LIS, BB, RegionBegin); 445293838Sdim } 446293838Sdim 447293838Sdim MachineBasicBlock *getBB() { return BB; } 448293838Sdim MachineBasicBlock::iterator getCurrentTop() { return CurrentTop; }; 449293838Sdim MachineBasicBlock::iterator getCurrentBottom() { return CurrentBottom; }; 450293838Sdim LiveIntervals *getLIS() { return LIS; } 451293838Sdim MachineRegisterInfo *getMRI() { return &MRI; } 452293838Sdim const TargetRegisterInfo *getTRI() { return TRI; } 453293838Sdim SUnit& getEntrySU() { return EntrySU; }; 454293838Sdim SUnit& getExitSU() { return ExitSU; }; 455293838Sdim 456293838Sdim void restoreSULinksLeft(); 457293838Sdim 458293838Sdim template<typename _Iterator> void fillVgprSgprCost(_Iterator First, 459293838Sdim _Iterator End, 460293838Sdim unsigned &VgprUsage, 461293838Sdim unsigned &SgprUsage); 462293838Sdim std::set<unsigned> getInRegs() { 463293838Sdim std::set<unsigned> InRegs (RPTracker.getPressure().LiveInRegs.begin(), 464293838Sdim RPTracker.getPressure().LiveInRegs.end()); 465293838Sdim return InRegs; 466293838Sdim }; 467293838Sdim 468293838Sdim unsigned getVGPRSetID() const { return VGPRSetID; } 469293838Sdim unsigned getSGPRSetID() const { return SGPRSetID; } 470293838Sdim 471293838Sdimprivate: 472293838Sdim void topologicalSort(); 473293838Sdim // After scheduling is done, improve low latency placements. 474293838Sdim void moveLowLatencies(); 475293838Sdim 476293838Sdimpublic: 477293838Sdim // Some stats for scheduling inside blocks. 478293838Sdim std::vector<unsigned> IsLowLatencySU; 479293838Sdim std::vector<unsigned> LowLatencyOffset; 480293838Sdim std::vector<unsigned> IsHighLatencySU; 481293838Sdim // Topological sort 482293838Sdim // Maps topological index to the node number. 483293838Sdim std::vector<int> TopDownIndex2SU; 484293838Sdim std::vector<int> BottomUpIndex2SU; 485293838Sdim}; 486293838Sdim 487293838Sdim} // namespace llvm 488293838Sdim 489293838Sdim#endif /* SIMACHINESCHEDULER_H_ */ 490