File indexing completed on 2026-05-10 08:43:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 #ifndef LLVM_CODEGEN_RDFGRAPH_H
0225 #define LLVM_CODEGEN_RDFGRAPH_H
0226
0227 #include "RDFRegisters.h"
0228 #include "llvm/ADT/ArrayRef.h"
0229 #include "llvm/ADT/SmallVector.h"
0230 #include "llvm/MC/LaneBitmask.h"
0231 #include "llvm/Support/Allocator.h"
0232 #include "llvm/Support/MathExtras.h"
0233 #include <cassert>
0234 #include <cstdint>
0235 #include <cstring>
0236 #include <map>
0237 #include <memory>
0238 #include <set>
0239 #include <unordered_map>
0240 #include <utility>
0241 #include <vector>
0242
0243
0244
0245
0246 static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
0247
0248 namespace llvm {
0249
0250 class MachineBasicBlock;
0251 class MachineDominanceFrontier;
0252 class MachineDominatorTree;
0253 class MachineFunction;
0254 class MachineInstr;
0255 class MachineOperand;
0256 class raw_ostream;
0257 class TargetInstrInfo;
0258 class TargetRegisterInfo;
0259
0260 namespace rdf {
0261
0262 using NodeId = uint32_t;
0263
0264 struct DataFlowGraph;
0265
0266 struct NodeAttrs {
0267
0268 enum : uint16_t {
0269 None = 0x0000,
0270
0271
0272 TypeMask = 0x0003,
0273 Code = 0x0001,
0274 Ref = 0x0002,
0275
0276
0277 KindMask = 0x0007 << 2,
0278 Def = 0x0001 << 2,
0279 Use = 0x0002 << 2,
0280 Phi = 0x0003 << 2,
0281 Stmt = 0x0004 << 2,
0282 Block = 0x0005 << 2,
0283 Func = 0x0006 << 2,
0284
0285
0286 FlagMask = 0x007F << 5,
0287 Shadow = 0x0001 << 5,
0288 Clobbering = 0x0002 << 5,
0289 PhiRef = 0x0004 << 5,
0290 Preserving = 0x0008 << 5,
0291 Fixed = 0x0010 << 5,
0292 Undef = 0x0020 << 5,
0293 Dead = 0x0040 << 5,
0294 };
0295
0296
0297 static uint16_t type(uint16_t T) {
0298 return T & TypeMask;
0299 }
0300 static uint16_t kind(uint16_t T) {
0301 return T & KindMask;
0302 }
0303 static uint16_t flags(uint16_t T) {
0304 return T & FlagMask;
0305 }
0306 static uint16_t set_type(uint16_t A, uint16_t T) {
0307 return (A & ~TypeMask) | T;
0308 }
0309
0310 static uint16_t set_kind(uint16_t A, uint16_t K) {
0311 return (A & ~KindMask) | K;
0312 }
0313
0314 static uint16_t set_flags(uint16_t A, uint16_t F) {
0315 return (A & ~FlagMask) | F;
0316 }
0317
0318
0319 static bool contains(uint16_t A, uint16_t B) {
0320 if (type(A) != Code)
0321 return false;
0322 uint16_t KB = kind(B);
0323 switch (kind(A)) {
0324 case Func:
0325 return KB == Block;
0326 case Block:
0327 return KB == Phi || KB == Stmt;
0328 case Phi:
0329 case Stmt:
0330 return type(B) == Ref;
0331 }
0332 return false;
0333 }
0334 };
0335
0336 struct BuildOptions {
0337 enum : unsigned {
0338 None = 0x00,
0339 KeepDeadPhis = 0x01,
0340 OmitReserved = 0x02,
0341 };
0342 };
0343
0344 template <typename T> struct NodeAddr {
0345 NodeAddr() = default;
0346 NodeAddr(T A, NodeId I) : Addr(A), Id(I) {}
0347
0348
0349
0350 template <typename S>
0351 NodeAddr(const NodeAddr<S> &NA) : Addr(static_cast<T>(NA.Addr)), Id(NA.Id) {}
0352
0353 bool operator==(const NodeAddr<T> &NA) const {
0354 assert((Addr == NA.Addr) == (Id == NA.Id));
0355 return Addr == NA.Addr;
0356 }
0357 bool operator!=(const NodeAddr<T> &NA) const {
0358 return !operator==(NA);
0359 }
0360
0361 T Addr = nullptr;
0362 NodeId Id = 0;
0363 };
0364
0365 struct NodeBase;
0366
0367 struct RefNode;
0368 struct DefNode;
0369 struct UseNode;
0370 struct PhiUseNode;
0371
0372 struct CodeNode;
0373 struct InstrNode;
0374 struct PhiNode;
0375 struct StmtNode;
0376 struct BlockNode;
0377 struct FuncNode;
0378
0379
0380
0381 using Node = NodeAddr<NodeBase *>;
0382
0383 using Ref = NodeAddr<RefNode *>;
0384 using Def = NodeAddr<DefNode *>;
0385 using Use = NodeAddr<UseNode *>;
0386 using PhiUse = NodeAddr<PhiUseNode *>;
0387
0388 using Code = NodeAddr<CodeNode *>;
0389 using Instr = NodeAddr<InstrNode *>;
0390 using Phi = NodeAddr<PhiNode *>;
0391 using Stmt = NodeAddr<StmtNode *>;
0392 using Block = NodeAddr<BlockNode *>;
0393 using Func = NodeAddr<FuncNode *>;
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 struct NodeAllocator {
0412
0413 enum { NodeMemSize = 32 };
0414
0415 NodeAllocator(uint32_t NPB = 4096)
0416 : NodesPerBlock(NPB), BitsPerIndex(Log2_32(NPB)),
0417 IndexMask((1 << BitsPerIndex) - 1) {
0418 assert(isPowerOf2_32(NPB));
0419 }
0420
0421 NodeBase *ptr(NodeId N) const {
0422 uint32_t N1 = N - 1;
0423 uint32_t BlockN = N1 >> BitsPerIndex;
0424 uint32_t Offset = (N1 & IndexMask) * NodeMemSize;
0425 return reinterpret_cast<NodeBase *>(Blocks[BlockN] + Offset);
0426 }
0427
0428 NodeId id(const NodeBase *P) const;
0429 Node New();
0430 void clear();
0431
0432 private:
0433 void startNewBlock();
0434 bool needNewBlock();
0435
0436 uint32_t makeId(uint32_t Block, uint32_t Index) const {
0437
0438 return ((Block << BitsPerIndex) | Index) + 1;
0439 }
0440
0441 const uint32_t NodesPerBlock;
0442 const uint32_t BitsPerIndex;
0443 const uint32_t IndexMask;
0444 char *ActiveEnd = nullptr;
0445 std::vector<char *> Blocks;
0446 using AllocatorTy = BumpPtrAllocatorImpl<MallocAllocator, 65536>;
0447 AllocatorTy MemPool;
0448 };
0449
0450 using RegisterSet = std::set<RegisterRef>;
0451
0452 struct TargetOperandInfo {
0453 TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
0454 virtual ~TargetOperandInfo() = default;
0455
0456 virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const;
0457 virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const;
0458 virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const;
0459
0460 const TargetInstrInfo &TII;
0461 };
0462
0463
0464 struct PackedRegisterRef {
0465 RegisterId Reg;
0466 uint32_t MaskId;
0467 };
0468
0469 struct LaneMaskIndex : private IndexedSet<LaneBitmask> {
0470 LaneMaskIndex() = default;
0471
0472 LaneBitmask getLaneMaskForIndex(uint32_t K) const {
0473 return K == 0 ? LaneBitmask::getAll() : get(K);
0474 }
0475
0476 uint32_t getIndexForLaneMask(LaneBitmask LM) {
0477 assert(LM.any());
0478 return LM.all() ? 0 : insert(LM);
0479 }
0480
0481 uint32_t getIndexForLaneMask(LaneBitmask LM) const {
0482 assert(LM.any());
0483 return LM.all() ? 0 : find(LM);
0484 }
0485 };
0486
0487 struct NodeBase {
0488 public:
0489
0490 NodeBase() = default;
0491
0492 uint16_t getType() const { return NodeAttrs::type(Attrs); }
0493 uint16_t getKind() const { return NodeAttrs::kind(Attrs); }
0494 uint16_t getFlags() const { return NodeAttrs::flags(Attrs); }
0495 NodeId getNext() const { return Next; }
0496
0497 uint16_t getAttrs() const { return Attrs; }
0498 void setAttrs(uint16_t A) { Attrs = A; }
0499 void setFlags(uint16_t F) { setAttrs(NodeAttrs::set_flags(getAttrs(), F)); }
0500
0501
0502 void append(Node NA);
0503
0504
0505 void init() { memset(this, 0, sizeof *this); }
0506
0507 void setNext(NodeId N) { Next = N; }
0508
0509 protected:
0510 uint16_t Attrs;
0511 uint16_t Reserved;
0512 NodeId Next;
0513
0514
0515
0516 struct Def_struct {
0517 NodeId DD, DU;
0518 };
0519 struct PhiU_struct {
0520 NodeId PredB;
0521 };
0522 struct Code_struct {
0523 void *CP;
0524 NodeId FirstM, LastM;
0525 };
0526 struct Ref_struct {
0527 NodeId RD, Sib;
0528 union {
0529 Def_struct Def;
0530 PhiU_struct PhiU;
0531 };
0532 union {
0533 MachineOperand *Op;
0534 PackedRegisterRef PR;
0535 };
0536 };
0537
0538
0539 union {
0540 Ref_struct RefData;
0541 Code_struct CodeData;
0542 };
0543 };
0544
0545
0546
0547 static_assert(sizeof(NodeBase) <= NodeAllocator::NodeMemSize,
0548 "NodeBase must be at most NodeAllocator::NodeMemSize bytes");
0549
0550 using NodeList = SmallVector<Node, 4>;
0551 using NodeSet = std::set<NodeId>;
0552
0553 struct RefNode : public NodeBase {
0554 RefNode() = default;
0555
0556 RegisterRef getRegRef(const DataFlowGraph &G) const;
0557
0558 MachineOperand &getOp() {
0559 assert(!(getFlags() & NodeAttrs::PhiRef));
0560 return *RefData.Op;
0561 }
0562
0563 void setRegRef(RegisterRef RR, DataFlowGraph &G);
0564 void setRegRef(MachineOperand *Op, DataFlowGraph &G);
0565
0566 NodeId getReachingDef() const { return RefData.RD; }
0567 void setReachingDef(NodeId RD) { RefData.RD = RD; }
0568
0569 NodeId getSibling() const { return RefData.Sib; }
0570 void setSibling(NodeId Sib) { RefData.Sib = Sib; }
0571
0572 bool isUse() const {
0573 assert(getType() == NodeAttrs::Ref);
0574 return getKind() == NodeAttrs::Use;
0575 }
0576
0577 bool isDef() const {
0578 assert(getType() == NodeAttrs::Ref);
0579 return getKind() == NodeAttrs::Def;
0580 }
0581
0582 template <typename Predicate>
0583 Ref getNextRef(RegisterRef RR, Predicate P, bool NextOnly,
0584 const DataFlowGraph &G);
0585 Node getOwner(const DataFlowGraph &G);
0586 };
0587
0588 struct DefNode : public RefNode {
0589 NodeId getReachedDef() const { return RefData.Def.DD; }
0590 void setReachedDef(NodeId D) { RefData.Def.DD = D; }
0591 NodeId getReachedUse() const { return RefData.Def.DU; }
0592 void setReachedUse(NodeId U) { RefData.Def.DU = U; }
0593
0594 void linkToDef(NodeId Self, Def DA);
0595 };
0596
0597 struct UseNode : public RefNode {
0598 void linkToDef(NodeId Self, Def DA);
0599 };
0600
0601 struct PhiUseNode : public UseNode {
0602 NodeId getPredecessor() const {
0603 assert(getFlags() & NodeAttrs::PhiRef);
0604 return RefData.PhiU.PredB;
0605 }
0606 void setPredecessor(NodeId B) {
0607 assert(getFlags() & NodeAttrs::PhiRef);
0608 RefData.PhiU.PredB = B;
0609 }
0610 };
0611
0612 struct CodeNode : public NodeBase {
0613 template <typename T> T getCode() const {
0614 return static_cast<T>(CodeData.CP);
0615 }
0616 void setCode(void *C) { CodeData.CP = C; }
0617
0618 Node getFirstMember(const DataFlowGraph &G) const;
0619 Node getLastMember(const DataFlowGraph &G) const;
0620 void addMember(Node NA, const DataFlowGraph &G);
0621 void addMemberAfter(Node MA, Node NA, const DataFlowGraph &G);
0622 void removeMember(Node NA, const DataFlowGraph &G);
0623
0624 NodeList members(const DataFlowGraph &G) const;
0625 template <typename Predicate>
0626 NodeList members_if(Predicate P, const DataFlowGraph &G) const;
0627 };
0628
0629 struct InstrNode : public CodeNode {
0630 Node getOwner(const DataFlowGraph &G);
0631 };
0632
0633 struct PhiNode : public InstrNode {
0634 MachineInstr *getCode() const { return nullptr; }
0635 };
0636
0637 struct StmtNode : public InstrNode {
0638 MachineInstr *getCode() const {
0639 return CodeNode::getCode<MachineInstr *>();
0640 }
0641 };
0642
0643 struct BlockNode : public CodeNode {
0644 MachineBasicBlock *getCode() const {
0645 return CodeNode::getCode<MachineBasicBlock *>();
0646 }
0647
0648 void addPhi(Phi PA, const DataFlowGraph &G);
0649 };
0650
0651 struct FuncNode : public CodeNode {
0652 MachineFunction *getCode() const {
0653 return CodeNode::getCode<MachineFunction *>();
0654 }
0655
0656 Block findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const;
0657 Block getEntryBlock(const DataFlowGraph &G);
0658 };
0659
0660 struct DataFlowGraph {
0661 DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
0662 const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
0663 const MachineDominanceFrontier &mdf);
0664 DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
0665 const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
0666 const MachineDominanceFrontier &mdf,
0667 const TargetOperandInfo &toi);
0668
0669 struct Config {
0670 Config() = default;
0671 Config(unsigned Opts) : Options(Opts) {}
0672 Config(ArrayRef<const TargetRegisterClass *> RCs) : Classes(RCs) {}
0673 Config(ArrayRef<MCPhysReg> Track) : TrackRegs(Track.begin(), Track.end()) {}
0674 Config(ArrayRef<RegisterId> Track)
0675 : TrackRegs(Track.begin(), Track.end()) {}
0676
0677 unsigned Options = BuildOptions::None;
0678 SmallVector<const TargetRegisterClass *> Classes;
0679 std::set<RegisterId> TrackRegs;
0680 };
0681
0682 NodeBase *ptr(NodeId N) const;
0683 template <typename T> T ptr(NodeId N) const {
0684 return static_cast<T>(ptr(N));
0685 }
0686
0687 NodeId id(const NodeBase *P) const;
0688
0689 template <typename T> NodeAddr<T> addr(NodeId N) const {
0690 return {ptr<T>(N), N};
0691 }
0692
0693 Func getFunc() const { return TheFunc; }
0694 MachineFunction &getMF() const { return MF; }
0695 const TargetInstrInfo &getTII() const { return TII; }
0696 const TargetRegisterInfo &getTRI() const { return TRI; }
0697 const PhysicalRegisterInfo &getPRI() const { return PRI; }
0698 const MachineDominatorTree &getDT() const { return MDT; }
0699 const MachineDominanceFrontier &getDF() const { return MDF; }
0700 const RegisterAggr &getLiveIns() const { return LiveIns; }
0701
0702 struct DefStack {
0703 DefStack() = default;
0704
0705 bool empty() const { return Stack.empty() || top() == bottom(); }
0706
0707 private:
0708 using value_type = Def;
0709 struct Iterator {
0710 using value_type = DefStack::value_type;
0711
0712 Iterator &up() {
0713 Pos = DS.nextUp(Pos);
0714 return *this;
0715 }
0716 Iterator &down() {
0717 Pos = DS.nextDown(Pos);
0718 return *this;
0719 }
0720
0721 value_type operator*() const {
0722 assert(Pos >= 1);
0723 return DS.Stack[Pos - 1];
0724 }
0725 const value_type *operator->() const {
0726 assert(Pos >= 1);
0727 return &DS.Stack[Pos - 1];
0728 }
0729 bool operator==(const Iterator &It) const { return Pos == It.Pos; }
0730 bool operator!=(const Iterator &It) const { return Pos != It.Pos; }
0731
0732 private:
0733 friend struct DefStack;
0734
0735 Iterator(const DefStack &S, bool Top);
0736
0737
0738
0739 const DefStack &DS;
0740 unsigned Pos;
0741 };
0742
0743 public:
0744 using iterator = Iterator;
0745
0746 iterator top() const { return Iterator(*this, true); }
0747 iterator bottom() const { return Iterator(*this, false); }
0748 unsigned size() const;
0749
0750 void push(Def DA) { Stack.push_back(DA); }
0751 void pop();
0752 void start_block(NodeId N);
0753 void clear_block(NodeId N);
0754
0755 private:
0756 friend struct Iterator;
0757
0758 using StorageType = std::vector<value_type>;
0759
0760 bool isDelimiter(const StorageType::value_type &P, NodeId N = 0) const {
0761 return (P.Addr == nullptr) && (N == 0 || P.Id == N);
0762 }
0763
0764 unsigned nextUp(unsigned P) const;
0765 unsigned nextDown(unsigned P) const;
0766
0767 StorageType Stack;
0768 };
0769
0770
0771
0772 using DefStackMap = std::unordered_map<RegisterId, DefStack>;
0773
0774 void build(const Config &config);
0775 void build() { build(Config()); }
0776
0777 void pushAllDefs(Instr IA, DefStackMap &DM);
0778 void markBlock(NodeId B, DefStackMap &DefM);
0779 void releaseBlock(NodeId B, DefStackMap &DefM);
0780
0781 PackedRegisterRef pack(RegisterRef RR) {
0782 return {RR.Reg, LMI.getIndexForLaneMask(RR.Mask)};
0783 }
0784 PackedRegisterRef pack(RegisterRef RR) const {
0785 return {RR.Reg, LMI.getIndexForLaneMask(RR.Mask)};
0786 }
0787 RegisterRef unpack(PackedRegisterRef PR) const {
0788 return RegisterRef(PR.Reg, LMI.getLaneMaskForIndex(PR.MaskId));
0789 }
0790
0791 RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const;
0792 RegisterRef makeRegRef(const MachineOperand &Op) const;
0793
0794 Ref getNextRelated(Instr IA, Ref RA) const;
0795 Ref getNextShadow(Instr IA, Ref RA, bool Create);
0796
0797 NodeList getRelatedRefs(Instr IA, Ref RA) const;
0798
0799 Block findBlock(MachineBasicBlock *BB) const { return BlockNodes.at(BB); }
0800
0801 void unlinkUse(Use UA, bool RemoveFromOwner) {
0802 unlinkUseDF(UA);
0803 if (RemoveFromOwner)
0804 removeFromOwner(UA);
0805 }
0806
0807 void unlinkDef(Def DA, bool RemoveFromOwner) {
0808 unlinkDefDF(DA);
0809 if (RemoveFromOwner)
0810 removeFromOwner(DA);
0811 }
0812
0813 bool isTracked(RegisterRef RR) const;
0814 bool hasUntrackedRef(Stmt S, bool IgnoreReserved = true) const;
0815
0816
0817 template <uint16_t Kind> static bool IsRef(const Node BA) {
0818 return BA.Addr->getType() == NodeAttrs::Ref && BA.Addr->getKind() == Kind;
0819 }
0820
0821 template <uint16_t Kind> static bool IsCode(const Node BA) {
0822 return BA.Addr->getType() == NodeAttrs::Code && BA.Addr->getKind() == Kind;
0823 }
0824
0825 static bool IsDef(const Node BA) {
0826 return BA.Addr->getType() == NodeAttrs::Ref &&
0827 BA.Addr->getKind() == NodeAttrs::Def;
0828 }
0829
0830 static bool IsUse(const Node BA) {
0831 return BA.Addr->getType() == NodeAttrs::Ref &&
0832 BA.Addr->getKind() == NodeAttrs::Use;
0833 }
0834
0835 static bool IsPhi(const Node BA) {
0836 return BA.Addr->getType() == NodeAttrs::Code &&
0837 BA.Addr->getKind() == NodeAttrs::Phi;
0838 }
0839
0840 static bool IsPreservingDef(const Def DA) {
0841 uint16_t Flags = DA.Addr->getFlags();
0842 return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
0843 }
0844
0845 private:
0846 void reset();
0847
0848 RegisterAggr getLandingPadLiveIns() const;
0849
0850 Node newNode(uint16_t Attrs);
0851 Node cloneNode(const Node B);
0852 Use newUse(Instr Owner, MachineOperand &Op, uint16_t Flags = NodeAttrs::None);
0853 PhiUse newPhiUse(Phi Owner, RegisterRef RR, Block PredB,
0854 uint16_t Flags = NodeAttrs::PhiRef);
0855 Def newDef(Instr Owner, MachineOperand &Op, uint16_t Flags = NodeAttrs::None);
0856 Def newDef(Instr Owner, RegisterRef RR, uint16_t Flags = NodeAttrs::PhiRef);
0857 Phi newPhi(Block Owner);
0858 Stmt newStmt(Block Owner, MachineInstr *MI);
0859 Block newBlock(Func Owner, MachineBasicBlock *BB);
0860 Func newFunc(MachineFunction *MF);
0861
0862 template <typename Predicate>
0863 std::pair<Ref, Ref> locateNextRef(Instr IA, Ref RA, Predicate P) const;
0864
0865 using BlockRefsMap = RegisterAggrMap<NodeId>;
0866
0867 void buildStmt(Block BA, MachineInstr &In);
0868 void recordDefsForDF(BlockRefsMap &PhiM, Block BA);
0869 void buildPhis(BlockRefsMap &PhiM, Block BA);
0870 void removeUnusedPhis();
0871
0872 void pushClobbers(Instr IA, DefStackMap &DM);
0873 void pushDefs(Instr IA, DefStackMap &DM);
0874 template <typename T> void linkRefUp(Instr IA, NodeAddr<T> TA, DefStack &DS);
0875 template <typename Predicate>
0876 void linkStmtRefs(DefStackMap &DefM, Stmt SA, Predicate P);
0877 void linkBlockRefs(DefStackMap &DefM, Block BA);
0878
0879 void unlinkUseDF(Use UA);
0880 void unlinkDefDF(Def DA);
0881
0882 void removeFromOwner(Ref RA) {
0883 Instr IA = RA.Addr->getOwner(*this);
0884 IA.Addr->removeMember(RA, *this);
0885 }
0886
0887
0888 std::unique_ptr<TargetOperandInfo> DefaultTOI;
0889
0890 MachineFunction &MF;
0891 const TargetInstrInfo &TII;
0892 const TargetRegisterInfo &TRI;
0893 const PhysicalRegisterInfo PRI;
0894 const MachineDominatorTree &MDT;
0895 const MachineDominanceFrontier &MDF;
0896 const TargetOperandInfo &TOI;
0897
0898 RegisterAggr LiveIns;
0899 Func TheFunc;
0900 NodeAllocator Memory;
0901
0902 std::map<MachineBasicBlock *, Block> BlockNodes;
0903
0904 LaneMaskIndex LMI;
0905
0906 Config BuildCfg;
0907 std::set<unsigned> TrackedUnits;
0908 BitVector ReservedRegs;
0909 };
0910
0911 template <typename Predicate>
0912 Ref RefNode::getNextRef(RegisterRef RR, Predicate P, bool NextOnly,
0913 const DataFlowGraph &G) {
0914
0915
0916 auto NA = G.addr<NodeBase *>(getNext());
0917
0918 while (NA.Addr != this) {
0919 if (NA.Addr->getType() == NodeAttrs::Ref) {
0920 Ref RA = NA;
0921 if (G.getPRI().equal_to(RA.Addr->getRegRef(G), RR) && P(NA))
0922 return NA;
0923 if (NextOnly)
0924 break;
0925 NA = G.addr<NodeBase *>(NA.Addr->getNext());
0926 } else {
0927
0928 assert(NA.Addr->getType() == NodeAttrs::Code);
0929
0930
0931
0932
0933
0934
0935 if (NextOnly)
0936 break;
0937 Code CA = NA;
0938 NA = CA.Addr->getFirstMember(G);
0939 }
0940 }
0941
0942 return Ref();
0943 }
0944
0945 template <typename Predicate>
0946 NodeList CodeNode::members_if(Predicate P, const DataFlowGraph &G) const {
0947 NodeList MM;
0948 auto M = getFirstMember(G);
0949 if (M.Id == 0)
0950 return MM;
0951
0952 while (M.Addr != this) {
0953 if (P(M))
0954 MM.push_back(M);
0955 M = G.addr<NodeBase *>(M.Addr->getNext());
0956 }
0957 return MM;
0958 }
0959
0960 template <typename T> struct Print {
0961 Print(const T &x, const DataFlowGraph &g) : Obj(x), G(g) {}
0962
0963 const T &Obj;
0964 const DataFlowGraph &G;
0965 };
0966
0967 template <typename T> Print(const T &, const DataFlowGraph &) -> Print<T>;
0968
0969 template <typename T> struct PrintNode : Print<NodeAddr<T>> {
0970 PrintNode(const NodeAddr<T> &x, const DataFlowGraph &g)
0971 : Print<NodeAddr<T>>(x, g) {}
0972 };
0973
0974 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterRef> &P);
0975 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeId> &P);
0976 raw_ostream &operator<<(raw_ostream &OS, const Print<Def> &P);
0977 raw_ostream &operator<<(raw_ostream &OS, const Print<Use> &P);
0978 raw_ostream &operator<<(raw_ostream &OS, const Print<PhiUse> &P);
0979 raw_ostream &operator<<(raw_ostream &OS, const Print<Ref> &P);
0980 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeList> &P);
0981 raw_ostream &operator<<(raw_ostream &OS, const Print<NodeSet> &P);
0982 raw_ostream &operator<<(raw_ostream &OS, const Print<Phi> &P);
0983 raw_ostream &operator<<(raw_ostream &OS, const Print<Stmt> &P);
0984 raw_ostream &operator<<(raw_ostream &OS, const Print<Instr> &P);
0985 raw_ostream &operator<<(raw_ostream &OS, const Print<Block> &P);
0986 raw_ostream &operator<<(raw_ostream &OS, const Print<Func> &P);
0987 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterSet> &P);
0988 raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterAggr> &P);
0989 raw_ostream &operator<<(raw_ostream &OS,
0990 const Print<DataFlowGraph::DefStack> &P);
0991
0992 }
0993 }
0994
0995 #endif