diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-09-07 20:10:56 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-09-07 20:10:56 +0000 |
commit | 80708afe4319e96a3e77b5d21aa9ddbe1a4d5acb (patch) | |
tree | 1dfd1a09b4133987ec7eed4fc6672705c5667c47 /lib/Target/Hexagon/RDFGraph.h | |
parent | f1708bca4900b4695afcc7f5dcd6051b45aa3283 (diff) |
[RDF] Introduce "undef" flag for ref nodes
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280851 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Hexagon/RDFGraph.h')
-rw-r--r-- | lib/Target/Hexagon/RDFGraph.h | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/Target/Hexagon/RDFGraph.h b/lib/Target/Hexagon/RDFGraph.h index 56ae6a7c507..981ad1471e2 100644 --- a/lib/Target/Hexagon/RDFGraph.h +++ b/lib/Target/Hexagon/RDFGraph.h @@ -175,7 +175,22 @@ // - Clobbering: applied only to defs, indicates that the value generated // by this def is unspecified. A typical example would be volatile registers // after function calls. -// +// - Fixed: the register in this def/use cannot be replaced with any other +// register. A typical case would be a parameter register to a call, or +// the register with the return value from a function. +// - Undef: the register in this reference the register is assumed to have +// no pre-existing value, even if it appears to be reached by some def. +// This is typically used to prevent keeping registers artificially live +// in cases when they are defined via predicated instructions. For example: +// r0 = add-if-true cond, r10, r11 (1) +// r0 = add-if-false cond, r12, r13, r0<imp-use> (2) +// ... = r0 (3) +// Before (1), r0 is not intended to be live, and the use of r0 in (3) is +// not meant to be reached by any def preceding (1). However, since the +// defs in (1) and (2) are both preserving, these properties alone would +// imply that the use in (3) may indeed be reached by some prior def. +// Adding Undef flag to the def in (1) prevents that. The Undef flag +// may be applied to both defs and uses. // // *** Shadow references // @@ -244,13 +259,14 @@ namespace rdf { Block = 0x0005 << 2, // 101 Func = 0x0006 << 2, // 110 - // Flags: 5 bits for now - FlagMask = 0x001F << 5, - Shadow = 0x0001 << 5, // 00001, Has extra reaching defs. - Clobbering = 0x0002 << 5, // 00010, Produces unspecified values. - PhiRef = 0x0004 << 5, // 00100, Member of PhiNode. - Preserving = 0x0008 << 5, // 01000, Def can keep original bits. - Fixed = 0x0010 << 5, // 10000, Fixed register. + // Flags: 6 bits for now + FlagMask = 0x003F << 5, + Shadow = 0x0001 << 5, // 000001, Has extra reaching defs. + Clobbering = 0x0002 << 5, // 000010, Produces unspecified values. + PhiRef = 0x0004 << 5, // 000100, Member of PhiNode. + Preserving = 0x0008 << 5, // 001000, Def can keep original bits. + Fixed = 0x0010 << 5, // 010000, Fixed register. + Undef = 0x0020 << 5, // 100000, Has no pre-existing value. }; static uint16_t type(uint16_t T) { return T & TypeMask; } @@ -742,6 +758,10 @@ namespace rdf { return BA.Addr->getType() == NodeAttrs::Code && BA.Addr->getKind() == NodeAttrs::Phi; } + static bool IsPreservingDef(const NodeAddr<DefNode*> DA) { + uint16_t Flags = DA.Addr->getFlags(); + return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef); + } private: void reset(); |