reintroduce simple constant folding; will need for array size expressions

This commit is contained in:
Aras Pranckevicius 2012-10-25 23:10:17 +03:00
Родитель 6ae11c587f
Коммит 9a64bd097d
4 изменённых файлов: 139 добавлений и 4 удалений

Просмотреть файл

@ -332,6 +332,10 @@
Name="Machine Independent"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;y;l"
>
<File
RelativePath="hlslang\MachineIndependent\ConstantFolding.cpp"
>
</File>
<File
RelativePath=".\hlslang\MachineIndependent\HLSL2GLSL.cpp"
>

Просмотреть файл

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
2B6C96AF1639C18100CB13EE /* ConstantFolding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B6C96AE1639C18100CB13EE /* ConstantFolding.cpp */; };
2B951C9D1135197300DBAF46 /* atom.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AC10EA70AF109530045E29C /* atom.c */; };
2B951C9F1135197300DBAF46 /* cpp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AC10EA80AF109530045E29C /* cpp.c */; };
2B951CA01135197300DBAF46 /* cppstruct.c in Sources */ = {isa = PBXBuildFile; fileRef = 3AC10EA90AF109530045E29C /* cppstruct.c */; };
@ -43,6 +44,7 @@
/* Begin PBXFileReference section */
08FB77AAFE841565C02AAC07 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
2B67D1C615DFFC4D0073924D /* sourceloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sourceloc.h; path = hlslang/MachineIndependent/preprocessor/sourceloc.h; sourceTree = SOURCE_ROOT; };
2B6C96AE1639C18100CB13EE /* ConstantFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantFolding.cpp; path = hlslang/MachineIndependent/ConstantFolding.cpp; sourceTree = SOURCE_ROOT; };
2B951C991135194700DBAF46 /* libhlsl2glsl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libhlsl2glsl.a; sourceTree = BUILT_PRODUCTS_DIR; };
2B951CC011351A2500DBAF46 /* hlsl2glsl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hlsl2glsl.h; path = include/hlsl2glsl.h; sourceTree = SOURCE_ROOT; };
2B951CE1113527BC00DBAF46 /* hlslang.l */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lex; name = hlslang.l; path = hlslang/MachineIndependent/hlslang.l; sourceTree = SOURCE_ROOT; };
@ -219,6 +221,7 @@
3AC10DB90AF102990045E29C /* MachineIndependent */ = {
isa = PBXGroup;
children = (
2B6C96AE1639C18100CB13EE /* ConstantFolding.cpp */,
2B951CE1113527BC00DBAF46 /* hlslang.l */,
2B951CE2113527BC00DBAF46 /* hlslang.y */,
3AC10DBF0AF102B20045E29C /* Headers */,
@ -421,6 +424,7 @@
2B951CBD1135197300DBAF46 /* SymbolTable.cpp in Sources */,
2B951CBE1135197300DBAF46 /* tokens.c in Sources */,
2B951CBF1135197300DBAF46 /* typeSamplers.cpp in Sources */,
2B6C96AF1639C18100CB13EE /* ConstantFolding.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

Просмотреть файл

@ -0,0 +1,102 @@
// Copyright (c) The HLSL2GLSLFork Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE.txt file.
#include "../Include/intermediate.h"
// Limited constant folding functionality; we mostly want it for array sizes
// with constant expressions.
// Returns the node to keep using, or NULL.
TIntermConstant* FoldBinaryConstantExpression(TOperator op, TIntermConstant* nodeA, TIntermConstant* nodeB)
{
if (!nodeA || !nodeB)
return NULL;
if (nodeA->getType() != nodeB->getType())
return NULL;
// for now, only support integers; we really only need constant folding for array sizes
if (nodeA->getBasicType() != EbtInt)
return NULL;
TIntermConstant* newNode = new TIntermConstant(nodeA->getType());
switch (op)
{
case EOpAdd:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt + nodeB->getValue(i).asInt);
break;
case EOpSub:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt - nodeB->getValue(i).asInt);
break;
case EOpMul:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt * nodeB->getValue(i).asInt);
break;
case EOpDiv:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeB->getValue(i).asInt ? nodeA->getValue(i).asInt / nodeB->getValue(i).asInt : 0);
break;
case EOpMod:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeB->getValue(i).asInt ? nodeA->getValue(i).asInt % nodeB->getValue(i).asInt : 0);
break;
case EOpRightShift:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt >> nodeB->getValue(i).asInt);
break;
case EOpLeftShift:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt << nodeB->getValue(i).asInt);
break;
case EOpAnd:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt & nodeB->getValue(i).asInt);
break;
case EOpInclusiveOr:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt | nodeB->getValue(i).asInt);
break;
case EOpExclusiveOr:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, nodeA->getValue(i).asInt ^ nodeB->getValue(i).asInt);
break;
default:
delete newNode;
return NULL;
}
newNode->setLine(nodeA->getLine());
return newNode;
}
TIntermConstant* FoldUnaryConstantExpression(TOperator op, TIntermConstant* node)
{
if (!node)
return NULL;
// for now, only support integers; we really only need constant folding for array sizes
if (node->getBasicType() != EbtInt)
return NULL;
TIntermConstant* newNode = new TIntermConstant(node->getType());
switch (op)
{
case EOpNegative:
for (unsigned i = 0; i < newNode->getCount(); ++i)
newNode->setValue(i, -node->getValue(i).asInt);
break;
default:
delete newNode;
return NULL;
}
newNode->setLine(node->getLine());
return newNode;
}

Просмотреть файл

@ -218,6 +218,20 @@ TIntermTyped* ir_add_binary_math(TOperator op, TIntermTyped* left, TIntermTyped*
if (! node->promote(infoSink))
return 0;
//
// See if we can fold constants
TIntermConstant* constA = left->getAsConstant();
TIntermConstant* constB = right->getAsConstant();
if (constA && constB)
{
TIntermConstant* FoldBinaryConstantExpression(TOperator op, TIntermConstant* nodeA, TIntermConstant* nodeB);
TIntermConstant* res = FoldBinaryConstantExpression(node->getOp(), constA, constB);
if (res)
return res;
}
return node;
}
@ -333,9 +347,7 @@ TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc
default: break;
}
TIntermConstant *childTempConstant = 0;
if (child->getAsConstant())
childTempConstant = child->getAsConstant();
TIntermConstant* childConst = child->getAsConstant();
//
// Make a new node for the operator.
@ -348,8 +360,21 @@ TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc
if (! node->promote(infoSink))
return 0;
//
// See if we can fold constants
if (childConst)
{
TIntermConstant* FoldUnaryConstantExpression(TOperator op, TIntermConstant* node);
TIntermConstant* res = FoldUnaryConstantExpression(node->getOp(), childConst);
if (res)
return res;
}
return node;
return node;
}