Commit b955d5b4 by Nicolas Capens

Support assigning constants to values.

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/7370Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 22479eb6
......@@ -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)
......
......@@ -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);
}
}
......
......@@ -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
......
......@@ -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();
......
......@@ -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)
......
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