Estou tentando entender melhor o que seria necessário para um compilador ser capaz de fazer escolhas inteligentes em relação à simultaneidade em nome do programador. Percebo que há muitos aspectos difíceis desse problema, por exemplo:
- Garantir que não haja condições de corrida
Garantir que o código seja executado simultaneamente não terá efeitos colaterais que afetam o significado semântico do código
Decidindo se a sobrecarga de girar threads vale a pena, dado o grau de paralelismo disponível no código
Meu entendimento é que as duas principais representações intermediárias usadas em compiladores modernos são atribuição única estática para linguagens procedurais e orientadas a objetos e continuações passando estilo para linguagens funcionais. Raciocinar sobre qualquer um dos problemas listados acima parece difícil usando essas formas intermediárias. Mesmo as linguagens que, em teoria, deveriam ter a melhor chance de paralelização automática (linguagens funcionais puras como Haskell, com garantia de nenhum efeito colateral), fizeram progressos limitados nessa frente.
Então, minha pergunta é realmente que representações intermediárias foram usadas para tentar resolver esse problema? Existem outras representações que foram usadas na pesquisa acadêmica que eu não conheço e que são mais adequadas para essa tarefa? Esse é um problema que fundamentalmente precisa ser resolvido pelo front end do compilador, manipulando a árvore de sintaxe abstrata antes que a compilação alcance uma representação intermediária?