message: Sort the control_inputs edges when converting graph to function def
  This ensures that semantically equivalent graphs always convert to identical FunctionDef. In TPUCompileOp, the compilation cache key includes the fingerprint of the function library run time. Thus, the consistency in the FunctionDef from equivalent graphs avoids unnecessary recompilations in TPUCompileOp.
diff: @@ -208,10 +208,18 @@ Status GraphToFunctionDef(const Graph& graph, const string& name,
  node_def->add_input(
  strings::StrCat(edge->src()->name(), ":", edge->src_output()));
  }
  -
  // Add control inputs
  + std::vector<std::string> control_inputs;
  + control_inputs.reserve(control_edges.size());
  for (const Edge* edge : control_edges) {
  - node_def->add_input(strings::StrCat("^", edge->src()->name()));
  + control_inputs.push_back(strings::StrCat("^", edge->src()->name()));
  + }
  + // Sort the control inputs so that nodes that are semantically equivalent
  + // generate idential node_def.
  + std::sort(control_inputs.begin(), control_inputs.end());
  +
  + for (const auto& input : control_inputs) {
  + node_def->add_input(input);
  }
  // Populate tensor_renaming.
  