1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include "fpconfig.hh"
#include "fparser.hh"
#include "extrasrc/fptypes.hh"
#ifdef FP_SUPPORT_OPTIMIZER
#include <algorithm>
#include <assert.h>
#include "optimize.hh"
using namespace FPoptimizer_CodeTree;
using namespace FPoptimizer_Optimize;
namespace
{
/* Synthesize the given grammatic parameter into the codetree */
template<typename Value_t>
CodeTree<Value_t> SynthesizeParam(
const ParamSpec& parampair,
MatchInfo<Value_t> & info,
bool inner = true)
{
switch( parampair.first )
{
case NumConstant:
{ const ParamSpec_NumConstant<Value_t>& param = *(const ParamSpec_NumConstant<Value_t>*) parampair.second;
return CodeTreeImmed( param.constvalue );
}
case ParamHolder:
{ const ParamSpec_ParamHolder& param = *(const ParamSpec_ParamHolder*) parampair.second;
return info.GetParamHolderValue( param.index );
}
case SubFunction:
{ const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second;
CodeTree<Value_t> tree;
tree.SetOpcode( param.data.subfunc_opcode );
for(unsigned a=0; a < param.data.param_count; ++a)
{
CodeTree<Value_t> nparam =
SynthesizeParam( ParamSpec_Extract<Value_t>(param.data.param_list, a),
info, true );
tree.AddParamMove(nparam);
}
if(param.data.restholder_index != 0)
{
std::vector<CodeTree<Value_t> > trees
( info.GetRestHolderValues( param.data.restholder_index ) );
tree.AddParamsMove(trees);
// ^note: this fails if the same restholder is synth'd twice
if(tree.GetParamCount() == 1)
{
/* Convert cMul <1> into <1> when <1> only contains one operand.
* This is redundant code; it is also done in ConstantFolding(),
* but it might be better for performance to do it here, too.
*/
assert(tree.GetOpcode() == cAdd || tree.GetOpcode() == cMul
|| tree.GetOpcode() == cMin || tree.GetOpcode() == cMax
|| tree.GetOpcode() == cAnd || tree.GetOpcode() == cOr
|| tree.GetOpcode() == cAbsAnd || tree.GetOpcode() == cAbsOr);
tree.Become(tree.GetParam(0));
}
else if(tree.GetParamCount() == 0)
{
switch(tree.GetOpcode())
{
case cAdd: case cOr:
tree = CodeTreeImmed(Value_t(0));
break;
case cMul: case cAnd:
tree = CodeTreeImmed(Value_t(1));
default: break;
}
}
}
if(inner) tree.Rehash();
return tree;
}
}
return CodeTree<Value_t> ();
}
}
namespace FPoptimizer_Optimize
{
template<typename Value_t>
void SynthesizeRule(
const Rule& rule,
CodeTree<Value_t>& tree,
MatchInfo<Value_t>& info)
{
switch(rule.ruletype)
{
case ProduceNewTree:
{
tree.Become(
SynthesizeParam( ParamSpec_Extract<Value_t>(rule.repl_param_list, 0),
info, false ) );
break;
}
case ReplaceParams:
default:
{
/* Delete the matched parameters from the source tree */
std::vector<unsigned> list = info.GetMatchedParamIndexes();
std::sort(list.begin(), list.end());
for(size_t a=list.size(); a-->0; )
tree.DelParam( list[a] );
/* Synthesize the replacement params */
for(unsigned a=0; a < rule.repl_param_count; ++a)
{
CodeTree<Value_t> nparam
= SynthesizeParam( ParamSpec_Extract<Value_t>(rule.repl_param_list, a),
info, true );
tree.AddParamMove(nparam);
}
break;
}
}
}
}
/* BEGIN_EXPLICIT_INSTANTATION */
#include "instantiate.hh"
namespace FPoptimizer_Optimize
{
#define FP_INSTANTIATE(type) \
template \
void SynthesizeRule( \
const Rule& rule, \
CodeTree<type>& tree, \
MatchInfo<type>& info);
FPOPTIMIZER_EXPLICITLY_INSTANTIATE(FP_INSTANTIATE)
#undef FP_INSTANTIATE
}
/* END_EXPLICIT_INSTANTATION */
#endif
|