aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2017-06-21 13:46:58 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-06-21 13:51:15 -0700
commit40f81fb2a9740289f37f919383880c493077b9fc (patch)
tree2e5ce54de3565c174a83ad8bba90a97c55a70106 /tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc
parent9e8005d7771e3f98b0a2ce74e4b0bc3765410a27 (diff)
[XLA:HLO] Split Hlo{Value,Buffer} out of Hlo{Dataflow,Alias}Analysis.
This will make dependencies cleaner for upcoming CLs that will convert HeapSimulator and HloOrdering to use the new analyses. No change in functionality. PiperOrigin-RevId: 159737265
Diffstat (limited to 'tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc')
-rw-r--r--tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc265
1 files changed, 0 insertions, 265 deletions
diff --git a/tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc b/tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc
index 7e951721ba..8f372c3420 100644
--- a/tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc
+++ b/tensorflow/compiler/xla/service/hlo_dataflow_analysis.cc
@@ -16,14 +16,11 @@ limitations under the License.
#include "tensorflow/compiler/xla/service/hlo_dataflow_analysis.h"
#include <algorithm>
-#include <iosfwd>
#include <queue>
-#include <set>
#include <vector>
#include "tensorflow/compiler/xla/map_util.h"
#include "tensorflow/compiler/xla/ptr_util.h"
-#include "tensorflow/compiler/xla/service/dfs_hlo_visitor_with_default.h"
#include "tensorflow/compiler/xla/service/hlo_computation.h"
#include "tensorflow/compiler/xla/service/hlo_instruction.h"
#include "tensorflow/compiler/xla/service/hlo_opcode.h"
@@ -35,7 +32,6 @@ limitations under the License.
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
-#include "tensorflow/core/lib/strings/stringprintf.h"
#include "tensorflow/core/platform/logging.h"
namespace xla {
@@ -43,267 +39,6 @@ namespace xla {
using ::tensorflow::strings::StrAppend;
using ::tensorflow::strings::StrCat;
-string HloLocation::ToString() const {
- string index_str =
- ShapeUtil::IsTuple(instruction->shape()) ? (" " + index.ToString()) : "";
- return StrCat(instruction->FullyQualifiedName(), index_str);
-}
-
-std::ostream& operator<<(std::ostream& out, const HloLocation& location) {
- out << location.ToString();
- return out;
-}
-
-string HloUse::ToString() const {
- string index_str =
- ShapeUtil::IsTuple(instruction->operand(operand_number)->shape())
- ? (" " + operand_index.ToString())
- : "";
- return StrCat(instruction->FullyQualifiedName(), ", operand ", operand_number,
- index_str);
-}
-
-std::ostream& operator<<(std::ostream& out, const HloUse& use) {
- out << use.ToString();
- return out;
-}
-
-HloValue::HloValue(HloValue::Id id, HloInstruction* instruction,
- const ShapeIndex& index, bool is_phi)
- : id_(id), is_phi_(is_phi) {
- // The defining location is always the first element in the locations_ vector.
- AddLocation(instruction, index);
-}
-
-bool HloValue::operator==(const HloValue& other) const {
- bool equal = defining_instruction() == other.defining_instruction() &&
- defining_index() == other.defining_index();
- // If the values are equal they most both be phi (or non phi).
- CHECK(!(equal && is_phi() != other.is_phi()));
- return equal;
-}
-
-bool HloValue::operator!=(const HloValue& other) const {
- return !(*this == other);
-}
-
-string HloValue::ToShortString() const {
- string index_str = ShapeUtil::IsTuple(defining_instruction()->shape())
- ? defining_index().ToString()
- : "";
- return StrCat(is_phi_ ? "PHI " : "",
- defining_instruction()->FullyQualifiedName(), index_str);
-}
-
-string HloValue::ToString(int indent) const {
- string indentation(indent, ' ');
- string out = StrCat(indentation, ToShortString(), ", locations:\n");
- for (const HloLocation& location : locations()) {
- StrAppend(&out, indentation, " ", location.ToString(), "\n");
- }
- StrAppend(&out, indentation, " uses:\n");
- for (const HloUse& use : uses()) {
- StrAppend(&out, indentation, " ", use.ToString(), "\n");
- }
- return out;
-}
-
-namespace {
-
-// Returns true if the instruction 'user' may use the value at the given
-// ShapeIndex in the given operand. Generally, instruction which pass through
-// values transparently without reading the value are not considered to use the
-// value.
-bool MayUseOperandValue(int64 operand_number, const ShapeIndex& index,
- const HloInstruction* user) {
- switch (user->opcode()) {
- case HloOpcode::kGetTupleElement:
- case HloOpcode::kCopy:
- // These instructions only access the top-level values of their
- // operand. Non-top-level (nested) values are passed through
- // transparently.
- CHECK_EQ(operand_number, 0);
- return index.empty();
- case HloOpcode::kSelect:
- // Select does not use any nested elements of its selected-from operands
- // (operand 1 and 2)
- CHECK_GE(operand_number, 0);
- CHECK_LE(operand_number, 2);
- return operand_number == 0 || index.empty();
-
- case HloOpcode::kCall:
- case HloOpcode::kTuple:
- // These instructions always pass through their operands transparently.
- return false;
-
- case HloOpcode::kWhile:
- // Though the while instructions passes through its operands, we return
- // true because in SSA form there may be a Phi at the parameter of the
- // while which is considered a use of its incoming value because the Phi
- // input values are not passed through into the body computation. Because
- // this function is used in both SSA and non-SSA forms of the analysis
- // conservatively return true.
- return true;
-
- default:
- return true;
- }
-}
-
-} // namespace
-
-void HloValue::AddLocation(HloInstruction* instruction,
- const ShapeIndex& index) {
- // The given location should not already exist in locations_.
- for (const HloLocation& location : locations_) {
- DCHECK(!(location.instruction == instruction && location.index == index));
- }
-
- locations_.push_back(HloLocation{instruction, index});
-
- // Update uses.
- for (HloInstruction* user : instruction->users()) {
- for (int64 operand_number : user->OperandIndices(instruction)) {
- if (MayUseOperandValue(operand_number, index, user)) {
- for (const HloUse& use : uses_) {
- // Verify that this use does not already exist.
- DCHECK(!(use.instruction == user &&
- use.operand_number == operand_number &&
- use.operand_index == index));
- }
-
- uses_.push_back(HloUse{user, operand_number, index});
- }
- }
- }
-
- // Update liveout status of this HloValue.
- const HloModule& module = *instruction->parent()->parent();
- if (instruction == module.entry_computation()->root_instruction()) {
- live_out_of_module_ = true;
- }
-
- if (instruction == instruction->parent()->root_instruction()) {
- live_out_of_computation_ = true;
- }
-}
-
-void HloValue::RemoveLocation(HloInstruction* instruction,
- const ShapeIndex& index) {
- // The defining location cannot be removed.
- CHECK(!(instruction == defining_instruction() && index == defining_index()));
-
- int64 size_before = locations_.size();
- locations_.erase(
- std::remove_if(locations_.begin(), locations_.end(),
- [instruction, &index](const HloLocation& location) {
- return location.instruction == instruction &&
- location.index == index;
- }),
- locations_.end());
- // Only a single location should have been removed.
- CHECK_EQ(locations_.size(), size_before - 1);
-
- // Update uses which referred to this location.
- uses_.erase(std::remove_if(uses_.begin(), uses_.end(),
- [instruction, &index](const HloUse& use) {
- return use.instruction->operand(
- use.operand_number) == instruction &&
- use.operand_index == index;
- }),
- uses_.end());
-
- // Returns whether this value is contained in the given instruction's output.
- auto is_contained_in = [this](const HloInstruction* instruction) {
- for (const HloLocation& location : locations()) {
- if (location.instruction == instruction) {
- return true;
- }
- }
- return false;
- };
-
- const HloModule& module = *instruction->parent()->parent();
- if (instruction == module.entry_computation()->root_instruction()) {
- // Value has been removed from a location in the entry root instruction.
- live_out_of_module_ =
- is_contained_in(module.entry_computation()->root_instruction());
- }
- if (instruction == defining_instruction()->parent()->root_instruction()) {
- // Value has been removed from the root of the computation the value has
- // been defined in.
- live_out_of_computation_ =
- is_contained_in(defining_instruction()->parent()->root_instruction());
- }
-}
-
-std::ostream& operator<<(std::ostream& out, const HloValue& value) {
- out << value.ToShortString();
- return out;
-}
-
-void HloValueSet::SortAndUniquifyValues() {
- std::sort(value_ids_.begin(), value_ids_.end());
- value_ids_.erase(std::unique(value_ids_.begin(), value_ids_.end()),
- value_ids_.end());
-}
-
-string HloValueSet::ToString() const {
- return StrCat("HloValueSet: ", tensorflow::str_util::Join(value_ids_, ", "));
-}
-
-/*static */
-HloValueSet HloValueSet::Union(
- tensorflow::gtl::ArraySlice<const HloValueSet*> inputs) {
- HloValueSet union_set;
- for (const HloValueSet* input : inputs) {
- for (HloValue::Id value_id : input->value_ids()) {
- union_set.value_ids_.push_back(value_id);
- }
- }
- union_set.SortAndUniquifyValues();
- return union_set;
-}
-
-std::ostream& operator<<(std::ostream& out, const HloValueSet& value_set) {
- out << value_set.ToString();
- return out;
-}
-
-InstructionValueSet InstructionValueSet::Union(
- tensorflow::gtl::ArraySlice<const InstructionValueSet*> inputs) {
- CHECK_GT(inputs.size(), 0);
- for (int i = 1; i < inputs.size(); ++i) {
- CHECK(ShapeUtil::Compatible(inputs[0]->shape(), inputs[i]->shape()));
- }
- InstructionValueSet union_set(inputs[0]->shape());
- union_set.ForEachMutableElement(
- [&inputs](const ShapeIndex& index, HloValueSet* value_set) {
- std::vector<const HloValueSet*> input_sets;
- for (const InstructionValueSet* input : inputs) {
- input_sets.push_back(&input->element(index));
- }
- *value_set = HloValueSet::Union(input_sets);
- });
- return union_set;
-}
-
-std::ostream& operator<<(std::ostream& out,
- const InstructionValueSet& instruction_value_set) {
- out << instruction_value_set.ToString();
- return out;
-}
-
-string InstructionValueSet::ToString() const {
- string out =
- StrCat("InstructionValueSet(", ShapeUtil::HumanString(shape()), ")\n");
- ForEachElement([this, &out](const ShapeIndex& index,
- const HloValueSet& value_set) {
- StrAppend(&out, " ", index.ToString(), " : ", value_set.ToString(), "\n");
- });
- return out;
-}
-
HloDataflowAnalysis::HloDataflowAnalysis(HloModule* module, bool ssa_form,
bool bitcast_defines_value)
: module_(module),