namespace GL {
namespace SL {
-ConstantSpecializer::ConstantSpecializer():
- values(0)
-{ }
-
-void ConstantSpecializer::apply(Stage &stage, const map<string, int> *v)
+void ConstantIdAssigner::apply(Module &module, const Features &features)
{
- values = v;
- stage.content.visit(*this);
-}
+ for(list<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)
+ i->content.visit(*this);
-void ConstantSpecializer::visit(VariableDeclaration &var)
-{
- bool specializable = false;
- if(var.layout)
+ for(vector<VariableDeclaration *>::iterator i=auto_constants.begin(); i!=auto_constants.end(); ++i)
{
- vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
- for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
- if(i->name=="constant_id")
+ unsigned id = hash32((*i)->name)%features.constant_id_range;
+ while(used_ids.count(id))
+ id = (id+1)%features.constant_id_range;
+
+ vector<Layout::Qualifier> &qualifiers = (*i)->layout->qualifiers;
+ for(vector<Layout::Qualifier>::iterator j=qualifiers.begin(); j!=qualifiers.end(); ++j)
+ if(j->name=="constant_id")
{
- specializable = true;
- if(values)
- qualifiers.erase(i);
- else if(i->value==-1)
- i->value = hash32(var.name)&0x7FFFFFFF;
+ j->value = id;
break;
}
- if(qualifiers.empty())
- var.layout = 0;
+ used_ids.insert(id);
}
+}
- if(specializable && values)
+void ConstantIdAssigner::visit(VariableDeclaration &var)
+{
+ if(var.layout)
{
- map<string, int>::const_iterator i = values->find(var.name);
- if(i!=values->end())
- {
- RefPtr<Literal> literal = new Literal;
- if(var.type=="bool")
- {
- literal->token = (i->second ? "true" : "false");
- literal->value = static_cast<bool>(i->second);
- }
- else if(var.type=="int")
+ vector<Layout::Qualifier> &qualifiers = var.layout->qualifiers;
+ for(vector<Layout::Qualifier>::iterator i=qualifiers.begin(); i!=qualifiers.end(); ++i)
+ if(i->name=="constant_id" && i->has_value)
{
- literal->token = lexical_cast<string>(i->second);
- literal->value = i->second;
+ if(i->value==-1)
+ auto_constants.push_back(&var);
+ else
+ used_ids.insert(i->value);
+ break;
}
- var.init_expression = literal;
- }
}
}
InterfaceBlock *InterfaceGenerator::generate_interface(InterfaceBlock &out_block)
{
- if(stage->interface_blocks.count("in"+out_block.block_name))
+ if(stage->interface_blocks.count("in "+out_block.block_name))
return 0;
InterfaceBlock *in_block = new InterfaceBlock;
}
iface_target_block->body.insert(iface_insert_point, in_block);
- stage->interface_blocks.insert(make_pair("in"+in_block->block_name, in_block));
+ stage->interface_blocks.insert(make_pair("in "+in_block->block_name, in_block));
if(!in_block->instance_name.empty())
- stage->interface_blocks.insert(make_pair("_"+in_block->instance_name, in_block));
+ stage->interface_blocks.insert(make_pair(in_block->instance_name, in_block));
SetFlag set_scope(function_scope, false);
SetForScope<Block *> set_block(current_block, &stage->content);
}
const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
- map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find("_"+var.name);
+ map<string, InterfaceBlock *>::const_iterator j = prev_blocks.find(var.name);
if(j!=prev_blocks.end() && j->second->interface=="out")
{
generate_interface(*j->second);
if(!iface.linked_block && stage->previous)
{
const map<string, InterfaceBlock *> &prev_blocks = stage->previous->interface_blocks;
- map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out"+iface.block_name);
+ map<string, InterfaceBlock *>::const_iterator i = prev_blocks.find("out "+iface.block_name);
if(i!=prev_blocks.end())
{
iface.linked_block = i->second;