void qGoBoardLocalInterface::slot_passComputer()
{
    doPass();
    boardwindow->getBoardHandler()->updateMove(tree->getCurrent());
    if (tree->getCurrent()->parent->isPassMove())
        enterScoreMode();
    else
        checkComputersTurn();
}
/*
 * sends a "pass" move to GTP
 */
void qGoBoardLocalInterface::sendPassToInterface(StoneColor c)
{
    doPass();
    boardwindow->getBoardHandler()->updateMove(tree->getCurrent());

    // if simple pass, tell computer and move on
    switch (c)
    {
        case stoneWhite :
        if (gtp->playwhitePass())
        {
            QMessageBox::warning(boardwindow, PACKAGE, tr("Failed to pass within program \n") + gtp->getLastMessage());
            return;
        }
        else
            qDebug("comp notified of white pass");
    //	if (win->blackPlayerType==COMPUTER)
    //		playComputer(c);

        break;

        case stoneBlack :
        if (gtp->playblackPass())
        {
            QMessageBox::warning(boardwindow, PACKAGE, tr("Failed to pass within program \n") + gtp->getLastMessage());
            return;
        }

//		if (win->whitePlayerType==COMPUTER)
//			playComputer(c);
        break;

        default :
        ;
    }
    if (tree->getCurrent()->parent->isPassMove())
        enterScoreMode();
    else
        checkComputersTurn();
}
Exemple #3
0
void qGoBoardNetworkInterface::handleMove(MoveRecord * m)
{
    // This handles territory marks provided by the server.
    /* Separate handling is needed because we want to
     * avoid GUI updates until the full information is available.
     * The remaining part of the function should in principle also be rewritten in such a way that
     * GUI updates are only made when needed. */
    if (m->flags == MoveRecord::TERRITORY)
    {
        tree->getCurrent()->getMatrix()->insertMark(m->x,m->y,m->color == stoneBlack ? markTerrBlack : markTerrWhite);
        return;
    } else if (m->flags == MoveRecord::DONE_SCORING)
    {
        tree->countMarked();
        tree->setCurrent(tree->getCurrent()); // Updates GUI
        return;
    }

	int move_number, move_counter, handicap;
	Move * remember, * last;
	Move * goto_move;
	//static bool offset_1 = false;
	int i;
	
	dontsend = false;		//clear the dontsend bit
	
	/* In case we join in score phase */
	if(m->flags == MoveRecord::NONE && boardwindow->getGamePhase() == phaseScore)
		m->flags = MoveRecord::REMOVE;

	remember = tree->getCurrent();
	
	if(boardwindow->getGameData()->gameMode == modeReview)
	{
		if(!reviewCurrent)
			reviewCurrent = tree->findLastMoveInMainBranch();
		last = reviewCurrent;
	}
	else
		last = tree->findLastMoveInMainBranch();
	tree->setCurrent(last);

	move_number = m->number;
	//bool hcp_move = tree->getCurrent()->isHandicapMove();
	move_counter = tree->getCurrent()->getMoveNumber();
	if(move_number == NOMOVENUMBER)	//not all services number
		move_number = move_counter + 1;		//since we add one to move counter later
	
	//qDebug("MN: %d MC: %d", move_number, move_counter);
	
	handicap = boardwindow->getGameData()->handicap;

	/* This is insanely ugly: setHandicap should properly update the
	 * move counter */
	//if(handicap)
	//	move_counter++;
	//if(offset_1)
	move_counter++;
		
	switch(m->flags)
    {
		case MoveRecord::UNDO_TERRITORY:
		{
            int boardsize = last->getMatrix()->getSize();
            for(int i = 1; i <= boardsize; i++)
			{
                for(int j = 1; j <= boardsize; j++)
				{
                    if(last->getMatrix()->isStoneDead(i, j))
                        markLiveStone(i, j);
				}
			}
			break;
		}
		case MoveRecord::REQUESTUNDO:
		{
			qDebug("Got undo message in network interface!!\n");
			BoardDispatch * dispatch = boardwindow->getBoardDispatch();
			//move_number = mv_counter - 1;
			QString opp = dispatch->getOpponentName();
			UndoPrompt * up = new UndoPrompt(&opp,
							 dispatch->supportsMultipleUndo(),
							 m->number);
			
			int up_return = up->exec();
			if (up_return != -1)
			{
				dispatch->sendMove(new MoveRecord(m->number, MoveRecord::UNDO));
			}
			else
			{
				dispatch->sendMove(new MoveRecord(m->number, MoveRecord::REFUSEUNDO));
			}
		}
			break;
		case MoveRecord::UNDO:
			{
			/* Are we supposed to make a brother node or something ??? FIXME 
			* qgoboard.cpp also does this.*/
			BoardDispatch * dispatch = boardwindow->getBoardDispatch();
			if(dispatch->supportsMultipleUndo())
			{
				while(move_counter > move_number + 1)	//move_numbe r+ 1 if our turn?
				{
					tree->undoMove();
                    move_counter--;
				}
			}
			else
			{
				tree->undoMove();
				if ((getBlackTurn() && m->color == stoneBlack) ||
					((!getBlackTurn()) && m->color == stoneWhite))
                {
					tree->undoMove();
				}
			}
			/* I've turned off multiple undo for tygem, just for now... 
			 * since NOMOVENUMBER FIXME, actually I'm not sure if tygem
			 * has a normal multiple undo, though it might for review games */
			qDebug("Undoing move %d = %d - 1", move_number, move_counter);
			/* FIXME This can get screwy especially around the scoreMode
			 * stuff.... apparently we can only undo our own passes
			 * unlike other WING moves and it only takes 2 undos, not
			 * 3... as if the first undo just gets you out of the 
			 * score place. */
			if(boardwindow->getGamePhase() == phaseScore)
			{
				/* Not sure if this is always true, but it appears
				 * that the last pass doesn't count as a move or
				 * something, meaning that we should delete twice
				 * for it. This is going to be a problem later
				 * FIXME FIXME FIXME*/
				/* IGS does not leave score mode, ever !!!
				 * nor should anything else do to what scoremode
				 * does. Simply clears some of the dead marks*/
				/* Actually, I'm not sure, its possible that the
				 * glGo client we've been using to test this
				 * doesn't handle undo from score very well.  I've
				 * seen some bugs in it before. */
				tree->undoMove();
				leaveScoreMode();
			}
			}
			break;
		case MoveRecord::PASS:
			/* FIXME what about a kibitz here saying opponent name
			 * has passed.  I think IGS needs it, not sure about
			 * other protocols which may have it, but if they do,
			 * it should be moved here.  Otherwise easy to miss. */
			/* If there's three passes, we should stop the clock,
			 * although some servers might have two pass models
			 * and we need a flag for that */
			//if(!boardwindow->getMyColorIsBlack())	//if we're white
			if(!boardwindow->getBoardDispatch()->netWillEnterScoreMode())	//ugly for oro FIXME
			{
				if(boardwindow->getBoardDispatch()->twoPassesEndsGame())
				{
                    if(last->isPassMove())
						enterScoreMode();
				}
				else
				{
                    if(last->parent &&
                    last->isPassMove() &&
                    last->parent->isPassMove())
						enterScoreMode();
						//boardwindow->setGamePhase ( phaseScore );	//okay?	
				}
			}
			//FIXME potentially white/black here should come from color from network which is unreliable now
            kibitzReceived(QString(getBlackTurn() ? "Black" : "White") + " passes.");
			doPass();
			break;
		case MoveRecord::HANDICAP:
			handicap = boardwindow->getGameData()->handicap;
			//if(!handicap)
			//{
				/* Double usage of x is a little ugly */
				setHandicap(m->x);
			//}
			break;
		case MoveRecord::REMOVE:
			//qDebug("md!! toggling life of %d %d", m->x, m->y);
            markDeadStone(m->x, m->y);
			//tree->getCurrent()->getMatrix()->toggleGroupAt(m->x, m->y);
			//boardwindow->qgoboard->kibitzReceived("removing @ " + pt);
			break;
		case MoveRecord::REMOVE_AREA:
			//FIXME
            markDeadArea(m->x, m->y);
			break;
		case MoveRecord::UNREMOVE_AREA:
			//FIXME
			if(boardwindow->getBoardDispatch()->unmarkUnmarksAllDeadStones())
			{
				/* Not sure where we get the dead groups from, FIXME 
				 * okay, really, we should have a list of dead groups
				 * for each player that can be checked on here.
				 * The thing is, ORO also has such a list that it tracks
				 * and I don't want duplication of that code but right
				 * now I have other things on my mind and I just want to
				 * get this done, so I'm going to do something really
				 * quick, dirty, and awkward here and I'll fix it in
				 * a later version... ignoring the stitch in time
				 * thing.  So cut this out soon.  Note also that it
				 * might make sense to have an evaluation function
				 * in the board code, to do something to every
				 * stone of a type... maybe not.*/
                int boardsize = last->getMatrix()->getSize();
                for(int i = 1; i <= boardsize; i++)
				{
                    for(int j = 1; j <= boardsize; j++)
					{
                        if(last->getMatrix()->isStoneDead(i, j))
						{
                            if(last->getMatrix()->getStoneAt(i, j) == m->color)
							{
                                markLiveArea(i, j);
							}
						}
					}
				}
				
			}
			else
                markLiveArea(m->x, m->y);
			break;
        case MoveRecord::REFUSEUNDO:
			//handled by protocol as a recvKibitz for whatever reason
			break;
		case MoveRecord::FORWARD:
            if(!boardwindow->getBoardDispatch()->getReviewInVariation() && tree->isInMainBranch(last))
			{
				/* In case it was in a variation previously to remove the marker.
				 * this should be elsewhere like on the setReviewInVariation(); FIXME */
                last->marker = NULL;
			}
			for(i = 0; i < move_number; i++)
			{
				/*if(boardwindow->getBoardDispatch()->getReviewInVariation() && tree->isInMainBranch(tree->getCurrent()))
				{
					boardwindow->getBoardHandler()->gotoMove(inVariationBranch);
				}
				else*/
                    tree->slotNavForward();
			}
			break;
		case MoveRecord::BACKWARD:
			for(i = 0; i < move_number; i++)
			{
                if(boardwindow->getBoardDispatch()->getReviewInVariation() && last && tree->isInMainBranch(last))
					break;
                tree->slotNavBackward();
			}
			break;
		case MoveRecord::RESETBRANCH:
		case MoveRecord::DELETEBRANCH:
            goto_move = last;
			if(goto_move->getMoveNumber() > lastMoveInGame->getMoveNumber())
				goto_move = lastMoveInGame;
			else
			{
				while(!tree->isInMainBranch(goto_move))
					goto_move = goto_move->parent;
			}
            tree->setCurrent(goto_move);
			if(m->flags == MoveRecord::DELETEBRANCH) {}
				
			break;
		case MoveRecord::RESETGAME:
			goto_move = tree->getRoot();
            tree->setCurrent(goto_move);
			break;
		case MoveRecord::TOEND:
			if(boardwindow->getBoardDispatch()->getReviewInVariation())
				goto_move = tree->findLastMoveInCurrentBranch();
			else
				goto_move = lastMoveInGame;
            tree->setCurrent(goto_move);
			break;
		case MoveRecord::SETMOVE:
			/* Might later want to record this
			 * also we should have already set the game to the last move and disabled nav*/
			goto_move = tree->findNode(tree->getRoot(), m->number);

			if (goto_move)
                tree->setCurrent(goto_move);
			else
			{
				QMessageBox::warning(boardwindow, tr("Invalid Move"), tr("Cannot set move to move number %1").arg(m->number));
			}
			break;
		default:
		case MoveRecord::NONE:
			
			if(move_number == move_counter)
			{
				/* FIXME Can we guess at the color here ? */
				if(m->color == stoneNone)
					m->color = (getBlackTurn() ? stoneBlack : stoneWhite);
                if (doMove(m->color, m->x, m->y) == NULL)
					QMessageBox::warning(boardwindow, tr("Invalid Move"), tr("The incoming move %1 %2 seems to be invalid").arg(QString::number(m->x), QString::number(m->y)));
				else if(m->color == stoneWhite && !boardTimerId)  //awkward ?  FIXME for always move 1?
				{
					onFirstMove();
				}
			}
			else if(move_number < move_counter)
			{
				/* FIXME, this prevents the next if statement
				* partly, this whole thing is screwy */
				/* IGS, certain games have this remove a legit first
				 * move */
				qDebug("Repeat move after undo?? %d %d", move_number, move_counter);
			}
			/* This is for resetting the stones for canadian
			 * timesystems, its awkward for it to be here...  but
			 * I guess I'm getting lazy. FIXME */
			/* I don't think this matters for ORO because time
			 * comes in right after move.  It might matter for IGS */
			/* For stones, this should be called before the move is sent or here
			 * but with getBlackTurn() negated.  Otherwise, its like our move
			 * gets decremented possibly when they play.  It looks weird... double
			 * check with other time style though. */
			boardwindow->getClockDisplay()->rerackTime(getBlackTurn());
			break;
	}
	
	if(boardwindow->getGameData()->gameMode == modeReview)	//for now review mode means no navigation, see interfacehandler comment
		reviewCurrent = tree->getCurrent();
	else
	{
		if (remember != last)
		{
            tree->setCurrent(remember);
		}
    }
}
Exemple #4
0
SocketConnection *LoadBalancer::newClient(int fd, const char *, uint16_t,
                                          ServerSocket *srv) {
    doPass(fd, nextWorker(), srv);
    rotateNextWorker();
    return nullptr;
}
Exemple #5
0
void optimize(IRUnit& unit, TransKind kind) {
  Timer timer(Timer::optimize, unit.logEntry().get_pointer());

  assertx(checkEverything(unit));

  fullDCE(unit);
  printUnit(6, unit, " after initial DCE ");
  assertx(checkEverything(unit));

  if (RuntimeOption::EvalHHIRPredictionOpts) {
    doPass(unit, optimizePredictions, DCE::None);
  }

  if (RuntimeOption::EvalHHIRSimplification) {
    doPass(unit, simplifyPass, DCE::Full);
    doPass(unit, cleanCfg, DCE::None);
  }

  if (RuntimeOption::EvalHHIRGlobalValueNumbering) {
    doPass(unit, gvn, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeLoads, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeStores, DCE::Full);
  }

  if (RuntimeOption::EvalHHIRPartialInlineFrameOpts) {
    doPass(unit, optimizeInlineReturns, DCE::Full);
  }

  doPass(unit, optimizePhis, DCE::Full);

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) {
    doPass(unit, optimizeRefcounts, DCE::Full);
  }

  if (RuntimeOption::EvalHHIRLICM && cfgHasLoop(unit) &&
      kind != TransKind::Profile) {
    doPass(unit, optimizeLoopInvariantCode, DCE::Minimal);
  }

  doPass(unit, simplifyOrdStrIdx, DCE::Minimal);

  doPass(unit, removeExitPlaceholders, DCE::Full);

  if (RuntimeOption::EvalHHIRGenerateAsserts) {
    doPass(unit, insertAsserts, DCE::None);
  }

  // Perform final cleanup passes to collapse any critical edges that were
  // split, and simplify our instructions before shipping off to codegen.
  doPass(unit, cleanCfg, DCE::None);

  if (kind != TransKind::Profile &&
      RuntimeOption::EvalHHIRGlobalValueNumbering) {
    doPass(unit, gvn, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRSimplification) {
    doPass(unit, simplifyPass, DCE::Full);
  }

  doPass(unit, fixBlockHints, DCE::None);
}
Exemple #6
0
void Pass::render() {
  //doPass(0, 0, numFrames);
  if (threadMethod == "tm1") {
    std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
    std::vector<std::thread> threads;

    if (ioMethod == "tio") {
      images.clear();
      physicalAddresses.clear();
      images.resize(numFrames);
      physicalAddresses.resize(numFrames);
    }

    int threadWorkload = 0;
    int remainder = 0;

    threadWorkload = numFrames / threadCount;

    if (numFrames % threadCount != 0) {
      remainder = numFrames - (threadWorkload * (threadCount - 1));
    }

    for (int i = 0; i < threadCount; i++) {
      if (i == threadCount - 1 && remainder > 0) {
        threads.push_back(std::thread(&Pass::threadedDoPass, this, i, (passIndex * numFrames), i * threadWorkload, (i * threadWorkload) + remainder));
      }
      else {
        threads.push_back(std::thread(&Pass::threadedDoPass, this, i, (passIndex * numFrames), i * threadWorkload, (i * threadWorkload) + threadWorkload));
      }
    }

    for (int i = 0; i < threadCount; i++) {
      threads[i].join();
    }

    if (ioMethod == "tio") {
      threads.clear();

      for (int i = 0; i < threadCount; i++) {
        if (i == threadCount - 1 && remainder > 0) {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + remainder));
        }
        else {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + threadWorkload));
        }
      }

      for (int i = 0; i < threadCount; i++) {
        threads[i].join();
      }
    }

    std::chrono::time_point<std::chrono::system_clock> endTime = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_time = endTime - start;
    total_elapsed_time += elapsed_time;
  }
  else if (threadMethod == "fi") {
    if (ioMethod == "tio") {
      images.clear();
      physicalAddresses.clear();
      images.resize(numFrames);
      physicalAddresses.resize(numFrames);
    }

    fiberDoPass(passIndex * numFrames, 0, numFrames);

    if (ioMethod == "tio") {
      std::chrono::time_point<std::chrono::system_clock> savingStart = std::chrono::system_clock::now();
      std::vector<std::thread> threads;

      int threadWorkload = 0;
      int remainder = 0;

      threadWorkload = numFrames / threadCount;

      if (numFrames % threadCount != 0) {
        remainder = numFrames - (threadWorkload * (threadCount - 1));
      }

      for (int i = 0; i < threadCount; i++) {
        if (i == threadCount - 1 && remainder > 0) {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + remainder));
        }
        else {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + threadWorkload));
        }
      }

      for (int i = 0; i < threadCount; i++) {
        threads[i].join();
      }
      std::chrono::time_point<std::chrono::system_clock> endTime = std::chrono::system_clock::now();
      std::chrono::duration<double> elapsed_time = endTime - savingStart;
      total_elapsed_time += elapsed_time;
    }
  }
  else {
    if (ioMethod == "tio") {
      images.clear();
      physicalAddresses.clear();
      images.resize(numFrames);
      physicalAddresses.resize(numFrames);
    }

    doPass(passIndex * numFrames, 0, numFrames);

    if (ioMethod == "tio") {
      std::chrono::time_point<std::chrono::system_clock> savingStart = std::chrono::system_clock::now();
      std::vector<std::thread> threads;

      int threadWorkload = 0;
      int remainder = 0;

      threadWorkload = numFrames / threadCount;

      if (numFrames % threadCount != 0) {
        remainder = numFrames - (threadWorkload * (threadCount - 1));
      }

      for (int i = 0; i < threadCount; i++) {
        if (i == threadCount - 1 && remainder > 0) {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + remainder));
        }
        else {
          threads.push_back(std::thread(&threadedFileSave, (passIndex * numFrames) + (i * threadWorkload), std::ref(directory), i * threadWorkload, (i * threadWorkload) + threadWorkload));
        }
      }

      for (int i = 0; i < threadCount; i++) {
        threads[i].join();
      }
      std::chrono::time_point<std::chrono::system_clock> endTime = std::chrono::system_clock::now();
      std::chrono::duration<double> elapsed_time = endTime - savingStart;
      total_elapsed_time += elapsed_time;
    }
  }
}
Exemple #7
0
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) {
  Timer timer(Timer::optimize);

  assertx(checkEverything(unit));

  auto const hasLoop = RuntimeOption::EvalJitLoops && cfgHasLoop(unit);
  auto const func = unit.entry()->front().marker().func();
  auto const regionMode = pgoRegionMode(*func);
  auto const traceMode = kind != TransKind::Optimize ||
                         regionMode == PGORegionMode::Hottrace;

  // TODO (#5792564): Guard relaxation doesn't work with loops.
  // TODO (#6599498): Guard relaxation is broken in wholecfg mode.
  if (shouldHHIRRelaxGuards() && !hasLoop && traceMode) {
    Timer _t(Timer::optimize_relaxGuards);
    const bool simple = kind == TransKind::Profile &&
                        (RuntimeOption::EvalJitRegionSelector == "tracelet" ||
                         RuntimeOption::EvalJitRegionSelector == "method");
    RelaxGuardsFlags flags = (RelaxGuardsFlags)
      (RelaxReflow | (simple ? RelaxSimple : RelaxNormal));
    auto changed = relaxGuards(unit, *irBuilder.guards(), flags);
    if (changed) {
      printUnit(6, unit, "after guard relaxation");
      mandatoryDCE(unit);  // relaxGuards can leave unreachable preds.
    }

    if (RuntimeOption::EvalHHIRSimplification) {
      doPass(unit, simplifyPass, DCE::Minimal);
      doPass(unit, cleanCfg, DCE::None);
    }
  }

  fullDCE(unit);
  printUnit(6, unit, " after initial DCE ");
  assertx(checkEverything(unit));

  if (RuntimeOption::EvalHHIRTypeCheckHoisting) {
    doPass(unit, hoistTypeChecks, DCE::None);
  }

  if (RuntimeOption::EvalHHIRPredictionOpts) {
    doPass(unit, optimizePredictions, DCE::None);
  }

  if (RuntimeOption::EvalHHIRSimplification) {
    doPass(unit, simplifyPass, DCE::Full);
    doPass(unit, cleanCfg, DCE::None);
  }

  if (RuntimeOption::EvalHHIRGlobalValueNumbering) {
    doPass(unit, gvn, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeLoads, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeStores, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) {
    doPass(unit, optimizeRefcounts2, DCE::Full);
  }

  if (RuntimeOption::EvalHHIRLICM) {
    if (kind != TransKind::Profile && hasLoop) {
      // The clean pass is just to stress lack of pre_headers for now, since
      // LICM is a disabled prototype pass.
      doPass(unit, cleanCfg, DCE::None);
      doPass(unit, optimizeLoopInvariantCode, DCE::Minimal);
    }
  }
  doPass(unit, removeExitPlaceholders, DCE::Full);

  if (RuntimeOption::EvalHHIRGenerateAsserts) {
    doPass(unit, insertAsserts, DCE::None);
  }
}
Exemple #8
0
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) {
  Timer timer(Timer::optimize);

  assertx(checkEverything(unit));

  fullDCE(unit);
  printUnit(6, unit, " after initial DCE ");
  assertx(checkEverything(unit));

  if (RuntimeOption::EvalHHIRTypeCheckHoisting) {
    doPass(unit, hoistTypeChecks, DCE::Minimal);
  }

  if (RuntimeOption::EvalHHIRPredictionOpts) {
    doPass(unit, optimizePredictions, DCE::None);
  }

  if (RuntimeOption::EvalHHIRSimplification) {
    doPass(unit, simplifyPass, DCE::Full);
    doPass(unit, cleanCfg, DCE::None);
  }

  if (RuntimeOption::EvalHHIRGlobalValueNumbering) {
    doPass(unit, gvn, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeLoads, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRMemoryOpts) {
    doPass(unit, optimizeStores, DCE::Full);
  }

  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRRefcountOpts) {
    doPass(unit, optimizeRefcounts2, DCE::Full);
  }

  if (RuntimeOption::EvalHHIRLICM && RuntimeOption::EvalJitLoops &&
      cfgHasLoop(unit) && kind != TransKind::Profile) {
    doPass(unit, optimizeLoopInvariantCode, DCE::Minimal);
  }

  doPass(unit, removeExitPlaceholders, DCE::Full);

  if (RuntimeOption::EvalHHIRGenerateAsserts) {
    doPass(unit, insertAsserts, DCE::None);
  }

  // Perform final cleanup passes to collapse any critical edges that were
  // split, and simplify our instructions before shipping off to codegen.
  doPass(unit, cleanCfg, DCE::None);
  if (kind != TransKind::Profile && RuntimeOption::EvalHHIRSimplification) {
    doPass(unit, simplifyPass, DCE::Full);
  }
}