summaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/dataflow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go/gofrontend/dataflow.cc')
-rw-r--r--gcc/go/gofrontend/dataflow.cc299
1 files changed, 0 insertions, 299 deletions
diff --git a/gcc/go/gofrontend/dataflow.cc b/gcc/go/gofrontend/dataflow.cc
deleted file mode 100644
index bf1d54ab26..0000000000
--- a/gcc/go/gofrontend/dataflow.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// dataflow.cc -- Go frontend dataflow.
-
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "go-system.h"
-
-#include "gogo.h"
-#include "expressions.h"
-#include "statements.h"
-#include "dataflow.h"
-
-// This class is used to traverse the tree to look for uses of
-// variables.
-
-class Dataflow_traverse_expressions : public Traverse
-{
- public:
- Dataflow_traverse_expressions(Dataflow* dataflow, Statement* statement)
- : Traverse(traverse_blocks | traverse_expressions),
- dataflow_(dataflow), statement_(statement)
- { }
-
- protected:
- // Only look at top-level expressions: do not descend into blocks.
- // They will be examined via Dataflow_traverse_statements.
- int
- block(Block*)
- { return TRAVERSE_SKIP_COMPONENTS; }
-
- int
- expression(Expression**);
-
- private:
- // The dataflow information.
- Dataflow* dataflow_;
- // The Statement in which we are looking.
- Statement* statement_;
-};
-
-// Given an expression, return the Named_object that it refers to, if
-// it is a local variable.
-
-static Named_object*
-get_var(Expression* expr)
-{
- Var_expression* ve = expr->var_expression();
- if (ve == NULL)
- return NULL;
- Named_object* no = ve->named_object();
- go_assert(no->is_variable() || no->is_result_variable());
- if (no->is_variable() && no->var_value()->is_global())
- return NULL;
- return no;
-}
-
-// Look for a reference to a variable in an expression.
-
-int
-Dataflow_traverse_expressions::expression(Expression** expr)
-{
- Named_object* no = get_var(*expr);
- if (no != NULL)
- this->dataflow_->add_ref(no, this->statement_);
- return TRAVERSE_CONTINUE;
-}
-
-// This class is used to handle an assignment statement.
-
-class Dataflow_traverse_assignment : public Traverse_assignments
-{
- public:
- Dataflow_traverse_assignment(Dataflow* dataflow, Statement* statement)
- : dataflow_(dataflow), statement_(statement)
- { }
-
- protected:
- void
- initialize_variable(Named_object*);
-
- void
- assignment(Expression** lhs, Expression** rhs);
-
- void
- value(Expression**, bool, bool);
-
- private:
- // The dataflow information.
- Dataflow* dataflow_;
- // The Statement in which we are looking.
- Statement* statement_;
-};
-
-// Handle a variable initialization.
-
-void
-Dataflow_traverse_assignment::initialize_variable(Named_object* var)
-{
- Expression* init = var->var_value()->init();
- this->dataflow_->add_def(var, init, this->statement_, true);
- if (init != NULL)
- {
- Expression* e = init;
- this->value(&e, true, true);
- go_assert(e == init);
- }
-}
-
-// Handle an assignment in a statement.
-
-void
-Dataflow_traverse_assignment::assignment(Expression** plhs, Expression** prhs)
-{
- Named_object* no = get_var(*plhs);
- if (no != NULL)
- {
- Expression* rhs = prhs == NULL ? NULL : *prhs;
- this->dataflow_->add_def(no, rhs, this->statement_, false);
- }
- else
- {
- // If this is not a variable it may be some computed lvalue, and
- // we want to look for references to variables in that lvalue.
- this->value(plhs, false, false);
- }
- if (prhs != NULL)
- this->value(prhs, true, false);
-}
-
-// Handle a value in a statement.
-
-void
-Dataflow_traverse_assignment::value(Expression** pexpr, bool, bool)
-{
- Named_object* no = get_var(*pexpr);
- if (no != NULL)
- this->dataflow_->add_ref(no, this->statement_);
- else
- {
- Dataflow_traverse_expressions dte(this->dataflow_, this->statement_);
- Expression::traverse(pexpr, &dte);
- }
-}
-
-// This class is used to traverse the tree to look for statements.
-
-class Dataflow_traverse_statements : public Traverse
-{
- public:
- Dataflow_traverse_statements(Dataflow* dataflow)
- : Traverse(traverse_statements),
- dataflow_(dataflow)
- { }
-
- protected:
- int
- statement(Block*, size_t* pindex, Statement*);
-
- private:
- // The dataflow information.
- Dataflow* dataflow_;
-};
-
-// For each Statement, we look for expressions.
-
-int
-Dataflow_traverse_statements::statement(Block* block, size_t* pindex,
- Statement *statement)
-{
- Dataflow_traverse_assignment dta(this->dataflow_, statement);
-
- // For thunk statements, make sure to traverse the call expression to
- // find any reference to a variable being used as an argument.
- if (!statement->traverse_assignments(&dta)
- || statement->thunk_statement() != NULL)
- {
- // Case statements in selects will be lowered into temporaries at this
- // point so our dataflow analysis will miss references between a/c and ch
- // in case statements of the form a,c := <-ch. Do a special dataflow
- // analysis for select statements here; the analysis for the blocks will
- // be handled as usual.
- if (statement->select_statement() != NULL)
- statement->select_statement()->analyze_dataflow(this->dataflow_);
-
- Dataflow_traverse_expressions dte(this->dataflow_, statement);
- statement->traverse(block, pindex, &dte);
- }
- return TRAVERSE_CONTINUE;
-}
-
-// Compare variables.
-
-bool
-Dataflow::Compare_vars::operator()(const Named_object* no1,
- const Named_object* no2) const
-{
- if (no1->name() < no2->name())
- return true;
- if (no1->name() > no2->name())
- return false;
-
- // We can have two different variables with the same name.
- Location loc1 = no1->location();
- Location loc2 = no2->location();
- if (loc1 < loc2)
- return false;
- if (loc1 > loc2)
- return true;
- if (Linemap::is_predeclared_location(loc1))
- return false;
-
- if (no1 == no2
- || (no1->is_result_variable()
- && no2->is_result_variable())
- || ((no1->is_variable()
- && no1->var_value()->is_type_switch_var())
- && (no2->is_variable()
- && no2->var_value()->is_type_switch_var())))
- return false;
-
- // We can't have two variables with the same name in the same
- // location unless they are type switch variables which share the same
- // fake location.
- go_unreachable();
-}
-
-// Class Dataflow.
-
-Dataflow::Dataflow()
- : defs_(), refs_()
-{
-}
-
-// Build the dataflow information.
-
-void
-Dataflow::initialize(Gogo* gogo)
-{
- Dataflow_traverse_statements dts(this);
- gogo->traverse(&dts);
-}
-
-// Add a definition of a variable.
-
-void
-Dataflow::add_def(Named_object* var, Expression* val, Statement* statement,
- bool is_init)
-{
- Defs* defnull = NULL;
- std::pair<Defmap::iterator, bool> ins =
- this->defs_.insert(std::make_pair(var, defnull));
- if (ins.second)
- ins.first->second = new Defs;
- Def def;
- def.statement = statement;
- def.val = val;
- def.is_init = is_init;
- ins.first->second->push_back(def);
-}
-
-// Add a reference to a variable.
-
-void
-Dataflow::add_ref(Named_object* var, Statement* statement)
-{
- Refs* refnull = NULL;
- std::pair<Refmap::iterator, bool> ins =
- this->refs_.insert(std::make_pair(var, refnull));
- if (ins.second)
- ins.first->second = new Refs;
- Ref ref;
- ref.statement = statement;
- ins.first->second->push_back(ref);
-}
-
-// Return the definitions of a variable.
-
-const Dataflow::Defs*
-Dataflow::find_defs(Named_object* var) const
-{
- Defmap::const_iterator p = this->defs_.find(var);
- if (p == this->defs_.end())
- return NULL;
- else
- return p->second;
-}
-
-// Return the references of a variable.
-
-const Dataflow::Refs*
-Dataflow::find_refs(Named_object* var) const
-{
- Refmap::const_iterator p = this->refs_.find(var);
- if (p == this->refs_.end())
- return NULL;
- else
- return p->second;
-}