diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFGraph.h')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFGraph.h | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFGraph.h b/llvm/lib/Target/Hexagon/RDFGraph.h index 56ae6a7c507..981ad1471e2 100644 --- a/llvm/lib/Target/Hexagon/RDFGraph.h +++ b/llvm/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(); |