private void connectTerminalOps(ParseContext pCtx) {
    // The map which contains the virtual edges from non-semijoin terminal ops to semjoin RSs.
    Multimap<TerminalOperator<?>, ReduceSinkOperator> terminalOpToRSMap = ArrayListMultimap.create();

    // Map of semijoin RS to work ops to ensure no work is examined more than once.
    Map<ReduceSinkOperator, TerminalOpsInfo> rsToTerminalOpsInfo = new HashMap<>();

    // Get all the terminal ops
    for (ReduceSinkOperator rs : pCtx.getRsToSemiJoinBranchInfo().keySet()) {
      TerminalOpsInfo terminalOpsInfo = rsToTerminalOpsInfo.get(rs);
      if (terminalOpsInfo != null) {
        continue; // done with this one
      }

      Set<ReduceSinkOperator> workRSOps = new HashSet<>();
      Set<TerminalOperator<?>> workTerminalOps = new HashSet<>();
      // Get the SEL Op in the semijoin-branch, SEL->GBY1->RS1->GBY2->RS2
      SelectOperator selOp = OperatorUtils.ancestor(rs, SelectOperator.class, 0, 0, 0, 0);
      OperatorUtils.findWorkOperatorsAndSemiJoinEdges(selOp,
              pCtx.getRsToSemiJoinBranchInfo(), workRSOps, workTerminalOps);

      TerminalOpsInfo candidate = new TerminalOpsInfo(workTerminalOps);

      // A work may contain multiple semijoin edges, traverse rsOps and add for each
      for (ReduceSinkOperator rsFound : workRSOps) {
        rsToTerminalOpsInfo.put(rsFound, candidate);
        for (TerminalOperator<?> terminalOp : candidate.terminalOps) {
          terminalOpToRSMap.put(terminalOp, rsFound);
        }
      }
    }

    pCtx.setTerminalOpToRSMap(terminalOpToRSMap);
  }
TezCompiler translates the operator plan into TezTasks.
ql/src/java/org/apache/hadoop/hive/ql/parse/TezCompiler.java