OSDN Git Service

Support assigning constants to values.
authorNicolas Capens <capn@google.com>
Thu, 29 Sep 2016 02:36:28 +0000 (22:36 -0400)
committerNicolas Capens <capn@google.com>
Thu, 29 Sep 2016 18:19:18 +0000 (18:19 +0000)
Subzero has unrelated types for constants and variables. Both are
operands to instructions, but we can't express this relationship at
the Nucleus level. We'd require a large number of Value to Operand
conversions. Instead, an Assign instruction is provided to convert
a Constant into a Value.

Bug swiftshader:12

Change-Id: Ie35a2cea3e485c4012ed949f92825a41caca3367
Reviewed-on: https://swiftshader-review.googlesource.com/7370
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/Reactor/LLVMReactor.cpp
src/Reactor/Main.cpp
src/Reactor/Nucleus.hpp
src/Reactor/Reactor.hpp
src/Reactor/SubzeroReactor.cpp

index 8d1c43d..d1dafda 100644 (file)
@@ -433,6 +433,11 @@ namespace sw
                return V(::builder->CreateXor(lhs, rhs));
        }
 
+       Value *Nucleus::createAssign(Constant *constant)
+       {
+               return V(constant);
+       }
+
        Value *Nucleus::createNeg(Value *v)
        {
                return V(::builder->CreateNeg(v));
@@ -456,12 +461,14 @@ namespace sw
 
        Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
        {
-               return V(::builder->Insert(new StoreInst(value, ptr, isVolatile, align)));
+               ::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
+               return value;
        }
 
-       Value *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
+       Constant *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
        {
-               return V(::builder->Insert(new StoreInst(constant, ptr, isVolatile, align)));
+               ::builder->Insert(new StoreInst(constant, ptr, isVolatile, align));
+               return constant;
        }
 
        Value *Nucleus::createGEP(Value *ptr, Value *index)
index ae1b7fa..0e2e739 100644 (file)
@@ -28,8 +28,9 @@ int main()
                        Pointer<Int> p = function.Arg<0>();
                        Int x = *p;
                        Int y = function.Arg<1>();
-   
-                       Int sum = x + y;
+                       Int z = 4;
+
+                       Int sum = x + y + z;
    
                        Return(sum);
                }
@@ -41,7 +42,7 @@ int main()
                        int (*add)(int*, int) = (int(*)(int*,int))routine->getEntry();
                        int one = 1;
                        int result = add(&one, 2);
-                       assert(result == 3);
+                       assert(result == 7);
                }
        }
 
index afc5d52..f384687 100644 (file)
@@ -88,6 +88,9 @@ namespace sw
                static Value *createAnd(Value *lhs, Value *rhs);
                static Value *createOr(Value *lhs, Value *rhs);
                static Value *createXor(Value *lhs, Value *rhs);
+
+               // Unary operators
+               static Value *createAssign(Constant *c);
                static Value *createNeg(Value *V);
                static Value *createFNeg(Value *V);
                static Value *createNot(Value *V);
@@ -95,7 +98,7 @@ namespace sw
                // Memory instructions
                static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
                static Value *createStore(Value *value, Value *ptr, bool isVolatile = false, unsigned int align = 0);
-               static Value *createStore(Constant *constant, Value *ptr, bool isVolatile = false, unsigned int align = 0);
+               static Constant *createStore(Constant *constant, Value *ptr, bool isVolatile = false, unsigned int align = 0);
                static Value *createGEP(Value *ptr, Value *index);
 
                // Atomic instructions
index e8cc5c9..2b84a8c 100644 (file)
@@ -81,7 +81,7 @@ namespace sw
 
                Value *loadValue(unsigned int alignment = 0) const;
                Value *storeValue(Value *value, unsigned int alignment = 0) const;
-               Value *storeValue(Constant *constant, unsigned int alignment = 0) const;
+               Constant *storeValue(Constant *constant, unsigned int alignment = 0) const;
                Value *getAddress(Value *index) const;
 
        protected:
@@ -158,6 +158,7 @@ namespace sw
        {
        public:
                explicit RValue(Value *rvalue);
+               explicit RValue(Constant *constant);
 
                RValue(const T &lvalue);
                RValue(typename IntLiteral<T>::type i);
@@ -2363,7 +2364,7 @@ namespace sw
        }
 
        template<class T>
-       Value *LValue<T>::storeValue(Constant *constant, unsigned int alignment) const
+       Constant *LValue<T>::storeValue(Constant *constant, unsigned int alignment) const
        {
                return Nucleus::createStore(constant, address, false, alignment);
        }
@@ -2433,6 +2434,12 @@ namespace sw
        }
 
        template<class T>
+       RValue<T>::RValue(Constant *constant)
+       {
+               value = Nucleus::createAssign(constant);
+       }
+
+       template<class T>
        RValue<T>::RValue(const T &lvalue)
        {
                value = lvalue.loadValue();
index dbb4802..594f748 100644 (file)
@@ -53,6 +53,7 @@ namespace
 namespace sw
 {
        class Value : public Ice::Variable {};
+       class Constant : public Ice::Constant {};
        class BasicBlock : public Ice::CfgNode {};
 
        Ice::Type T(Type *t)
@@ -70,6 +71,11 @@ namespace sw
                return reinterpret_cast<Value*>(v);
        }
 
+       Constant *C(Ice::Constant *c)
+       {
+               return reinterpret_cast<Constant*>(c);
+       }
+
        Optimization optimization[10] = {InstructionCombining, Disabled};
 
        void *loadImage(uint8_t *const elfImage)
@@ -421,6 +427,15 @@ namespace sw
                assert(false && "UNIMPLEMENTED"); return nullptr;
        }
 
+       Value *Nucleus::createAssign(Constant *constant)
+       {
+               Ice::Variable *value = ::function->makeVariable(constant->getType());
+               auto assign = Ice::InstAssign::create(::function, value, constant);
+               ::basicBlock->appendInst(assign);
+
+               return V(value);
+       }
+
        Value *Nucleus::createNeg(Value *v)
        {
                assert(false && "UNIMPLEMENTED"); return nullptr;
@@ -451,9 +466,11 @@ namespace sw
                return value;
        }
 
-       Value *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
+       Constant *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
        {
-               assert(false && "UNIMPLEMENTED"); return nullptr;
+               auto store = Ice::InstStore::create(::function, constant, ptr, align);
+               ::basicBlock->appendInst(store);
+               return constant;
        }
 
        Value *Nucleus::createGEP(Value *ptr, Value *index)
@@ -720,7 +737,7 @@ namespace sw
 
        Constant *Nucleus::createConstantInt(int i)
        {
-               assert(false && "UNIMPLEMENTED"); return nullptr;
+               return C(::context->getConstantInt32(i));
        }
 
        Constant *Nucleus::createConstantInt(unsigned int i)