2015-10-07 3 views
0

Lorsque vous utilisez un nœud phi dans un bloc de base, il y a un ordre suggéré dans lequel je devrais placer les étiquettes s'il y a une probabilité plus élevée que le prédécesseur soit un certain bloc. Par exemple, prenez la fonction factorielle simple listée ci-dessous.LLVM Position IR des étiquettes de blocs prédécesseurs dans l'instruction de nœud phi

define private i64 @fact(i64 %start) { 
entry: 
    %0 = icmp sle i64 1, %start 
    br i1 %0, label %loop, label %endcond 

loop:            ; preds = %loop, %entry 
    %1 = phi i64 [ %res, %loop ], [ 1, %entry ]  ; if %start > 2 predecessor 
    %2 = phi i64 [ %3, %loop ], [ %start, %entry ] ; is likely %loop 
    %res = mul i64 %1, %2 
    %3 = sub i64 %2, 1 
    %cond = icmp sle i64 1, %3 
    br i1 %cond, label %loop, label %endcond 

endcond:           ; preds = %loop, %entry 
    %fin = phi i64 [ %res, %loop ], [ 1, %entry ] ; highly unlikely 
    ret i64 %fin          ; predecessor is %entry 
} 

Bien qu'il soit possible que l'utilisateur entrée @fact(1) il est peu probable, donc je pense dans la plupart des cas, le bloc prédécesseur pour le noeud phi dans endcond à être post.loop. Telle est mon hypothèse que, dans ce cas

%fin = phi i64 [ %res, %post.loop ], [ 1, %entry ] 

est mieux que

%fin = phi i64 [ 1, %entry ], [ %res, %post.loop ] 

correcte? Et si oui, pourquoi ou pourquoi pas?

Répondre

1

Cela ne fait pas de différence. LLVM fera une analyse sur votre code pour estimer les probabilités de branchement, et il l'utilise pour ordonner le bloc résultant.

Vous pouvez influencer cela en utilisant les métadonnées de poids de la branche: http://llvm.org/docs/BlockFrequencyTerminology.html

+0

Merci! Réponse fantastique! Le lien suivant sur [Métadonnées de poids de branche] (http://llvm.org/docs/BranchWeightMetadata.html) que j'ai trouvé sur le lien que vous avez donné était également très instructif –