aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/compiler/xla/service/hlo_ordering.cc
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-03-15 14:27:04 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-03-15 14:31:07 -0700
commit002b488dcd9c1eaac4f4aba2ac1301c32c6beb06 (patch)
tree2c3bc504a99d0bc112a55875d678c6dbbe197c3c /tensorflow/compiler/xla/service/hlo_ordering.cc
parent856438f65e5705b373413bce29758a92194ff9b6 (diff)
Fix the HLO alias analysis and copy insertion to cope with the new kConditional instruction.
PiperOrigin-RevId: 189245979
Diffstat (limited to 'tensorflow/compiler/xla/service/hlo_ordering.cc')
-rw-r--r--tensorflow/compiler/xla/service/hlo_ordering.cc42
1 files changed, 37 insertions, 5 deletions
diff --git a/tensorflow/compiler/xla/service/hlo_ordering.cc b/tensorflow/compiler/xla/service/hlo_ordering.cc
index 1b24d8da9e..e89d94bede 100644
--- a/tensorflow/compiler/xla/service/hlo_ordering.cc
+++ b/tensorflow/compiler/xla/service/hlo_ordering.cc
@@ -66,6 +66,28 @@ bool HloOrdering::ExecutesBefore(const HloInstruction* a,
}
}
+ // If the common ancestor is a conditional instruction, even though the true
+ // and false computations are not really ordered per-se, we define the true
+ // computation to be ordered before the false one.
+ // This ensures that buffers can still be shared among the two computations
+ // as they will forcibly have disjoint liveness.
+ if (a_ancestor == b_ancestor &&
+ a_ancestor->opcode() == HloOpcode::kConditional) {
+ const HloComputation* true_computation = a_ancestor->true_computation();
+ const HloComputation* false_computation = a_ancestor->false_computation();
+ if (call_graph_->InstructionIsNestedIn(a, true_computation) &&
+ call_graph_->InstructionIsNestedIn(b, false_computation)) {
+ return true;
+ }
+ // If 'b' is the conditional ancestor, and 'a' is within the true or false
+ // computations, 'a' executes before 'b'.
+ if (b == a_ancestor &&
+ (call_graph_->InstructionIsNestedIn(a, true_computation) ||
+ call_graph_->InstructionIsNestedIn(a, false_computation))) {
+ return true;
+ }
+ }
+
return ExecutesBeforeInSameComputation(a_ancestor, b_ancestor);
}
@@ -118,7 +140,18 @@ bool HloOrdering::IsDefinedBefore(const HloValue& a, const HloValue& b) const {
b.defining_instruction()->while_condition()))) {
return true;
}
-
+ // If 'b' is a conditional phi and 'a' is in the true or false computation,
+ // then 'a' executes before 'b'.
+ if (b.is_phi() &&
+ b.defining_instruction()->opcode() == HloOpcode::kConditional &&
+ (call_graph_->InstructionIsNestedIn(
+ a.defining_instruction(),
+ b.defining_instruction()->true_computation()) ||
+ call_graph_->InstructionIsNestedIn(
+ a.defining_instruction(),
+ b.defining_instruction()->false_computation()))) {
+ return true;
+ }
return ExecutesBefore(a.defining_instruction(), b.defining_instruction());
}
@@ -212,18 +245,17 @@ bool HloOrdering::LiveRangeStrictlyBefore(
VLOG(4) << "LiveRangeStrictlyBefore(a = " << a.ToShortString()
<< ", b = " << b.ToShortString() << ")";
if (!IsDefinedBefore(a, b)) {
- VLOG(4) << "a not defined before b";
+ VLOG(4) << a << " not defined before " << b;
return false;
}
-
// All uses of 'a' must be before 'b' is defined.
for (const HloUse& use : a.uses()) {
if (!UseIsBeforeValueDefinition(use, b, dataflow)) {
- VLOG(4) << "use of a (" << use << ") not before b is defined";
+ VLOG(4) << "use of " << a << " (" << use << ") not before " << b
+ << " is defined";
return false;
}
}
-
return true;
}