Как выяснилось, WordPress Popular Posts не дружит с Polylang. Лечится это одним ударом молотка по файлу wordpress-popular-posts.php

// WPML support, get original post/page ID
if ( defined('ICL_LANGUAGE_CODE') && function_exists('icl_object_id') ) {
	$id = pll_get_post( $id, 'en' ); # вместо того, что было
}

В результате:
во-первых, подсчет таки начинает работать;
во-вторых, просмотры считаются суммарно по всем языковым версиям записи. В виджете выводится ссылка на запись на текущем языке.

UPD Для «асимметричных» сайтов в районе 1722 строки перед Build query добавить

$current_language = pll_current_language();
$current_language_tt_id = $wpdb->get_var("
  SELECT tt.term_taxonomy_id
  FROM $wpdb->terms as t
  LEFT JOIN $wpdb->term_taxonomy as tt USING (term_id)
  WHERE t.slug = '$current_language'
");
$from .= " LEFT JOIN $wpdb->term_relationships as lang ON (lang.object_id = p.ID)";
$where .= " AND lang.term_taxonomy_id = '$current_language_tt_id'";

UPD 2 В WPP 4+ уже есть фильтры, так что можно обойтись без грязного хака.

add_filter( 'wpp_query_join', 'polylang_wpp_query_join' );
function polylang_wpp_query_join( $join ) {
	global $wpdb;
	$join .= " LEFT JOIN $wpdb->term_relationships as lang ON (lang.object_id = p.ID)";
	return $join;
}

add_filter( 'wpp_query_where', 'polylang_wpp_query_where' );
function polylang_wpp_query_where( $where ) {
	global $wpdb;
	$current_language = pll_current_language();
	$current_language_tt_id = $wpdb->get_var("
		SELECT tt.term_taxonomy_id
		FROM $wpdb->terms as t
		LEFT JOIN $wpdb->term_taxonomy as tt USING (term_id)
		WHERE t.slug = '$current_language'
	");
	$where = str_replace("p.post_type IN(%s)", "p.post_type = 'post'", $where); # костыль # при наличии фильтра с какого-то бодуна не выполняется prepare
	$where .= " AND lang.term_taxonomy_id = '$current_language_tt_id'";
	return $where;
}

Опубликовано в рамках программы “Антисклероз”.