Commit 9958acf0 by Nicolas Capens Committed by Nicolas Capens

Eliminate conversion operations.

They've been replaced by using constructor nodes, so any code handling conversion operators can be removed. BUG=15415045 Change-Id: Ibf277f3014800b6e9503d65f102f8d8b6013a2d7 Reviewed-on: https://swiftshader-review.googlesource.com/1114Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 7c0ec1ef
......@@ -74,18 +74,6 @@ const char* getOperatorString(TOperator op) {
case EOpPreIncrement: return "++";
case EOpPreDecrement: return "--";
// Fall-through.
case EOpConvIntToBool:
case EOpConvFloatToBool: return "bool";
// Fall-through.
case EOpConvBoolToFloat:
case EOpConvIntToFloat: return "float";
// Fall-through.
case EOpConvFloatToInt:
case EOpConvBoolToInt: return "int";
case EOpRadians: return "radians";
case EOpDegrees: return "degrees";
case EOpSin: return "sin";
......@@ -359,123 +347,6 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
}
//
// Convert one type to another.
//
// Returns the node representing the conversion, which could be the same
// node passed in if no conversion was needed.
//
// Return 0 if a conversion can't be done.
//
TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
{
//
// Does the base type allow operation?
//
if (node->getBasicType() == EbtVoid || IsSampler(node->getBasicType()))
{
return 0;
}
//
// Otherwise, if types are identical, no problem
//
if (type == node->getType())
return node;
//
// If one's a structure, then no conversions.
//
if (type.getStruct() || node->getType().getStruct())
return 0;
//
// If one's an array, then no conversions.
//
if (type.isArray() || node->getType().isArray())
return 0;
TBasicType promoteTo;
switch (op) {
//
// Explicit conversions
//
case EOpConstructBool:
promoteTo = EbtBool;
break;
case EOpConstructFloat:
promoteTo = EbtFloat;
break;
case EOpConstructInt:
promoteTo = EbtInt;
break;
default:
//
// implicit conversions were removed from the language.
//
if (type.getBasicType() != node->getType().getBasicType())
return 0;
//
// Size and structure could still differ, but that's
// handled by operator promotion.
//
return node;
}
if (node->getAsConstantUnion()) {
return (promoteConstantUnion(promoteTo, node->getAsConstantUnion()));
} else {
//
// Add a new newNode for the conversion.
//
TIntermUnary* newNode = 0;
TOperator newOp = EOpNull;
switch (promoteTo) {
case EbtFloat:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
break;
case EbtBool:
switch (node->getBasicType()) {
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
break;
case EbtInt:
switch (node->getBasicType()) {
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
return 0;
}
break;
default:
infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
return 0;
}
TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
newNode = new TIntermUnary(newOp, type);
newNode->setLine(node->getLine());
newNode->setOperand(node);
return newNode;
}
}
//
// Safe way to combine two nodes into an aggregate. Works with null pointers,
// a node that's not a aggregate yet, etc.
//
......
......@@ -601,12 +601,6 @@ namespace sh
assignLvalue(arg, result);
}
break;
case EOpConvIntToBool: if(visit == PostVisit) emit(sw::Shader::OPCODE_F2B, result, arg); break; // Integers are implemented as float
case EOpConvFloatToBool: if(visit == PostVisit) emit(sw::Shader::OPCODE_F2B, result, arg); break;
case EOpConvBoolToFloat: if(visit == PostVisit) emit(sw::Shader::OPCODE_B2F, result, arg); break;
case EOpConvIntToFloat: if(visit == PostVisit) emit(sw::Shader::OPCODE_MOV, result, arg); break; // Integers are implemented as float
case EOpConvFloatToInt: if(visit == PostVisit) emit(sw::Shader::OPCODE_TRUNC, result, arg); break; // Integers are implemented as float
case EOpConvBoolToInt: if(visit == PostVisit) emit(sw::Shader::OPCODE_B2F, result, arg); break; // Integers are implemented as float
case EOpRadians: if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &rad); break;
case EOpDegrees: if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, arg, &deg); break;
case EOpSin: if(visit == PostVisit) emit(sw::Shader::OPCODE_SIN, result, arg); break;
......
......@@ -1160,95 +1160,6 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co
return 0;
}
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
// for the parameter to the constructor (passed to this function). Essentially, it converts
// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
// float, then float is converted to int.
//
// Returns 0 for an error or the constructed node.
//
TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
{
TIntermTyped* newNode;
TOperator basicOp;
//
// First, convert types as needed.
//
switch (op) {
case EOpConstructVec2:
case EOpConstructVec3:
case EOpConstructVec4:
case EOpConstructMat2:
case EOpConstructMat3:
case EOpConstructMat4:
case EOpConstructFloat:
basicOp = EOpConstructFloat;
break;
case EOpConstructIVec2:
case EOpConstructIVec3:
case EOpConstructIVec4:
case EOpConstructInt:
basicOp = EOpConstructInt;
break;
case EOpConstructBVec2:
case EOpConstructBVec3:
case EOpConstructBVec4:
case EOpConstructBool:
basicOp = EOpConstructBool;
break;
default:
error(line, "unsupported construction", "");
recover();
return 0;
}
newNode = intermediate.addUnaryMath(basicOp, node, node->getLine());
if (newNode == 0) {
error(line, "can't convert", "constructor");
return 0;
}
//
// Now, if there still isn't an operation to do the construction, and we need one, add one.
//
// Otherwise, skip out early.
if (subset || (newNode != node && newNode->getType() == *type))
return newNode;
// setAggregateOperator will insert a new node for the constructor, as needed.
return intermediate.setAggregateOperator(newNode, op, line);
}
// This function tests for the type of the parameters to the structures constructors. Raises
// an error message if the expected type does not match the parameter passed to the constructor.
//
// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
//
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
{
if (*type == node->getAsTyped()->getType()) {
if (subset)
return node->getAsTyped();
else
return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
} else {
std::stringstream extraInfoStream;
extraInfoStream << "cannot convert parameter " << paramCount
<< " from '" << node->getAsTyped()->getType().getBasicString()
<< "' to '" << type->getBasicString() << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "constructor", extraInfo.c_str());
recover();
}
return 0;
}
//
// This function returns the tree representation for the vector field(s) being accessed from contant vector.
// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
......
......@@ -118,8 +118,6 @@ struct TParseContext {
TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc);
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
......
......@@ -152,13 +152,6 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
case EOpPreIncrement: out << "Pre-Increment"; break;
case EOpPreDecrement: out << "Pre-Decrement"; break;
case EOpConvIntToBool: out << "Convert int to bool"; break;
case EOpConvFloatToBool:out << "Convert float to bool";break;
case EOpConvBoolToFloat:out << "Convert bool to float";break;
case EOpConvIntToFloat: out << "Convert int to float"; break;
case EOpConvFloatToInt: out << "Convert float to int"; break;
case EOpConvBoolToInt: out << "Convert bool to int"; break;
case EOpRadians: out << "radians"; break;
case EOpDegrees: out << "degrees"; break;
case EOpSin: out << "sine"; break;
......
......@@ -46,13 +46,6 @@ enum TOperator {
EOpPreIncrement,
EOpPreDecrement,
EOpConvIntToBool,
EOpConvFloatToBool,
EOpConvBoolToFloat,
EOpConvIntToFloat,
EOpConvFloatToInt,
EOpConvBoolToInt,
//
// binary operations
//
......
......@@ -20,12 +20,11 @@ struct TVectorFields {
//
class TInfoSink;
class TIntermediate {
public:
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermediate(TInfoSink& i) : infoSink(i) { }
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
......@@ -37,14 +36,14 @@ public:
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*);
bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false);
TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
bool postProcess(TIntermNode*);
void remove(TIntermNode*);
void remove(TIntermNode*);
void outputTree(TIntermNode*);
protected:
......
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