diff options
Diffstat (limited to 'src/jit/sideeffects.h')
-rw-r--r-- | src/jit/sideeffects.h | 158 |
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_ |