Retrieve Variable type through an abstract method
This is just a refactoring which avoids storing the type as a Variable
fields, since the 'LValue<T>' subclass knows the type statically and we
only need it during materialization.
This gives us a vtable for overloading other methods in subsequent
changes, at no additional storage cost for Variable.
Bug: b/155302798
Change-Id: I36f6ef8f5f4d2b50ba04d539dc8b9735481c816a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/44668
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index e76e653..d254aea 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -637,7 +637,7 @@
jit = new JITBuilder(Nucleus::getDefaultConfig());
ASSERT(Variable::unmaterializedVariables == nullptr);
- Variable::unmaterializedVariables = new std::unordered_set<Variable *>();
+ Variable::unmaterializedVariables = new std::unordered_set<const Variable *>();
}
Nucleus::~Nucleus()
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index de85b03..5922a58 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -64,11 +64,10 @@
}
// Set of variables that do not have a stack location yet.
-thread_local std::unordered_set<Variable *> *Variable::unmaterializedVariables = nullptr;
+thread_local std::unordered_set<const Variable *> *Variable::unmaterializedVariables = nullptr;
-Variable::Variable(Type *type, int arraySize)
+Variable::Variable(int arraySize)
: arraySize(arraySize)
- , type(type)
{
#if REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
materialize();
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index f9b986d..552e128 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -102,7 +102,6 @@
class Variable
{
friend class Nucleus;
- friend class PrintValue;
Variable() = delete;
Variable &operator=(const Variable &) = delete;
@@ -116,13 +115,14 @@
Value *getBaseAddress() const;
Value *getElementPointer(Value *index, bool unsignedIndex) const;
+ virtual Type *getType() const = 0;
+ int getArraySize() const { return arraySize; }
+
protected:
- Variable(Type *type, int arraySize);
+ Variable(int arraySize);
Variable(const Variable &) = default;
- ~Variable();
-
- const int arraySize;
+ virtual ~Variable();
private:
static void materializeAll();
@@ -130,9 +130,9 @@
// This has to be a raw pointer because glibc 2.17 doesn't support __cxa_thread_atexit_impl
// for destructing objects at exit. See crbug.com/1074222
- static thread_local std::unordered_set<Variable *> *unmaterializedVariables;
+ static thread_local std::unordered_set<const Variable *> *unmaterializedVariables;
- Type *const type;
+ const int arraySize;
mutable Value *rvalue = nullptr;
mutable Value *address = nullptr;
};
@@ -145,6 +145,11 @@
RValue<Pointer<T>> operator&();
+ Type *getType() const override
+ {
+ return T::type();
+ }
+
// self() returns the this pointer to this LValue<T> object.
// This function exists because operator&() is overloaded.
inline LValue<T> *self() { return this; }
@@ -240,6 +245,7 @@
RValue(typename FloatLiteral<T>::type f);
RValue(const Reference<T> &rhs);
+ // Rvalues cannot be assigned to: "(a + b) = c;"
RValue<T> &operator=(const RValue<T> &) = delete;
Value *value; // FIXME: Make private
@@ -2592,7 +2598,7 @@
template<class T>
LValue<T>::LValue(int arraySize)
- : Variable(T::type(), arraySize)
+ : Variable(arraySize)
{
#ifdef ENABLE_RR_DEBUG_INFO
materialize();
@@ -2603,7 +2609,7 @@
{
if(!address)
{
- address = Nucleus::allocateStackVariable(type, arraySize);
+ address = Nucleus::allocateStackVariable(getType(), arraySize);
RR_DEBUG_INFO_EMIT_VAR(address);
if(rvalue)
@@ -2627,14 +2633,14 @@
materialize();
}
- return Nucleus::createLoad(address, type, false, 0);
+ return Nucleus::createLoad(address, getType(), false, 0);
}
inline Value *Variable::storeValue(Value *value) const
{
if(address)
{
- return Nucleus::createStore(value, address, type, false, 0);
+ return Nucleus::createStore(value, address, getType(), false, 0);
}
rvalue = value;
@@ -2651,7 +2657,7 @@
inline Value *Variable::getElementPointer(Value *index, bool unsignedIndex) const
{
- return Nucleus::createGEP(getBaseAddress(), type, index, unsignedIndex);
+ return Nucleus::createGEP(getBaseAddress(), getType(), index, unsignedIndex);
}
template<class T>
@@ -3060,7 +3066,7 @@
template<class T, int S>
Reference<T> Array<T, S>::operator[](int index)
{
- assert(index < Variable::arraySize);
+ assert(index < Variable::getArraySize());
Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), false);
return Reference<T>(element);
@@ -3069,7 +3075,7 @@
template<class T, int S>
Reference<T> Array<T, S>::operator[](unsigned int index)
{
- assert(index < static_cast<unsigned int>(Variable::arraySize));
+ assert(index < static_cast<unsigned int>(Variable::getArraySize()));
Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), true);
return Reference<T>(element);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 16ff015..67026e5 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -903,7 +903,7 @@
}
ASSERT(Variable::unmaterializedVariables == nullptr);
- Variable::unmaterializedVariables = new std::unordered_set<Variable *>();
+ Variable::unmaterializedVariables = new std::unordered_set<const Variable *>();
}
Nucleus::~Nucleus()