++count;
/* Don't inline functions which are called more than once or are called
recursively. */
- if(count>1 || def==current_function)
+ if((count>1 && def->source!=BUILTIN_SOURCE) || def==current_function)
inlineable.erase(def);
}
has_out_params = ((*i)->interface=="out");
unsigned &count = refcounts[func.definition];
- if(count<=1 && !has_out_params)
+ if((count<=1 || func.source==BUILTIN_SOURCE) && !has_out_params)
inlineable.insert(func.definition);
SetForScope<FunctionDeclaration *> set(current_function, &func);
staging_block.parent = &tgt_blk;
staging_block.variables.clear();
- std::vector<RefPtr<VariableDeclaration> > params;
+ vector<RefPtr<VariableDeclaration> > params;
params.reserve(source_func->parameters.size());
for(NodeArray<VariableDeclaration>::iterator i=source_func->parameters.begin(); i!=source_func->parameters.end(); ++i)
{
}
+UnreachableCodeRemover::UnreachableCodeRemover():
+ reachable(true)
+{ }
+
+bool UnreachableCodeRemover::apply(Stage &stage)
+{
+ stage.content.visit(*this);
+ NodeRemover().apply(stage, unreachable_nodes);
+ return !unreachable_nodes.empty();
+}
+
+void UnreachableCodeRemover::visit(Block &block)
+{
+ NodeList<Statement>::iterator i = block.body.begin();
+ for(; (reachable && i!=block.body.end()); ++i)
+ (*i)->visit(*this);
+ for(; i!=block.body.end(); ++i)
+ unreachable_nodes.insert(i->get());
+}
+
+void UnreachableCodeRemover::visit(FunctionDeclaration &func)
+{
+ TraversingVisitor::visit(func);
+ reachable = true;
+}
+
+void UnreachableCodeRemover::visit(Conditional &cond)
+{
+ cond.body.visit(*this);
+ bool reachable_if_true = reachable;
+ reachable = true;
+ cond.else_body.visit(*this);
+
+ reachable |= reachable_if_true;
+}
+
+void UnreachableCodeRemover::visit(Iteration &iter)
+{
+ TraversingVisitor::visit(iter);
+
+ /* Always consider code after a loop reachable, since there's no checking
+ for whether the loop executes. */
+ reachable = true;
+}
+
+
bool UnusedTypeRemover::apply(Stage &stage)
{
stage.content.visit(*this);
r_assignment(0),
assignment_target(false),
r_side_effects(false),
+ in_struct(false),
composite_reference(false)
{ }
unused_nodes.insert(&expr);
}
+void UnusedVariableRemover::visit(StructDeclaration &strct)
+{
+ SetFlag set_struct(in_struct);
+ TraversingVisitor::visit(strct);
+}
+
void UnusedVariableRemover::visit(VariableDeclaration &var)
{
+ TraversingVisitor::visit(var);
+
+ if(in_struct)
+ return;
+
VariableInfo &var_info = variables[&var];
var_info.interface_block = interface_block;
var_info.initialized = true;
record_assignment(&var, *var.init_expression);
}
- TraversingVisitor::visit(var);
}
void UnusedVariableRemover::visit(InterfaceBlock &iface)