Commit 932640b2 by Alexis Hetu Committed by Alexis Hétu

Std:unordered_map removed from Optimizer for improved performance

The use of std::unordered_map was the main source of slowdowns in the optimizer code, so it was re-written without any maps. In order to do so, the information originally carried by the maps was moved to user-defined information stored within Subzero classes. The optimizer now manages the memory used to store this information. Bug swiftshader:69 Bug b/67872293 Change-Id: I2757169f0d3d467766317af6e00e149b4317fb9c Reviewed-on: https://swiftshader-review.googlesource.com/19508Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent a9969b2a
...@@ -127,6 +127,9 @@ public: ...@@ -127,6 +127,9 @@ public:
} }
CfgNode *shortCircuit(); CfgNode *shortCircuit();
inline void* getExternalData() const { return externalData; }
inline void setExternalData(void* data) { externalData = data; }
private: private:
CfgNode(Cfg *Func, SizeT Number) CfgNode(Cfg *Func, SizeT Number)
: Func(Func), Number(Number), NumberOrig(Number), : Func(Func), Number(Number), NumberOrig(Number),
...@@ -145,6 +148,11 @@ private: ...@@ -145,6 +148,11 @@ private:
NodeList OutEdges; /// in no particular order NodeList OutEdges; /// in no particular order
PhiList Phis; /// unordered set of phi instructions PhiList Phis; /// unordered set of phi instructions
InstList Insts; /// ordered list of non-phi instructions InstList Insts; /// ordered list of non-phi instructions
/// External data can be set by an optimizer to compute and retain any
/// information related to the current node. All the memory used to
/// store this information must be managed by the optimizer.
void* externalData = nullptr;
}; };
} // end of namespace Ice } // end of namespace Ice
......
...@@ -199,6 +199,9 @@ public: ...@@ -199,6 +199,9 @@ public:
llvm::report_fatal_error("Inst unexpectedly deleted"); llvm::report_fatal_error("Inst unexpectedly deleted");
} }
inline void* getExternalData() const { return externalData; }
inline void setExternalData(void* data) { externalData = data; }
protected: protected:
Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest); Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest);
void addSource(Operand *Src) { void addSource(Operand *Src) {
...@@ -236,6 +239,10 @@ protected: ...@@ -236,6 +239,10 @@ protected:
/// live range recorded in a basic block has at most one start and at most one /// live range recorded in a basic block has at most one start and at most one
/// end. /// end.
bool IsDestRedefined = false; bool IsDestRedefined = false;
/// External data can be set by an optimizer to compute and retain any
/// information related to the current instruction. All the memory used to
/// store this information must be managed by the optimizer.
void* externalData = nullptr;
Variable *Dest; Variable *Dest;
const SizeT MaxSrcs; // only used for assert const SizeT MaxSrcs; // only used for assert
......
...@@ -106,6 +106,9 @@ public: ...@@ -106,6 +106,9 @@ public:
return 0; return 0;
} }
inline void* getExternalData() const { return externalData; }
inline void setExternalData(void* data) { externalData = data; }
protected: protected:
Operand(OperandKind Kind, Type Ty) : Ty(Ty), Kind(Kind) { Operand(OperandKind Kind, Type Ty) : Ty(Ty), Kind(Kind) {
// It is undefined behavior to have a larger value in the enum // It is undefined behavior to have a larger value in the enum
...@@ -117,6 +120,11 @@ protected: ...@@ -117,6 +120,11 @@ protected:
/// Vars and NumVars are initialized by the derived class. /// Vars and NumVars are initialized by the derived class.
SizeT NumVars = 0; SizeT NumVars = 0;
Variable **Vars = nullptr; Variable **Vars = nullptr;
/// External data can be set by an optimizer to compute and retain any
/// information related to the current operand. All the memory used to
/// store this information must be managed by the optimizer.
void* externalData = nullptr;
}; };
template <class StreamType> template <class StreamType>
...@@ -854,6 +862,9 @@ public: ...@@ -854,6 +862,9 @@ public:
SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); } SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); }
inline void* getExternalData() const { return externalData; }
inline void setExternalData(void* data) { externalData = data; }
protected: protected:
Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index)
: Operand(K, Ty), Number(Index), : Operand(K, Ty), Number(Index),
...@@ -895,6 +906,10 @@ protected: ...@@ -895,6 +906,10 @@ protected:
/// This Variable may be "linked" to another Variable, such that if neither /// This Variable may be "linked" to another Variable, such that if neither
/// Variable gets a register, they are guaranteed to share a stack location. /// Variable gets a register, they are guaranteed to share a stack location.
Variable *LinkedTo = nullptr; Variable *LinkedTo = nullptr;
/// External data can be set by an optimizer to compute and retain any
/// information related to the current variable. All the memory used to
/// store this information must be managed by the optimizer.
void* externalData = nullptr;
}; };
// Variable64On32 represents a 64-bit variable on a 32-bit architecture. In // Variable64On32 represents a 64-bit variable on a 32-bit architecture. In
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment