summaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/RDFGraph.h
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-09-07 20:10:56 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-09-07 20:10:56 +0000
commit80708afe4319e96a3e77b5d21aa9ddbe1a4d5acb (patch)
tree1dfd1a09b4133987ec7eed4fc6672705c5667c47 /lib/Target/Hexagon/RDFGraph.h
parentf1708bca4900b4695afcc7f5dcd6051b45aa3283 (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.h36
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();