Eliminate the array size from rr::Variable
We only need to know the array size during materialization of Array<>
types, so store it only for that class and make the allocation a
virtual method.
This change removes the REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
option, since it requires knowing the full size of Variable at
construction, which would require Array<> to still pass that into the
Variable constructor. If we need an debugging feature like this again,
we could also materialize variables on first use instead of at
construction.
Bug: b/155302798
Change-Id: I65b02c1258643dcbd3ae18f3f097cb815efa0830
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/45148
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/Reactor/Reactor.cpp b/src/Reactor/Reactor.cpp
index 2ddeaa3..cedbe96 100644
--- a/src/Reactor/Reactor.cpp
+++ b/src/Reactor/Reactor.cpp
@@ -20,12 +20,6 @@
#include <algorithm>
#include <cmath>
-// Define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION to non-zero to ensure all
-// variables have a stack location obtained throuch alloca().
-#ifndef REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
-# define REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION 0
-#endif
-
namespace rr {
const Config::Edit Config::Edit::None = {};
@@ -66,14 +60,9 @@
// Set of variables that do not have a stack location yet.
thread_local std::unordered_set<const Variable *> *Variable::unmaterializedVariables = nullptr;
-Variable::Variable(int arraySize)
- : arraySize(arraySize)
+Variable::Variable()
{
-#if REACTOR_MATERIALIZE_LVALUES_ON_DEFINITION
- materialize();
-#else
unmaterializedVariables->emplace(this);
-#endif
}
Variable::~Variable()
@@ -81,6 +70,11 @@
unmaterializedVariables->erase(this);
}
+Value *Variable::allocate() const
+{
+ return Nucleus::allocateStackVariable(getType());
+}
+
void Variable::materializeAll()
{
for(auto *var : *unmaterializedVariables)
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 92cfdf0..95dae47 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -103,7 +103,6 @@
{
friend class Nucleus;
- Variable() = delete;
Variable &operator=(const Variable &) = delete;
public:
@@ -116,10 +115,9 @@
Value *getElementPointer(Value *index, bool unsignedIndex) const;
virtual Type *getType() const = 0;
- int getArraySize() const { return arraySize; }
protected:
- Variable(int arraySize);
+ Variable();
Variable(const Variable &) = default;
virtual ~Variable();
@@ -128,11 +126,12 @@
static void materializeAll();
static void killUnmaterialized();
+ virtual Value *allocate() const;
+
// 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<const Variable *> *unmaterializedVariables;
- const int arraySize;
mutable Value *rvalue = nullptr;
mutable Value *address = nullptr;
};
@@ -141,7 +140,7 @@
class LValue : public Variable
{
public:
- LValue(int arraySize = 0);
+ LValue();
RValue<Pointer<T>> operator&();
@@ -2511,6 +2510,11 @@
// self() returns the this pointer to this Array object.
// This function exists because operator&() is overloaded by LValue<T>.
inline Array *self() { return this; }
+
+private:
+ Value *allocate() const override;
+
+ const int arraySize;
};
// RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment
@@ -2617,8 +2621,7 @@
namespace rr {
template<class T>
-LValue<T>::LValue(int arraySize)
- : Variable(arraySize)
+LValue<T>::LValue()
{
#ifdef ENABLE_RR_DEBUG_INFO
materialize();
@@ -2629,7 +2632,7 @@
{
if(!address)
{
- address = Nucleus::allocateStackVariable(getType(), arraySize);
+ address = allocate();
RR_DEBUG_INFO_EMIT_VAR(address);
if(rvalue)
@@ -3084,14 +3087,20 @@
template<class T, int S>
Array<T, S>::Array(int size)
- : LValue<T>(size)
+ : arraySize(size)
{
}
template<class T, int S>
+Value *Array<T, S>::allocate() const
+{
+ return Nucleus::allocateStackVariable(T::type(), arraySize);
+}
+
+template<class T, int S>
Reference<T> Array<T, S>::operator[](int index)
{
- assert(index < Variable::getArraySize());
+ assert(index < arraySize);
Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), false);
return Reference<T>(element);
@@ -3100,7 +3109,7 @@
template<class T, int S>
Reference<T> Array<T, S>::operator[](unsigned int index)
{
- assert(index < static_cast<unsigned int>(Variable::getArraySize()));
+ assert(index < static_cast<unsigned int>(arraySize));
Value *element = LValue<T>::getElementPointer(Nucleus::createConstantInt(index), true);
return Reference<T>(element);