Go to the documentation of this file.
224 #ifndef LLVM_CODEGEN_RDFGRAPH_H
225 #define LLVM_CODEGEN_RDFGRAPH_H
238 #include <unordered_map>
245 static_assert(
sizeof(
uint32_t) ==
sizeof(
unsigned),
"Those should be equal");
249 class MachineBasicBlock;
250 class MachineDominanceFrontier;
251 class MachineDominatorTree;
252 class MachineFunction;
254 class MachineOperand;
256 class TargetInstrInfo;
257 class TargetRegisterInfo;
319 return KB ==
Phi || KB ==
Stmt;
379 : NodesPerBlock(NPB), BitsPerIndex(
Log2_32(NPB)),
380 IndexMask((1 << BitsPerIndex)-1) {
386 uint32_t BlockN = N1 >> BitsPerIndex;
388 return reinterpret_cast<NodeBase*
>(Blocks[BlockN]+Offset);
396 void startNewBlock();
401 return ((Block << BitsPerIndex) |
Index) + 1;
407 char *ActiveEnd =
nullptr;
408 std::vector<char*> Blocks;
446 return LM.
all() ? 0 :
find(LM);
468 void init() { memset(
this, 0,
sizeof *
this); }
511 "NodeBase must be at most NodeAllocator::NodeMemSize bytes");
553 template <
typename Predicate>
593 return static_cast<T>(
Code.
CP);
607 template <
typename Predicate>
623 return CodeNode::getCode<MachineInstr*>();
629 return CodeNode::getCode<MachineBasicBlock*>();
637 return CodeNode::getCode<MachineFunction*>();
655 return static_cast<T>(
ptr(
N));
661 return { ptr<T>(
N),
N };
683 Iterator &up() { Pos = DS.nextUp(Pos);
return *
this; }
684 Iterator &down() { Pos = DS.nextDown(Pos);
return *
this; }
688 return DS.Stack[Pos-1];
690 const value_type *operator->()
const {
692 return &DS.Stack[Pos-1];
713 unsigned size()
const;
723 using StorageType = std::vector<value_type>;
725 bool isDelimiter(
const StorageType::value_type &
P,
NodeId N = 0)
const {
726 return (
P.Addr ==
nullptr) && (
N == 0 ||
P.Id ==
N);
729 unsigned nextUp(
unsigned P)
const;
730 unsigned nextDown(
unsigned P)
const;
768 return BlockNodes.at(
BB);
784 template <u
int16_t Kind>
790 template <u
int16_t Kind>
839 template <
typename Predicate>
844 using BlockRefsMap = std::map<NodeId, RegisterSet>;
848 void buildPhis(BlockRefsMap &PhiM,
RegisterSet &AllRefs,
850 void removeUnusedPhis();
856 template <
typename Predicate>
void linkStmtRefs(
DefStackMap &DefM,
865 IA.Addr->removeMember(
RA, *
this);
869 std::unique_ptr<TargetOperandInfo> DefaultTOI;
874 const PhysicalRegisterInfo PRI;
877 const TargetOperandInfo &TOI;
879 RegisterAggr LiveIns;
880 NodeAddr<FuncNode*> Func;
883 std::map<MachineBasicBlock*,NodeAddr<BlockNode*>> BlockNodes;
888 template <
typename Predicate>
895 while (NA.Addr !=
this) {
898 if (
RA.Addr->getRegRef(
G) == RR &&
P(NA))
902 NA =
G.addr<
NodeBase*>(NA.Addr->getNext());
907 NA = CA.
Addr->getFirstMember(
G);
914 template <
typename Predicate>
921 while (
M.Addr !=
this) {
929 template <
typename T>
939 template <
typename T>
950 const Print<NodeAddr<PhiUseNode *>> &
P);
956 const Print<NodeAddr<StmtNode *>> &
P);
958 const Print<NodeAddr<InstrNode *>> &
P);
960 const Print<NodeAddr<BlockNode *>> &
P);
962 const Print<NodeAddr<FuncNode *>> &
P);
966 const Print<DataFlowGraph::DefStack> &
P);
972 #endif // LLVM_CODEGEN_RDFGRAPH_H
MachineFunction & getMF() const
NodeId getSibling() const
static uint16_t kind(uint16_t T)
NodeId getPredecessor() const
std::set< RegisterRef > RegisterSet
virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const
This is an optimization pass for GlobalISel generic memory operations.
void setReachedUse(NodeId U)
TargetOperandInfo(const TargetInstrInfo &tii)
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
NodeList getRelatedRefs(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA) const
void push(NodeAddr< DefNode * > DA)
void setReachingDef(NodeId RD)
static bool IsPreservingDef(const NodeAddr< DefNode * > DA)
NodeList members_if(Predicate P, const DataFlowGraph &G) const
NodeId id(const NodeBase *P) const
bool operator!=(const NodeAddr< T > &NA) const
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
NodeId getReachedUse() const
void linkToDef(NodeId Self, NodeAddr< DefNode * > DA)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
const TargetInstrInfo & TII
virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void addPhi(NodeAddr< PhiNode * > PA, const DataFlowGraph &G)
Reg
All possible values of the reg field in the ModR/M byte.
LaneBitmask get(uint32_t Idx) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void unlinkUse(NodeAddr< UseNode * > UA, bool RemoveFromOwner)
void releaseBlock(NodeId B, DefStackMap &DefM)
virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const
bool operator!=(uint64_t V1, const APInt &V2)
uint16_t getAttrs() const
NodeAddr< RefNode * > getNextRelated(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA) const
should just be implemented with a CLZ instruction Since there are other e g
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
static bool contains(uint16_t A, uint16_t B)
unsigned const TargetRegisterInfo * TRI
uint32_t getIndexForLaneMask(LaneBitmask LM) const
uint16_t getFlags() const
const TargetInstrInfo & getTII() const
NodeAddr< FuncNode * > getFunc() const
TargetInstrInfo - Interface to description of machine instruction set.
const MachineDominatorTree & getDT() const
static uint16_t set_flags(uint16_t A, uint16_t F)
PrintNode(const NodeAddr< T > &x, const DataFlowGraph &g)
RegisterRef getRegRef(const DataFlowGraph &G) const
(vector float) vec_cmpeq(*A, *B) C
NodeAllocator(uint32_t NPB=4096)
static uint16_t set_type(uint16_t A, uint16_t T)
const HexagonInstrInfo * TII
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii, const TargetRegisterInfo &tri, const MachineDominatorTree &mdt, const MachineDominanceFrontier &mdf)
static bool IsDef(const NodeAddr< NodeBase * > BA)
NodeBase * ptr(NodeId N) const
void addMemberAfter(NodeAddr< NodeBase * > MA, NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
void clear_block(NodeId N)
void linkToDef(NodeId Self, NodeAddr< DefNode * > DA)
RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
static bool IsCode(const NodeAddr< NodeBase * > BA)
void setReachedDef(NodeId D)
NodeAddr< T > addr(NodeId N) const
static bool IsRef(const NodeAddr< NodeBase * > BA)
Representation of each machine instruction.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
const TargetRegisterInfo & getTRI() const
void addMember(NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
RegisterRef unpack(PackedRegisterRef PR) const
NodeList members(const DataFlowGraph &G) const
void setPredecessor(NodeId B)
const PhysicalRegisterInfo & getPRI() const
constexpr bool any() const
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
void markBlock(NodeId B, DefStackMap &DefM)
LaneBitmask getLaneMaskForIndex(uint32_t K) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool IsPhi(const NodeAddr< NodeBase * > BA)
uint32_t find(LaneBitmask Val) const
bool operator==(uint64_t V1, const APInt &V2)
SI optimize exec mask operations pre RA
bool operator==(const NodeAddr< T > &NA) const
Print(const T &x, const DataFlowGraph &g)
void pushAllDefs(NodeAddr< InstrNode * > IA, DefStackMap &DM)
MachineInstr * getCode() const
NodeAddr< NodeBase * > getFirstMember(const DataFlowGraph &G) const
APInt operator*(APInt a, uint64_t RHS)
This class provides various memory handling functions that manipulate MemoryBlock instances.
const MachineDominanceFrontier & getDF() const
MachineFunction * getCode() const
Print(const T &, const DataFlowGraph &) -> Print< T >
static uint16_t type(uint16_t T)
static bool IsUse(const NodeAddr< NodeBase * > BA)
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
const RegisterAggr & getLiveIns() const
void removeMember(NodeAddr< NodeBase * > NA, const DataFlowGraph &G)
void setRegRef(RegisterRef RR, DataFlowGraph &G)
PackedRegisterRef pack(RegisterRef RR)
void build(unsigned Options=BuildOptions::None)
NodeAddr< NodeBase * > getLastMember(const DataFlowGraph &G) const
void setAttrs(uint16_t A)
constexpr bool all() const
void setFlags(uint16_t F)
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
NodeId getReachedDef() const
MachineInstr * getCode() const
static uint16_t set_kind(uint16_t A, uint16_t K)
PackedRegisterRef pack(RegisterRef RR) const
NodeAddr< BlockNode * > getEntryBlock(const DataFlowGraph &G)
NodeId getReachingDef() const
void unlinkDef(NodeAddr< DefNode * > DA, bool RemoveFromOwner)
std::set< NodeId > NodeSet
uint32_t insert(LaneBitmask Val)
MachineBasicBlock * getCode() const
uint32_t getIndexForLaneMask(LaneBitmask LM)
static uint16_t flags(uint16_t T)
NodeBase * ptr(NodeId N) const
void append(NodeAddr< NodeBase * > NA)
NodeAddr< BlockNode * > findBlock(const MachineBasicBlock *BB, const DataFlowGraph &G) const
void start_block(NodeId N)
NodeAddr< RefNode * > getNextShadow(NodeAddr< InstrNode * > IA, NodeAddr< RefNode * > RA, bool Create)
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
NodeAddr(const NodeAddr< S > &NA)
NodeAddr< RefNode * > getNextRef(RegisterRef RR, Predicate P, bool NextOnly, const DataFlowGraph &G)
virtual ~TargetOperandInfo()=default
NodeId id(const NodeBase *P) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
NodeAddr< BlockNode * > findBlock(MachineBasicBlock *BB) const
void setSibling(NodeId Sib)
static constexpr LaneBitmask getAll()
A Use represents the edge between a Value definition and its users.
std::unordered_map< RegisterId, DefStack > DefStackMap
NodeAddr< NodeBase * > getOwner(const DataFlowGraph &G)
NodeAddr< NodeBase * > New()