MachineBasicBlock.h revision 210299
1193323Sed//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// Collect the sequence of machine instructions for a basic block. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H 15193323Sed#define LLVM_CODEGEN_MACHINEBASICBLOCK_H 16193323Sed 17193323Sed#include "llvm/CodeGen/MachineInstr.h" 18193323Sed#include "llvm/ADT/GraphTraits.h" 19193323Sed 20193323Sednamespace llvm { 21193323Sed 22210299Sedclass Pass; 23193323Sedclass BasicBlock; 24193323Sedclass MachineFunction; 25203954Srdivackyclass MCSymbol; 26203954Srdivackyclass StringRef; 27198090Srdivackyclass raw_ostream; 28193323Sed 29193323Sedtemplate <> 30193323Sedstruct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> { 31193323Sedprivate: 32198090Srdivacky mutable ilist_half_node<MachineInstr> Sentinel; 33193323Sed 34193323Sed // this is only set by the MachineBasicBlock owning the LiveList 35193323Sed friend class MachineBasicBlock; 36193323Sed MachineBasicBlock* Parent; 37193323Sed 38193323Sedpublic: 39193323Sed MachineInstr *createSentinel() const { 40193323Sed return static_cast<MachineInstr*>(&Sentinel); 41193323Sed } 42193323Sed void destroySentinel(MachineInstr *) const {} 43193323Sed 44193323Sed MachineInstr *provideInitialHead() const { return createSentinel(); } 45193323Sed MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); } 46193323Sed static void noteHead(MachineInstr*, MachineInstr*) {} 47193323Sed 48193323Sed void addNodeToList(MachineInstr* N); 49193323Sed void removeNodeFromList(MachineInstr* N); 50193323Sed void transferNodesFromList(ilist_traits &SrcTraits, 51193323Sed ilist_iterator<MachineInstr> first, 52193323Sed ilist_iterator<MachineInstr> last); 53193323Sed void deleteNode(MachineInstr *N); 54193323Sedprivate: 55193323Sed void createNode(const MachineInstr &); 56193323Sed}; 57193323Sed 58193323Sedclass MachineBasicBlock : public ilist_node<MachineBasicBlock> { 59193323Sed typedef ilist<MachineInstr> Instructions; 60193323Sed Instructions Insts; 61193323Sed const BasicBlock *BB; 62193323Sed int Number; 63193323Sed MachineFunction *xParent; 64193323Sed 65193323Sed /// Predecessors/Successors - Keep track of the predecessor / successor 66193323Sed /// basicblocks. 67193323Sed std::vector<MachineBasicBlock *> Predecessors; 68193323Sed std::vector<MachineBasicBlock *> Successors; 69193323Sed 70193323Sed /// LiveIns - Keep track of the physical registers that are livein of 71193323Sed /// the basicblock. 72193323Sed std::vector<unsigned> LiveIns; 73193323Sed 74193323Sed /// Alignment - Alignment of the basic block. Zero if the basic block does 75193323Sed /// not need to be aligned. 76193323Sed unsigned Alignment; 77193323Sed 78193323Sed /// IsLandingPad - Indicate that this basic block is entered via an 79193323Sed /// exception handler. 80193323Sed bool IsLandingPad; 81193323Sed 82198892Srdivacky /// AddressTaken - Indicate that this basic block is potentially the 83198892Srdivacky /// target of an indirect branch. 84198892Srdivacky bool AddressTaken; 85198892Srdivacky 86193323Sed // Intrusive list support 87193323Sed MachineBasicBlock() {} 88193323Sed 89193323Sed explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb); 90193323Sed 91193323Sed ~MachineBasicBlock(); 92193323Sed 93193323Sed // MachineBasicBlocks are allocated and owned by MachineFunction. 94193323Sed friend class MachineFunction; 95193323Sed 96193323Sedpublic: 97193323Sed /// getBasicBlock - Return the LLVM basic block that this instance 98199989Srdivacky /// corresponded to originally. Note that this may be NULL if this instance 99199989Srdivacky /// does not correspond directly to an LLVM basic block. 100193323Sed /// 101193323Sed const BasicBlock *getBasicBlock() const { return BB; } 102193323Sed 103199989Srdivacky /// getName - Return the name of the corresponding LLVM basic block, or 104199989Srdivacky /// "(null)". 105199989Srdivacky StringRef getName() const; 106199989Srdivacky 107198892Srdivacky /// hasAddressTaken - Test whether this block is potentially the target 108198892Srdivacky /// of an indirect branch. 109198892Srdivacky bool hasAddressTaken() const { return AddressTaken; } 110198892Srdivacky 111198892Srdivacky /// setHasAddressTaken - Set this block to reflect that it potentially 112198892Srdivacky /// is the target of an indirect branch. 113198892Srdivacky void setHasAddressTaken() { AddressTaken = true; } 114198892Srdivacky 115193323Sed /// getParent - Return the MachineFunction containing this basic block. 116193323Sed /// 117193323Sed const MachineFunction *getParent() const { return xParent; } 118193323Sed MachineFunction *getParent() { return xParent; } 119193323Sed 120193323Sed typedef Instructions::iterator iterator; 121193323Sed typedef Instructions::const_iterator const_iterator; 122193323Sed typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 123193323Sed typedef std::reverse_iterator<iterator> reverse_iterator; 124193323Sed 125193323Sed unsigned size() const { return (unsigned)Insts.size(); } 126193323Sed bool empty() const { return Insts.empty(); } 127193323Sed 128193323Sed MachineInstr& front() { return Insts.front(); } 129193323Sed MachineInstr& back() { return Insts.back(); } 130193323Sed const MachineInstr& front() const { return Insts.front(); } 131193323Sed const MachineInstr& back() const { return Insts.back(); } 132193323Sed 133193323Sed iterator begin() { return Insts.begin(); } 134193323Sed const_iterator begin() const { return Insts.begin(); } 135193323Sed iterator end() { return Insts.end(); } 136193323Sed const_iterator end() const { return Insts.end(); } 137193323Sed reverse_iterator rbegin() { return Insts.rbegin(); } 138193323Sed const_reverse_iterator rbegin() const { return Insts.rbegin(); } 139193323Sed reverse_iterator rend () { return Insts.rend(); } 140193323Sed const_reverse_iterator rend () const { return Insts.rend(); } 141193323Sed 142193323Sed // Machine-CFG iterators 143193323Sed typedef std::vector<MachineBasicBlock *>::iterator pred_iterator; 144193323Sed typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator; 145193323Sed typedef std::vector<MachineBasicBlock *>::iterator succ_iterator; 146193323Sed typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator; 147193323Sed typedef std::vector<MachineBasicBlock *>::reverse_iterator 148193323Sed pred_reverse_iterator; 149193323Sed typedef std::vector<MachineBasicBlock *>::const_reverse_iterator 150193323Sed const_pred_reverse_iterator; 151193323Sed typedef std::vector<MachineBasicBlock *>::reverse_iterator 152193323Sed succ_reverse_iterator; 153193323Sed typedef std::vector<MachineBasicBlock *>::const_reverse_iterator 154193323Sed const_succ_reverse_iterator; 155193323Sed 156193323Sed pred_iterator pred_begin() { return Predecessors.begin(); } 157193323Sed const_pred_iterator pred_begin() const { return Predecessors.begin(); } 158193323Sed pred_iterator pred_end() { return Predecessors.end(); } 159193323Sed const_pred_iterator pred_end() const { return Predecessors.end(); } 160193323Sed pred_reverse_iterator pred_rbegin() 161193323Sed { return Predecessors.rbegin();} 162193323Sed const_pred_reverse_iterator pred_rbegin() const 163193323Sed { return Predecessors.rbegin();} 164193323Sed pred_reverse_iterator pred_rend() 165193323Sed { return Predecessors.rend(); } 166193323Sed const_pred_reverse_iterator pred_rend() const 167193323Sed { return Predecessors.rend(); } 168193323Sed unsigned pred_size() const { 169193323Sed return (unsigned)Predecessors.size(); 170193323Sed } 171193323Sed bool pred_empty() const { return Predecessors.empty(); } 172193323Sed succ_iterator succ_begin() { return Successors.begin(); } 173193323Sed const_succ_iterator succ_begin() const { return Successors.begin(); } 174193323Sed succ_iterator succ_end() { return Successors.end(); } 175193323Sed const_succ_iterator succ_end() const { return Successors.end(); } 176193323Sed succ_reverse_iterator succ_rbegin() 177193323Sed { return Successors.rbegin(); } 178193323Sed const_succ_reverse_iterator succ_rbegin() const 179193323Sed { return Successors.rbegin(); } 180193323Sed succ_reverse_iterator succ_rend() 181193323Sed { return Successors.rend(); } 182193323Sed const_succ_reverse_iterator succ_rend() const 183193323Sed { return Successors.rend(); } 184193323Sed unsigned succ_size() const { 185193323Sed return (unsigned)Successors.size(); 186193323Sed } 187193323Sed bool succ_empty() const { return Successors.empty(); } 188193323Sed 189193323Sed // LiveIn management methods. 190193323Sed 191193323Sed /// addLiveIn - Add the specified register as a live in. Note that it 192193323Sed /// is an error to add the same register to the same set more than once. 193193323Sed void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); } 194193323Sed 195193323Sed /// removeLiveIn - Remove the specified register from the live in set. 196193323Sed /// 197193323Sed void removeLiveIn(unsigned Reg); 198193323Sed 199193323Sed /// isLiveIn - Return true if the specified register is in the live in set. 200193323Sed /// 201193323Sed bool isLiveIn(unsigned Reg) const; 202193323Sed 203193323Sed // Iteration support for live in sets. These sets are kept in sorted 204193323Sed // order by their register number. 205207618Srdivacky typedef std::vector<unsigned>::const_iterator livein_iterator; 206207618Srdivacky livein_iterator livein_begin() const { return LiveIns.begin(); } 207207618Srdivacky livein_iterator livein_end() const { return LiveIns.end(); } 208193323Sed bool livein_empty() const { return LiveIns.empty(); } 209193323Sed 210193323Sed /// getAlignment - Return alignment of the basic block. 211193323Sed /// 212193323Sed unsigned getAlignment() const { return Alignment; } 213193323Sed 214193323Sed /// setAlignment - Set alignment of the basic block. 215193323Sed /// 216193323Sed void setAlignment(unsigned Align) { Alignment = Align; } 217193323Sed 218193323Sed /// isLandingPad - Returns true if the block is a landing pad. That is 219193323Sed /// this basic block is entered via an exception handler. 220193323Sed bool isLandingPad() const { return IsLandingPad; } 221193323Sed 222193323Sed /// setIsLandingPad - Indicates the block is a landing pad. That is 223193323Sed /// this basic block is entered via an exception handler. 224193323Sed void setIsLandingPad() { IsLandingPad = true; } 225193323Sed 226193323Sed // Code Layout methods. 227193323Sed 228193323Sed /// moveBefore/moveAfter - move 'this' block before or after the specified 229193323Sed /// block. This only moves the block, it does not modify the CFG or adjust 230193323Sed /// potential fall-throughs at the end of the block. 231193323Sed void moveBefore(MachineBasicBlock *NewAfter); 232193323Sed void moveAfter(MachineBasicBlock *NewBefore); 233199481Srdivacky 234199481Srdivacky /// updateTerminator - Update the terminator instructions in block to account 235199481Srdivacky /// for changes to the layout. If the block previously used a fallthrough, 236199481Srdivacky /// it may now need a branch, and if it previously used branching it may now 237199481Srdivacky /// be able to use a fallthrough. 238199481Srdivacky void updateTerminator(); 239199481Srdivacky 240193323Sed // Machine-CFG mutators 241193323Sed 242193323Sed /// addSuccessor - Add succ as a successor of this MachineBasicBlock. 243193323Sed /// The Predecessors list of succ is automatically updated. 244193323Sed /// 245193323Sed void addSuccessor(MachineBasicBlock *succ); 246193323Sed 247193323Sed /// removeSuccessor - Remove successor from the successors list of this 248193323Sed /// MachineBasicBlock. The Predecessors list of succ is automatically updated. 249193323Sed /// 250193323Sed void removeSuccessor(MachineBasicBlock *succ); 251193323Sed 252193323Sed /// removeSuccessor - Remove specified successor from the successors list of 253193323Sed /// this MachineBasicBlock. The Predecessors list of succ is automatically 254193323Sed /// updated. Return the iterator to the element after the one removed. 255193323Sed /// 256193323Sed succ_iterator removeSuccessor(succ_iterator I); 257193323Sed 258193323Sed /// transferSuccessors - Transfers all the successors from MBB to this 259193323Sed /// machine basic block (i.e., copies all the successors fromMBB and 260199481Srdivacky /// remove all the successors from fromMBB). 261193323Sed void transferSuccessors(MachineBasicBlock *fromMBB); 262210299Sed 263210299Sed /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as 264210299Sed /// in transferSuccessors, and update PHI operands in the successor blocks 265210299Sed /// which refer to fromMBB to refer to this. 266210299Sed void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB); 267193323Sed 268193323Sed /// isSuccessor - Return true if the specified MBB is a successor of this 269193323Sed /// block. 270193323Sed bool isSuccessor(const MachineBasicBlock *MBB) const; 271193323Sed 272193323Sed /// isLayoutSuccessor - Return true if the specified MBB will be emitted 273193323Sed /// immediately after this block, such that if this block exits by 274193323Sed /// falling through, control will transfer to the specified MBB. Note 275193323Sed /// that MBB need not be a successor at all, for example if this block 276193323Sed /// ends with an unconditional branch to some other block. 277193323Sed bool isLayoutSuccessor(const MachineBasicBlock *MBB) const; 278193323Sed 279199989Srdivacky /// canFallThrough - Return true if the block can implicitly transfer 280199989Srdivacky /// control to the block after it by falling off the end of it. This should 281199989Srdivacky /// return false if it can reach the block after it, but it uses an explicit 282199989Srdivacky /// branch to do so (e.g., a table jump). True is a conservative answer. 283199989Srdivacky bool canFallThrough(); 284199989Srdivacky 285210299Sed /// Returns a pointer to the first instructon in this block that is not a 286210299Sed /// PHINode instruction. When adding instruction to the beginning of the 287210299Sed /// basic block, they should be added before the returned value, not before 288210299Sed /// the first instruction, which might be PHI. 289210299Sed /// Returns end() is there's no non-PHI instruction. 290210299Sed iterator getFirstNonPHI(); 291210299Sed 292193323Sed /// getFirstTerminator - returns an iterator to the first terminator 293193323Sed /// instruction of this basic block. If a terminator does not exist, 294193323Sed /// it returns end() 295193323Sed iterator getFirstTerminator(); 296193323Sed 297210299Sed /// SplitCriticalEdge - Split the critical edge from this block to the 298210299Sed /// given successor block, and return the newly created block, or null 299210299Sed /// if splitting is not possible. 300210299Sed /// 301210299Sed /// This function updates LiveVariables, MachineDominatorTree, and 302210299Sed /// MachineLoopInfo, as applicable. 303210299Sed MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P); 304210299Sed 305193323Sed void pop_front() { Insts.pop_front(); } 306193323Sed void pop_back() { Insts.pop_back(); } 307193323Sed void push_back(MachineInstr *MI) { Insts.push_back(MI); } 308193323Sed template<typename IT> 309193323Sed void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); } 310193323Sed iterator insert(iterator I, MachineInstr *M) { return Insts.insert(I, M); } 311193323Sed 312193323Sed // erase - Remove the specified element or range from the instruction list. 313193323Sed // These functions delete any instructions removed. 314193323Sed // 315193323Sed iterator erase(iterator I) { return Insts.erase(I); } 316193323Sed iterator erase(iterator I, iterator E) { return Insts.erase(I, E); } 317193323Sed MachineInstr *remove(MachineInstr *I) { return Insts.remove(I); } 318193323Sed void clear() { Insts.clear(); } 319193323Sed 320193323Sed /// splice - Take an instruction from MBB 'Other' at the position From, 321193323Sed /// and insert it into this MBB right before 'where'. 322193323Sed void splice(iterator where, MachineBasicBlock *Other, iterator From) { 323193323Sed Insts.splice(where, Other->Insts, From); 324193323Sed } 325193323Sed 326193323Sed /// splice - Take a block of instructions from MBB 'Other' in the range [From, 327193323Sed /// To), and insert them into this MBB right before 'where'. 328193323Sed void splice(iterator where, MachineBasicBlock *Other, iterator From, 329193323Sed iterator To) { 330193323Sed Insts.splice(where, Other->Insts, From, To); 331193323Sed } 332193323Sed 333193323Sed /// removeFromParent - This method unlinks 'this' from the containing 334193323Sed /// function, and returns it, but does not delete it. 335193323Sed MachineBasicBlock *removeFromParent(); 336193323Sed 337193323Sed /// eraseFromParent - This method unlinks 'this' from the containing 338193323Sed /// function and deletes it. 339193323Sed void eraseFromParent(); 340193323Sed 341193323Sed /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to 342193323Sed /// 'Old', change the code and CFG so that it branches to 'New' instead. 343193323Sed void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New); 344193323Sed 345193323Sed /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in 346193323Sed /// the CFG to be inserted. If we have proven that MBB can only branch to 347193323Sed /// DestA and DestB, remove any other MBB successors from the CFG. DestA and 348193323Sed /// DestB can be null. Besides DestA and DestB, retain other edges leading 349193323Sed /// to LandingPads (currently there can be only one; we don't check or require 350193323Sed /// that here). Note it is possible that DestA and/or DestB are LandingPads. 351193323Sed bool CorrectExtraCFGEdges(MachineBasicBlock *DestA, 352193323Sed MachineBasicBlock *DestB, 353193323Sed bool isCond); 354193323Sed 355202878Srdivacky /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping 356203954Srdivacky /// any DBG_VALUE instructions. Return UnknownLoc if there is none. 357202878Srdivacky DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI); 358202878Srdivacky 359193323Sed // Debugging methods. 360193323Sed void dump() const; 361198090Srdivacky void print(raw_ostream &OS) const; 362193323Sed 363193323Sed /// getNumber - MachineBasicBlocks are uniquely numbered at the function 364193323Sed /// level, unless they're not in a MachineFunction yet, in which case this 365193323Sed /// will return -1. 366193323Sed /// 367193323Sed int getNumber() const { return Number; } 368193323Sed void setNumber(int N) { Number = N; } 369193323Sed 370203954Srdivacky /// getSymbol - Return the MCSymbol for this basic block. 371203954Srdivacky /// 372205218Srdivacky MCSymbol *getSymbol() const; 373203954Srdivacky 374193323Sedprivate: // Methods used to maintain doubly linked list of blocks... 375193323Sed friend struct ilist_traits<MachineBasicBlock>; 376193323Sed 377193323Sed // Machine-CFG mutators 378193323Sed 379193323Sed /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock. 380193323Sed /// Don't do this unless you know what you're doing, because it doesn't 381193323Sed /// update pred's successors list. Use pred->addSuccessor instead. 382193323Sed /// 383193323Sed void addPredecessor(MachineBasicBlock *pred); 384193323Sed 385193323Sed /// removePredecessor - Remove pred as a predecessor of this 386193323Sed /// MachineBasicBlock. Don't do this unless you know what you're 387193323Sed /// doing, because it doesn't update pred's successors list. Use 388193323Sed /// pred->removeSuccessor instead. 389193323Sed /// 390193323Sed void removePredecessor(MachineBasicBlock *pred); 391193323Sed}; 392193323Sed 393198090Srdivackyraw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB); 394193323Sed 395199481Srdivackyvoid WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t); 396199481Srdivacky 397193323Sed//===--------------------------------------------------------------------===// 398193323Sed// GraphTraits specializations for machine basic block graphs (machine-CFGs) 399193323Sed//===--------------------------------------------------------------------===// 400193323Sed 401193323Sed// Provide specializations of GraphTraits to be able to treat a 402193323Sed// MachineFunction as a graph of MachineBasicBlocks... 403193323Sed// 404193323Sed 405193323Sedtemplate <> struct GraphTraits<MachineBasicBlock *> { 406193323Sed typedef MachineBasicBlock NodeType; 407193323Sed typedef MachineBasicBlock::succ_iterator ChildIteratorType; 408193323Sed 409193323Sed static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; } 410193323Sed static inline ChildIteratorType child_begin(NodeType *N) { 411193323Sed return N->succ_begin(); 412193323Sed } 413193323Sed static inline ChildIteratorType child_end(NodeType *N) { 414193323Sed return N->succ_end(); 415193323Sed } 416193323Sed}; 417193323Sed 418193323Sedtemplate <> struct GraphTraits<const MachineBasicBlock *> { 419193323Sed typedef const MachineBasicBlock NodeType; 420193323Sed typedef MachineBasicBlock::const_succ_iterator ChildIteratorType; 421193323Sed 422193323Sed static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; } 423193323Sed static inline ChildIteratorType child_begin(NodeType *N) { 424193323Sed return N->succ_begin(); 425193323Sed } 426193323Sed static inline ChildIteratorType child_end(NodeType *N) { 427193323Sed return N->succ_end(); 428193323Sed } 429193323Sed}; 430193323Sed 431193323Sed// Provide specializations of GraphTraits to be able to treat a 432193323Sed// MachineFunction as a graph of MachineBasicBlocks... and to walk it 433193323Sed// in inverse order. Inverse order for a function is considered 434193323Sed// to be when traversing the predecessor edges of a MBB 435193323Sed// instead of the successor edges. 436193323Sed// 437193323Sedtemplate <> struct GraphTraits<Inverse<MachineBasicBlock*> > { 438193323Sed typedef MachineBasicBlock NodeType; 439193323Sed typedef MachineBasicBlock::pred_iterator ChildIteratorType; 440193323Sed static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) { 441193323Sed return G.Graph; 442193323Sed } 443193323Sed static inline ChildIteratorType child_begin(NodeType *N) { 444193323Sed return N->pred_begin(); 445193323Sed } 446193323Sed static inline ChildIteratorType child_end(NodeType *N) { 447193323Sed return N->pred_end(); 448193323Sed } 449193323Sed}; 450193323Sed 451193323Sedtemplate <> struct GraphTraits<Inverse<const MachineBasicBlock*> > { 452193323Sed typedef const MachineBasicBlock NodeType; 453193323Sed typedef MachineBasicBlock::const_pred_iterator ChildIteratorType; 454193323Sed static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) { 455193323Sed return G.Graph; 456193323Sed } 457193323Sed static inline ChildIteratorType child_begin(NodeType *N) { 458193323Sed return N->pred_begin(); 459193323Sed } 460193323Sed static inline ChildIteratorType child_end(NodeType *N) { 461193323Sed return N->pred_end(); 462193323Sed } 463193323Sed}; 464193323Sed 465193323Sed} // End llvm namespace 466193323Sed 467193323Sed#endif 468