summaryrefslogtreecommitdiff
path: root/src/jit/sideeffects.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/sideeffects.h')
-rw-r--r--src/jit/sideeffects.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/jit/sideeffects.h b/src/jit/sideeffects.h
new file mode 100644
index 0000000000..33fac16f05
--- /dev/null
+++ b/src/jit/sideeffects.h
@@ -0,0 +1,158 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifndef _SIDEEFFECTS_H_
+#define _SIDEEFFECTS_H_
+
+//------------------------------------------------------------------------
+// LclVarSet:
+// Represents a set of lclVars. Optimized for the case that the set
+// never holds more than a single element. This type is used internally
+// by `AliasSet` to track the sets of lclVars that are read and
+// written for a given alias set.
+//
+class LclVarSet final
+{
+ union {
+ hashBv* m_bitVector;
+ unsigned m_lclNum;
+ };
+
+ bool m_hasAnyLcl;
+ bool m_hasBitVector;
+
+public:
+ LclVarSet();
+
+ inline bool IsEmpty() const
+ {
+ return !m_hasAnyLcl || !m_hasBitVector || !m_bitVector->anySet();
+ }
+
+ void Add(Compiler* compiler, unsigned lclNum);
+ bool Intersects(const LclVarSet& other) const;
+ bool Contains(unsigned lclNum) const;
+ void Clear();
+};
+
+//------------------------------------------------------------------------
+// AliasSet:
+// Represents a set of reads and writes for the purposes of alias
+// analysis. This type partitions storage into two categories:
+// lclVars and addressable locations. The definition of the former is
+// intuitive. The latter is the union of the set of address-exposed
+// lclVars with the set of all other memory locations. Any memory
+// access is assumed to alias any other memory access.
+//
+class AliasSet final
+{
+ LclVarSet m_lclVarReads;
+ LclVarSet m_lclVarWrites;
+
+ bool m_readsAddressableLocation;
+ bool m_writesAddressableLocation;
+
+public:
+ //------------------------------------------------------------------------
+ // AliasSet::NodeInfo:
+ // Represents basic alias information for a single IR node.
+ //
+ class NodeInfo final
+ {
+ enum : unsigned
+ {
+ ALIAS_NONE = 0x0,
+ ALIAS_READS_ADDRESSABLE_LOCATION = 0x1,
+ ALIAS_WRITES_ADDRESSABLE_LOCATION = 0x2,
+ ALIAS_READS_LCL_VAR = 0x4,
+ ALIAS_WRITES_LCL_VAR = 0x8
+ };
+
+ Compiler* m_compiler;
+ GenTree* m_node;
+ unsigned m_flags;
+ unsigned m_lclNum;
+
+ public:
+ NodeInfo(Compiler* compiler, GenTree* node);
+
+ inline Compiler* TheCompiler() const
+ {
+ return m_compiler;
+ }
+
+ inline GenTree* Node() const
+ {
+ return m_node;
+ }
+
+ inline bool ReadsAddressableLocation() const
+ {
+ return (m_flags & ALIAS_READS_ADDRESSABLE_LOCATION) != 0;
+ }
+
+ inline bool WritesAddressableLocation() const
+ {
+ return (m_flags & ALIAS_WRITES_ADDRESSABLE_LOCATION) != 0;
+ }
+
+ inline bool IsLclVarRead() const
+ {
+ return (m_flags & ALIAS_READS_LCL_VAR) != 0;
+ }
+
+ inline bool IsLclVarWrite() const
+ {
+ return (m_flags & ALIAS_WRITES_LCL_VAR) != 0;
+ }
+
+ inline unsigned LclNum() const
+ {
+ assert(IsLclVarRead() || IsLclVarWrite());
+ return m_lclNum;
+ }
+
+ inline bool WritesAnyLocation() const
+ {
+ return (m_flags & (ALIAS_WRITES_ADDRESSABLE_LOCATION | ALIAS_WRITES_LCL_VAR)) != 0;
+ }
+ };
+
+ AliasSet();
+
+ inline bool WritesAnyLocation() const
+ {
+ return m_writesAddressableLocation || !m_lclVarWrites.IsEmpty();
+ }
+
+ void AddNode(Compiler* compiler, GenTree* node);
+ bool InterferesWith(const AliasSet& other) const;
+ bool InterferesWith(const NodeInfo& node) const;
+ void Clear();
+};
+
+//------------------------------------------------------------------------
+// SideEffectSet:
+// Represents a set of side effects for the purposes of analyzing code
+// motion.
+//
+class SideEffectSet final
+{
+ unsigned m_sideEffectFlags; // A mask of GTF_* flags that represents exceptional and barrier side effects.
+ AliasSet m_aliasSet; // An AliasSet that represents read and write side effects.
+
+ template <typename TOtherAliasInfo>
+ bool InterferesWith(unsigned otherSideEffectFlags, const TOtherAliasInfo& otherAliasInfo, bool strict) const;
+
+public:
+ SideEffectSet();
+ SideEffectSet(Compiler* compiler, GenTree* node);
+
+ void AddNode(Compiler* compiler, GenTree* node);
+ bool InterferesWith(const SideEffectSet& other, bool strict) const;
+ bool InterferesWith(Compiler* compiler, GenTree* node, bool strict) const;
+ void Clear();
+};
+
+#endif // _SIDEEFFECTS_H_