Commit 5e16bc45 by Nicolas Capens Committed by Nicolas Capens

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: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: Nicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent cc5cda0f
......@@ -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 @@ void rr::Config::Edit::apply(const std::vector<std::pair<ListEdit, T>> &edits, s
// 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 @@ Variable::~Variable()
unmaterializedVariables->erase(this);
}
Value *Variable::allocate() const
{
return Nucleus::allocateStackVariable(getType());
}
void Variable::materializeAll()
{
for(auto *var : *unmaterializedVariables)
......
......@@ -103,7 +103,6 @@ class Variable
{
friend class Nucleus;
Variable() = delete;
Variable &operator=(const Variable &) = delete;
public:
......@@ -116,10 +115,9 @@ public:
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 @@ private:
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 @@ template<class T>
class LValue : public Variable
{
public:
LValue(int arraySize = 0);
LValue();
RValue<Pointer<T>> operator&();
......@@ -2511,6 +2510,11 @@ public:
// 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 @@ RValue<Long> Ticks();
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 @@ inline void Variable::materialize() const
{
if(!address)
{
address = Nucleus::allocateStackVariable(getType(), arraySize);
address = allocate();
RR_DEBUG_INFO_EMIT_VAR(address);
if(rvalue)
......@@ -3084,14 +3087,20 @@ Type *Pointer<T>::type()
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 @@ Reference<T> Array<T, S>::operator[](int index)
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);
......
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